[
  {
    "path": ".gitattributes",
    "content": "\n\n*.c text eol=lf\n\n"
  },
  {
    "path": ".github/workflows/unittests.yml",
    "content": "name: masscan unit tests\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [master]\n\npermissions:\n  contents: read\n\njobs:\n  regress:\n    name: Run regression tests\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest]\n    steps:\n      - name: Checkout masscan\n        uses: actions/checkout@v3\n      - name: Install libpcap-dev\n        if: ${{ vars.RUNNER_OS == 'Linux' }}\n        run: sudo apt-get install -y libpcap-dev\n      - name: Run regression tests\n        run: make test\n"
  },
  {
    "path": ".gitignore",
    "content": "paused.conf\r\n.Makefile.swp\r\n.vscode\r\nvs10/.vs/\r\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "Makefile",
    "content": "# If Windows, then assume the compiler is `gcc` for the\n# MinGW environment. I can't figure out how to tell if it's\n# actually MingGW. FIXME TODO\nifeq ($(OS),Windows_NT)\n    CC = gcc\nendif\n\n# Try to figure out the default compiler. I dont know the best\n# way to do this with `gmake`. If you have better ideas, please\n# submit a pull request on github.\nifeq ($(CC),)\nifneq (, $(shell which clang))\nCC = clang\nelse ifneq (, $(shell which gcc))\nCC = gcc\nelse\nCC = cc\nendif\nendif\n\nPREFIX ?= /usr\nBINDIR ?= $(PREFIX)/bin\nSYS := $(shell $(CC) -dumpmachine)\nGITVER := $(shell git describe --tags)\nINSTALL_DATA := -pDm755\n\nifeq ($(GITVER),)\nGITVER = \"unknown\"\nendif\n\n# LINUX\n# The automated regression tests run on Linux, so this is the one\n# environment where things likely will work -- as well as anything\n# works on the bajillion of different Linux environments\nifneq (, $(findstring linux, $(SYS)))\nifneq (, $(findstring musl, $(SYS)))\nLIBS = \nelse\nLIBS = -lm -lrt -ldl -lpthread\nendif\nINCLUDES =\nFLAGS2 = \nendif\n\n# MAC OS X\n# I occassionally develope code on Mac OS X, but it's not part of\n# my regularly regression-test environment. That means at any point\n# in time, something might be minorly broken in Mac OS X.\nifneq (, $(findstring darwin, $(SYS)))\nLIBS = -lm \nINCLUDES = -I.\nFLAGS2 = \nINSTALL_DATA = -pm755\nendif\n\n# MinGW on Windows\n# I develope on Visual Studio 2010, so that's the Windows environment\n# that'll work. However, 'git' on Windows runs under MingGW, so one\n# day I acccidentally typed 'make' instead of 'git, and felt compelled\n# to then fix all the errors, so this kinda works now. It's not the\n# intended environment, so it make break in the future.\nifneq (, $(findstring mingw, $(SYS)))\nINCLUDES = -Ivs10/include\nLIBS = -L vs10/lib -lIPHLPAPI -lWs2_32\n#FLAGS2 = -march=i686\nendif\n\n# Cygwin\n# I hate Cygwin, use Visual Studio or MingGW instead. I just put this\n# second here for completeness, or in case I gate tired of hitting my\n# head with a hammer and want to feel a different sort of pain.\nifneq (, $(findstring cygwin, $(SYS)))\nINCLUDES = -I.\nLIBS = \nFLAGS2 = \nendif\n\n# OpenBSD\nifneq (, $(findstring openbsd, $(SYS)))\nLIBS = -lm -lpthread\nINCLUDES = -I.\nFLAGS2 = \nendif\n\n# FreeBSD\nifneq (, $(findstring freebsd, $(SYS)))\nLIBS = -lm -lpthread\nINCLUDES = -I.\nFLAGS2 =\nendif\n\n# NetBSD\nifneq (, $(findstring netbsd, $(SYS)))\nLIBS = -lm -lpthread\nINCLUDES = -I.\nFLAGS2 =\nendif\n\n\nDEFINES = \nCFLAGS = -g -ggdb $(FLAGS2) $(INCLUDES) $(DEFINES) -Wall -O2\n.SUFFIXES: .c .cpp\n\nall: bin/masscan \n\n\ntmp/main-conf.o: src/main-conf.c src/*.h\n\t$(CC) $(CFLAGS) -c $< -o $@ -DGIT=\\\"$(GITVER)\\\"\n\n\n# just compile everything in the 'src' directory. Using this technique\n# means that include file dependencies are broken, so sometimes when\n# the program crashes unexpectedly, 'make clean' then 'make' fixes the\n# problem that a .h file was out of date\ntmp/%.o: src/%.c src/*.h\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n\nSRC = $(sort $(wildcard src/*.c))\nOBJ = $(addprefix tmp/, $(notdir $(addsuffix .o, $(basename $(SRC))))) \n\n\nbin/masscan: $(OBJ)\n\t$(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)\n\nclean:\n\trm -f tmp/*.o\n\trm -f bin/masscan\n\nregress: bin/masscan\n\tbin/masscan --selftest\n\ntest: regress\n\ninstall: bin/masscan\n\tinstall $(INSTALL_DATA) bin/masscan $(DESTDIR)$(BINDIR)/masscan\n\t\ndefault: bin/masscan\n"
  },
  {
    "path": "README.md",
    "content": "[![unittests](https://github.com/robertdavidgraham/masscan/actions/workflows/unittests.yml/badge.svg?branch=master)](https://github.com/robertdavidgraham/masscan/actions/workflows/unittests.yml/?branch=master)\n\n# MASSCAN: Mass IP port scanner\n\nThis is an Internet-scale port scanner. It can scan the entire Internet\nin under 5 minutes, transmitting 10 million packets per second,\nfrom a single machine.\n\nIts usage (parameters, output) is similar to `nmap`, the most famous port scanner.\nWhen in doubt, try one of those features -- features that support widespread\nscanning of many machines are supported, while in-depth scanning of single\nmachines aren't.\n\nInternally, it uses asynchronous transmission, similar to port scanners\nlike  `scanrand`, `unicornscan`, and `ZMap`. It's more flexible, allowing\narbitrary port and address ranges.\n\nNOTE: masscan uses its own **ad hoc TCP/IP stack**. Anything other than\nsimple port scans may cause conflict with the local TCP/IP stack. This means you \nneed to use either the `--src-ip` option to run from a different IP address, or\nuse `--src-port` to configure which source ports masscan uses, then also\nconfigure the internal firewall (like `pf` or `iptables`) to firewall those ports\nfrom the rest of the operating system.\n\nThis tool is free, but consider contributing money to its development:\nBitcoin wallet address: 1MASSCANaHUiyTtR3bJ2sLGuMw5kDBaj4T\n\n\n# Building\n\nOn Debian/Ubuntu, it goes something like the following. It doesn't\nreally have any dependencies other than a C compiler (such as `gcc`\nor `clang`).\n\n\tsudo apt-get --assume-yes install git make gcc\n\tgit clone https://github.com/robertdavidgraham/masscan\n\tcd masscan\n\tmake\n\nThis puts the program in the `masscan/bin` subdirectory. \nTo install it (on Linux) run:\n\n    make install\n\nThe source consists of a lot of small files, so building goes a lot faster\nby using the multi-threaded build. This requires more than 2gigs on a \nRaspberry Pi (and breaks), so you might use a smaller number, like `-j4` rather than\nall possible threads.\n\n\tmake -j\n\nWhile Linux is the primary target platform, the code runs well on many other\nsystems (Windows, macOS, etc.). Here's some additional build info:\n\n  * Windows w/ Visual Studio: use the VS10 project\n  * Windows w/ MinGW: just type `make`\n  * Windows w/ cygwin: won't work\n  * Mac OS X /w XCode: use the XCode4 project\n  * Mac OS X /w cmdline: just type `make`\n  * FreeBSD: type `gmake`\n  * other: try just compiling all the files together, `cc src/*.c -o bin/masscan`\n\nOn macOS, the x86 binaries seem to work just as fast under ARM emulation.\n\n# Usage\n\nUsage is similar to `nmap`. To scan a network segment for some ports:\n\n\t# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112\n\nThis will:\n* scan the `10.x.x.x` subnet, and `2603:3001:2d00:da00::x` subnets\n* scans port 80 and the range 8000 to 8100, or 102 ports total, on both subnets\n* print output to `<stdout>` that can be redirected to a file\n\nTo see the complete list of options, use the `--echo` feature. This\ndumps the current configuration and exits. This output can be used as input back\ninto the program:\n\n\t# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112 --echo > xxx.conf\n\t# masscan -c xxx.conf --rate 1000\n\n\n## Banner checking\n\nMasscan can do more than just detect whether ports are open. It can also\ncomplete the TCP connection and interaction with the application at that\nport in order to grab simple \"banner\" information.\n\nMasscan supports banner checking on the following protocols:\n  * FTP\n  * HTTP\n  * IMAP4\n  * memcached\n  * POP3\n  * SMTP\n  * SSH\n  * SSL\n  * SMBv1\n  * SMBv2\n  * Telnet\n  * RDP\n  * VNC\n\nThe problem with this is that masscan contains its own TCP/IP stack\nseparate from the system you run it on. When the local system receives\na SYN-ACK from the probed target, it responds with a RST packet that kills\nthe connection before masscan can grab the banner.\n\nThe easiest way to prevent this is to assign masscan a separate IP\naddress. This would look like one of the following examples:\n\n\t# masscan 10.0.0.0/8 -p80 --banners --source-ip 192.168.1.200\n      # masscan 2a00:1450:4007:810::/112 -p80 --banners --source-ip 2603:3001:2d00:da00:91d7:b54:b498:859d\n\nThe address you choose has to be on the local subnet and not otherwise\nbe used by another system. Masscan will warn you that you've made a\nmistake, but you might've messed up the other machine's communications\nfor several minutes, so be careful.\n\nIn some cases, such as WiFi, this isn't possible. In those cases, you can\nfirewall the port that masscan uses. This prevents the local TCP/IP stack\nfrom seeing the packet, but masscan still sees it since it bypasses the\nlocal stack. For Linux, this would look like:\n\n\t# iptables -A INPUT -p tcp --dport 61000 -j DROP\n\t# masscan 10.0.0.0/8 -p80 --banners --source-port 61000\n\nYou probably want to pick ports that don't conflict with ports Linux might otherwise\nchoose for source-ports. You can see the range Linux uses, and reconfigure\nthat range, by looking in the file:\n\n    /proc/sys/net/ipv4/ip_local_port_range\n\nOn the latest version of Kali Linux (2018-August), that range is  32768  to  60999, so\nyou should choose ports either below 32768 or 61000 and above.\n\nSetting an `iptables` rule only lasts until the next reboot. You need to lookup how to\nsave the configuration depending upon your distro, such as using `iptables-save` \nand/or `iptables-persistent`.\n\nOn Mac OS X and BSD, there are similar steps. To find out the ranges to avoid,\nuse a command like the following:\n\n    # sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last\n\nOn FreeBSD and older MacOS, use an `ipfw` command: \n\n\t# sudo ipfw add 1 deny tcp from any to any 40000 in\n\t# masscan 10.0.0.0/8 -p80 --banners --source-port 40000\n\nOn newer MacOS and OpenBSD, use the `pf` packet-filter utility. \nEdit the file `/etc/pf.conf` to add a line like the following:\n\n    block in proto tcp from any to any port 40000:40015\n    \nThen to enable the firewall, run the command:\n    \n    # pfctl -E    \n\nIf the firewall is already running, then either reboot or reload the rules\nwith the following command:\n\n    # pfctl -f /etc/pf.conf\n\nWindows doesn't respond with RST packets, so neither of these techniques\nare necessary. However, masscan is still designed to work best using its\nown IP address, so you should run that way when possible, even when it is\nnot strictly necessary.\n\nThe same thing is needed for other checks, such as the `--heartbleed` check,\nwhich is just a form of banner checking.\n\n\n## How to scan the entire Internet\n\nWhile useful for smaller, internal networks, the program is really designed\nwith the entire Internet in mind. It might look something like this:\n\n\t# masscan 0.0.0.0/0 -p0-65535\n\nScanning the entire Internet is bad. For one thing, parts of the Internet react\nbadly to being scanned. For another thing, some sites track scans and add you\nto a ban list, which will get you firewalled from useful parts of the Internet.\nTherefore, you want to exclude a lot of ranges. To blacklist or exclude ranges,\nyou want to use the following syntax:\n\n\t# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt\n\nThis just prints the results to the command-line. You probably want them\nsaved to a file instead. Therefore, you want something like:\n\n\t# masscan 0.0.0.0/0 -p0-65535 -oX scan.xml\n\nThis saves the results in an XML file, allowing you to easily dump the\nresults in a database or something.\n\nBut, this only goes at the default rate of 100 packets/second, which will\ntake forever to scan the Internet. You need to speed it up as so:\n\n\t# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000\n\nThis increases the rate to 100,000 packets/second, which will scan the\nentire Internet (minus excludes) in about 10 hours per port (or 655,360 hours\nif scanning all ports).\n\nThe thing to notice about this command-line is that these are all `nmap`\ncompatible options. In addition, \"invisible\" options compatible with `nmap`\nare also set for you: `-sS -Pn -n --randomize-hosts --send-eth`. Likewise,\nthe format of the XML file is inspired by `nmap`. There are, of course, a\nlot of differences, because the *asynchronous* nature of the program\nleads to a fundamentally different approach to the problem.\n\nThe above command-line is a bit cumbersome. Instead of putting everything\non the command-line, it can be stored in a file instead. The above settings\nwould look like this:\n\n\t# My Scan\n\trate =  100000.00\n\toutput-format = xml\n\toutput-status = all\n\toutput-filename = scan.xml\n\tports = 0-65535\n\trange = 0.0.0.0-255.255.255.255\n\texcludefile = exclude.txt\n\nTo use this configuration file, use the `-c`:\n\n\t# masscan -c myscan.conf\n\nThis also makes things easier when you repeat a scan.\n\nBy default, masscan first loads the configuration file \n`/etc/masscan/masscan.conf`. Any later configuration parameters override what's\nin this default configuration file. That's where I put my \"excludefile\" \nparameter so that I don't ever forget it. It just works automatically.\n\n\n## Getting output\n\nBy default, masscan produces fairly large text files, but it's easy \nto convert them into any other format. There are five supported output formats:\n\n1. xml:  Just use the parameter `-oX <filename>`. \n\tOr, use the parameters `--output-format xml` and `--output-filename <filename>`.\n\n2. binary: This is the masscan builtin format. It produces much smaller files so that\nwhen I scan the Internet my disk doesn't fill up. They need to be parsed,\nthough. The command-line option `--readscan` will read binary scan files.\nUsing `--readscan` with the `-oX` option will produce an XML version of the \nresults file.\n\n3. grepable: This is an implementation of the Nmap -oG\noutput that can be easily parsed by command-line tools. Just use the\nparameter `-oG <filename>`. Or, use the parameters `--output-format grepable` and\n`--output-filename <filename>`.\n\n4. json: This saves the results in JSON format. Just use the\nparameter `-oJ <filename>`. Or, use the parameters `--output-format json` and\n`--output-filename <filename>`.\n\n5. list: This is a simple list with one host and port pair \nper line. Just use the parameter `-oL <filename>`. Or, use the parameters \n`--output-format list` and `--output-filename <filename>`. The format is:\n\n\t```\n\t<port state> <protocol> <port number> <IP address> <POSIX timestamp>  \n\topen tcp 80 XXX.XXX.XXX.XXX 1390380064\n\t```\t\n\n\n## Comparison with Nmap\n\nWhere reasonable, every effort has been taken to make the program familiar\nto `nmap` users, even though it's fundamentally different. Masscan is tuned\nfor wide range scanning of a lot of machines, whereas nmap is designed for\nintensive scanning of a single machine or a small range.\n\nTwo important differences are:\n\n* no default ports to scan, you must specify `-p <ports>`\n* target hosts are IP addresses or simple ranges, not DNS names, nor \n  the funky subnet ranges `nmap` can use (like `10.0.0-255.0-255`).\n\nYou can think of `masscan` as having the following settings permanently\nenabled:\n* `-sS`: this does SYN scan only (currently, will change in the future)\n* `-Pn`: doesn't ping hosts first, which is fundamental to the async operation\n* `-n`: no DNS resolution happens\n* `--randomize-hosts`: scan completely randomized, always, you can't change this\n* `--send-eth`: sends using raw `libpcap`\n\nIf you want a list of additional `nmap` compatible settings, use the following\ncommand:\n\n\t# masscan --nmap\n\n\n## Transmit rate (IMPORTANT!!)\n\nThis program spews out packets very fast. On Windows, or from VMs,\nit can do 300,000 packets/second. On Linux (no virtualization) it'll\ndo 1.6 million packets-per-second. That's fast enough to melt most networks.\n\nNote that it'll only melt your own network. It randomizes the target\nIP addresses so that it shouldn't overwhelm any distant network.\n\nBy default, the rate is set to 100 packets/second. To increase the rate to\na million use something like `--rate 1000000`.\n\nWhen scanning the IPv4 Internet, you'll be scanning lots of subnets,\nso even though there's a high rate of packets going out, each\ntarget subnet will receive a small rate of incoming packets.\n\nHowever, with IPv6 scanning, you'll tend to focus on a single\ntarget subnet with billions of addresses. Thus, your default\nbehavior will overwhelm the target network. Networks often\ncrash under the load that masscan can generate.\n\n\n# Design\n\nThis section describes the major design issues of the program.\n\n\n## Code Layout\n\nThe file `main.c` contains the `main()` function, as you'd expect. It also\ncontains the `transmit_thread()` and `receive_thread()` functions. These\nfunctions have been deliberately flattened and heavily commented so that you\ncan read the design of the program simply by stepping line-by-line through\neach of these.\n\n\n## Asynchronous\n\nThis is an *asynchronous* design. In other words, it is to `nmap` what\nthe `nginx` web-server is to `Apache`. It has separate transmit and receive\nthreads that are largely independent from each other. It's the same sort of\ndesign found in `scanrand`, `unicornscan`, and `ZMap`.\n\nBecause it's asynchronous, it runs as fast as the underlying packet transmit\nallows.\n\n\n## Randomization\n\nA key difference between Masscan and other scanners is the way it randomizes\ntargets.\n\nThe fundamental principle is to have a single index variable that starts at\nzero and is incremented by one for every probe. In C code, this is expressed\nas:\n\n    for (i = 0; i < range; i++) {\n        scan(i);\n    }\n\nWe have to translate the index into an IP address. Let's say that you want to\nscan all \"private\" IP addresses. That would be the table of ranges like:\n    \n    192.168.0.0/16\n    10.0.0.0/8\n    172.16.0.0/12\n\nIn this example, the first 64k indexes are appended to 192.168.x.x to form\nthe target address. Then, the next 16-million are appended to 10.x.x.x.\nThe remaining indexes in the range are applied to 172.16.x.x.\n\nIn this example, we only have three ranges. When scanning the entire Internet,\nwe have in practice more than 100 ranges. That's because you have to blacklist\nor exclude a lot of sub-ranges. This chops up the desired range into hundreds\nof smaller ranges.\n\nThis leads to one of the slowest parts of the code. We transmit 10 million\npackets per second and have to convert an index variable to an IP address\nfor each and every probe. We solve this by doing a \"binary search\" in a small\namount of memory. At this packet rate, cache efficiencies start to dominate\nover algorithm efficiencies. There are a lot of more efficient techniques in\ntheory, but they all require so much memory as to be slower in practice.\n\nWe call the function that translates from an index into an IP address\nthe `pick()` function. In use, it looks like:\n\n    for (i = 0; i < range; i++) {\n        ip = pick(addresses, i);\n        scan(ip);\n    }\n\nMasscan supports not only IP address ranges, but also port ranges. This means\nwe need to pick from the index variable both an IP address and a port. This\nis fairly straightforward:\n\n    range = ip_count * port_count;\n    for (i = 0; i < range; i++) {\n        ip   = pick(addresses, i / port_count);\n        port = pick(ports,     i % port_count);\n        scan(ip, port);\n    }\n\nThis leads to another expensive part of the code. The division/modulus\ninstructions are around 90 clock cycles, or 30 nanoseconds, on x86 CPUs. When\ntransmitting at a rate of 10 million packets/second, we have only\n100 nanoseconds per packet. I see no way to optimize this any better. Luckily,\nthough, two such operations can be executed simultaneously, so doing two \nof these, as shown above, is no more expensive than doing one.\n\nThere are actually some easy optimizations for the above performance problems,\nbut they all rely upon `i++`, the fact that the index variable increases one\nby one through the scan. Actually, we need to randomize this variable. We\nneed to randomize the order of IP addresses that we scan or we'll blast the\nheck out of target networks that aren't built for this level of speed. We \nneed to spread our traffic evenly over the target.\n\nThe way we randomize is simply by encrypting the index variable. By definition,\nencryption is random and creates a 1-to-1 mapping between the original index\nvariable and the output. This means that while we linearly go through the\nrange, the output IP addresses are completely random. In code, this looks like:\n\n    range = ip_count * port_count;\n    for (i = 0; i < range; i++) {\n        x = encrypt(i);\n        ip   = pick(addresses, x / port_count);\n        port = pick(ports,     x % port_count);\n        scan(ip, port);\n    }\n\nThis also has a major cost. Since the range is an unpredictable size instead\nof a nice even power of 2, we can't use cheap binary techniques like\nAND (&) and XOR (^). Instead, we have to use expensive operations like \nMODULUS (%). In my current benchmarks, it's taking 40 nanoseconds to\nencrypt the variable.\n\nThis architecture allows for lots of cool features. For example, it supports\n\"shards\". You can set up 5 machines each doing a fifth of the scan or\n`range / shard_count`. Shards can be multiple machines, or simply multiple\nnetwork adapters on the same machine, or even (if you want) multiple IP\nsource addresses on the same network adapter.\n\nOr, you can use a 'seed' or 'key' to the encryption function, so that you get\na different order each time you scan, like `x = encrypt(seed, i)`.\n\nWe can also pause the scan by exiting out of the program, and simply\nremembering the current value of `i`, and restart it later. I do that a lot\nduring development. I see something going wrong with my Internet scan, so\nI hit <ctrl-c> to stop the scan, then restart it after I've fixed the bug.\n\nAnother feature is retransmits/retries. Packets sometimes get dropped on the\nInternet, so you can send two packets back-to-back. However, something that\ndrops one packet may drop the immediately following packet. Therefore, you\nwant to send the copy about 1 second apart. This is simple. We already have\na 'rate' variable, which is the number of packets-per-second rate we are\ntransmitting at, so the retransmit function is simply to use `i + rate`\nas the index. One of these days I'm going to do a study of the Internet,\nand differentiate \"back-to-back\", \"1 second\", \"10 second\", and \"1 minute\"\nretransmits this way in order to see if there is any difference in what\ngets dropped.\n\n\n## C10 Scalability\n\nThe asynchronous technique is known as a solution to the \"c10k problem\".\nMasscan is designed for the next level of scalability, the \"C10M problem\".\n\nThe C10M solution is to bypass the kernel. There are three primary kernel\nbypasses in Masscan:\n* custom network driver\n* user-mode TCP stack\n* user-mode synchronization\n\nMasscan can use the PF_RING DNA driver. This driver DMAs packets directly\nfrom user-mode memory to the network driver with zero kernel involvement.\nThat allows software, even with a slow CPU, to transmit packets at the maximum\nrate the hardware allows. If you put 8 10-gbps network cards in a computer,\nthis means it could transmit at 100-million packets/second.\n\nMasscan has its own built-in TCP stack for grabbing banners from TCP\nconnections. This means it can easily support 10 million concurrent TCP\nconnections, assuming of course that the computer has enough memory.\n\nMasscan has no \"mutex\". Modern mutexes (aka. futexes) are mostly user-mode,\nbut they have two problems. The first problem is that they cause cache-lines\nto bounce quickly back-and-forth between CPUs. The second is that when there\nis contention, they'll do a system call into the kernel, which kills\nperformance. A mutex on the fast path of a program severely limits scalability.\nInstead, Masscan uses \"rings\" to synchronize things, such as when the\nuser-mode TCP stack in the receive thread needs to transmit a packet without\ninterfering with the transmit thread.\n\n\n## Portability\n\nThe code runs well on Linux, Windows, and Mac OS X. All the important bits are\nin standard C (C90). Therefore, it compiles on Visual Studio with Microsoft's\ncompiler, the Clang/LLVM compiler on Mac OS X, and GCC on Linux.\n\nWindows and Macs aren't tuned for packet transmit, and get only about 300,000\npackets-per-second, whereas Linux can do 1,500,000 packets/second. That's\nprobably faster than you want anyway.\n\n\n## Safe code\n\nA bounty is offered for vulnerabilities, see the VULNINFO.md file for more\ninformation.\n\nThis project uses safe functions like `safe_strcpy()` instead of unsafe functions\nlike `strcpy()`.\n\nThis project has automated unit regression tests (`make regress`).\n\n\n## Compatibility\n\nA lot of effort has gone into making the input/output look like `nmap`, which\neveryone who does port scans is (or should be) familiar with.\n\n\n## IPv6 and IPv4 coexistence\n\nMasscan supports IPv6, but there is no special mode, both are supported\nat the same time. (There is no `-6` option -- it's always available).\n\nIn any example you see of masscan usage,\nsimply put an IPv6 address where you see an IPv4 address. You can include\nIPv4 and IPv6 addresses simultaneously in the same scan. Output includes\nthe appropriate address at the same location, with no special marking.\n\nJust remember that IPv6 address space is really big. You probably don't want to scan\nfor big ranges, except maybe the first 64k addresses of a subnet that were assigned\nvia DHCPv6.\n\nInstead, you'll probably want to scan large lists of addresses stored\nin a file (`--include-file filename.txt`) that you got from other sources.\nLike everywhere else, this file can contain lists of both IPv4 and IPv6 addresses.\nThe test file I use contains 8 million addresses. Files of that size need a couple\nextra seconds to be read on startup (masscan sorts the addresses and removes\nduplicates before scanning).\n\nRemember that masscan contains its own network stack. Thus, the local machine\nyou run masscan from does not need to be IPv6 enabled -- though the local\nnetwork needs to be able to route IPv6 packets.\n\n\n## PF_RING\n\nTo get beyond 2 million packets/second, you need an Intel 10-gbps Ethernet\nadapter and a special driver known as [\"PF_RING ZC\" from ntop](http://www.ntop.org/products/packet-capture/pf_ring/pf_ring-zc-zero-copy/). Masscan doesn't need to be rebuilt in order to use PF_RING. To use PF_RING,\nyou need to build the following components:\n\n  * `libpfring.so` (installed in /usr/lib/libpfring.so)\n  * `pf_ring.ko` (their kernel driver)\n  * `ixgbe.ko` (their version of the Intel 10-gbps Ethernet driver)\n\nYou don't need to build their version of `libpcap.so`.\n\nWhen Masscan detects that an adapter is named something like `zc:enp1s0` instead\nof something like `enp1s0`, it'll automatically switch to PF_RING ZC mode.\n\nA more detail discussion can be found in **PoC||GTFO 0x15**.\n\n\n## Regression testing\n\nThe project contains a built-in unit test:\n\n    $ make test\n    bin/masscan --selftest\n    selftest: success!\n\nThis tests a lot of tricky bits of the code. You should do this after building.\n\n\n## Performance testing\n\nTo test performance, run something like the following to a throw-away address,\nto avoid overloading your local router:\n\n    $ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11\n\nThe bogus `--router-mac` keeps packets on the local network segments so that\nthey won't go out to the Internet.\n\nYou can also test in \"offline\" mode, which is how fast the program runs\nwithout the transmit overhead:\n\n    $ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline\n    \nThis second benchmark shows roughly how fast the program would run if it were\nusing PF_RING, which has near zero overhead.\n\nBy the way, the randomization algorithm makes heavy use of \"integer arithmetic\",\na chronically slow operation on CPUs. Modern CPUs have doubled the speed\nat which they perform this calculation, making `masscan` much faster.\n\n\n# Authors\n\nThis tool created by Robert Graham:\nemail: robert_david_graham@yahoo.com\ntwitter: @ErrataRob\n\n# License\n\nCopyright (c) 2013 Robert David Graham\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as published by\nthe Free Software Foundation, version 3 of the License.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program.  If not, see <https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "VULNINFO.md",
    "content": "# Vulnerability Information and Policy\n\nThis document contains information about robustness of this project against\nhacker attacks. It describes known vulnerabilities that have been found\nin previous versions, and describes policies how vulnerabilities are handled.\n\n## Security contact\n\nrobert_david_graham@yahoo.com\n@ErrataRob on twitter\n\n\n## Known vulnerabilities and advisories\n\nnone\n\n## Bounty\n\nI'm offering $100, payable in cash or Bitcoin, for security vulnerabilities.\nThis is primarily for remote vulnerabilities, such as the ability of a target\nto buffer-overflow the scanner, or even cause it to crash.\n\nBut I'd consider other vulnerabilities as well. Does Kali ship this with suid\nand there's a preload bug? That's not really a vuln in this code, but if it's \nsomething I could fix, I'd consider paying a bounty for it.\n\n\n## Disclosure policy\n\nIf you've got a vuln, just announce it. Please send info to the contact above\nas well, please.\n\nI'll probably get around to fixing it within a month or so. This really isn't\nheavily used software, so I'm lax on this.\n\n## Threats\n\nThe primary threat is from hostile targets on the Internet sending back\nresponses in order to:\n* exploit a buffer-overflow vulnerability\n* spoof packets trying to give fraudulent scan results (mitigated with our\n  SYN cookies)\n* flood packets trying to overload bandwidth/storage\n* bad data, such as corrupting banners or DNS names trying to exploit\n  downstream consumers with bad html or script tags.\n\nThe secondary threat is from use of the program. For example, when a bad\nparameter is entered on the command-line, the program spits it back out\nin a helpful error message. This is fine for a command-line program that\nshould run as `root` anyway, but if somebody tries to make it into a \nscriptable service, this becomes a potential vulnerability.\n\n## Safe code policy\n\nUnsafe functions like `strcpy()` are banned.\n\nThe code contains an automated regression test by running with the \n`--regress` option. However, currently the regression only tests\na small percentage of the code.\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "bin/.gitignore",
    "content": "*\n!.gitignore\n\n\n"
  },
  {
    "path": "data/exclude.conf",
    "content": "# http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\n# http://tools.ietf.org/html/rfc5735\n# \"This\" network\n0.0.0.0/8\n# Private networks\n10.0.0.0/8\n# Carrier-grade NAT - RFC 6598\n100.64.0.0/10\n# Host loopback\n127.0.0.0/8\n# Link local\n169.254.0.0/16\n# Private networks\n172.16.0.0/12\n# IETF Protocol Assignments\n192.0.0.0/24\n# DS-Lite\n192.0.0.0/29\n# NAT64\n192.0.0.170/32\n# DNS64\n192.0.0.171/32\n# Documentation (TEST-NET-1)\n192.0.2.0/24\n# 6to4 Relay Anycast\n192.88.99.0/24\n# Private networks\n192.168.0.0/16\n# Benchmarking\n198.18.0.0/15\n# Documentation (TEST-NET-2)\n198.51.100.0/24\n# Documentation (TEST-NET-3)\n203.0.113.0/24\n# Reserved\n240.0.0.0/4\n# Limited Broadcast\n255.255.255.255/32\n\n\n#Received: from elbmasnwh002.us-ct-eb01.gdeb.com ([153.11.13.41]\n# helo=ebsmtp.gdeb.com)\tby mx1.gd-ms.com with esmtp (Exim 4.76)\t(envelope-from\n# <bmandes@gdeb.com>)\tid 1VS55c-0004qL-0F\tfor support@erratasec.com; Fri, 04\n# Oct 2013 09:06:40 -0400\n#To: <support@erratasec.com>\n#CC: <ebsoc@gdeb.com>\n#Subject: Scanning and Probing our network\n#From: Robert Mandes <bmandes@gdeb.com>\n#Date: Fri, 4 Oct 2013 09:06:36 -0400\n#\n#Stop scanning and probing our network, 153.11.0.0/16.  We are a defense \n#contractor and report to Federal law enforcement authorities when scans \n#and probes are directed at our network.  I assume you don't want to be \n#part of that report.   Please permanently  remove our network range from \n#your current and future research. \n#\n#Thank you \n#\n#Robert Mandes\n#Information Security Officer\n#General Dynamics \n#Electric Boat \n#\n#C 860-625-0605\n#P 860-433-1553\n\n153.11.0.0/16\n\n\n\n\n#Date: Mon, 7 Oct 2013 17:25:41 -0700\n#Subject: Re: please stop the attack to our router\n#From: Di Li <di@egihosting.com>\n#\n#Make sure you stop the scan immediately, that's not OK for any company or\n#organization scan our network at all.\n#\n#If you fail to do that we will block whole traffic from ASN 10439, and we\n#will file a police report after that.\n#\n#Let me know when you stop, since we still receive the attack from you, and\n#by the way your scan are not going anywhere, it's was dropped from our edge\n#since the first 5 scan\n#\n#Oct  7 17:17:32:I:SNMP: Auth. failure, intruder IP:  209.126.230.72\n#...\n#Oct  7 16:55:27:I:SNMP: Auth. failure, intruder IP:  209.126.230.72\n#\n#Di\n\n4.53.201.0/24\n5.152.179.0/24\n8.12.162.0-8.12.164.255\n8.14.84.0/22\n8.14.145.0-8.14.147.255\n8.17.250.0-8.17.252.255\n23.27.0.0/16\n23.231.128.0/17\n37.72.172.0/23\n38.72.200.0/22\n50.93.192.0-50.93.197.255\n50.115.128.0/20\n50.117.0.0/17\n50.118.128.0/17\n63.141.222.0/24\n64.62.253.0/24\n64.92.96.0/19\n64.145.79.0/24\n64.145.82.0/23\n64.158.146.0/23\n65.49.24.0/24\n65.49.93.0/24\n65.162.192.0/22\n66.79.160.0/19\n66.160.191.0/24\n68.68.96.0/20\n69.46.64.0/19\n69.176.80.0/20\n72.13.80.0/20\n72.52.76.0/24\n74.82.43.0/24\n74.82.160.0/19\n74.114.88.0/22\n74.115.0.0/24\n74.115.2.0/24\n74.115.4.0/24\n74.122.100.0/22\n75.127.0.0/24\n103.251.91.0/24\n108.171.32.0/24\n108.171.42.0/24\n108.171.52.0/24\n108.171.62.0/24\n118.193.78.0/23\n130.93.16.0/23\n136.0.0.0/16\n142.111.0.0/16\n142.252.0.0/16\n146.82.55.93\n149.54.136.0/21\n149.54.152.0/21\n166.88.0.0/16\n172.252.0.0/16\n173.245.64.0/19\n173.245.194.0/23\n173.245.220.0/22\n173.252.192.0/18\n178.18.16.0/22\n178.18.26.0-178.18.29.255\n183.182.22.0/24\n192.92.114.0/24\n192.155.160.0/19\n192.177.0.0/16\n192.186.0.0/18\n192.249.64.0/20\n192.250.240.0/20\n194.110.214.0/24\n198.12.120.0-198.12.122.255\n198.144.240.0/20\n199.33.120.0/24\n199.33.124.0/22\n199.48.147.0/24\n199.68.196.0/22\n199.127.240.0/21\n199.187.168.0/22\n199.188.238.0/23\n199.255.208.0/24\n203.12.6.0/24\n204.13.64.0/21\n204.16.192.0/21\n204.19.238.0/24\n204.74.208.0/20\n205.159.189.0/24\n205.164.0.0/18\n205.209.128.0/18\n206.108.52.0/23\n206.165.4.0/24\n208.77.40.0/21\n208.80.4.0/22\n208.123.223.0/24\n209.51.185.0/24\n209.54.48.0/20\n209.107.192.0/23\n209.107.210.0/24\n209.107.212.0/24\n211.156.110.0/23\n216.83.33.0-216.83.49.255\n216.83.51.0-216.83.63.255\n216.151.183.0/24\n216.151.190.0/23\n216.172.128.0/19\n216.185.36.0/24\n216.218.233.0/24\n216.224.112.0/20\n\n#Received: from [194.77.40.242] (HELO samba.agouros.de)\n# for abuse@erratasec.com; Sat, 12 Oct 2013 09:55:35 -0500\n#Received: from rumba.agouros.de (rumba-internal [192.168.8.1])\tby\n# samba.agouros.de (Postfix) with ESMTPS id 9055FBAD1D\tfor\n# <abuse@erratasec.com>; Sat, 12 Oct 2013 16:55:32 +0200 (CEST)\n#Received: from rumba.agouros.de (localhost [127.0.0.1])\tby rumba.agouros.de\n# (Postfix) with ESMTP id 7B5DD206099\tfor <abuse@erratasec.com>; Sat, 12 Oct\n# 2013 16:55:32 +0200 (CEST)\n#Received: from localhost.localdomain (localhost [127.0.0.1])\tby\n# rumba.agouros.de (Postfix) with ESMTP id 5FBC420601D\tfor\n# <abuse@erratasec.com>; Sat, 12 Oct 2013 16:55:32 +0200 (CEST)\n#To: <abuse@erratasec.com>\n#Subject: Loginattempts from Your net\n#Message-ID: <20131012145532.5FBC420601D@rumba.agouros.de>\n#Date: Sat, 12 Oct 2013 16:55:32 +0200\n#From: <elwood@agouros.de>\n#\n#The address 209.126.230.72 from Your network tried to log in to\n#our network using Port 22 (1)/tcp. Below You will find a listing of the dates and\n#times the incidents occured as well as the attacked IP-Addresses.\n#This is a matter of concern for us and continued tries might result in\n#legal action. If the machine was victim to a hack take it offline, repair\n#the damage and use better protection next time.\n#The times included are in Central European (Summer) Time.\n#Date\tSourceip\tport\tdestips\n#\n#07.10.2013 22:34:40 CEST\t209.126.230.72\t22\t194.77.40.242 (1)\n#08.10.2013 01:44:15 CEST\t209.126.230.72\t22\t194.77.40.246 (1)\n#\n#Regards,\n#Konstantin Agouros\n\n194.77.40.242\n194.77.40.246\n\n\n\n#Received: from [165.160.9.58] (HELO mx2.cscinfo.com)\n#X-Virus-Scanned: amavisd-new at cscinfo.com\n#Received: from mx2.cscinfo.com ([127.0.0.1])\tby localhost\n# (plmail02.wil.csc.local [127.0.0.1]) (amavisd-new, port 10024)\twith ESMTP id\n# GGQ7EiQaK2P0 for <protodev@erratasec.com>;\tWed, 30 Oct 2013 09:26:00 -0400\n# (EDT)\n#Received: from casarray.cscinfo.com (pwmailch02.cscinfo.com [172.20.53.94])\tby\n# mx2.cscinfo.com (Postfix) with ESMTPS id 4BA5E58170\tfor\n# <protodev@erratasec.com>; Wed, 30 Oct 2013 09:26:00 -0400 (EDT)\n#Received: from PWMAILM02.cscinfo.com ([169.254.7.52]) by\n# PWMAILCH02.cscinfo.com ([172.20.53.94]) with mapi id 14.02.0247.003; Wed, 30\n# Oct 2013 09:26:00 -0400\n#From: \"Derksen, Bill\" <bderksen@cscinfo.com>\n#Subject: Unauthorized Scanning\n#Date: Wed, 30 Oct 2013 13:25:59 +0000\n#Message-ID: <1F80316A0C861F40A9A88F18465F138E01EF885F@PWMAILM02.cscinfo.com>\n#x-originating-ip: [172.31.252.72]\n#\n#We have detected unauthorized activity from your systems on our public netw=\n#ork.   Please suspend scanning of our networks immediately.\n#\n#Our network block is 165.160/16\n#\n#Further scanning will result in reports of unauthorized activity being file=\n#d with law enforcement agencies.\n#\n#Corporation Service Company\n#\n#\n#\n#________________________________\n#\n#NOTICE: This e-mail and any attachments is intended only for use by the add=\n#ressee(s) named herein and may contain legally privileged, proprietary or c=\n#onfidential information. If you are not the intended recipient of this e-ma=\n#il, you are hereby notified that any dissemination, distribution or copying=\n# of this email, and any attachments thereto, is strictly prohibited. If you=\n# receive this email in error please immediately notify me via reply email o=\n#r at (800) 927-9800 and permanently delete the original copy and any copy o=\n#f any e-mail, and any printout.\n\n165.160.0.0/16\n\n#******************************\n#Greetings from the IT Security Team at Utah State University.\n#\n#We have detected network activity that might be suspicious or\n#malicious. We think it might be sourced from your network. We\n#include IP Addresses as well as description, log snippets, and\n#other useful information.\n#\n#Please review this information or forward to the responsible person.\n129.123.0.0/16\n144.39.0.0/16\n204.113.91.0/24\n\n\n#On Friday, November 17th 2017 starting at 03:39 EST (UTC-5:00), part of the\n#Physics Network at McGill University (132.206.9.0/24, 132.206.123.0/24\n#and/or 132.206.125.0/24) was scanned from xxx.xxx.xxx.xxx (see syslog\n#snippet below). The scan targetted the domain service (port 53/udp). We\n#consider this scan to be an attempt to unlawfully access or abuse our\n#network (intentionally or as a result of virus or worm activity).\n\n132.206.9.0/24\n132.206.123.0/24\n132.206.125.0/24\n\n\n#\n# Add DOD + US Military, often not a great idea to scan military ranges.\n# If you desire, you can comment these ranges out.\n#\n\n6.0.0.0/8\n7.0.0.0/8\n11.0.0.0/8\n21.0.0.0/8\n22.0.0.0/8\n26.0.0.0/8\n28.0.0.0/8\n29.0.0.0/8\n30.0.0.0/8\n33.0.0.0/8\n55.0.0.0/8\n205.0.0.0/8\n214.0.0.0/8\n215.0.0.0/8\n\n#******************************\n#Janet is a UK research and education network!\n#Please DO NOT scan, you been warned!\n\n31.25.0.0/23\n31.25.2.0/23\n31.25.4.0/22\n37.72.112.0/21\n46.254.200.0/21\n81.87.0.0/16\n85.12.64.0/18\n89.207.208.0/21\n92.245.224.0/19\n128.16.0.0/16\n128.40.0.0/16\n128.41.0.0/18\n128.86.0.0/16\n128.232.0.0/16\n128.240.0.0/16\n128.243.0.0/16\n129.11.0.0/16\n129.12.0.0/16\n129.31.0.0/16\n129.67.0.0/16\n129.169.0.0/16\n129.215.0.0/16\n129.234.0.0/16\n130.88.0.0/16\n130.159.0.0/16\n130.209.0.0/16\n130.246.0.0/16\n131.111.0.0/16\n131.227.0.0/16\n131.231.0.0/16\n131.251.0.0/16\n134.36.0.0/16\n134.83.0.0/16\n134.151.0.0/16\n134.219.0.0/16\n134.220.0.0/16\n134.225.0.0/16\n136.148.0.0/16\n136.156.0.0/16\n137.44.0.0/16\n137.50.0.0/16\n137.73.0.0/16\n137.108.0.0/16\n137.195.0.0/16\n137.222.0.0/16\n137.253.0.0/16\n138.38.0.0/16\n138.40.0.0/16\n138.250.0.0/15\n138.253.0.0/16\n139.133.0.0/16\n139.153.0.0/16\n139.166.0.0/16\n139.184.0.0/16\n139.222.0.0/16\n140.97.0.0/16\n141.163.0.0/16\n141.170.64.0/19\n141.170.96.0/22\n141.170.100.0/23\n141.241.0.0/16\n143.52.0.0/15\n143.117.0.0/16\n143.167.0.0/16\n143.210.0.0/16\n143.234.0.0/16\n144.32.0.0/16\n144.82.0.0/16\n144.124.0.0/16\n144.173.0.0/16\n146.87.0.0/16\n146.97.0.0/16\n146.169.0.0/16\n146.176.0.0/16\n146.179.0.0/16\n146.191.0.0/16\n146.227.0.0/16\n147.143.0.0/16\n147.188.0.0/16\n147.197.0.0/16\n148.79.0.0/16\n148.88.0.0/16\n148.197.0.0/16\n149.155.0.0/16\n149.170.0.0/16\n150.204.0.0/16\n152.71.0.0/16\n152.78.0.0/16\n152.105.0.0/16\n155.198.0.0/16\n155.245.0.0/16\n157.140.0.0/16\n157.228.0.0/16\n158.94.0.0/16\n158.125.0.0/16\n158.143.0.0/16\n158.223.0.0/16\n159.86.128.0/18\n159.92.0.0/16\n160.5.0.0/16\n160.9.0.0/16\n161.73.0.0/16\n161.74.0.0/16\n161.76.0.0/16\n161.112.0.0/16\n163.1.0.0/16\n163.119.0.0/16\n163.160.0.0/16\n163.167.0.0/16\n164.11.0.0/16\n185.83.168.0/22\n192.12.72.0/24\n192.18.195.0/24\n192.35.172.0/24\n192.41.104.0/21\n192.41.112.0/20\n192.41.128.0/22\n192.68.153.0/24\n192.76.6.0/23\n192.76.8.0/21\n192.76.16.0/20\n192.76.32.0/22\n192.82.153.0/24\n192.84.5.0/24\n192.84.75.0/24\n192.84.76.0/22\n192.84.80.0/22\n192.84.212.0/24\n192.88.9.0/24\n192.88.10.0/24\n192.94.235.0/24\n192.100.78.0/24\n192.100.154.0/24\n192.107.168.0/24\n192.108.120.0/24\n192.124.46.0/24\n192.133.244.0/24\n192.149.111.0/24\n192.150.180.0/22\n192.150.184.0/24\n192.153.213.0/24\n192.156.162.0/24\n192.160.194.0/24\n192.171.128.0/18\n192.171.192.0/21\n192.173.1.0/24\n192.173.2.0/23\n192.173.4.0/24\n192.173.128.0/21\n192.188.157.0/24\n192.188.158.0/24\n192.190.201.0/24\n192.190.202.0/24\n192.195.42.0/23\n192.195.105.0/24\n192.195.116.0/23\n192.195.118.0/24\n193.32.22.0/24\n193.37.225.0/24\n193.37.240.0/21\n193.38.143.0/24\n193.39.80.0/21\n193.39.172.0/22\n193.39.212.0/24\n193.60.0.0/14\n193.107.116.0/22\n193.130.15.0/24\n193.133.28.0/23\n193.138.86.0/24\n194.32.32.0/20\n194.35.93.0/24\n194.35.186.0/24\n194.35.192.0/19\n194.35.241.0/24\n194.36.1.0/24\n194.36.2.0/23\n194.36.121.0/24\n194.36.152.0/21\n194.60.218.0/24\n194.66.0.0/16\n194.80.0.0/14\n194.187.32.0/22\n195.194.0.0/15\n212.121.0.0/19\n212.121.192.0/19\n212.219.0.0/16\n\n"
  },
  {
    "path": "debian/.gitignore",
    "content": "files\nmasscan\nmasscan.debhelper.log\nmasscan.substvars\n"
  },
  {
    "path": "debian/README.Debian",
    "content": "masscan for Debian\n------------------\n\nInitial debianisation\n\n -- Vladimir Vitkov <vvitkov@sdl.com>  Fri, 24 Jan 2014 11:03:38 +0200\n"
  },
  {
    "path": "debian/changelog",
    "content": "masscan (1.0.3-46+gbbadb7b-1) precise; urgency=low\n\n  * Rebuild from current git\n  * Use propper git hash versioning\n\n -- Vladimir Vitkov (Packaging Key) <vvitkov@sdl.com>  Tue, 10 Jun 2014 12:11:04 +0300\n\nmasscan (1.0.1+git20140124-1) unstable; urgency=low\n\n  * Rebuild from current git\n\n -- Vladimir Vitkov <vvitkov@sdl.com>  Fri, 24 Jan 2014 14:37:30 +0200\n\nmasscan (1.0.1+git20140106-1) unstable; urgency=low\n\n  * Initial release\n\n -- Vladimir Vitkov <vvitkov@sdl.com>  Fri, 24 Jan 2014 11:03:38 +0200\n"
  },
  {
    "path": "debian/compat",
    "content": "8\n"
  },
  {
    "path": "debian/control",
    "content": "Source: masscan\nSection: net\nPriority: extra\nMaintainer: Vladimir Vitkov <vvitkov@sdl.com>\nBuild-Depends: debhelper (>= 8.0.0), libpcap-dev\nStandards-Version: 3.9.3\nHomepage: https://github.com/robertdavidgraham/masscan\n#Vcs-Git: https://github.com/robertdavidgraham/masscan.git\n#Vcs-Browser: http://git.debian.org/?p=collab-maint/masscan.git;a=summary\n\nPackage: masscan\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Mass IP port scanner\n This is the fastest Internet port scanner. It can scan the\n entire Internet in under 6 minutes, transmitting 10 million\n packets per second.\n .\n It produces results similar to nmap, the most famous port\n scanner. Internally, it operates more like scanrand,\n unicornscan, and ZMap, using asynchronous transmission.\n The major difference is that it's faster than these other\n scanners. In addition, it's more flexible, allowing\n arbitrary address ranges and port ranges.\n"
  },
  {
    "path": "debian/copyright",
    "content": "Format: http://dep.debian.net/deps/dep5\nUpstream-Name: masscan\nSource: https://github.com/robertdavidgraham/masscan\n\nFiles: *\nCopyright: 2013 Robert David Graham <robert_david_graham@yahoo.com>\nLicense: AGPL\n This program, \"masscan\", is not completely free software. It may not be\n used by the United States Department of Defense (DoD) or National Security\n Agency (NSA), or by agents acting on their behalf, such as contractors,\n sub-contractors, and so on. These entitities must contact me to acquire\n a different license.\n .\n Barring the above exception, you can use, redistribute, and/or modify\n this code under the terms of the GNU Affero General Public License\n version 3.\n .\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n GNU Affero General Public License for more details.\n .\n You should have received a copy of the GNU Affero General Public License\n along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nFiles: debian/*\nCopyright: 2014 Vladimir Vitkov <vvitkov@sdl.com>\nLicense: GPL-3.0+\n\nLicense: GPL-3.0+\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n .\n This package is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n GNU General Public License for more details.\n .\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n .\n On Debian systems, the complete text of the GNU General\n Public License version 3 can be found in \"/usr/share/common-licenses/GPL-3\".\n"
  },
  {
    "path": "debian/masscan.dirs",
    "content": "usr/bin\n"
  },
  {
    "path": "debian/masscan.docs",
    "content": "README.md\nVULNINFO.md\ndoc/algorithm.js\ndoc/bot.html\n"
  },
  {
    "path": "debian/masscan.install",
    "content": "bin/masscan usr/bin/\n"
  },
  {
    "path": "debian/masscan.manpages",
    "content": "doc/masscan.8\n"
  },
  {
    "path": "debian/rules",
    "content": "#!/usr/bin/make -f\n# -*- makefile -*-\n# Sample debian/rules that uses debhelper.\n# This file was originally written by Joey Hess and Craig Small.\n# As a special exception, when this file is copied by dh-make into a\n# dh-make output file, you may use that output file without restriction.\n# This special exception was added by Craig Small in version 0.37 of dh-make.\n\n# Uncomment this to turn on verbose mode.\n#export DH_VERBOSE=1\n\n%:\n\tdh $@ \n\noverride_dh_auto_test:\n\t$(MAKE) regress\n"
  },
  {
    "path": "debian/source/format",
    "content": "3.0 (quilt)\n"
  },
  {
    "path": "debian/watch",
    "content": "version=3\n\n# use the github release pages\nhttps://github.com/robertdavidgraham/masscan/releases .*/(\\d\\S*)\\.(?:tgz|tbz|txz|(?:tar\\.(?:gz|bz2|xz)))\n"
  },
  {
    "path": "doc/algorithm.js",
    "content": "/*\n\n    This is an implementation of the core Masscan scanning algorithm\n    in JavaScript/NodeJS. The core scanning algorithm is what makes\n    Masscan unique from other scanners, so it's worth highlighting\n    separately in a sample program.\n\n    REVIEW OF SCANNERS\n\n    The most famous port-scanner is \"nmap\". However, it is a\n    \"host-at-a-time\" scanner, and struggles at scanning large networks.\n\n    Masscan is an asynchronous, probe-at-a-time scanner. It spews out\n    probes to different ports, without caring if two probes happen to\n    be send to the same host. If the user wants a list of all ports\n    open on a single host, they have to post-process the masscan output\n    themselves, because masscan doesn't do it.\n\n    There are other asynchronous port-scanners, like scanrand, unicornscan,\n    and zmap. However, they have limitations in the way they do randomization\n    of their scans. They have limitations on the ranges of addresses and\n    ports that they'll accept, try to store an individual memory record\n    for everything scanned, or only partly randomize their scans.\n\n    THE WAY MASSCAN WORKS\n\n    Masscan first stores the targets as a \"list of ranges\". IP address\n    ranges are stored in one structure, and port ranges are stored\n    in another structure.\n\n    Then, a single index variable is used to enumerate the set of all \n    IP:port combinations. The scan works by simply incrementing the \n    index variable from 0 to the total number of probes (the 'range').\n\n    Then, before the enumeration step, the index is permuted into another\n    random index within the same range, in a 1-to-1 mapping. In other\n    words, the algorithm is theoretically reversable: given the output\n    of the permutation function, we can obtain the original index.\n\nEXAMPLE\n\n    This program can be run like the following:\n\n    node patent.js 10.0.0.0-10.0.0.5 192.168.0.0/31 80,U:161\n    10.0.0.0-10.0.0.5\n    192.168.0.0-192.168.0.1\n    0.0.0.80-0.0.0.80\n    0.1.0.161-0.1.0.161\n    --> 10.0.0.4 udp:161\n    --> 10.0.0.0 udp:161\n    --> 10.0.0.1 udp:161\n    --> 10.0.0.4 tcp:80\n    --> 192.168.0.1 tcp:80\n    --> 10.0.0.0 tcp:80\n    --> 10.0.0.2 udp:161\n    --> 10.0.0.5 udp:161\n    --> 192.168.0.0 tcp:80\n    --> 192.168.0.0 udp:161\n    --> 10.0.0.1 tcp:80\n    --> 10.0.0.3 udp:161\n    --> 10.0.0.2 tcp:80\n    --> 10.0.0.5 tcp:80\n    --> 192.168.0.1 udp:161\n    --> 10.0.0.3 tcp:80\n\n    What you see first is the target ranges being echoed back that it scans,\n    first the IP address ranges, followed by the port ranges. The port ranges\n    are in weird decimal-dot notation because they share the same code\n    as for IPv4 addresses.\n\n    Then we see the randomized output, where individual probes are sent to a\n    random IP address and port.\n\nTransmitThread\n\n    All the majic happens in the \"TransmitThread()\" function near the bottom\n    of this file.\n\n    We first see how the index variable 'i' is incremented from 0 to the\n    total number of packets that will be sent. We then see how first this\n    index is permuted to 'xXx', then this variable is separated into\n    one index for the IP address and another index for the port. Then,\n    those indexes are used to enumerate one of the IP addresses and\n    one of the ports.\n\nBlackrock\n\n    This is the permutation function. It implements an encryption algorithm\n    based on DES (Data Encryption Standard). However, the use of real DES\n    would impose a restricting on the range that it be an even power of 2.\n    In the above example, with 14 total probes, this doesn't apply.\n    Therefore, we have to change binary operators like XOR with their\n    non-binary equivelents.\n\n    The upshot is that we first initialize Blackrock with the range (and\n    a seed/key), and then shuffle the index. The process is stateless,\n    meaning that any time we shuffle the number '5' we always get the \n    same result, regardless of what has happened before.\n\nTargets, RangeList, Range\n\n    A Range is just a begin/end of an integer. We use this both for\n    IPv4 addresses (which are just 32-bit integers) and ports\n    (which are 16 bit integers).\n\n    A RangeList is just an array of Ranges. In Masscan, this object\n    sorts and combines ranges, making sure there are no duplicates,\n    but that isn't used in this example.\n\n    The RangeList object shows how an index can enumerate the \n    individual addresses/ports. This is down by walking the list\n    and subtracting from the index the size of each range, until\n    we reach a range that is larger than the index.\n\n    The Targets object just holds both the IP and port lists.\n\n*/\n\nfunction Range(begin, end) {\n    if (typeof begin == 'undefined' && typeof end == 'undefined') {\n        this.begin = 0xFFFFFFFF;\n        this.end = 0;\n    } else if (typeof end == 'undefined') {\n        this.begin = begin;\n        this.end = begin;\n    } else {\n        this.begin = begin;\n        this.end = end;\n    }\n\n    this.toString = function () {\n        return ((this.begin >> 24) & 0xFF)\n            + \".\" + ((this.begin >> 16) & 0xFF)\n            + \".\" + ((this.begin >> 8) & 0xFF)\n            + \".\" + ((this.begin >> 0) & 0xFF)\n            + \"-\" + ((this.end >> 24) & 0xFF)\n            + \".\" + ((this.end >> 16) & 0xFF)\n            + \".\" + ((this.end >> 8) & 0xFF)\n            + \".\" + ((this.end >> 0) & 0xFF);\n    }\n\n    this.count = function () {\n        return this.end - this.begin + 1;\n    }\n    this.pick = function (index) {\n        return this.begin + index;\n    }\n    return this;\n}\n\nfunction RangeList() {\n    this.list = [];\n    this.total_count = 0;\n\n    this.push = function (range) {\n        this.list.push(range);\n        this.total_count += range.count();\n    }\n\n    this.count = function () {\n        return this.total_count;\n    }\n\n    this.pick = function (index) {\n        for (var i in this.list) {\n            var item = this.list[i];\n            if (index < item.count())\n                return item.pick(index);\n            else\n                index -= item.count();\n        }\n        return null;\n    }\n}\n\n\nfunction Targets() {\n    this.ports = new RangeList();\n    this.ips = new RangeList();\n\n    this.parse_ip = function (text) {\n        var x = text.split(\".\");\n        var result = 0;\n        result |= parseInt(x[0]) << 24;\n        result |= parseInt(x[1]) << 16;\n        result |= parseInt(x[2]) << 8;\n        result |= parseInt(x[3]) << 0;\n        return result;\n    }\n\n    this.parse_ports = function (arg) {\n        var offset = 0;\n\n        if (arg.indexOf(\":\") !== -1) {\n            var x = arg.split(\":\");\n            if (x[0] == \"U\")\n                offset = 65536;\n            else if (x[0] == \"S\")\n                offset = 65536 * 2;\n            arg = x[1];\n        }\n\n        var target;\n        if (arg.indexOf(\"-\") !== -1) {\n            var x = arg.split(\"-\");\n            target = new Range(parseInt(x[0]), parseInt(x[1]));\n        } else\n            target = new Range(parseInt(arg));\n\n        target.begin += offset;\n        target.end += offset;\n        this.ports.push(target);\n    }\n    this.parse_args = function (argv) {\n        for (var i in argv) {\n            var arg = argv[i];\n\n            if (arg.indexOf(\",\") !== -1) {\n                var x = arg.split(\",\");\n                for (var j in x)\n                    this.parse_ports(x[j]);\n            } else if (arg.indexOf(\"/\") !== -1) {\n                var x = arg.split(\"/\");\n                var address = this.parse_ip(x[0]);\n                var prefix = parseInt(x[1]);\n                var mask = 0xFFFFFFFF << (32 - prefix);\n                address = address & mask;\n                var target = new Range(address, address | ~mask);\n                this.ips.push(target);\n            } else if (arg.indexOf(\"-\") !== -1) {\n                var x = arg.split(\"-\");\n                var begin = this.parse_ip(x[0]);\n                var end = this.parse_ip(x[1]);\n                var target = new Range(begin, end);\n                this.ips.push(target);\n            } else if (arg.indexOf(\".\") !== -1) {\n                var target = new Range(this.parse_ip(arg));\n                this.ips.push(target);\n            } else {\n                this.parse_ports(arg);\n            }\n        }\n    }\n    this.print = function () {\n        var i;\n        for (i in this.ips.list) {\n            console.log(this.ips.list[i].toString());\n        }\n        for (i in this.ports.list) {\n            console.log(this.ports.list[i].toString());\n        }\n    }\n    return this;\n}\n\n\n\nfunction Blackrock(range, seed) {\n    var split = Math.floor(Math.sqrt(range * 1.0));\n\n    this.rounds = 3;\n    this.seed = seed;\n    this.range = range;\n    this.a = split - 1;\n    this.b = split + 1;\n\n    while (this.a * this.b <= range)\n        this.b++;\n\n    /** Inner permutation function */\n    this.F = function (j, R, seed) {\n        var primes = [961752031, 982324657, 15485843, 961752031];\n        R = ((R << (R & 0x4)) + R + seed);\n        return Math.abs((((primes[j] * R + 25) ^ R) + j));\n    }\n\n    /** Outer feistal construction */\n    this.fe = function (r, a, b, m, seed) {\n        var L, R;\n        var j;\n        var tmp;\n\n        L = m % a;\n        R = Math.floor(m / a);\n\n        for (j = 1; j <= r; j++) {\n            if (j & 1) {\n                tmp = (L + this.F(j, R, seed)) % a;\n            } else {\n                tmp = (L + this.F(j, R, seed)) % b;\n            }\n            L = R;\n            R = tmp;\n        }\n        if (r & 1) {\n            return a * L + R;\n        } else {\n            return a * R + L;\n        }\n    }\n\n    /** Outer reverse feistal construction */\n    this.unfe = function (r, a, b, m, seed) {\n        var L, R;\n        var j;\n        var tmp;\n\n        if (r & 1) {\n            R = m % a;\n            L = Math.floor(m / a);\n        } else {\n            L = m % a;\n            R = Math.floor(m / a);\n        }\n\n        for (j = r; j >= 1; j--) {\n            if (j & 1) {\n                tmp = this.F(j, L, seed);\n                if (tmp > R) {\n                    tmp = (tmp - R);\n                    tmp = a - (tmp % a);\n                    if (tmp == a)\n                        tmp = 0;\n                } else {\n                    tmp = (R - tmp);\n                    tmp %= a;\n                }\n            } else {\n                tmp = this.F(j, L, seed);\n                if (tmp > R) {\n                    tmp = (tmp - R);\n                    tmp = b - (tmp % b);\n                    if (tmp == b)\n                        tmp = 0;\n                } else {\n                    tmp = (R - tmp);\n                    tmp %= b;\n                }\n            }\n            R = L;\n            L = tmp;\n        }\n        return a * R + L;\n    }\n\n    this.shuffle = function (m) {\n        var c;\n\n        c = this.fe(this.rounds, this.a, this.b, m, this.seed);\n        while (c >= this.range)\n            c = this.fe(this.rounds, this.a, this.b, c, this.seed);\n\n        return c;\n    }\n\n    this.unshuffle = function (m) {\n        var c;\n\n        c = unfe(this.rounds, this.a, this.b, m, this.seed);\n        while (c >= this.range)\n            c = unfe(this.rounds, this.a, this.b, c, this.seed);\n\n        return c;\n    }\n    return this;\n}\n\nfunction TransmitThread(targets, transmit, seed) {\n    var range = targets.ips.count() * targets.ports.count();\n    var b = Blackrock(range, seed);\n\n    for (var i = 0; i < range; i++) {\n        var xXx = b.shuffle(i);\n\n        var ip_index = Math.floor(xXx / targets.ports.count());\n        var port_index = Math.floor(xXx % targets.ports.count());\n\n        var ip = targets.ips.pick(ip_index);\n        var port = targets.ports.pick(port_index);\n\n        transmit(ip, port);\n    }\n}\n\nfunction Transmit2Thread(targets, transmit, seed, start, stop, increment) {\n    var range = targets.ips.count() * targets.ports.count();\n    var b = Blackrock(range, seed);\n\n    for (var i = start; i < range && i < stop; i += increment) {\n        var xXx = b.shuffle(i);\n\n        var ip_index = Math.floor(xXx / targets.ports.count());\n        var port_index = Math.floor(xXx % targets.ports.count());\n\n        var ip = targets.ips.pick(ip_index);\n        var port = targets.ports.pick(port_index);\n\n        transmit(ip, port);\n    }\n}\n\n\nfunction transmit(ip, port) {\n    var proto = \"tcp\";\n    if (port > 65536 * 2) {\n        proto = \"sctp\";\n        port -= 65536 * 2;\n    } else if (port > 65536) {\n        proto = \"udp\";\n        port -= 65536;\n    }\n\n    var ipstring = ((ip >> 24) & 0xFF)\n            + \".\" + ((ip >> 16) & 0xFF)\n            + \".\" + ((ip >> 8) & 0xFF)\n            + \".\" + ((ip >> 0) & 0xFF)\n\n    console.log(\"--> \" + ipstring + \" \" + proto + \":\" + port);\n}\n\nvar targets = new Targets();\ntargets.parse_args(process.argv.splice(2));\ntargets.print();\n\nTransmitThread(targets, transmit, 42);\n\n"
  },
  {
    "path": "doc/bot.html",
    "content": "<html>\n<head>\n<title>Masscan/1.0 - fast port scanner</title>\n</head>\n<body>\n<h1>Masscan/1.0 - fast port scanner</h1>\n\n<p>This tool is not a web spider, but a port scanner. It'll make only one request to a website, usually for the root / webpage. It then records the <b>Server:</b> field from the HTTP header, the <b>&lt;title&gt;</b> from the page contents, and possibly a few other interesting fields.</p>\n\n<p>This does not follow links, it doesn't scan your web pages, but the ports on your machine.</p>\n\n<p>The source code for this tool is at <a href=\"https://github.com/robertdavidgraham/masscan/\">https://github.com/robertdavidgraham/masscan/</a>. This is an open source project, so that this means it's not me (Robert Graham) who is using this tool to scan your website, but likely somebody else. I can't speak for their intentions, but this tool is more useful at doing surveys of the Internet than trying to hack in (tools like 'nmap' or 'nessus' are more often used for that).</p>\n\n\n\n</body>\n</html>\n"
  },
  {
    "path": "doc/faq/FAQ0001-slow.md",
    "content": "# Why is it not as fast as I expect?\r\n\r\n## Question\r\n\r\nWhy is scanning speed only around 100,000 packets-per-second instead of a million packets-per-second?\r\n\r\n## Answer\r\n\r\nI don't know.\r\n\r\nIf you have the latest Linux distro on the latest hardware, you can sometime\r\nsee scanning speeds of 1 million packets-per-second, even when virtualized.\r\n\r\nHowever, sometimes you also see only 100,000 packets-per-second.\r\n\r\nI've spent a lot of time trying to diagnose this situation and cannot\r\nfigure out what's going on. The box I use in a colo does 500,000 packets-per-second.\r\nA relatively slow machine in my home lab does 1.2 million packets-per-second.\r\n\r\nThe speed is determined by the operating system. The amount of CPU used by `masscan`\r\nitself is insignificant.\r\n\r\nMy theory is various configuration options within the operating system that can make\r\npacket transmission very slow. Simple features that would not otherwise impact network\r\nstacks that run at lower rates become really important at high rates.\r\n\r\nOne way around this is to install `PF_RING` and dedicate a network adapter to packet\r\ntransmission completely bypassing the operating system. In that case, packet transmission\r\nrates can reach 15 million packets-per-second.\r\n"
  },
  {
    "path": "doc/faq/FAQ0002-drops.md",
    "content": "# Why are many results missing that I expect?\r\n\r\n# Question\r\n\r\nWhen I do a scan, results are missing that I know are there.\r\nThey show up when I repeat the scan, but then others are missing.\r\nThe faster I scan, the more results are missing.\r\n\r\n# Answer\r\n\r\nNetwork infrastructure does not like high rates of small packets.\r\nEven though they can handle high **bit-rates** then cannot handle\r\nhigh **packet-rates**.\r\n\r\nThis is what makes `masscan` so unique. It transmits packets at rates\r\nfar higher than other things can cope with. It often crashes networks.\r\n\r\nTherefore, the faster you transmit packets, the more it overloads network\r\nequipment, causing the packets to be dropped, causing probes to fail.\r\n\r\nAs the issue #546 below indicates, they are experiencing this at very low\r\nrates of less than 10,000 packets-per-second. That seems excessively low.\r\nI assume the actual reason is because of policy enforcement limiting traffic\r\nrates rather than overloading network equipment.\r\n\r\n\r\n\r\n# Issues\r\n\r\n- [#546 fast scan get result](https://github.com/robertdavidgraham/masscan/issues/546)\r\n\r\n"
  },
  {
    "path": "doc/faq/FAQ0003-excludelist.md",
    "content": "# How can I add my IP address to an exclude list so that people stop scanning me?\r\n\r\n# Question\r\n\r\nI hate everyone probing me all the time and want them to stop.\r\nHow can I add my IP address ranges to an exclude list?\r\n\r\n# Answer\r\n\r\nYou can't.\r\n\r\nFirst of all, nobody is going to pay attention to a sample exclude list\r\nwithin this project. Sure, I can add IP addresses to the list, but that\r\nwon't help you.\r\n\r\nSecond, there's no way I can confirm who you are. So I can't simply\r\nadd to an exclude list just because you ask.\r\n\r\nThirdly, it'll just make you more of a target, as smart hackers know to\r\nuse the exclude-list as one of their first include-lists, as it marks\r\npeople who have something to hide.\r\n\r\nFourthly, and most importantly, it's Wrong Think on how to manage your\r\nnetwork.\r\n\r\n"
  },
  {
    "path": "doc/faq/FAQ0004-serverlogs.md",
    "content": "# Why is masscan in my server logs?\r\n\r\n## Question\r\n\r\nSome example questions:\r\n* Why is `masscan` appearing in my server logs?\r\n* Why are you scanning me?\r\n* Why is my server trying to connect to this github repo?\r\n\r\n## Answer\r\n\r\nWhen `masscan` connections to a webserver, it puts a link\r\nback to this repo in the `User-Agent` field.\r\n\r\nSince lots of people run Internet-wide scans using this tool,\r\nand an Internet wide scan hits every public web server, you'll\r\nsee this appear in your web server logs several times a day.\r\n\r\nIt's the **end-to-end** principle of the Internet. Having a public\r\nwebserver on the Internet means that anybody can and will try to\r\nconnect to the web server.\r\n\r\nIt's nothing necessarily malicious. Lots of people run Internet-wide\r\nscans to gather information about the state of the Internet. Of course,\r\nsome are indeed malicious, scanning to find vulnerabilities. However,\r\neven when malicious, they probably aren't targetting you in particular,\r\nbut are instead scanning everybody.\r\n\r\n"
  },
  {
    "path": "doc/faq/README.md",
    "content": "# FAQs (frequently asked questions)\r\n\r\nThis directory contains some documents discussing frequently asked\r\nquestions\r\n\r\n - 1 - [Why is it not as fast as I expect?](FAQ0001-slow.md)\r\n - 2 - [Why are many results missing that I expect?](FAQ0002-drops.md)\r\n - 3 - [How can I add my IPs to an official exclude list, to get people to stop scanning me?](FAQ0003-excludelist.md)\r\n - 4 - [Why is this in my server logs?](FAQ0004-serverlogs.md)\r\n"
  },
  {
    "path": "doc/howto-afl.md",
    "content": "Using afl fuzzer against masscan\n================================\n\nAFL (American-Fuzzy-Lop) is an automated *fuzzer*. It takes existing\ninput to a program, then morphs that input in order to test new \ncode paths through the code. It's extremely successful at finding \nbugs as well as *vulnerabilities*.\n\nThere are two inputs to *masscan*. One is the files it reads, which\ncome in various formats. The second is input from the network, in \nresponse to network probes, which consist of various network protocols.\n\nFor AFL, there is also the issue of how *masscan* crashes. It tries to\nprint a backtrace. This causes AFL to falsely mark this as a \"hang\"\nrather than a \"crash\". To fix this, run *masscan* with the *--nobacktrace*\noption.\n\n## Fuzzing file formats ##\n\nThe *masscan* program reads the following files. You can set the fuzzer\nat each one of these to fuzz how it parses the contents.\n\n*-c <filename.conf>*\n\n*Masscan* can read its configuration either from the command-line or from a file.\nTo create a file, run *masscan* as normal, then hit <ctrl-c>. This will save all\nit's settings, even default values, into a file. It's a good starting point for\nfuzzing.\n\n*--readscan <filename.mass>*\n\nOne of the possible outputs of *masscan* is in a proprietary binary format. You\ncan then run *masscan* to convert to any other output format.\n\nIn other words, you can run masscan to output XML like:\n\n    masscan <blah blah blah> -oX scan.xml\n    \nOr, in a two step process:\n\n    masscan <blah blah blah> -ob scan.mass\n    \n    masscan --readscan scan.mass -oX scan.xml\n    \n\n*--exclude-file <filename.ranges>*\n\n*Masscan* can scan large ragnes, like *0.0.0.0/0* (the entire Internet). You may\nwant to exclude specific addresses or ranges. These are configured in the\n\"exclude file\".\n\nYou can also read ranges using *--include-file <filename.ranges>* or \n*-iL <filename.ranges>*, but as far as fuzzing, I'm pretty sure it'll \nbe the same results.\n\n*--hello-file[<port>] <filename>*\n\nThis file is read, then dumped blindly across a TCP connection, in order\nto say \"hello\" to a service. Since there's no parsing here, I'm not sure\nyou'll find anything fuzzing this.\n\n*--nmap-payloads <filename>*\n\nThis file specifies the default payloads for UDP. It's in the same file\nformat as for *nmap*. There's some juicy parsing here that may lead\nto bugs.\n\n*--pcap-payloads <filename.pcap>*\n\nThis is the same as *--nmap-payloads*, but reads the UDP payloads from\na *libpcap* file.\n\n## Fuzzing network protocols ##\n\n*Masscan* parses several network protocols. It also must reassemble\nfragmented responses over TCP for any application protocol. Remember:\n*masscan* has it's own stack, so must parse everything that comes\nover the network.\n\nAFL has no ability to read from the network at this time. Moreover,\neven then it wouldn't work easily, since *masscan* has a network stack\nrather than just an application layer to deal with.\n\nThe trick is to first use *masscan* on a target that responds back\non a protocol, then save just the response side of the TCP connection\nto a file. Then, when running *masscan* under AFL, read in that file\nusing the option *--adapter file:<filename.pcap>*. Then, and this is \ncritical, you must hard code all the TCP stack values to match those\nof the original connection.\n\nI generated the file *masscan/data/afl-http.pcap* as an example file\nto read for fuzzing the parsing of HTTP. The command-line parameters\nto use are:\n\n    bin/masscan --nobacktrace --adapter file:data/afl-http.pcap --source-ip 10.20.30.200 --source-port 6000 --source-mac 00-11-22-33-44-55 --router-mac c0-c1-c0-a0-9b-9d --seed 0 --banners -p80 74.125.196.147 --nostatus\n\nThe explanation are:\n\n    *--nobacktrace*: so that AFL correctly marks crashes as crashes\n    and not as hangs.\n    \n    *--adapter file:*: This option normally specifies the adapter,\n    like *eth0* or *en1*. By putting the *file:* prefix on an adapter name,\n    it'll use a file (in *libpcap* format) to use instead. In this case,\n    transmits are dropped, and any packets are read from a file.\n    \n    *--source-ip*, *--source-port*, *--source-mac*, *--router-mac*:\n    These are the hard-coded TCP/IP stack settings that must match the packets\n    in the file.\n    \n    *--seed*: This must match the randomization seed in the packet file. Since\n    everything else is hardcoded, I think the only thing this will control\n    will be the sequence number of the TCP connection.\n    \n    *--banners*: this tell the scanner to not simply find open ports, but also\n    establish a TCP connection and interact with the protocol, and report on\n    the results.\n    \n    *-p<port>*: The destination IP address to connect to.\n    \n    *<ip-address>*: The IP address to connect to\n\nThis should produce an output like the following. If you get the\nbanner back, then you know you've successfully done everything\ncorrectly. Conversely, if you set *--seed 1*, then it won't work,\nbecause it'll reject responses that match the wrong seed.\n\n    Starting masscan 1.0.3 (http://bit.ly/14GZzcT) at 2016-06-06 05:19:03 GMT\n    -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth\n    Initiating SYN Stealth Scan\n    Scanning 1 hosts [1 port/host]\n    Discovered open port 80/tcp on 74.125.196.147\n    Banner on port 80/tcp on 74.125.196.147: [title] Google\n    Banner on port 80/tcp on 74.125.196.147: [http] HTTP/1.0 200 OK\\x0d\\x0a...\n    ...\n    \n(Additional output is truncated -- you get the idea).\n\nThe problem with this is that *masscan* will take about 10 seconds before it \nproduces the results. When it establishes a connection, it waits a few seconds\nfor the other side to transmit, then sends it's \"hello\", then waits many\nseconds for all output to be received. I don't know if this messes AFL up,\nwhether I need to add additional options to truncate any waiting.\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "doc/masscan.8",
    "content": ".\\\" generated with Ronn/v0.7.3\r\n.\\\" http://github.com/rtomayko/ronn/tree/0.7.3\r\n.\r\n.TH \"MASSCAN\" \"8\" \"January 2014\" \"\" \"\"\r\n.\r\n.SH \"NAME\"\r\n\\fBmasscan\\fR \\- Fast scan of the Internet\r\n.\r\n.SH \"SYNOPSIS\"\r\nmasscan [\\fIoptions\\fR] [<IP|RANGE>...  \\-p \\fIPORT\\fR[,\\fIPORT\\fR...]]\r\n.\r\n.SH \"DESCRIPTION\"\r\n\\fBmasscan\\fR is an Internet\\-scale port scanner, useful for large scale surveys of the Internet, or of internal networks\\. While the default transmit rate is only 100 packets/second, it can optional go as fast as 25 million packets/second, a rate sufficient to scan the Internet in 3 minutes for one port\\.\r\n.\r\n.SH \"OPTIONS\"\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB<IP|RANGE>\\fR: anything on the command\\-line not prefixed with a \\'\\-\\' is assumed to be an IP address or range\\. There are three valid formats\\. The first is a single IPv4 address like \"192\\.168\\.0\\.1\"\\. The second is a range like \"10\\.0\\.0\\.1\\-10\\.0\\.0\\.100\"\\. The third is a CIDR address, like \"0\\.0\\.0\\.0/0\"\\. At least one target must be specified\\. Multiple targets can be specified\\. This can be specified as multiple options separated by space, or can be separated by a comma as a single option, such as \\fB10\\.0\\.0\\.0/8,192\\.168\\.0\\.1\\fR\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-range <IP|RANGE>\\fR: the same as target range spec described above, except as a named parameter instead of an unnamed one\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-p PORT[,PORT...]\\fR, \\fB\\-\\-ports PORT[,PORT...]\\fR: specifies the port(s) to be scanned\\. A single port can be specified, like \\fB\\-p80\\fR\\. A range of ports can be specified, like \\fB\\-p 20\\-25\\fR\\. A list of ports/ranges can be specified, like \\fB\\-p80,20\\-25\\fR\\. UDP ports can also be specified, like \\fB\\-\\-ports U:161,U:1024\\-1100\\fR\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-banners\\fR: specifies that banners should be grabbed, like HTTP server versions, HTML title fields, and so forth\\. Only a few protocols are supported\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-rate RATE\\fR: specifies the desired rate for transmitting packets\\. This can be very small numbers, like \\fB0\\.1\\fR for transmitting packets at rates of one every 10 seconds, for very large numbers like 10000000, which attempts to transmit at 10 million packets/second\\. In my experience, Windows and can do 250 thousand packets per second, and latest versions of Linux can do 2\\.5 million packets per second\\. The PF_RING driver is needed to get to 25 million packets/second\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-c FILE\\fR, \\fB\\-\\-conf FILE\\fR: reads in a configuration file\\. The format of the configuration file is described below\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-resume FILE\\fR: the same as \\fB\\-\\-conf\\fR, except that a few options are automatically set, such as \\fB\\-\\-append\\-output\\fR\\. The format of the configuration file is described below\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-echo\\fR: don\\'t run, but instead dump the current configuration to a file\\. This file can then be used with the \\fB\\-c\\fR option\\. The format of this output is described below under \\'CONFIGURATION FILE\\'\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-e IFNAME\\fR, \\fB\\-\\-adapter IFNAME\\fR: use the named raw network interface, such as \"eth0\" or \"dna1\"\\. If not specified, the first network interface found with a default gateway will be used\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-adapter\\-ip IP\\fR: send packets using this IP address\\. If not specified, then the first IP address bound to the network interface will be used\\. Instead of a single IP address, a range may be specified\\. NOTE: The size of the range must be an even power of 2, such as 1, 2, 4, 8, 16, 1024 etc\\. addresses\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-adapter\\-port PORT\\fR: send packets using this port number as the source\\. If not specified, a random port will be chosen in the range 40000 through 60000\\. This port should be filtered by the host firewall (like iptables) to prevent the host network stack from interfering with arriving packets\\. Instead of a single port, a range can be specified, like \\fB40000\\-40003\\fR\\. NOTE: The size of the range must be an even power of 2, such as the example above that has a total of 4 addresses\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-adapter\\-mac MAC\\fR: send packets using this as the source MAC address\\. If not specified, then the first MAC address bound to the network interface will be used\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-router\\-mac MAC\\fR: send packets to this MAC address as the destination\\. If not specified, then the gateway address of the network interface will be ARPed\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-ping\\fR: indicates that the scan should include an ICMP echo request\\. This may be included with TCP and UDP scanning\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-exclude <IP|RANGE>\\fR: blacklist an IP address or range, preventing it from being scanned\\. This overrides any target specification, guaranteeing that this address/range won\\'t be scanned\\. This has the same format as the normal target specification\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-excludefile FILE\\fR: reads in a list of exclude ranges, in the same target format described above\\. These ranges override any targets, preventing them from being scanned\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-append\\-output\\fR: causes output to append to the file, rather than overwriting the file\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-iflist\\fR: list the available network interfaces, and then exits\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-retries NUM\\fR: the number of retries to send, at 1 second intervals\\. Note that since this scanner is stateless, retries are sent regardless if replies have already been received\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-nmap\\fR: print help about nmap\\-compatibility alternatives for these options\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-pcap\\-payloads FILE\\fR: read packets from a libpcap file containing packets and extract the UDP payloads, and associate those payloads with the destination port\\. These payloads will then be used when sending UDP packets with the matching destination port\\. Only one payload will be remembered per port\\. Similar to \\fB\\-\\-nmap\\-payloads\\fR\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-nmap\\-payloads FILE\\fR: read in a file in the same format as the nmap file \\fBnmap\\-payloads\\fR\\. This contains UDP payload, so that we can send useful UDP packets instead of empty ones\\. Similar to \\fB\\-\\-pcap\\-payloads\\fR\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-http\\-user\\-agent USER_AGENT\\fR: replaces the existing user\\-agent field with the indicated value when doing HTTP requests\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-open\\-only\\fR: report only open ports, not closed ports\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-pcap FILE\\fR: saves received packets (but not transmitted packets) to the libpcap\\-format file\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-packet\\-trace\\fR: prints a summary of those packets sent and received\\. This is useful at low rates, like a few packets per second, but will overwhelm the terminal at high rates\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-pfring\\fR: force the use of the PF_RING driver\\. The program will exit if PF_RING DNA drvers are not available\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-resume\\-index INDEX\\fR: the point in the scan at when it was paused\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-resume\\-count NUM\\fR: the maximum number of probes to send before exiting\\. This is useful with the \\fB\\-\\-resume\\-index\\fR to chop up a scan and split it among multiple instances, though the \\fB\\-\\-shards\\fR option might be better\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-shards X/Y\\fR: splits the scan among instances\\. \\fBx\\fR is the id for this scan, while \\fBy\\fR is the total number of instances\\. For example, \\fB\\-\\-shards 1/2\\fR tells an instance to send every other packet, starting with index 0\\. Likewise, \\fB\\-\\-shards 2/2\\fR sends every other packet, but starting with index 1, so that it doesn\\'t overlap with the first example\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-rotate TIME\\fR: rotates the output file, renaming it with the current timestamp, moving it to a separate directory\\. The time is specified in number of seconds, like \"3600\" for an hour\\. Or, units of time can be specified, such as \"hourly\", or \"6hours\", or \"10min\"\\. Times are aligned on an even boundary, so if \"daily\" is specified, then the file will be rotated every day at midnight\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-rotate\\-offset TIME\\fR: an offset in the time\\. This is to accommodate timezones\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-rotate\\-dir DIR\\fR: when rotating the file, this specifies which directory to move the file to\\. A useful directory is \\fB/var/log/masscan\\fR\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-seed INT\\fR: an integer that seeds the random number generator\\. Using a different seed will cause packets to be sent in a different random order\\. Instead of an integer, the string \\fBtime\\fR can be specified, which seeds using the local timestamp, automatically generating a differnet random order of scans\\. If no seed specified, \\fBtime\\fR is the default\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-regress\\fR: run a regression test, returns \\'0\\' on success and \\'1\\' on failure\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-ttl NUM\\fR: specifies the TTL of outgoing packets, defaults to 255\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-wait SECONDS\\fR: specifies the number of seconds after transmit is done to wait for receiving packets before exiting the program\\. The default is 10 seconds\\. The string \\fBforever\\fR can be specified to never terminate\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-offline\\fR: don\\'t actually transmit packets\\. This is useful with a low rate and \\fB\\-\\-packet\\-trace\\fR to look at what packets might\\'ve been transmitted\\. Or, it\\'s useful with \\fB\\-\\-rate 100000000\\fR in order to benchmark how fast transmit would work (assuming a zero\\-overhead driver)\\. PF_RING is about 20% slower than the benchmark result from offline mode\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-sL\\fR: this doesn\\'t do a scan, but instead creates a list of random addresses\\. This is useful for importing into other tools\\. The options \\fB\\-\\-shard\\fR, \\fB\\-\\-resume\\-index\\fR, and \\fB\\-\\-resume\\-count\\fR can be useful with this feature\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-interactive\\fR: show the results in realtime on the console\\. It has no effect if used with \\-\\-output\\-format or \\-\\-output\\-filename\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-output\\-format FMT\\fR: indicates the format of the output file, which can be \\fBxml\\fR, \\fBbinary\\fR, \\fBgrepable\\fR, \\fBlist\\fR, or \\fBJSON\\fR\\. The option \\fB\\-\\-output\\-filename\\fR must be specified\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-output\\-filename FILE\\fR: the file which to save results to\\. If the parameter \\fB\\-\\-output\\-format\\fR is not specified, then the default of \\fBxml\\fR will be used\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-oB FILE\\fR: sets the output format to binary and saves the output in the given filename\\. This is equivelent to using the \\fB\\-\\-output\\-format\\fR and \\fB\\-\\-output\\-filename\\fR parameters\\. The option \\fB\\-\\-readscan\\fR can then be used to read the binary file\\. Binary files are much smaller than their XML equivelents, but require a separate step to convert back into XML or another readable format\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-oX FILE\\fR: sets the output format to XML and saves the output in the given filename\\. This is equivelent to using the \\fB\\-\\-output\\-format xml\\fR and \\fB\\-\\-output\\-filename\\fR parameters\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-oG FILE\\fR: sets the output format to grepable and saves the output in the given filename\\. This is equivelent to using the \\-\\-output\\-format grepable and \\-\\-output\\-filename parameters\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-oJ FILE\\fR: sets the output format to JSON and saves the output in the given filename\\. This is equivelent to using the \\-\\-output\\-format json and \\-\\-output\\-filename parameters\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-oL FILE\\fR: sets the output format to a simple list format and saves the output in the given filename\\. This is equivelent to using the \\-\\-output\\-format list and \\-\\-output\\-filename parameters\\.\r\n.\r\n.IP \"\\(bu\" 4\r\n\\fB\\-\\-readscan FILE\\fR: reads the files created by the \\fB\\-oB\\fR option from a scan, then outputs them in one of the other formats, depending on command\\-line parameters\\. In other words, it can take the binary version of the output and convert it to an XML or JSON format\\.\r\n.\r\n.IP \"\" 0\r\n.\r\n.SH \"CONFIGURATION FILE FORMAT\"\r\nThe configuration file uses the same parameter names as on the commandline, but without the \\fB\\-\\-\\fR prefix, and with an \\fB=\\fR sign between the name and the value\\. An example configuration file might be:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# targets\r\nrange = 10\\.0\\.0\\.0/8,192\\.168\\.0\\.0/16\r\nrange = 172\\.16\\.0\\.0/14\r\nports = 20\\-25,80,U:53\r\nping = true\r\n\r\n# adapter\r\nadapter = eth0\r\nadapter\\-ip = 192\\.168\\.0\\.1\r\nrouter\\-mac = 66\\-55\\-44\\-33\\-22\\-11\r\n\r\n# other\r\nexclude\\-file = /etc/masscan/exludes\\.txt\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nBy default, the program will read default configuration from the file \\fB/etc/masscan/masscan\\.conf\\fR\\. This is useful for system\\-specific settings, such as the \\fB\\-\\-adapter\\-xxx\\fR options\\. This is also useful for excluded IP addresses, so that you can scan the entire Internet, while skipping dangerous addresses, like those owned by the DoD, and not make an accidental mistake\\.\r\n.\r\n.SH \"CONTROL\\-C BEHAVIOR\"\r\nWhen the user presses \\fIctrl\\-c\\fR, the scan will stop, and the current state of the scan will be saved in the file \\'paused\\.conf\\'\\. The scan can be resumed with the \\fB\\-\\-resume\\fR option:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan \\-\\-resume paused\\.conf\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nThe program will not exit immediately, but will wait a default of 10 seconds to receive results from the Internet and save the results before exiting completely\\. This time can be changed with the \\fB\\-\\-wait\\fR option\\.\r\n.\r\n.SH \"SIMPLE EXAMPLES\"\r\nThe following example scans all private networks for webservers, and prints all open ports that were found\\.\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 10\\.0\\.0\\.0/8 192\\.168\\.0\\.0/16 172\\.16\\.0\\.0/12 \\-p80 \\-\\-open\\-only\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nThe following example scans the entire Internet for DNS servers, grabbing their versions, then saves the results in an XML file\\.\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 0\\.0\\.0\\.0/0 \\-\\-excludefile no\\-dod\\.txt \\-pU:53 \\-\\-banners \\-\\-output\\-filename dns\\.xml\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nYou should be able to import the XML into databases and such\\.\r\n.\r\n.P\r\nThe following example reads a binary scan results file called bin\\-test\\.scan and prints results to console\\.\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan \\-\\-readscan bin\\-test\\.scan\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nThe following example reads a binary scan results file called bin\\-test\\.scan and creates an XML output file called bin\\-test\\.xml\\.\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan \\-\\-readscan bin\\-test\\.scan \\-oX bin\\-test\\.xml\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.SH \"ADVANCED EXAMPLES\"\r\nLet\\'s say that you want to scan the entire Internet and spread the scan across three machines\\. Masscan would be launched on all three machines using the following command\\-lines:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-shard 1/3\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-shard 2/3\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-shard 3/3\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nAn alternative is with the \"resume\" feature\\. A scan has an internal index that goes from zero to the number of ports times then number of IP addresses\\. The following example shows splitting up a scan into chunks of a 1000 items each:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-resume\\-index 0 \\-\\-resume\\-count 1000\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-resume\\-index 1000 \\-\\-resume\\-count 1000\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-resume\\-index 2000 \\-\\-resume\\-count 1000\r\n# masscan 0\\.0\\.0\\.0/0 \\-p0\\-65535 \\-\\-resume\\-index 3000 \\-\\-resume\\-count 1000\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nA script can use this to split smaller tasks across many other machines, such as Amazon EC2 instances\\. As each instance completes a job, the script might send a request to a central coordinating server for more work\\.\r\n.\r\n.SH \"SPURIOUS RESETS\"\r\nWhen scanning TCP using the default IP address of your adapter, the built\\-in stack will generate RST packets\\. This will prevent banner grabbing\\. There are are two ways to solve this\\. The first way is to create a firewall rule to block that port from being seen by the stack\\. How this works is dependent on the operating system, but on Linux this looks something like:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# iptables \\-A INPUT \\-p tcp \\-i eth0 \\-\\-dport 61234 \\-j DROP\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nThen, when scanning, that same port must be used as the source:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 10\\.0\\.0\\.0/8 \\-p80 \\-\\-banners \\-\\-adapter\\-port 61234\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nAn alternative is to \"spoof\" a different IP address\\. This IP address must be within the range of the local network, but must not otherwise be in use by either your own computer or another computer on the network\\. An example of this would look like:\r\n.\r\n.IP \"\" 4\r\n.\r\n.nf\r\n\r\n# masscan 10\\.0\\.0\\.0/8 \\-p80 \\-\\-banners \\-\\-adapter\\-ip 192\\.168\\.1\\.101\r\n.\r\n.fi\r\n.\r\n.IP \"\" 0\r\n.\r\n.P\r\nSetting your source IP address this way is the preferred way of running this scanner\\.\r\n.\r\n.SH \"ABUSE COMPLAINTS\"\r\nThis scanner is designed for large\\-scale surveys, of either an organization, or of the Internet as a whole\\. This scanning will be noticed by those monitoring their logs, which will generate complaints\\.\r\n.\r\n.P\r\nIf you are scanning your own organization, this may lead to you being fired\\. Never scan outside your local subnet without getting permission from your boss, with a clear written declaration of why you are scanning\\.\r\n.\r\n.P\r\nThe same applies to scanning the Internet from your employer\\. This is another good way to get fired, as your IT department gets flooded with complaints as to why your organization is hacking them\\.\r\n.\r\n.P\r\nWhen scanning on your own, such as your home Internet or ISP, this will likely cause them to cancel your account due to the abuse complaints\\.\r\n.\r\n.P\r\nOne solution is to work with your ISP, to be clear about precisely what we are doing, to prove to them that we are researching the Internet, not \"hacking\" it\\. We have our ISP send the abuse complaints directly to us\\. For anyone that asks, we add them to our \"\\-\\-excludefile\", blacklisting them so that we won\\'t scan them again\\. While interacting with such people, some instead add us to their whitelist, so that their firewalls won\\'t log us anymore (they\\'ll still block us, of course, they just won\\'t log that fact to avoid filling up their logs with our scans)\\.\r\n.\r\n.P\r\nUltimately, I don\\'t know if it\\'s possible to completely solve this problem\\. Despite the Internet being a public, end\\-to\\-end network, you are still \"guilty until proven innocent\" when you do a scan\\.\r\n.\r\n.SH \"COMPATIBILITY\"\r\nWhile not listed in this document, a lot of parameters compatible with \\fBnmap\\fR will also work\\.\r\n.\r\n.SH \"SEE ALSO\"\r\nnmap(8), pcap(3)\r\n.\r\n.SH \"AUTHORS\"\r\nThis tool was written by Robert Graham\\. The source code is available at https://github\\.com/robertdavidgraham/masscan\\.\r\n"
  },
  {
    "path": "doc/masscan.8.markdown",
    "content": "masscan(8) -- Fast scan of the Internet\n=======================================\n\n## SYNOPSIS\n\nmasscan \\[options\\] \\[<IP|ranges>... -p PORT\\[,PORT...\\]\\]\n\n## DESCRIPTION\n\n**masscan** is an Internet-scale port scanner, useful for large scale surveys\nof the Internet, or of internal networks. While the default transmit rate\nis only 100 packets/second, it can optionally go as fast as 25 million\npackets/second, a rate sufficient to scan the Internet in 3 minutes for\none port.\n\n## OPTIONS\n\n  * `<IP|RANGE>`: anything on the command-line not prefixed with a '-' is\n    assumed to be an IP address or range. There are three valid formats.\n\tThe first is a single IP address like `192.168.0.1` or `2001:db8::1`. The second\n\tis a range like `10.0.0.1-10.0.0.100`. The third is a CIDR address,\n\tlike `0.0.0.0/0` or `2001:db8::/90`. At least one target must be specified. Multiple \n\ttargets can be specified. This can be specified as multiple options\n\tseparated by space, or can be separated by a comma as a single option,\n\tsuch as `10.0.0.0/8,192.168.0.1,2001:db8::1`.\n\n  * `--range <IP|RANGE>`: the same as target range spec described above,\n    except as a named parameter instead of an unnamed one.\n\n  * `-p PORT[,PORT..]`, `--ports PORT[,PORT...]`: specifies the port(s) to be scanned. A \n    single port can be specified, like `-p80`. A range of ports can be \n    specified, like `-p 20-25`. A list of ports/ranges can be specified, like\n\t`-p80,20-25`. UDP ports can also be specified, like\n\t`--ports U:161,U:1024-1100`.\n\n  * `--banners`: specifies that banners should be grabbed after establishing\n\ta TCP connection. Protocols supported include HTTP, FTP, IMAP4, memcached,\n\tPOP3, SMTP, SSH, SSL, SMB, Telnet, RDP, and VNC.\n\n  * `--rate RATE`: specifies the desired rate for transmitting\n    packets. This can be very small numbers, like `0.1` for transmitting \n    packets at rates of one every 10 seconds, for very large numbers like \n    10000000, which attempts to transmit at 10 million packets/second. In my\n    experience, Windows and can do 250 thousand packets per second, and latest\n    versions of Linux can do 2.5 million packets per second. The PF_RING driver\n    is needed to get to 25 million packets/second.\n\n  * `-c FILE`, `--conf FILE`: reads in a configuration file. \n    If not specified, then will read from `/etc/masscan/masscan.conf` by default.\n\tThe format is described below under 'CONFIGURATION FILE'.\n\n  * `--resume FILE`: the same as `--conf`, except that a few options\n    are automatically set, such as `--append-output`. The format of the \n\tconfiguration file is described below. The purpose is to resume a scan\n\tsaved in `paused.conf` that was interupted with [ctrl-c].\n\n  * `--echo`: don't run, but instead dump the current configuration to a file.\n    This file can then be used with the `-c` option. The format of this\n\toutput is described below under 'CONFIGURATION FILE'.\n\n  * `-e IFNAME`, `--adapter IFNAME`: use the named raw network interface,\n\tsuch as \"eth0\" or \"dna1\". If not specified, the first network interface\n\tfound with a default gateway will be used.\n\n  * `--adapter-ip IP`, `--source-ip IP`: send packets using this IP address. If not\n    specified, then the first IP address bound to the network interface\n\twill be used. Instead of a single IP address, a range may be specified.\n\tNOTE: The size of the range must be an even power of 2, such as 1, 2, 4,\n\t8, 16, 1024 etc. addresses.\n\n  * `--adapter-port PORT`: send packets using this port number as the\n    source. If not specified, a random port will be chosen in the range 40000\n\tthrough 60000. This port should be filtered by the host firewall (like\n\tiptables) to prevent the host network stack from interfering with arriving\n\tpackets. Instead of a single port, a range can be specified, like\n\t`40000-40003`. NOTE: The size of the range must be an even power of 2,\n\tsuch as the example above that has a total of 4 addresses.\n\n  * `--adapter-mac MAC`: send packets using this as the source MAC\n    address. If not specified, then the first MAC address bound to the network\n\tinterface will be used.\n    \n  * `--adapter-vlan VLANID`: send packets using this 802.1q VLAN ID\n\n  * `--router-mac MAC`: send packets to this MAC address as the\n    destination. If not specified, then the gateway address of the network\n\tinterface will be ARPed.\n\n  * `--ping`: indicates that the scan should include an ICMP echo request.\n    This may be included with TCP and UDP scanning.\n\n  * `--exclude <IP|RANGE>`: blacklist an IP address or range, preventing it\n    from being scanned. This overrides any target specification, guaranteeing\n\tthat this address/range won't be scanned. This has the same format\n\tas the normal target specification.\n\n  * `--excludefile FILE`: reads in a list of exclude ranges, in the same\n    target format described above. These ranges override any targets,\n\tpreventing them from being scanned.\n\n  * `-iL FILE`, `--includefile FILE`: reads in a list of ranges to scan, in the same\n    target format described above for IP addresses and ranges. This file can contain\n\tmillions of addresses and ranges.\n\n  * `--append-output`: causes output to append to the file, rather than\n    overwriting the file. Useful for when resumeing scans (see `--resume`).\n\n  * `--iflist`: list the available network interfaces, and then exits. The\n    `-e IFNAME` can then be used with one of the listed adapters.\n\n  * `--retries <num>`: the number of retries to send, at 1 second intervals. Note\n    that since this scanner is stateless, retries are sent regardless if\n\treplies have already been received.\n\n  * `--nmap`: print help about nmap-compatibility alternatives for these\n    options.\n\n  * `--pcap-payloads FILE`: read packets from a libpcap file containing packets\n    and extract the UDP payloads, and associate those payloads with the\n\tdestination port. These payloads will then be used when sending UDP\n\tpackets with the matching destination port. Only one payload will\n\tbe remembered per port. Similar to `--nmap-payloads`.\n\n  * `--nmap-payloads FILE`: read in a file in the same format as \n    the nmap file `nmap-payloads`. This contains UDP payload, so that we\n\tcan send useful UDP packets instead of empty ones. Similar to\n\t`--pcap-payloads`.\n\n  * `--http-* HEADER`: replaces the existing field in the HTTP header\n    with a new one. Fields that can be replaced are `--http-method`, `--http-url`,\n\t `--http-version`,`--http-host`, and `--http-user-agent`.\n\t Example: `--http-user-agent Keurig K575 Coffee Maker`. See also `--http-field` and `--http-cookie`.\n\n  * `--http-field NAME:VALUE`: replaces the existing HTTP header field,\n    or inserts a new one if the field doesn't exist, given as a `name:value` pair. \n\tCannot be used to replace the fields in the request-line (method, url, version).\n\tExample: `--http-field Accept:image/gif`.\n    \n  * `--http-field-remove NAME`: removes the first field from the header that matches\n       (may be needed multiple times for fields like `Cookie` that can exist multiple times)\n\n  * `--http-cookie VALUE`: adds a `Cookie:` field to the HTTP header, even\n    if other cookie fields exist. The other `--http-*` options replace existing\n\tfields in the HTTP header, this one adds more even if some already exist.\n\n  * `--http-payload STR`: adds a payload string after the header; this will\n    automatically add a `--http-field Content-Length:LEN` field to match the length of the string,\n    but the user will have to add their own `--http-field Content-Type:TYPE` field to match\n    the string. Presumably, the user will also change the method to something like\n    `--http-method POST`. Common conntent types would be `application/x-www-form-urlencoded`,\n    `application/json`,  or `text/xml`.\n\n\n  * `--show [open|closed]`: tells which port status to display, such\n    as 'open' for those ports that respond with a SYN-ACK on TCP, or\n\t'closed' for those ports that repsond with RST. The default is\n\tonly to display 'open' ports.\n\n  * `--noshow [open|closed]`: disables a port status to display, such\n    as to no longer display 'open' ports.\n\n  * `--pcap FILE`: saves received packets (but not transmitted\n    packets) to the libpcap-format file.\n\n  * `--packet-trace`: prints a summary of those packets sent and received.\n    This is useful at low rates, like a few packets per second, but will\n\toverwhelm the terminal at high rates.\n\n  * `--pfring`: force the use of the PF_RING driver. The program will exit\n    if PF_RING DNA drvers are not available.\n\n  * `--resume-index INDEX`: the point in the scan at when it was paused.\n\n  * `--resume-count NUM`: the maximum number of probes to send before exiting.\n    This is useful with the `--resume-index` to chop up a scan and split\n\tit among multiple instances, though the `--shards` option might be \n\tbetter.\n\n  * `--shards X/Y`: splits the scan among instances. `x` is the id \n\t  for this scan, while `y` is the total number of instances. For example,\n\t  `--shards 1/2` tells an instance to send every other packet, starting\n\t  with index 0. Likewise, `--shards 2/2` sends every other packet, but\n\t  starting with index 1, so that it doesn't overlap with the first example.\n\n  * `--rotate TIME`: rotates the output file, renaming it with the \n    current timestamp, moving it to a separate directory. The time is\n\tspecified in number of seconds, like \"3600\" for an hour. Or, units\n\tof time can be specified, such as \"hourly\", or \"6hours\", or \"10min\".\n\tTimes are aligned on an even boundary, so if \"daily\" is specified,\n\tthen the file will be rotated every day at midnight.\n\n  * `--rotate-offset TIME`: an offset in the time. This is to accomodate\n    timezones.\n\n  * `--rotate-size SIZE`: rotates the output file when it exceeds the\n    given size. Typical suffixes can be applied (k,m,g,t) for kilo, mega,\n\tgiga, tera.\n\n  * `--rotate-dir DIR`: when rotating the file, this specifies which\n    directory to move the file to. A useful directory is `/var/log/masscan`.\n\n  * `--seed INT`: an integer that seeds the random number generator.\n    Using a different seed will cause packets to be sent in a different\n\trandom order. Instead of an integer, the string `time` can be specified,\n\twhich seeds using the local timestamp, automatically generating a \n\tdifferent random order of scans. If no seed specified, `time` is the\n\tdefault.\n\n  * `--regress`: run a regression test, returns '0' on success and '1' on\n    failure.\n\t\n  * `--ttl NUM`: specifies the TTL of outgoing packets, defaults to 255.\n  \n  * `--wait SECONDS`: specifies the number of seconds after transmit is\n    done to wait for receiving packets before exiting the program. The default\n\tis 10 seconds. The string `forever` can be specified to never terminate.\n\t\n  * `--offline`: don't actually transmit packets. This is useful with\n    a low rate and `--packet-trace` to look at what packets might've been\n\ttransmitted. Or, it's useful with `--rate 100000000` in order to \n\tbenchmark how fast transmit would work (assuming a zero-overhead\n\tdriver). PF_RING is about 20% slower than the benchmark result from\n\toffline mode.\n\n  * `-sL`: this doesn't do a scan, but instead creates a list of random\n    addresses. This is useful for importing into other tools. The options\n\t`--shard`, `--resume-index`, and `--resume-count` can be useful with\n\tthis feature.\n    \n  * `--interactive`: show the results in realtime on the console. It has \n    no effect if used with --output-format or --output-filename.\t\t\n  \n  * `--output-format FMT`: indicates the format of the output file, which\n    can be `xml`, `binary`, `grepable`, `list`, or `JSON`. The \n\toption `--output-filename` must be specified.\n\n  * `--output-filename FILE`: the file which to save results to. If\n    the parameter `--output-format` is not specified, then the default of \n\t`xml` will be used.\n\t\t   \n  * `-oB FILE`: sets the output format to binary and saves the output in\n    the given filename. This is equivalent to using the `--output-format` and\n    `--output-filename` parameters. The option `--readscan` can then be used to\n    read the binary file. Binary files are mush smaller than their XML\n    equivalents, but require a separate step to convert back into XML or\n    another readable format.\n\t\n  * `-oX FILE`: sets the output format to XML and saves the output in the\n    given filename. This is equivalent to using the `--output-format xml` and\n    `--output-filename` parameters.\n\t\n  * `-oG FILE`: sets the output format to grepable and saves the output \n\t  in the given filename. This is equivalent to using the --output-format grepable \n\t  and --output-filename parameters.\n  \n  * `-oJ FILE`: sets the output format to JSON and saves the output in \n\t  the given filename. This is equivalent to using the --output-format json \n\t  and --output-filename parameters.\n  \n  * `-oL FILE`: sets the output format to a simple list format and saves \n\t  the output in the given filename. This is equivalent to using \n\t  the --output-format list and --output-filename parameters.\n\n  *  `--readscan FILE`: reads the files created by the `-oB` option\n    from a scan, then outputs them in one of the other formats, depending\n    on command-line parameters. In other words, it can take the binary\n    version of the output and convert it to an XML or JSON format. When this option\n    is given, defaults from `/etc/masscan/masscan.conf` will not be read.\n\n  * `--connection-timeout SECS`: when doing banner checks, this specifies the\n    maximum number of seconds that a TCP connection can be held open. The default\n    is 30 seconds. Increase this time if banners are incomplete. For example,\n    we have to increase the timeout when downloading all the SSL certs from\n    the Internet, because some sites take that long to deliver all the certs\n    in the chain. However, beware that when this is set to a large value, it'll\n    consume a lot of memory on fast scans. While the code may handle millions of \n    open TCP connections, you may not have enough memory for that.\n\n  * `--hello-file[PORT] FILE`: send the contents of the file once the \n    TCP connection has been established with the given port. Requires that\n    `--banners` also be set. Heuristics will be performed on the reponse in\n    an attempt to discover what protocol, so HTTP responses will be parsed\n    differently than other protocols.\n\n  * `--hello-string[PORT] BASE64`: same as `--hello-file` except that the\n    contents of the BASE64 encoded string are decoded, then used as the hello\n    string that greets the server.\n\n  * `--capture TYPE` or `--nocapture TYPE`: when doing banners (`--banner`), this\n    determines what to capture from the banners. By default, only the TITLE field from\n\tHTML documents is captured, to get the entire document, use `--capture html`.\n\tBy default, the entire certificate from SSL is captured, to disable this, use\n\t`--nocapture cert`. Currently, only the values `html` and `cert` are currently\n\tsupported for this option, but many more will be added in the future.\n    \n\n## CONFIGURATION FILE FORMAT\n\nThe configuration file uses the same parameter names as on the\ncommandline, but without the `--` prefix, and with an `=` sign\nbetween the name and the value. An example configuration file\nmight be:\n\n\t# targets\n\trange = 10.0.0.0/8,192.168.0.0/16\n\trange = 172.16.0.0/12\n\tports = 20-25,80,U:53\n\tping = true\n\n\t# adapter\n\tadapter = eth0\n\tadapter-ip = 192.168.0.1\n\trouter-mac = 66-55-44-33-22-11\n\n\t# other\n\texclude-file = /etc/masscan/exludes.txt\n\nBy default, the program will read default configuration from the file\n`/etc/masscan/masscan.conf`. This is useful for system-specific settings,\nsuch as the `--adapter-xxx` options. This is also useful for \nexcluded IP addresses, so that you can scan the entire Internet,\nwhile skipping dangerous addresses, like those owned by the DoD, \nand not make an accidental mistake.\n\n\n## CONTROL-C BEHAVIOR\n\nWhen the user presses <ctrl-c>, the scan will stop, and the current \nstate of the scan will be saved in the file 'paused.conf'. The scan\ncan be resumed with the `--resume` option:\n\n\t# masscan --resume paused.conf\n\nThe program will not exit immediately, but will wait a default of 10\nseconds to receive results from the Internet and save the results before\nexiting completely. This time can be changed with the `--wait` option.\n\n## USER-MODE STACK\n\nMasscan has a user-mode TCP/IP stack that co-exists with the operating-system's\nstack. Normally, this works fine but sometimes can cause problems, especially\nwith the `--banners` option that establishes a TCP/IP connection. In some\ncases, all the stack's parameters will have to be specified separately:\n\n    --adapter-port PORT\n    --adapter-ip IP\n    --adapter-mac MAC\n    --adapter-vlan VLANID\n    --router-mac MAC\n\nIf the user-mode stack shares the same IP address as the operating-system,\nthen the kernel will send RST packets during a scan. This can cause\nunnecessary traffic during a simple port scan, and will terminate TCP\nconnections when doing a `--banners` scan. To prevent, this, the built-in\nfirewall should be used to filter the source ports. On Linux, this can be done\nby doing something like:\n\n    # iptables -A INPUT -i eth0 -p tcp --dport 44444 -j DROP\n    \nThis will prevent the Linux kernel from processing incoming packets to port\n44444, but `masscan` will still see the packets. Set the maching parameter\nof `--adapter-port 44444` to force `masscan` to use that port instead of\na random port.\n    \n\n## SIMPLE EXAMPLES\n\nThe following example scans all private networks for webservers, and prints\nall open ports that were found.\n\n\t# masscan 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 -p80 --open-only\n\nThe following example scans the entire Internet for DNS servers, grabbing\ntheir versions, then saves the results in an XML file.\n\n\t# masscan 0.0.0.0/0 --excludefile no-dod.txt -pU:53 --banners --output-filename dns.xml\n\nYou should be able to import the XML into databases and such.\n\nThe following example reads a binary scan results file called bin-test.scan and prints\nresults to console.\n\n\t# masscan --readscan bin-test.scan\n\t\nThe following example reads a binary scan results file called bin-test.scan and creates\nan XML output file called bin-test.xml.\n\n\t# masscan --readscan bin-test.scan -oX bin-test.xml\n\n## ADVANCED EXAMPLES\n\nLet's say that you want to scan the entire Internet and spread the scan\nacross three machines. Masscan would be launched on all three machines\nusing the following command-lines:\n\n\t# masscan 0.0.0.0/0 -p0-65535 --shard 1/3\n\t# masscan 0.0.0.0/0 -p0-65535 --shard 2/3\n\t# masscan 0.0.0.0/0 -p0-65535 --shard 3/3\n\nAn alternative is with the \"resume\" feature. A scan has an internal index that\ngoes from zero to the number of ports times the number of IP addresses. The\nfollowing example shows splitting up a scan into chunks of a 1000 items each:\n\n\t# masscan 0.0.0.0/0 -p0-65535 --resume-index 0 --resume-count 1000\n\t# masscan 0.0.0.0/0 -p0-65535 --resume-index 1000 --resume-count 1000\n\t# masscan 0.0.0.0/0 -p0-65535 --resume-index 2000 --resume-count 1000\n\t# masscan 0.0.0.0/0 -p0-65535 --resume-index 3000 --resume-count 1000\n\nA script can use this to split smaller tasks across many other machines,\nsuch as Amazon EC2 instances. As each instance completes a job, the\nscript might send a request to a central coordinating server for more \nwork.\n\n    \n## SPURIOUS RESETS\n\nWhen scanning TCP using the default IP address of your adapter, the built-in\nstack will generate RST packets. This will prevent banner grabbing. There are\nare two ways to solve this. The first way is to create a firewall rule\nto block that port from being seen by the stack. How this works is dependent\non the operating system, but on Linux this looks something like:\n\n    # iptables -A INPUT -p tcp -i eth0 --dport 61234 -j DROP\n\nThen, when scanning, that same port must be used as the source:\n\n    # masscan 10.0.0.0/8 -p80 --banners --adapter-port 61234\n    \nAn alternative is to \"spoof\" a different IP address. This IP address must be\nwithin the range of the local network, but must not otherwise be in use by\neither your own computer or another computer on the network. An example of this\nwould look like:\n\n    # masscan 10.0.0.0/8 -p80 --banners --adapter-ip 192.168.1.101\n\nSetting your source IP address this way is the preferred way of running this\nscanner.\n\n\n## ABUSE COMPLAINTS\n\nThis scanner is designed for large-scale surveys, of either an organization,\nor of the Internet as a whole. This scanning will be noticed by those \nmonitoring their logs, which will generate complaints.\n\nIf you are scanning your own organization, this may lead to you being fired.\nNever scan outside your local subnet without getting permission from your boss,\nwith a clear written declaration of why you are scanning.\n\nThe same applies to scanning the Internet from your employer. This is another\ngood way to get fired, as your IT department gets flooded with complaints as\nto why your organization is hacking them.\n\nWhen scanning on your own, such as your home Internet or ISP, this will likely\ncause them to cancel your account due to the abuse complaints.\n\nOne solution is to work with your ISP, to be clear about precisely what we are\ndoing, to prove to them that we are researching the Internet, not \"hacking\" it.\nWe have our ISP send the abuse complaints directly to us. For anyone that asks,\nwe add them to our \"--excludefile\", blacklisting them so that we won't scan\nthem again. While interacting with such people, some instead add us to their\nwhitelist, so that their firewalls won't log us anymore (they'll still block\nus, of course, they just won't log that fact to avoid filling up their logs\nwith our scans).\n\nUltimately, I don't know if it's possible to completely solve this problem.\nDespite the Internet being a public, end-to-end network, you are still\n\"guilty until proven innocent\" when you do a scan.\n\n\n## COMPATIBILITY\n\nWhile not listed in this document, a lot of parameters compatible with\n`nmap` will also work. It runs on macOS, Linux, and Windows. It's compiled\nin fairly portable C language. It supports IPv4 and IPv6.\n\n## SEE ALSO\n\nnmap(8), pcap(3)\n\n## AUTHORS\n\nThis tool was written by Robert Graham. The source code is available at\nhttps://github.com/robertdavidgraham/masscan.\n"
  },
  {
    "path": "src/crypto-base64.c",
    "content": "#include \"crypto-base64.h\"\n#include <ctype.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n\n/*****************************************************************************\n *****************************************************************************/\nsize_t\nbase64_encode(void *vdst, size_t sizeof_dst, \n              const void *vsrc, size_t sizeof_src)\n{\n    static const char *b64 =\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n        \"abcdefghijklmnopqrstuvwxyz\"\n        \"0123456789\"\n        \"+/\";\n    size_t i = 0;\n    size_t d = 0;\n    unsigned char *dst = (unsigned char *)vdst;\n    const unsigned char *src = (const unsigned char *)vsrc;\n\n    /* encode every 3 bytes of source into 4 bytes of destination text */\n    while (i + 3 <= sizeof_src) {\n        unsigned n;\n        \n        /* make sure there is enough space */\n        if (d + 4 > sizeof_dst)\n            return d;\n\n        /* convert the chars */\n        n = src[i]<<16 | src[i+1]<<8 | src[i+2];\n        dst[d+0] = b64[ (n>>18) & 0x3F ];\n        dst[d+1] = b64[ (n>>12) & 0x3F ];\n        dst[d+2] = b64[ (n>> 6) & 0x3F ];\n        dst[d+3] = b64[ (n>> 0) & 0x3F ];\n\n        i += 3;\n        d += 4;\n    }\n\n    /* If the source text isn't an even multiple of 3 characters, then we'll\n     * have to append a '=' or '==' to the output to compensate */\n    if (i + 2 <= sizeof_src && d + 4 <= sizeof_dst) {\n        unsigned n = src[i]<<16 | src[i+1]<<8;\n        dst[d+0] = b64[ (n>>18) & 0x3F ];\n        dst[d+1] = b64[ (n>>12) & 0x3F ];\n        dst[d+2] = b64[ (n>> 6) & 0x3F ];\n        dst[d+3] = '=';\n        d += 4;\n    } else if (i + 1 <= sizeof_src && d + 4 <= sizeof_dst) {\n        unsigned n = src[i]<<16;\n        dst[d+0] = b64[ (n>>18) & 0x3F ];\n        dst[d+1] = b64[ (n>>12) & 0x3F ];\n        dst[d+2] = '=';\n        dst[d+3] = '=';\n        d += 4;\n    }\n\n    return d;\n}\n\n\n/*****************************************************************************\n *****************************************************************************/\nsize_t\nbase64_decode(void *vdst, size_t sizeof_dst, \n              const void *vsrc, size_t sizeof_src)\n{\n\tstatic const unsigned char rstr[] = {\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,\t62,\t\t0xFF,   0xFF,   0xFF,\t63,\n\t\t52,\t\t53,\t\t54,\t\t55,\t\t56,\t\t57,\t\t58,\t\t59,\t\t\n        60,\t\t61,\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0,\t\t1,\t\t2,\t\t3,\t\t4,\t\t5,\t\t6,\t\t\n        7,\t\t8,\t\t9,\t\t10,\t\t11,\t\t12,\t\t13,\t\t14,\n\t\t15,\t\t16,\t\t17,\t\t18,\t\t19,\t\t20,\t\t21,\t\t22,\t\t\n        23,\t\t24,\t\t25,\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,\t26,\t\t27,\t\t28,\t\t29,\t\t30,\t\t31,\t\t32,\t\t\n        33,\t\t34,\t\t35,\t\t36,\t\t37,\t\t38,\t\t39,\t\t40,\n\t\t41,\t\t42,\t\t43,\t\t44,\t\t45,\t\t46,\t\t47,\t\t48,\t\t\n        49,\t\t50,\t\t51,\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t\t0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   \n        0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF,\n\t};\n    size_t i = 0;\n    size_t d = 0;\n    unsigned char *dst = (unsigned char *)vdst;\n    const unsigned char *src = (const unsigned char *)vsrc;\n\n\n\twhile (i < sizeof_src) {\n        unsigned b;\n\t\tunsigned c=0;\n\n\t\t/* byte#1 */\n\t\twhile (i<sizeof_src && (c = rstr[src[i]]) > 64)\n\t\t\ti++;\n\t\tif (src[i] == '=' || i++ >= sizeof_src)\n\t\t\tbreak;\n\t\tb = (c << 2) & 0xfc;\n\t\n\t\twhile (i<sizeof_src && (c = rstr[src[i]]) > 64)\n\t\t\ti++;\n\t\tif (src[i] == '=' || i++ >= sizeof_src)\n\t\t\tbreak;\n\t\tb |= (c>>4) & 0x03;\n\t\tif (d<sizeof_dst)\n\t\t\tdst[d++] = (unsigned char)b;\n\t\tif (i>=sizeof_src)\n\t\t\tbreak;\n\n\t\t/* byte#2 */\n\t\tb = (c<<4) & 0xF0;\n\t\twhile (i<sizeof_src && src[i] != '=' && (c = rstr[src[i]]) > 64)\n\t\t\t;\n\t\tif (src[i] == '=' || i++ >= sizeof_src)\n\t\t\tbreak;\n\t\tb |= (c>>2) & 0x0F;\n\t\tif (d<sizeof_dst)\n\t\t\tdst[d++] = (unsigned char)b;\n\t\tif (i>=sizeof_src)\n\t\t\tbreak;\n\n\t\t/* byte#3*/\n\t\tb = (c<<6) & 0xC0;\n\t\twhile (i<sizeof_src && src[i] != '=' && (c = rstr[src[i]]) > 64)\n\t\t\t;\n\t\tif (src[i] == '=' || i++ >= sizeof_src)\n\t\t\tbreak;\n\t\tb |= c;\n\t\tif (d<sizeof_dst)\n\t\t\tdst[d++] = (unsigned char)b;\n\t\tif (i>=sizeof_src)\n\t\t\tbreak;\n\t}\n\n\tif (d<sizeof_dst)\n\t\tdst[d] = '\\0';\n\treturn d;\n}\n\n/*****************************************************************************\n * Provide my own rand() simply to avoid static-analysis warning me that\n * 'rand()' is unrandom, when in fact we want the non-random properties of\n * rand() for regression testing.\n *****************************************************************************/\nstatic unsigned\nr_rand(unsigned *seed)\n{\n    static const unsigned a = 214013;\n    static const unsigned c = 2531011;\n    \n    *seed = (*seed) * a + c;\n    return (*seed)>>16 & 0x7fff;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nint\nbase64_selftest(void)\n{\n    char buf[100];\n    char buf2[100];\n    char buf3[100];\n    size_t buf_len;\n    size_t buf2_len;\n    unsigned i;\n    unsigned seed = (unsigned)time(0);\n\n    buf_len = base64_encode(buf, sizeof(buf), \"hello\", 5);\n    buf2_len = base64_decode(buf2, sizeof(buf2), buf, buf_len);\n    if (buf2_len != 5 && memcmp(buf2, \"hello\", 5) != 0) {\n        fprintf(stderr, \"base64: selftest failed\\n\");\n        return 1;\n    }\n\n    /*\n     * Generate a bunch of random strings, encode them, then decode them,\n     * making sure the final result matches the original string\n     */\n    for (i=0; i<100; i++) {\n        unsigned j;\n        size_t buf3_len;\n\n        /* create a string of random bytes */\n        buf_len = r_rand(&seed) % 50;\n        for (j=0; j<buf_len; j++) {\n            buf[j] = (char)r_rand(&seed);\n        }\n\n        /* encode it */\n        buf2_len = base64_encode(buf2, sizeof(buf2), buf, buf_len);\n\n        /* decode it back again */\n        buf3_len = base64_decode(buf3, sizeof(buf3), buf2, buf2_len);\n\n        /* now make sure result equals original */\n        if (buf3_len != buf_len && memcmp(buf3, buf, buf_len) != 0) {\n            fprintf(stderr, \"base64: selftest failed\\n\");\n            return 1;\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/crypto-base64.h",
    "content": "#ifndef CRYPTO_BASE64_H\n#define CRYPTO_BASE64_H\n#include <stdio.h>\n\nsize_t base64_decode(void *dst, size_t sizeof_dst, const void *src, size_t sizeof_src);\nsize_t base64_encode(void *dst, size_t sizeof_dst, const void *src, size_t sizeof_src);\n\nint base64_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/crypto-blackrock.c",
    "content": "/*\n    BlackRock cipher\n\n    (h/t Marsh Ray @marshray for this idea)\n\n    This is a randomization/reshuffling function based on a crypto\n    \"Feistel network\" as described in the paper:\n\n    'Ciphers with Arbitrary Finite Domains'\n        by John Black and Phillip Rogaway\n        http://www.cs.ucdavis.edu/~rogaway/papers/subset.pdf\n\n    This is a crypto-like construction that encrypts an arbitrary sized\n    range. Given a number in the range [0..9999], it'll produce a mapping\n    to a distinct different number in the same range (and back again).\n    In other words, it randomizes the order of numbers in a sequence.\n\n    For example, it can be used to  randomize the sequence [0..9]:\n\n     0 ->      6\n     1 ->      4\n     2 ->      8\n     3 ->      1\n     4 ->      9\n     5 ->      3\n     6 ->      0\n     7 ->      5\n     8 ->      2\n     9 ->      7\n\n    As you can see on the right hand side, the numbers are in random\n    order, and they don't repeat.\n\n    This is create for port scanning. We can take an index variable\n    and increment it during a scan, then use this function to\n    randomize it, yet be assured that we've probed every IP and port\n    within the range.\n\n    The cryptographic strength of this construction depends upon the\n    number of rounds, and the exact nature of the inner \"READ()\" function.\n    Because it's a Feistel network, that \"READ()\" function can be almost\n    anything.\n\n    We don't care about cryptographic strength, just speed, so we are\n    using a trivial READ() function.\n\n    This is a class of \"format-preserving encryption\". There are\n    probably better constructions than what I'm using.\n*/\n#include \"crypto-blackrock.h\"\n#include \"pixie-timer.h\"\n#include \"util-malloc.h\"\n#include <stdint.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <math.h>\n#include <ctype.h>\n#include <time.h>\n\n#if defined(_MSC_VER)\n#define inline _inline\n#endif\n\n/***************************************************************************\n * It's an s-box. You gotta have an s-box\n ***************************************************************************/\nconst unsigned char sbox[256] = {\n0x91, 0x58, 0xb3, 0x31, 0x6c, 0x33, 0xda, 0x88,\n0x57, 0xdd, 0x8c, 0xf2, 0x29, 0x5a, 0x08, 0x9f,\n0x49, 0x34, 0xce, 0x99, 0x9e, 0xbf, 0x0f, 0x81,\n0xd4, 0x2f, 0x92, 0x3f, 0x95, 0xf5, 0x23, 0x00,\n0x0d, 0x3e, 0xa8, 0x90, 0x98, 0xdd, 0x20, 0x00,\n0x03, 0x69, 0x0a, 0xca, 0xba, 0x12, 0x08, 0x41,\n0x6e, 0xb9, 0x86, 0xe4, 0x50, 0xf0, 0x84, 0xe2,\n0xb3, 0xb3, 0xc8, 0xb5, 0xb2, 0x2d, 0x18, 0x70,\n\n0x0a, 0xd7, 0x92, 0x90, 0x9e, 0x1e, 0x0c, 0x1f,\n0x08, 0xe8, 0x06, 0xfd, 0x85, 0x2f, 0xaa, 0x5d,\n0xcf, 0xf9, 0xe3, 0x55, 0xb9, 0xfe, 0xa6, 0x7f,\n0x44, 0x3b, 0x4a, 0x4f, 0xc9, 0x2f, 0xd2, 0xd3,\n0x8e, 0xdc, 0xae, 0xba, 0x4f, 0x02, 0xb4, 0x76,\n0xba, 0x64, 0x2d, 0x07, 0x9e, 0x08, 0xec, 0xbd,\n0x52, 0x29, 0x07, 0xbb, 0x9f, 0xb5, 0x58, 0x6f,\n0x07, 0x55, 0xb0, 0x34, 0x74, 0x9f, 0x05, 0xb2,\n\n0xdf, 0xa9, 0xc6, 0x2a, 0xa3, 0x5d, 0xff, 0x10,\n0x40, 0xb3, 0xb7, 0xb4, 0x63, 0x6e, 0xf4, 0x3e,\n0xee, 0xf6, 0x49, 0x52, 0xe3, 0x11, 0xb3, 0xf1,\n0xfb, 0x60, 0x48, 0xa1, 0xa4, 0x19, 0x7a, 0x2e,\n0x90, 0x28, 0x90, 0x8d, 0x5e, 0x8c, 0x8c, 0xc4,\n0xf2, 0x4a, 0xf6, 0xb2, 0x19, 0x83, 0xea, 0xed,\n0x6d, 0xba, 0xfe, 0xd8, 0xb6, 0xa3, 0x5a, 0xb4,\n0x48, 0xfa, 0xbe, 0x5c, 0x69, 0xac, 0x3c, 0x8f,\n\n0x63, 0xaf, 0xa4, 0x42, 0x25, 0x50, 0xab, 0x65,\n0x80, 0x65, 0xb9, 0xfb, 0xc7, 0xf2, 0x2d, 0x5c,\n0xe3, 0x4c, 0xa4, 0xa6, 0x8e, 0x07, 0x9c, 0xeb,\n0x41, 0x93, 0x65, 0x44, 0x4a, 0x86, 0xc1, 0xf6,\n0x2c, 0x97, 0xfd, 0xf4, 0x6c, 0xdc, 0xe1, 0xe0,\n0x28, 0xd9, 0x89, 0x7b, 0x09, 0xe2, 0xa0, 0x38,\n0x74, 0x4a, 0xa6, 0x5e, 0xd2, 0xe2, 0x4d, 0xf3,\n0xf4, 0xc6, 0xbc, 0xa2, 0x51, 0x58, 0xe8, 0xae,\n};\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nblackrock_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds)\n{\n    double foo = sqrt(range * 1.0);\n\n    /* This algorithm gets very non-random at small numbers, so I'm going\n     * to try to fix some constants here to make it work. It doesn't have\n     * to be good, since it's kinda pointless having ranges this small */\n    switch (range) {\n        case 0:\n            br->a = 0;\n            br->b = 0;\n            break;\n        case 1:\n            br->a = 1;\n            br->b = 1;\n            break;\n        case 2:\n            br->a = 1;\n            br->b = 2;\n            break;\n        case 3:\n            br->a = 2;\n            br->b = 2;\n            break;\n        case 4:\n        case 5:\n        case 6:\n            br->a = 2;\n            br->b = 3;\n            break;\n        case 7:\n        case 8:\n            br->a = 3;\n            br->b = 3;\n            break;\n        default:\n            br->range = range;\n            br->a = (uint64_t)(foo - 2);\n            br->b = (uint64_t)(foo + 3);\n            break;\n    }\n\n    while (br->a * br->b <= range)\n        br->b++;\n\n    br->rounds = rounds;\n    br->seed = seed;\n    br->range = range;\n}\n\n\n/***************************************************************************\n * The inner round/mixer function. In DES, it's a series of S-box lookups,\n * which \n ***************************************************************************/\nstatic inline uint64_t\nREAD(uint64_t r, uint64_t R, uint64_t seed)\n{\n    uint64_t r0, r1, r2, r3;\n\n#define GETBYTE(R,n) ((((R)>>(n*8))^seed^r)&0xFF)\n\n    R ^= (seed << r) ^ (seed >> (64 - r));\n\n    r0 = sbox[GETBYTE(R,0)]<< 0 | sbox[GETBYTE(R,1)]<< 8;\n    r1 = (sbox[GETBYTE(R,2)]<<16UL | sbox[GETBYTE(R,3)]<<24UL)&0x0ffffFFFFUL;\n    r2 = sbox[GETBYTE(R,4)]<< 0 | sbox[GETBYTE(R,5)]<< 8;\n    r3 = (sbox[GETBYTE(R,6)]<<16UL | sbox[GETBYTE(R,7)]<<24UL)&0x0ffffFFFFUL;\n\n    R = r0 ^ r1 ^ r2<<23UL ^ r3<<33UL;\n\n    return R;\n}\n\n\n/***************************************************************************\n *\n * NOTE:\n *  the names in this function are cryptic in order to match as closely\n *  as possible the pseudocode in the following paper:\n *      http://www.cs.ucdavis.edu/~rogaway/papers/subset.pdf\n * Read that paper in order to understand this code.\n ***************************************************************************/\nstatic inline uint64_t\nENCRYPT(unsigned r, uint64_t a, uint64_t b, uint64_t m, uint64_t seed)\n{\n    uint64_t L, R;\n    unsigned j;\n    uint64_t tmp;\n\n    L = m % a;\n    R = m / a;\n\n    for (j=1; j<=r; j++) {\n        if (j & 1) {\n            tmp = (L + READ(j, R, seed)) % a;\n        } else {\n            tmp = (L + READ(j, R, seed)) % b;\n        }\n        L = R;\n        R = tmp;\n    }\n    if (r & 1) {\n        return a * L + R;\n    } else {\n        return a * R + L;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic inline uint64_t\nUNENCRYPT(unsigned r, uint64_t a, uint64_t b, uint64_t m, uint64_t seed)\n{\n    uint64_t L, R;\n    unsigned j;\n    uint64_t tmp;\n\n    if (r & 1) {\n        R = m % a;\n        L = m / a;\n    } else {\n        L = m % a;\n        R = m / a;\n    }\n\n    for (j=r; j>=1; j--) {\n        if (j & 1) {\n            tmp = READ(j, L, seed);\n            if (tmp > R) {\n                tmp = (tmp - R);\n                tmp = a - (tmp%a);\n                if (tmp == a)\n                    tmp = 0;\n            } else {\n                tmp = (R - tmp);\n                tmp %= a;\n            }\n        } else {\n            tmp = READ(j, L, seed);\n            if (tmp > R) {\n                tmp = (tmp - R);\n                tmp = b - (tmp%b);\n                if (tmp == b)\n                    tmp = 0;\n            } else {\n                tmp = (R - tmp);\n                tmp %= b;\n            }\n        }\n        R = L;\n        L = tmp;\n    }\n    return a * R + L;\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nblackrock_shuffle(const struct BlackRock *br, uint64_t m)\n{\n    uint64_t c;\n\n    c = ENCRYPT(br->rounds, br->a, br->b, m, br->seed);\n    while (c >= br->range)\n        c = ENCRYPT(br->rounds, br->a, br->b,  c, br->seed);\n\n    return c;\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nblackrock_unshuffle(const struct BlackRock *br, uint64_t m)\n{\n    uint64_t c;\n\n    c = UNENCRYPT(br->rounds, br->a, br->b, m, br->seed);\n    while (c >= br->range)\n        c = UNENCRYPT(br->rounds, br->a, br->b,  c, br->seed);\n\n    return c;\n}\n\n\n/***************************************************************************\n * This function called only during selftest/regression-test.\n ***************************************************************************/\nstatic unsigned\nblackrock_verify(struct BlackRock *br, uint64_t max)\n{\n    unsigned char *list;\n    uint64_t i;\n    unsigned is_success = 1;\n    uint64_t range = br->range;\n\n    /* Allocate a list of 1-byte counters */\n    list = CALLOC(1, (size_t)((range<max)?range:max));\n    \n    /* For all numbers in the range, verify increment the counter for\n     * the output. */\n    for (i=0; i<range; i++) {\n        uint64_t x = blackrock_shuffle(br, i);\n        if (x < max)\n            list[x]++;\n    }\n\n    /* Now check the output to make sure that every counter is set exactly\n     * to the value of '1'. */\n    for (i=0; i<max && i<range; i++) {\n        if (list[i] != 1)\n            is_success = 0;\n    }\n\n    free(list);\n\n    return is_success;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nblackrock_benchmark(unsigned rounds)\n{\n    struct BlackRock br;\n    uint64_t range = 0x012356789123ULL;\n    uint64_t i;\n    uint64_t result = 0;\n    uint64_t start, stop;\n    static const uint64_t ITERATIONS = 5000000ULL;\n\n    printf(\"-- blackrock-1 -- \\n\");\n    printf(\"rounds = %u\\n\", rounds);\n    blackrock_init(&br, range, 1, rounds);\n\n    /*\n     * Time the algorithm\n     */\n    start = pixie_nanotime();\n    for (i=0; i<ITERATIONS; i++) {\n        result += blackrock_shuffle(&br, i);\n    }\n    stop = pixie_nanotime();\n\n    /*\n     * Print the results\n     */\n    if (result) {\n        double elapsed = ((double)(stop - start))/(1000000000.0);\n        double rate = ITERATIONS/elapsed;\n\n        rate /= 1000000.0;\n\n        printf(\"iterations/second = %5.3f-million\\n\", rate);\n\n    }\n\n    printf(\"\\n\");\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nblackrock_selftest(void)\n{\n    uint64_t i;\n    uint64_t range;\n\n    /* @marshray\n     * Basic test of decryption. I take the index, encrypt it, then decrypt it,\n     * which means I should get the original index back again. Only, it's not\n     * working. The decryption fails. The reason it's failing is obvious -- I'm\n     * just not seeing it though. The error is probably in the 'UNENCRYPT()'\n     * function above.\n     */\n    {\n        struct BlackRock br;\n        \n        blackrock_init(&br, 1000, 0, 4);\n\n        for (i=0; i<10; i++) {\n            uint64_t result, result2;\n            result = blackrock_shuffle(&br, i);\n            result2 = blackrock_unshuffle(&br, result);\n            if (i != result2)\n                return 1; /*fail*/\n        }\n\n    }\n\n\n    range = 3015 * 3;\n\n    for (i=0; i<5; i++) {\n        struct BlackRock br;\n        int is_success;\n\n        range += 10 + i;\n        range *= 2;\n\n        blackrock_init(&br, range, time(0), 4);\n\n        is_success = blackrock_verify(&br, range);\n        if (!is_success) {\n            fprintf(stderr, \"BLACKROCK: randomization failed\\n\");\n            return 1; /*fail*/\n        }\n    }\n\n    return 0; /*success*/\n}\n"
  },
  {
    "path": "src/crypto-blackrock.h",
    "content": "#ifndef RAND_BLACKROCK_H\n#define RAND_BLACKROCK_H\n#include <stdint.h>\n\nstruct BlackRock {\n    uint64_t range;\n    uint64_t a;\n    uint64_t b;\n    uint64_t seed;\n    unsigned rounds;\n    uint64_t a_bits;\n    uint64_t a_mask;\n    uint64_t b_bits;\n    uint64_t b_mask;\n};\n\n/**\n * Initializes a structure for shuffling numbers within\n * a range.\n *\n * @param range\n *      The size of the range of numbers needing to be\n *      shuffled/randomized.\n */\nvoid\nblackrock_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds);\nvoid\nblackrock2_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds);\n\n/**\n * Given a number within a range, produce a different number with\n * the same range. There is a 1-to-1 mapping between the two,\n * so when linearly incrementing through the range, the output\n * of this function won't repeat. In other words, encrypt the index variable.\n * @param br\n *      The randomization parameters created with 'blackrock_init()'\n * @param index\n *      An input within the specified range. We call it an 'index' variable\n *      because that's how we intend to use this function, shuffling a\n *      monotonically increasing index variable, but in truth, any sort\n *      of integer can be used. This must be within the 'range' specified\n *      during the call to blackrock_init(), or the results are undefined.\n * @return\n *      A one-to-one matching index that's in the same range.\n */\nuint64_t\nblackrock_shuffle(const struct BlackRock *br, uint64_t index);\nuint64_t\nblackrock2_shuffle(const struct BlackRock *br, uint64_t index);\n\n/**\n * The reverse of the shuffle function above: given the shuffled/encrypted\n * integer, return the original index value before the shuffling/encryption.\n */\nuint64_t\nblackrock_unshuffle(const struct BlackRock *br, uint64_t m);\nuint64_t\nblackrock2_unshuffle(const struct BlackRock *br, uint64_t m);\n\n\n/**\n * Do a regression test.\n * @return\n *      0 of the regression test succeeds or non-zero if it fails\n */\nint\nblackrock_selftest(void);\nint\nblackrock2_selftest(void);\n\n/**\n * Do a benchmark of this module regression test.\n */\nvoid\nblackrock_benchmark(unsigned rounds);\nvoid\nblackrock2_benchmark(unsigned rounds);\n\n#endif\n"
  },
  {
    "path": "src/crypto-blackrock2.c",
    "content": "#include \"crypto-blackrock.h\"\n#include \"pixie-timer.h\"\n#include \"unusedparm.h\"\n#include \"util-malloc.h\"\n#include \"util-safefunc.h\"\n#include <stdint.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <math.h>\n#include <ctype.h>\n#include <time.h>\n\n#if defined(_MSC_VER)\n#define inline _inline\n#endif\n\n/*\n * Expanded DES S-boxes\n */\nstatic const uint32_t SB1[64] =\n{\n    0x01010400, 0x00000000, 0x00010000, 0x01010404,\n    0x01010004, 0x00010404, 0x00000004, 0x00010000,\n    0x00000400, 0x01010400, 0x01010404, 0x00000400,\n    0x01000404, 0x01010004, 0x01000000, 0x00000004,\n    0x00000404, 0x01000400, 0x01000400, 0x00010400,\n    0x00010400, 0x01010000, 0x01010000, 0x01000404,\n    0x00010004, 0x01000004, 0x01000004, 0x00010004,\n    0x00000000, 0x00000404, 0x00010404, 0x01000000,\n    0x00010000, 0x01010404, 0x00000004, 0x01010000,\n    0x01010400, 0x01000000, 0x01000000, 0x00000400,\n    0x01010004, 0x00010000, 0x00010400, 0x01000004,\n    0x00000400, 0x00000004, 0x01000404, 0x00010404,\n    0x01010404, 0x00010004, 0x01010000, 0x01000404,\n    0x01000004, 0x00000404, 0x00010404, 0x01010400,\n    0x00000404, 0x01000400, 0x01000400, 0x00000000,\n    0x00010004, 0x00010400, 0x00000000, 0x01010004\n};\n\nstatic const uint32_t SB2[64] =\n{\n    0x80108020, 0x80008000, 0x00008000, 0x00108020,\n    0x00100000, 0x00000020, 0x80100020, 0x80008020,\n    0x80000020, 0x80108020, 0x80108000, 0x80000000,\n    0x80008000, 0x00100000, 0x00000020, 0x80100020,\n    0x00108000, 0x00100020, 0x80008020, 0x00000000,\n    0x80000000, 0x00008000, 0x00108020, 0x80100000,\n    0x00100020, 0x80000020, 0x00000000, 0x00108000,\n    0x00008020, 0x80108000, 0x80100000, 0x00008020,\n    0x00000000, 0x00108020, 0x80100020, 0x00100000,\n    0x80008020, 0x80100000, 0x80108000, 0x00008000,\n    0x80100000, 0x80008000, 0x00000020, 0x80108020,\n    0x00108020, 0x00000020, 0x00008000, 0x80000000,\n    0x00008020, 0x80108000, 0x00100000, 0x80000020,\n    0x00100020, 0x80008020, 0x80000020, 0x00100020,\n    0x00108000, 0x00000000, 0x80008000, 0x00008020,\n    0x80000000, 0x80100020, 0x80108020, 0x00108000\n};\n\nstatic const uint32_t SB3[64] =\n{\n    0x00000208, 0x08020200, 0x00000000, 0x08020008,\n    0x08000200, 0x00000000, 0x00020208, 0x08000200,\n    0x00020008, 0x08000008, 0x08000008, 0x00020000,\n    0x08020208, 0x00020008, 0x08020000, 0x00000208,\n    0x08000000, 0x00000008, 0x08020200, 0x00000200,\n    0x00020200, 0x08020000, 0x08020008, 0x00020208,\n    0x08000208, 0x00020200, 0x00020000, 0x08000208,\n    0x00000008, 0x08020208, 0x00000200, 0x08000000,\n    0x08020200, 0x08000000, 0x00020008, 0x00000208,\n    0x00020000, 0x08020200, 0x08000200, 0x00000000,\n    0x00000200, 0x00020008, 0x08020208, 0x08000200,\n    0x08000008, 0x00000200, 0x00000000, 0x08020008,\n    0x08000208, 0x00020000, 0x08000000, 0x08020208,\n    0x00000008, 0x00020208, 0x00020200, 0x08000008,\n    0x08020000, 0x08000208, 0x00000208, 0x08020000,\n    0x00020208, 0x00000008, 0x08020008, 0x00020200\n};\n\nstatic const uint32_t SB4[64] =\n{\n    0x00802001, 0x00002081, 0x00002081, 0x00000080,\n    0x00802080, 0x00800081, 0x00800001, 0x00002001,\n    0x00000000, 0x00802000, 0x00802000, 0x00802081,\n    0x00000081, 0x00000000, 0x00800080, 0x00800001,\n    0x00000001, 0x00002000, 0x00800000, 0x00802001,\n    0x00000080, 0x00800000, 0x00002001, 0x00002080,\n    0x00800081, 0x00000001, 0x00002080, 0x00800080,\n    0x00002000, 0x00802080, 0x00802081, 0x00000081,\n    0x00800080, 0x00800001, 0x00802000, 0x00802081,\n    0x00000081, 0x00000000, 0x00000000, 0x00802000,\n    0x00002080, 0x00800080, 0x00800081, 0x00000001,\n    0x00802001, 0x00002081, 0x00002081, 0x00000080,\n    0x00802081, 0x00000081, 0x00000001, 0x00002000,\n    0x00800001, 0x00002001, 0x00802080, 0x00800081,\n    0x00002001, 0x00002080, 0x00800000, 0x00802001,\n    0x00000080, 0x00800000, 0x00002000, 0x00802080\n};\n\nstatic const uint32_t SB5[64] =\n{\n    0x00000100, 0x02080100, 0x02080000, 0x42000100,\n    0x00080000, 0x00000100, 0x40000000, 0x02080000,\n    0x40080100, 0x00080000, 0x02000100, 0x40080100,\n    0x42000100, 0x42080000, 0x00080100, 0x40000000,\n    0x02000000, 0x40080000, 0x40080000, 0x00000000,\n    0x40000100, 0x42080100, 0x42080100, 0x02000100,\n    0x42080000, 0x40000100, 0x00000000, 0x42000000,\n    0x02080100, 0x02000000, 0x42000000, 0x00080100,\n    0x00080000, 0x42000100, 0x00000100, 0x02000000,\n    0x40000000, 0x02080000, 0x42000100, 0x40080100,\n    0x02000100, 0x40000000, 0x42080000, 0x02080100,\n    0x40080100, 0x00000100, 0x02000000, 0x42080000,\n    0x42080100, 0x00080100, 0x42000000, 0x42080100,\n    0x02080000, 0x00000000, 0x40080000, 0x42000000,\n    0x00080100, 0x02000100, 0x40000100, 0x00080000,\n    0x00000000, 0x40080000, 0x02080100, 0x40000100\n};\n\nstatic const uint32_t SB6[64] =\n{\n    0x20000010, 0x20400000, 0x00004000, 0x20404010,\n    0x20400000, 0x00000010, 0x20404010, 0x00400000,\n    0x20004000, 0x00404010, 0x00400000, 0x20000010,\n    0x00400010, 0x20004000, 0x20000000, 0x00004010,\n    0x00000000, 0x00400010, 0x20004010, 0x00004000,\n    0x00404000, 0x20004010, 0x00000010, 0x20400010,\n    0x20400010, 0x00000000, 0x00404010, 0x20404000,\n    0x00004010, 0x00404000, 0x20404000, 0x20000000,\n    0x20004000, 0x00000010, 0x20400010, 0x00404000,\n    0x20404010, 0x00400000, 0x00004010, 0x20000010,\n    0x00400000, 0x20004000, 0x20000000, 0x00004010,\n    0x20000010, 0x20404010, 0x00404000, 0x20400000,\n    0x00404010, 0x20404000, 0x00000000, 0x20400010,\n    0x00000010, 0x00004000, 0x20400000, 0x00404010,\n    0x00004000, 0x00400010, 0x20004010, 0x00000000,\n    0x20404000, 0x20000000, 0x00400010, 0x20004010\n};\n\nstatic const uint32_t SB7[64] =\n{\n    0x00200000, 0x04200002, 0x04000802, 0x00000000,\n    0x00000800, 0x04000802, 0x00200802, 0x04200800,\n    0x04200802, 0x00200000, 0x00000000, 0x04000002,\n    0x00000002, 0x04000000, 0x04200002, 0x00000802,\n    0x04000800, 0x00200802, 0x00200002, 0x04000800,\n    0x04000002, 0x04200000, 0x04200800, 0x00200002,\n    0x04200000, 0x00000800, 0x00000802, 0x04200802,\n    0x00200800, 0x00000002, 0x04000000, 0x00200800,\n    0x04000000, 0x00200800, 0x00200000, 0x04000802,\n    0x04000802, 0x04200002, 0x04200002, 0x00000002,\n    0x00200002, 0x04000000, 0x04000800, 0x00200000,\n    0x04200800, 0x00000802, 0x00200802, 0x04200800,\n    0x00000802, 0x04000002, 0x04200802, 0x04200000,\n    0x00200800, 0x00000000, 0x00000002, 0x04200802,\n    0x00000000, 0x00200802, 0x04200000, 0x00000800,\n    0x04000002, 0x04000800, 0x00000800, 0x00200002\n};\n\nstatic const uint32_t SB8[64] =\n{\n    0x10001040, 0x00001000, 0x00040000, 0x10041040,\n    0x10000000, 0x10001040, 0x00000040, 0x10000000,\n    0x00040040, 0x10040000, 0x10041040, 0x00041000,\n    0x10041000, 0x00041040, 0x00001000, 0x00000040,\n    0x10040000, 0x10000040, 0x10001000, 0x00001040,\n    0x00041000, 0x00040040, 0x10040040, 0x10041000,\n    0x00001040, 0x00000000, 0x00000000, 0x10040040,\n    0x10000040, 0x10001000, 0x00041040, 0x00040000,\n    0x00041040, 0x00040000, 0x10041000, 0x00001000,\n    0x00000040, 0x10040040, 0x00001000, 0x00041040,\n    0x10001000, 0x00000040, 0x10000040, 0x10040000,\n    0x10040040, 0x10000000, 0x00040000, 0x10001040,\n    0x00000000, 0x10041040, 0x00040040, 0x10000040,\n    0x10040000, 0x10001000, 0x10001040, 0x00000000,\n    0x10041040, 0x00041000, 0x00041000, 0x00001040,\n    0x00001040, 0x00040040, 0x10000000, 0x10041000\n};\n/***************************************************************************\n * It's an s-box. You gotta have an s-box\n ***************************************************************************/\nconst unsigned char sbox2[] = {\n0x91, 0x58, 0xb3, 0x31, 0x6c, 0x33, 0xda, 0x88,\n0x57, 0xdd, 0x8c, 0xf2, 0x29, 0x5a, 0x08, 0x9f,\n0x49, 0x34, 0xce, 0x99, 0x9e, 0xbf, 0x0f, 0x81,\n0xd4, 0x2f, 0x92, 0x3f, 0x95, 0xf5, 0x23, 0x00,\n0x0d, 0x3e, 0xa8, 0x90, 0x98, 0xdd, 0x20, 0x00,\n0x03, 0x69, 0x0a, 0xca, 0xba, 0x12, 0x08, 0x41,\n0x6e, 0xb9, 0x86, 0xe4, 0x50, 0xf0, 0x84, 0xe2,\n0xb3, 0xb3, 0xc8, 0xb5, 0xb2, 0x2d, 0x18, 0x70,\n\n0x0a, 0xd7, 0x92, 0x90, 0x9e, 0x1e, 0x0c, 0x1f,\n0x08, 0xe8, 0x06, 0xfd, 0x85, 0x2f, 0xaa, 0x5d,\n0xcf, 0xf9, 0xe3, 0x55, 0xb9, 0xfe, 0xa6, 0x7f,\n0x44, 0x3b, 0x4a, 0x4f, 0xc9, 0x2f, 0xd2, 0xd3,\n0x8e, 0xdc, 0xae, 0xba, 0x4f, 0x02, 0xb4, 0x76,\n0xba, 0x64, 0x2d, 0x07, 0x9e, 0x08, 0xec, 0xbd,\n0x52, 0x29, 0x07, 0xbb, 0x9f, 0xb5, 0x58, 0x6f,\n0x07, 0x55, 0xb0, 0x34, 0x74, 0x9f, 0x05, 0xb2,\n\n0xdf, 0xa9, 0xc6, 0x2a, 0xa3, 0x5d, 0xff, 0x10,\n0x40, 0xb3, 0xb7, 0xb4, 0x63, 0x6e, 0xf4, 0x3e,\n0xee, 0xf6, 0x49, 0x52, 0xe3, 0x11, 0xb3, 0xf1,\n0xfb, 0x60, 0x48, 0xa1, 0xa4, 0x19, 0x7a, 0x2e,\n0x90, 0x28, 0x90, 0x8d, 0x5e, 0x8c, 0x8c, 0xc4,\n0xf2, 0x4a, 0xf6, 0xb2, 0x19, 0x83, 0xea, 0xed,\n0x6d, 0xba, 0xfe, 0xd8, 0xb6, 0xa3, 0x5a, 0xb4,\n0x48, 0xfa, 0xbe, 0x5c, 0x69, 0xac, 0x3c, 0x8f,\n\n0x63, 0xaf, 0xa4, 0x42, 0x25, 0x50, 0xab, 0x65,\n0x80, 0x65, 0xb9, 0xfb, 0xc7, 0xf2, 0x2d, 0x5c,\n0xe3, 0x4c, 0xa4, 0xa6, 0x8e, 0x07, 0x9c, 0xeb,\n0x41, 0x93, 0x65, 0x44, 0x4a, 0x86, 0xc1, 0xf6,\n0x2c, 0x97, 0xfd, 0xf4, 0x6c, 0xdc, 0xe1, 0xe0,\n0x28, 0xd9, 0x89, 0x7b, 0x09, 0xe2, 0xa0, 0x38,\n0x74, 0x4a, 0xa6, 0x5e, 0xd2, 0xe2, 0x4d, 0xf3,\n0xf4, 0xc6, 0xbc, 0xa2, 0x51, 0x58, 0xe8, 0xae,\n\n0x91, 0x58, 0xb3, 0x31, 0x6c, 0x33, 0xda, 0x88,\n};\n\n\n/****************************************************************************\n * Given a number, figure out the nearest power-of-two (16,32,64,128,etc.)\n * that can hold that number. We do this so that we can convert multiplies\n * into shifts.\n ****************************************************************************/\nstatic uint64_t\nnext_power_of_two(uint64_t num)\n{\n    uint64_t power_of_two = 1;\n\n    num++;\n\n    while ((uint64_t)(1ULL << power_of_two) < num)\n        power_of_two++;\n\n    return (1ULL << power_of_two);\n}\nstatic uint64_t\nbit_count(uint64_t num)\n{\n    uint64_t bits = 0;\n\n    while ((num >> bits) > 1)\n        bits++;\n\n    return bits;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nblackrock2_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds)\n{\n    uint64_t a;\n    uint64_t b;\n\n    a = next_power_of_two(\n                                (uint64_t)sqrt(range * 1.0)\n                          );\n    b = next_power_of_two(range/a);\n\n    //printf(\"a=%llu b=%llu seed = 0x%llu\\n\", a, b, seed);\n\n    br->range = range;\n\n    br->a = a;\n    br->a_bits = bit_count(br->a);\n    br->a_mask = br->a - 1ULL;\n\n    br->b = b;\n    br->b_bits = bit_count(br->b);\n    br->b_mask = br->b - 1ULL;\n\n    //printf(\"a: 0x%llx / %llu\\n\", br->a_mask, br->a_bits);\n    //printf(\"b: 0x%llx / %llu\\n\", br->b_mask, br->b_bits);\n\n    br->rounds = rounds;\n    br->seed = seed;\n    br->range = range;\n}\n\n\n/***************************************************************************\n * The inner round/mixer function. In DES, it's a series of S-box lookups,\n * which \n ***************************************************************************/\nstatic inline uint64_t\nROUND(uint64_t r, uint64_t R, uint64_t seed)\n{\n#define GETBYTE(R,n) ((uint64_t)(((((R)>>(n*8ULL)))&0xFFULL)))\n#if 0    \n    uint64_t r0, r1, r2, r3;\n#endif\n    uint64_t T, Y;\n\n    T = R ^ ((seed>>r) | (seed<<(64-r)));\n\n\n    if (r & 1) {\n        Y = SB8[ (T      ) & 0x3F ] ^              \\\n             SB6[ (T >>  8) & 0x3F ] ^              \\\n             SB4[ (T >> 16) & 0x3F ] ^              \\\n             SB2[ (T >> 24) & 0x3F ];               \\\n    } else {\n        Y = SB7[ (T      ) & 0x3F ] ^              \\\n             SB5[ (T >>  8) & 0x3F ] ^              \\\n             SB3[ (T >> 16) & 0x3F ] ^              \\\n             SB1[ (T >> 24) & 0x3F ]; \n    }\n    return Y;\n#if 0\n    r0 = sbox2[GETBYTE(R,0)]<< 6 | sbox2[GETBYTE(R,1)]<< 0;\n    r1 = sbox2[GETBYTE(R,2)]<< 6 | sbox2[GETBYTE(R,5)]<< 0;\n    r2 = sbox2[GETBYTE(R,4)]<< 6 | sbox2[GETBYTE(R,5)]<< 0;\n    r3 = sbox2[GETBYTE(R,6)]<< 6 | sbox2[GETBYTE(R,7)]<< 0;\n\n    R = r0 ^ (r1<<12) * (r2 << 24) ^ (r3 << 36) * r;\n\n    return R;\n    /*return((uint64_t)sbox2[GETBYTE(R,7ULL)]<< 0ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,6ULL)]<< 8ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,5ULL)]<<16ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,4ULL)]<<24ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,3ULL)]<<32ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,2ULL)]<<40ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,1ULL)]<<48ULL)\n        | ((uint64_t)sbox2[GETBYTE(R,0ULL)]<<56ULL)\n        ;*/\n    return R;\n#endif\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic inline uint64_t\nENCRYPT(unsigned r, uint64_t a_bits, uint64_t a_mask, uint64_t b_bits, uint64_t b_mask, uint64_t m, uint64_t seed)\n{\n    uint64_t L, R;\n    unsigned j = 1;\n    uint64_t tmp;\n\n    UNUSEDPARM(b_bits);\n\n    L = m & a_mask;\n    R = m >> a_bits;\n\n    for (j=1; j<=r; j++) {\n        tmp = (L + ROUND(j, R, seed)) & a_mask;\n        L = R;\n        R = tmp;\n        j++;\n\n        tmp = (L + ROUND(j, R, seed)) & b_mask;\n        L = R;\n        R = tmp;\n    }\n\n    if ((j-1) & 1) {\n        return (L << (a_bits)) + R;\n    } else {\n        return (R << (a_bits)) + L;\n    }\n}\nstatic inline uint64_t\nDECRYPT(unsigned r, uint64_t a, uint64_t b, uint64_t m, uint64_t seed)\n{\n    uint64_t L, R;\n    unsigned j;\n    uint64_t tmp;\n\n    if (r & 1) {\n        R = m % a;\n        L = m / a;\n    } else {\n        L = m % a;\n        R = m / a;\n    }\n\n    for (j=r; j>=1; j--) {\n        if (j & 1) {\n            tmp = ROUND(j, L, seed);\n            if (tmp > R) {\n                tmp = (tmp - R);\n                tmp = a - (tmp%a);\n                if (tmp == a)\n                    tmp = 0;\n            } else {\n                tmp = (R - tmp);\n                tmp %= a;\n            }\n        } else {\n            tmp = ROUND(j, L, seed);\n            if (tmp > R) {\n                tmp = (tmp - R);\n                tmp = b - (tmp%b);\n                if (tmp == b)\n                    tmp = 0;\n            } else {\n                tmp = (R - tmp);\n                tmp %= b;\n            }\n        }\n        R = L;\n        L = tmp;\n    }\n    return a * R + L;\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nblackrock2_shuffle(const struct BlackRock *br, uint64_t m)\n{\n    uint64_t c;\n\n    c = ENCRYPT(br->rounds, br->a_bits, br->a_mask, br->b_bits, br->b_mask, m, br->seed);\n    while (c >= br->range)\n        c = ENCRYPT(br->rounds, br->a_bits, br->a_mask, br->b_bits, br->b_mask, c, br->seed);\n\n    return c;\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nblackrock2_unshuffle(const struct BlackRock *br, uint64_t m)\n{\n    uint64_t c;\n\n    c = DECRYPT(br->rounds, br->a, br->b, m, br->seed);\n    while (c >= br->range)\n        c = DECRYPT(br->rounds, br->a, br->b,  c, br->seed);\n\n    return c;\n}\n\n\n/***************************************************************************\n * This function called only during selftest/regression-test.\n ***************************************************************************/\nstatic unsigned\nverify(struct BlackRock *br, uint64_t max)\n{\n    unsigned char *list;\n    uint64_t i;\n    unsigned is_success = 1;\n    uint64_t range = br->range;\n\n    /* Allocate a list of 1-byte counters */\n    list = CALLOC(1, (size_t)((range<max)?range:max));\n    \n    /* For all numbers in the range, verify increment the counter for\n     * the output. */\n    for (i=0; i<range; i++) {\n        uint64_t x = blackrock2_shuffle(br, i);\n        if (x < max)\n            list[x]++;\n    }\n\n    /* Now check the output to make sure that every counter is set exactly\n     * to the value of '1'. */\n    for (i=0; i<max && i<range; i++) {\n        if (list[i] != 1)\n            is_success = 0;\n    }\n\n    free(list);\n\n    return is_success;\n}\n\n/***************************************************************************\n * Benchmarks the crypto function.\n ***************************************************************************/\nvoid\nblackrock2_benchmark(unsigned rounds)\n{\n    struct BlackRock br;\n    uint64_t range = 0x010356789123ULL;\n    uint64_t i;\n    uint64_t result = 0;\n    uint64_t start, stop;\n    static const uint64_t ITERATIONS = 5000000ULL;\n\n    printf(\"-- blackrock-2 -- \\n\");\n    printf(\"rounds = %u\\n\", rounds);\n    blackrock2_init(&br, range, 1, rounds);\n/*printf(\"range = 0x%10\" PRIx64 \"\\n\", range);\nprintf(\"rangex= 0x%10\" PRIx64 \"\\n\", br.a*br.b);\nprintf(\"    a = 0x%10\" PRIx64 \"\\n\", br.a);\nprintf(\"    b = 0x%10\" PRIx64 \"\\n\", br.b);*/\n\n    /*\n     * Time the algorithm\n     */\n    start = pixie_nanotime();\n    for (i=0; i<ITERATIONS; i++) {\n        result += blackrock2_shuffle(&br, i);\n    }\n    stop = pixie_nanotime();\n\n    /*\n     * Print the results\n     */\n    if (result) {\n        double elapsed = ((double)(stop - start))/(1000000000.0);\n        double rate = ITERATIONS/elapsed;\n\n        rate /= 1000000.0;\n\n        printf(\"iterations/second = %5.3f-million\\n\", rate);\n\n    }\n\n    printf(\"\\n\");\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nblackrock2_selftest(void)\n{\n    uint64_t i;\n    int is_success = 0;\n    uint64_t range;\n\n    /* @marshray\n     * Basic test of decryption. I take the index, encrypt it, then decrypt it,\n     * which means I should get the original index back again. Only, it's not\n     * working. The decryption fails. The reason it's failing is obvious -- I'm\n     * just not seeing it though. The error is probably in the 'unfe()'\n     * function above.\n     */\n    {\n        struct BlackRock br;\n        uint64_t result, result2;\n        blackrock2_init(&br, 1000, 0, 6);\n\n        for (i=0; i<10; i++) {\n            result = blackrock2_shuffle(&br, i);\n            result2 = blackrock2_unshuffle(&br, result);\n            if (i != result2)\n                return 1; /*fail*/\n        }\n\n    }\n\n\n    range = 3015 * 3;\n\n    for (i=0; i<5; i++) {\n        struct BlackRock br;\n\n        range += 11 + i;\n        range *= 1 + i;\n\n        blackrock2_init(&br, range, time(0), 6);\n\n        is_success = verify(&br, range);\n\n        if (!is_success) {\n            fprintf(stderr, \"BLACKROCK: randomization failed\\n\");\n            return 1; /*fail*/\n        }\n    }\n\n    return 0; /*success*/\n}\n"
  },
  {
    "path": "src/crypto-lcg.c",
    "content": "/*\n    This is a \"linear-congruent-generator\", a type of random number\n    generator.\n*/\n\n#include \"crypto-lcg.h\"\n#include \"crypto-primegen.h\" /* DJB's prime factoring code */\n#include \"util-safefunc.h\"\n#include \"util-malloc.h\"\n\n#include <math.h>  /* for 'sqrt()', may need -lm for gcc */\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n\n\n/**\n * A 64 bit number can't have more than 16 prime factors. The first factors\n * are:\n * 2*3*5*7*11*13*17*19*23*29*31*37*41*43*47*53 = 0xC443F2F861D29C3A\n *                                                 0123456789abcdef\n * We zero termiante this list, so we are going to reserve 20 slots.\n */\ntypedef uint64_t PRIMEFACTORS[20];\n\n\n/****************************************************************************\n * Break down the number into prime factors using DJB's sieve code, which\n * is about 5 to 10 times faster than the Sieve of Eratosthenes.\n *\n * @param number\n *      The integer that we are factoring. It can be any value up to 64 bits\n *      in size.\n * @param factors\n *      The list of all the prime factors, zero terminated.\n * @param non_factors\n *      A list of smallest numbers that aren't prime factors. We return\n *      this because we are going to use prime non-factors for finding\n *      interesting numbers.\n ****************************************************************************/\nstatic unsigned\nsieve_prime_factors(uint64_t number, PRIMEFACTORS factors,\n                    PRIMEFACTORS non_factors, double *elapsed)\n{\n    primegen pg;\n    clock_t start;\n    clock_t stop;\n    uint64_t prime;\n    uint64_t max;\n    unsigned factor_count = 0;\n    unsigned non_factor_count = 0;\n\n    /*\n     * We only need to sieve up to the square-root of the target number. Only\n     * one prime factor can be bigger than the square root, so once we find\n     * all the other primes, the square root is the only one left.\n     * Note: you have to link to the 'm' math library for some gcc platforms.\n     */\n    max = (uint64_t)sqrt(number + 1.0);\n\n    /*\n     * Init the DJB primegen library.\n     */\n    primegen_init(&pg);\n\n    /*\n     * Enumerate all the primes starting with 2\n     */\n    start = clock();\n    for (;;) {\n\n        /* Sieve the next prime */\n        prime = primegen_next(&pg);\n\n        /* If we've reached the square root, then that's as far as we need\n         * to go */\n        if (prime > max)\n            break;\n\n        /* If this prime is not a factor (evenly divisible with no remainder)\n         * then loop back and get the next prime */\n        if ((number % prime) != 0) {\n            if (non_factor_count < 12)\n                non_factors[non_factor_count++] = prime;\n            continue;\n        }\n\n        /* Else we've found a prime factor, so add this to the list of primes */\n        factors[factor_count++] = prime;\n\n        /* At the end, we may have one prime factor left that's bigger than the\n         * sqrt. Therefore, as we go along, divide the original number\n         * (possibly several times) by the prime factor so that this large\n         * remaining factor will be the only one left */\n        while ((number % prime) == 0)\n            number /= prime;\n\n        /* exit early if we've found all prime factors. comment out this\n         * code if you want to benchmark it */\n        if (number == 1 && non_factor_count > 10)\n            break;\n    }\n\n    /*\n     * See if there is one last prime that's bigger than the square root.\n     * Note: This is the only number that can be larger than 32-bits in the\n     * way this code is written.\n     */\n    if (number != 1)\n        factors[factor_count++] = number;\n\n    /*\n     * Zero terminate the results.\n     */\n    factors[factor_count] = 0;\n    non_factors[non_factor_count] = 0;\n\n    /*\n     * Since prime factorization takes a long time, especially on slow\n     * CPUs, we benchmark it to keep track of performance.\n     */\n    stop = clock();\n    if (elapsed)\n        *elapsed = ((double)stop - (double)start)/(double)CLOCKS_PER_SEC;\n\n    /* should always be at least 1, because if the number itself is prime,\n     * then that's it's only prime factor */\n    return factor_count;\n}\n\n\n\n/****************************************************************************\n * Do a pseudo-random 1-to-1 translation of a number within a range to\n * another number in that range.\n *\n * The constants 'a' and 'c' must be chosen to match the LCG algorithm\n * to fit 'm' (range).\n *\n * This the same as the function 'rand()', except all the constants and\n * seeds are specified as parameters.\n *\n * @param index\n *      The index within the range that we are randomizing.\n * @param a\n *      The 'multiplier' of the LCG algorithm.\n * @param c\n *      The 'increment' of the LCG algorithm.\n * @param range\n *      The 'modulus' of the LCG algorithm.\n ****************************************************************************/\nuint64_t\nlcg_rand(uint64_t index, uint64_t a, uint64_t c, uint64_t range)\n{\n    return (index * a + c) % range;\n}\n\n\n/****************************************************************************\n * Verify the LCG algorithm. You shouldn't do this for large ranges,\n * because we'll run out of memory. Therefore, this algorithm allocates\n * a buffer only up to a smaller range. We still have to traverse the\n * entire range of numbers, but we only need store values for a smaller\n * range. If 10% of the range checks out, then there's a good chance\n * it applies to the other 90% as well.\n *\n * This works by counting the results of rand(), which should be produced\n * exactly once.\n ****************************************************************************/\nstatic unsigned\nlcg_verify(uint64_t a, uint64_t c, uint64_t range, uint64_t max)\n{\n    unsigned char *list;\n    uint64_t i;\n    unsigned is_success = 1;\n\n    /* Allocate a list of 1-byte counters */\n    list = CALLOC(1, (size_t)((range<max)?range:max));\n    \n    /* For all numbers in the range, verify increment the counter for the\n     * the output. */\n    for (i=0; i<range; i++) {\n        uint64_t x = lcg_rand(i, a, c, range);\n        if (x < max)\n            list[x]++;\n    }\n\n    /* Now check the output to make sure that every counter is set exactly\n     * to the value of '1'. */\n    for (i=0; i<max && i<range; i++) {\n        if (list[i] != 1)\n            is_success = 0;\n    }\n\n    free(list);\n\n    return is_success;\n}\n\n\n/****************************************************************************\n * Count the number of digits in a number so that we can pretty-print a\n * bunch of numbers in nice columns.\n ****************************************************************************/\nstatic unsigned\ncount_digits(uint64_t num)\n{\n    unsigned result = 0;\n\n    while (num) {\n        result++;\n        num /= 10;\n    }\n\n    return result;\n}\n\n/****************************************************************************\n * Tell whether the number has any prime factors in common with the list\n * of factors. In other words, if it's not coprime with the other number.\n * @param c\n *      The number we want to see has common factors with the other number.\n * @param factors\n *      The factors from the other number\n * @return\n *      !is_coprime(c, factors)\n ****************************************************************************/\nstatic uint64_t\nhas_factors_in_common(uint64_t c, PRIMEFACTORS factors)\n{\n    unsigned i;\n\n    for (i=0; factors[i]; i++) {\n        if ((c % factors[i]) == 0)\n            return factors[i]; /* found a common factor */\n    }\n    return 0; /* no factors in common */\n}\n\n\n/****************************************************************************\n * Given a range, calculate some possible constants for the LCG algorithm\n * for randomizing the order of the array.\n * @parm m\n *      The range for which we'll be finding random numbers. If we are\n *      looking for random numbers between [0..100), this number will\n *      be 100.\n * @parm a\n *      The LCG 'a' constant that will be the result of this function.\n * @param c\n *      The LCG 'c' constant that will be the result of this function. This\n *      should be set to 0 on the input to this function, or a suggested\n *      value.\n ****************************************************************************/\nvoid\nlcg_calculate_constants(uint64_t m, uint64_t *out_a, uint64_t *inout_c, int is_debug)\n{\n    uint64_t a;\n    uint64_t c = *inout_c;\n    double elapsed = 0.0; /* Benchmark of 'sieve' algorithm */\n    PRIMEFACTORS factors; /* List of prime factors of 'm' */\n    PRIMEFACTORS non_factors;\n    unsigned i;\n\n    /*\n     * Find all the prime factors of the number. This step can take several\n     * seconds for 48 bit numbers, which is why we benchmark how long it\n     * takes.\n     */\n    sieve_prime_factors(m, factors, non_factors, &elapsed);\n\n    /*\n     * Calculate the 'a-1' constant. It must share all the prime factors\n     * with the range, and if the range is a multiple of 4, must also\n     * be a multiple of 4\n     */\n    if (factors[0] == m) {\n        /* this number has no prime factors, so we can choose anything.\n         * Therefore, we are going to pick something at random */\n        unsigned j;\n\n        a = 1;\n        for (j=0; non_factors[j] && j < 5; j++)\n            a *= non_factors[j];\n    } else {\n        //unsigned j;\n        a = 1;\n        for (i=0; factors[i]; i++)\n            a = a * factors[i];\n        if ((m % 4) == 0)\n            a *= 2;\n\n        /*for (j=0; j<0 && non_factors[j]; j++)\n            a *= non_factors[j];*/\n    }\n    a += 1;\n\n    /*\n     * Calculate the 'c' constant. It must have no prime factors in\n     * common with the range.\n     */\n    if (c == 0)\n        c = 2531011 ; /* something random */\n    while (has_factors_in_common(c, factors))\n        c++;\n\n    if (is_debug) {\n        /*\n         * print the results\n         */\n        //printf(\"sizeof(int) = %\" PRIu64 \"-bits\\n\", (uint64_t)(sizeof(size_t)*8));\n        printf(\"elapsed     = %5.3f-seconds\\n\", elapsed);\n        printf(\"factors     = \");\n        for (i=0; factors[i]; i++)\n            printf(\"%\" PRIu64 \" \", factors[i]);\n        printf(\"%s\\n\", factors[0]?\"\":\"(none)\");\n        printf(\"m           = %-24\" PRIu64 \" (0x%\" PRIx64 \")\\n\", m, m);\n        printf(\"a           = %-24\" PRIu64 \" (0x%\" PRIx64 \")\\n\", a, a);\n        printf(\"c           = %-24\" PRIu64 \" (0x%\" PRIx64 \")\\n\", c, c);\n        printf(\"c%%m         = %-24\" PRIu64 \" (0x%\" PRIx64 \")\\n\", c%m, c%m);\n        printf(\"a%%m         = %-24\" PRIu64 \" (0x%\" PRIx64 \")\\n\", a%m, a%m);\n\n        if (m < 1000000000) {\n            if (lcg_verify(a, c+1, m, 280))\n                printf(\"verify      = success\\n\");\n            else\n                printf(\"verify      = failure\\n\");\n        } else {\n            printf(\"verify      = too big to check\\n\");\n        }\n\n\n        /*\n         * Print some first numbers. We use these to visually inspect whether\n         * the results are random or not.\n         */\n        {\n            unsigned count = 0;\n            uint64_t x = 0;\n            unsigned digits = count_digits(m);\n\n            for (i=0; i<100 && i < m; i++) {\n                x = lcg_rand(x, a, c, m);\n                count += printf(\"%*\" PRIu64 \" \", digits, x);\n                if (count >= 70) {\n                    count = 0;\n                    printf(\"\\n\");\n                }\n            }\n            printf(\"\\n\");\n        }\n    }\n\n    *out_a = a;\n    *inout_c = c;\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nlcg_selftest(void)\n{\n    unsigned i;\n    int is_success = 0;\n    uint64_t m, a, c;\n\n\n    m = 3015 * 3;\n\n    for (i=0; i<5; i++) {\n        a = 0;\n        c = 0;\n\n        m += 10 + i;\n\n        lcg_calculate_constants(m, &a, &c, 0);\n\n        is_success = lcg_verify(a, c, m, m);\n\n        if (!is_success) {\n            fprintf(stderr, \"LCG: randomization failed\\n\");\n            return 1; /*fail*/\n        }\n    }\n\n    return 0; /*success*/\n}\n"
  },
  {
    "path": "src/crypto-lcg.h",
    "content": "#ifndef RAND_LCG_H\n#define RAND_LCG_H\n#include <stdint.h>\n\n\nvoid\nlcg_calculate_constants(uint64_t m, uint64_t *out_a, uint64_t *inout_c, int is_debug);\n\nuint64_t\nlcg_rand(uint64_t index, uint64_t a, uint64_t c, uint64_t range);\n\n/**\n * Performs a regression test on this module.\n * @return\n *      0 on success, or a positive integer on failure\n */\nint\nlcg_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/crypto-primegen.c",
    "content": "/*\n    This is DJB's code for calculating primes, with a few modifications,\n    such as making it work with Microsoft's compiler on Windows, and\n    getting rid of warnings.\n*/\n#include \"crypto-primegen.h\"\n\n/*\nB is 32 times X.\nTotal memory use for one generator is 2B bytes = 64X bytes.\nCovers primes in an interval of length 1920X.\nWorking set size for one generator is B bits = 4X bytes.\n\nSpeedup by a factor of 2 or 3 for L1 cache instead of L2 cache.\nSlowdown by a factor of roughly n for primes past (nB)^2.\n\nPossible choices of X:\n  2002 to fit inside an 8K L1 cache (e.g., Pentium).\n  4004 to fit inside a 16K L1 cache (e.g., Pentium II).\n  64064 to fit inside a 256K L2 cache.\n\nThere are various word-size limits on X; 1000000 should still be okay.\n*/\n\n#define B32 PRIMEGEN_WORDS\n#define B (PRIMEGEN_WORDS * 32)\n\n#ifdef _MSC_VER\n#pragma warning(disable:4244)\n#endif\n\nstatic const uint32_t two[32] = {\n  0x00000001 , 0x00000002 , 0x00000004 , 0x00000008\n, 0x00000010 , 0x00000020 , 0x00000040 , 0x00000080\n, 0x00000100 , 0x00000200 , 0x00000400 , 0x00000800\n, 0x00001000 , 0x00002000 , 0x00004000 , 0x00008000\n, 0x00010000 , 0x00020000 , 0x00040000 , 0x00080000\n, 0x00100000 , 0x00200000 , 0x00400000 , 0x00800000\n, 0x01000000 , 0x02000000 , 0x04000000 , 0x08000000\n, 0x10000000 , 0x20000000 , 0x40000000 , 0x80000000\n} ;\n\nstatic void clear(register uint32_t (*buf)[B32])\n{\n  register int i;\n  register int j;\n\n  for (j = 0;j < 16;++j) {\n    for (i = 0;i < B32;++i)\n      (*buf)[i] = (uint32_t)~0;\n    ++buf;\n  }\n}\n\nstatic void doit4(register uint32_t *a,register long x,register long y,int64_t start)\n{\n  long i0;\n  long y0;\n  register long i;\n  register uint32_t data;\n  register uint32_t pos;\n  register uint32_t bits;\n\n  x += x; x += 15;\n  y += 15;\n\n  start += 1000000000;\n  while (start < 0) { start += x; x += 30; }\n  start -= 1000000000;\n  i = start;\n\n  while (i < B) { i += x; x += 30; }\n\n  for (;;) {\n    x -= 30;\n    if (x <= 15) return;\n    i -= x;\n\n    while (i < 0) { i += y; y += 30; }\n\n    i0 = i; y0 = y;\n    while (i < B) {\n      pos = (uint32_t)i; data = (uint32_t)i;\n      pos >>= 5; data &= 31;\n      i += y; y += 30;\n      bits = a[pos]; data = two[data];\n      bits ^= data;\n      a[pos] = bits;\n    }\n    i = i0; y = y0;\n  }\n}\n\nstatic void doit6(register uint32_t *a,register long x,register long y,int64_t start)\n{\n  long i0;\n  long y0;\n  register long i;\n  register uint32_t data;\n  register uint32_t pos;\n  register uint32_t bits;\n\n  x += 5;\n  y += 15;\n\n  start += 1000000000;\n  while (start < 0) { start += x; x += 10; }\n  start -= 1000000000;\n  i = start;\n  while (i < B) { i += x; x += 10; }\n\n  for (;;) {\n    x -= 10;\n    if (x <= 5) return;\n    i -= x;\n\n    while (i < 0) { i += y; y += 30; }\n\n    i0 = i; y0 = y;\n    while (i < B) {\n      pos = (uint32_t)i; data = (uint32_t)i;\n      pos >>= 5; data &= 31;\n      i += y; y += 30;\n      bits = a[pos]; data = two[data];\n      bits ^= data;\n      a[pos] = bits;\n    }\n    i = i0; y = y0;\n  }\n}\n\nstatic void doit12(register uint32_t *a,register long x,register long y,int64_t start)\n{\n  register long i;\n  register uint32_t data;\n  register uint32_t bits;\n\n  x += 5;\n\n  start += 1000000000;\n  while (start < 0) { start += x; x += 10; }\n  start -= 1000000000;\n  i = start;\n  while (i < 0) { i += x; x += 10; }\n\n  y += 15;\n  x += 10;\n\n  for (;;) {\n    long i0;\n    long y0;\n    while (i >= B) {\n      if (x <= y) return;\n      i -= y;\n      y += 30;\n    }\n    i0 = i;\n    y0 = y;\n    while ((i >= 0) && (y < x)) {\n      register uint32_t pos;\n      pos = (uint32_t)i; data = (uint32_t)i;\n      pos >>= 5; data &= 31;\n      i -= y;\n      y += 30;\n      bits = a[pos]; data = two[data];\n      bits ^= data;\n      a[pos] = bits;\n    }\n    i = i0;\n    y = y0;\n    i += x - 10;\n    x += 10;\n  }\n}\n\nstatic const int deltainverse[60] = {\n -1,B32 * 0,-1,-1,-1,-1,-1,B32 * 1,-1,-1,-1,B32 * 2,-1,B32 * 3,-1\n,-1,-1,B32 * 4,-1,B32 * 5,-1,-1,-1,B32 * 6,-1,-1,-1,-1,-1,B32 * 7\n,-1,B32 * 8,-1,-1,-1,-1,-1,B32 * 9,-1,-1,-1,B32 * 10,-1,B32 * 11,-1\n,-1,-1,B32 * 12,-1,B32 * 13,-1,-1,-1,B32 * 14,-1,-1,-1,-1,-1,B32 * 15\n} ;\n\nstatic void squarefree1big(uint32_t (*buf)[B32],uint64_t base,uint32_t q,uint64_t qq)\n{\n  uint64_t i;\n  uint32_t pos;\n  int n;\n  uint64_t bound = base + 60 * B;\n\n  while (qq < bound) {\n    if (bound < 2000000000)\n      i = qq - (((uint32_t) base) % ((uint32_t) qq));\n    else\n      i = qq - (base % qq);\n    if (!(i & 1)) i += qq;\n\n    if (i < B * 60) {\n      pos = (uint32_t)i;\n      n = deltainverse[pos % 60];\n      if (n >= 0) {\n        pos /= 60;\n        (*buf)[n + (pos >> 5)] |= two[pos & 31];\n      }\n    }\n\n    qq += q; q += 1800;\n  }\n}\n\nstatic void squarefree1(register uint32_t (*buf)[B32],uint64_t L,uint32_t q)\n{\n  uint32_t qq;\n  register uint32_t qqhigh;\n  uint32_t i;\n  register uint32_t ilow;\n  register uint32_t ihigh;\n  register int n;\n  uint64_t base;\n\n  base = 60 * L;\n  qq = q * q;\n  q = 60 * q + 900;\n\n  while (qq < B * 60) {\n    if (base < 2000000000)\n      i = qq - (((uint32_t) base) % qq);\n    else\n      i = qq - (base % qq);\n    if (!(i & 1)) i += qq;\n\n    if (i < B * 60) {\n      qqhigh = qq / 60;\n      ilow = i % 60; ihigh = i / 60;\n\n      qqhigh += qqhigh;\n      while (ihigh < B) {\n        n = deltainverse[ilow];\n        if (n >= 0)\n          (*buf)[n + (ihigh >> 5)] |= two[ihigh & 31];\n\n        ilow += 2; ihigh += qqhigh;\n        if (ilow >= 60) { ilow -= 60; ihigh += 1; }\n      }\n    }\n\n    qq += q; q += 1800;\n  }\n\n  squarefree1big(buf,base,q,qq);\n}\n\nstatic void squarefree49big(uint32_t (*buf)[B32],uint64_t base,uint32_t q,uint64_t qq)\n{\n  uint64_t i;\n  uint32_t pos;\n  int n;\n  uint64_t bound = base + 60 * B;\n\n  while (qq < bound) {\n    if (bound < 2000000000)\n      i = qq - (((uint32_t) base) % ((uint32_t) qq));\n    else\n      i = qq - (base % qq);\n    if (!(i & 1)) i += qq;\n\n    if (i < B * 60) {\n      pos = (uint32_t)i;\n      n = deltainverse[pos % 60];\n      if (n >= 0) {\n        pos /= 60;\n        (*buf)[n + (pos >> 5)] |= two[pos & 31];\n      }\n    }\n\n    qq += q; q += 1800;\n  }\n}\n\nstatic void squarefree49(register uint32_t (*buf)[B32],uint64_t L,uint32_t q)\n{\n  uint32_t qq;\n  register uint32_t qqhigh;\n  uint32_t i;\n  register uint32_t ilow;\n  register uint32_t ihigh;\n  register int n;\n  uint64_t base = 60 * L;\n\n  qq = q * q;\n  q = 60 * q + 900;\n\n  while (qq < B * 60) {\n    if (base < 2000000000)\n      i = qq - (((uint32_t) base) % qq);\n    else\n      i = qq - (base % qq);\n    if (!(i & 1)) i += qq;\n\n    if (i < B * 60) {\n      qqhigh = qq / 60;\n      ilow = i % 60; ihigh = i / 60;\n\n      qqhigh += qqhigh;\n      qqhigh += 1;\n      while (ihigh < B) {\n        n = deltainverse[ilow];\n        if (n >= 0)\n          (*buf)[n + (ihigh >> 5)] |= two[ihigh & 31];\n\n        ilow += 38; ihigh += qqhigh;\n        if (ilow >= 60) { ilow -= 60; ihigh += 1; }\n      }\n    }\n\n    qq += q; q += 1800;\n  }\n\n  squarefree49big(buf,base,q,qq);\n}\n\n/* squares of primes >= 7, < 240 */\nuint32_t qqtab[49] = {\n  49,121,169,289,361,529,841,961,1369,1681\n ,1849,2209,2809,3481,3721,4489,5041,5329,6241,6889\n ,7921,9409,10201,10609,11449,11881,12769,16129,17161,18769\n ,19321,22201,22801,24649,26569,27889,29929,32041,32761,36481\n ,37249,38809,39601,44521,49729,51529,52441,54289,57121\n} ;\n\n/* (qq * 11 + 1) / 60 or (qq * 59 + 1) / 60 */\nuint32_t qq60tab[49] = {\n  9,119,31,53,355,97,827,945,251,1653\n ,339,405,515,3423,3659,823,4957,977,6137\n ,1263,7789,1725,10031,1945,2099,11683,2341,2957\n ,16875,3441,18999,21831,22421,4519,4871,5113,5487\n ,31507,32215,35873,6829,7115,38941,43779,9117,9447,51567,9953,56169\n} ;\n\nstatic void squarefreetiny(register uint32_t *a,uint32_t *Lmodqq,int d)\n{\n  int j;\n\n  for (j = 0;j < 49;++j) {\n    register uint32_t k;\n    register uint32_t qq;\n    qq = qqtab[j];\n    k = qq - 1 - ((Lmodqq[j] + qq60tab[j] * d - 1) % qq);\n    while (k < B) {\n      register uint32_t pos;\n      register uint32_t data;\n      register uint32_t bits;\n      pos = k;\n      data = k;\n      pos >>= 5;\n      data &= 31;\n      k += qq;\n      bits = a[pos];\n      data = two[data];\n      bits |= data;\n      a[pos] = bits;\n    }\n  }\n}\n\ntypedef struct { char index; char f; char g; char k; } todo;\n\nstatic const todo for4[] = {\n  {0,2,15,4} , {0,3,5,1} , {0,3,25,11} , {0,5,9,3}\n, {0,5,21,9} , {0,7,15,7} , {0,8,15,8} , {0,10,9,8}\n, {0,10,21,14} , {0,12,5,10} , {0,12,25,20} , {0,13,15,15}\n, {0,15,1,15} , {0,15,11,17} , {0,15,19,21} , {0,15,29,29}\n, {3,1,3,0} , {3,1,27,12} , {3,4,3,1} , {3,4,27,13}\n, {3,6,7,3} , {3,6,13,5} , {3,6,17,7} , {3,6,23,11}\n, {3,9,7,6} , {3,9,13,8} , {3,9,17,10} , {3,9,23,14}\n, {3,11,3,8} , {3,11,27,20} , {3,14,3,13} , {3,14,27,25}\n, {4,2,1,0} , {4,2,11,2} , {4,2,19,6} , {4,2,29,14}\n, {4,7,1,3} , {4,7,11,5} , {4,7,19,9} , {4,7,29,17}\n, {4,8,1,4} , {4,8,11,6} , {4,8,19,10} , {4,8,29,18}\n, {4,13,1,11} , {4,13,11,13} , {4,13,19,17} , {4,13,29,25}\n, {7,1,5,0} , {7,1,25,10} , {7,4,5,1} , {7,4,25,11}\n, {7,5,7,2} , {7,5,13,4} , {7,5,17,6} , {7,5,23,10}\n, {7,10,7,7} , {7,10,13,9} , {7,10,17,11} , {7,10,23,15}\n, {7,11,5,8} , {7,11,25,18} , {7,14,5,13} , {7,14,25,23}\n, {9,2,9,1} , {9,2,21,7} , {9,3,1,0} , {9,3,11,2}\n, {9,3,19,6} , {9,3,29,14} , {9,7,9,4} , {9,7,21,10}\n, {9,8,9,5} , {9,8,21,11} , {9,12,1,9} , {9,12,11,11}\n, {9,12,19,15} , {9,12,29,23} , {9,13,9,12} , {9,13,21,18}\n, {10,2,5,0} , {10,2,25,10} , {10,5,1,1} , {10,5,11,3}\n, {10,5,19,7} , {10,5,29,15} , {10,7,5,3} , {10,7,25,13}\n, {10,8,5,4} , {10,8,25,14} , {10,10,1,6} , {10,10,11,8}\n, {10,10,19,12} , {10,10,29,20} , {10,13,5,11} , {10,13,25,21}\n, {13,1,15,3} , {13,4,15,4} , {13,5,3,1} , {13,5,27,13}\n, {13,6,5,2} , {13,6,25,12} , {13,9,5,5} , {13,9,25,15}\n, {13,10,3,6} , {13,10,27,18} , {13,11,15,11} , {13,14,15,16}\n, {13,15,7,15} , {13,15,13,17} , {13,15,17,19} , {13,15,23,23}\n, {14,1,7,0} , {14,1,13,2} , {14,1,17,4} , {14,1,23,8}\n, {14,4,7,1} , {14,4,13,3} , {14,4,17,5} , {14,4,23,9}\n, {14,11,7,8} , {14,11,13,10} , {14,11,17,12} , {14,11,23,16}\n, {14,14,7,13} , {14,14,13,15} , {14,14,17,17} , {14,14,23,21}\n} ;\n\nstatic const todo for6[] = {\n  {1,1,2,0} , {1,1,8,1} , {1,1,22,8} , {1,1,28,13}\n, {1,3,10,2} , {1,3,20,7} , {1,7,10,4} , {1,7,20,9}\n, {1,9,2,4} , {1,9,8,5} , {1,9,22,12} , {1,9,28,17}\n, {5,1,4,0} , {5,1,14,3} , {5,1,16,4} , {5,1,26,11}\n, {5,5,2,1} , {5,5,8,2} , {5,5,22,9} , {5,5,28,14}\n, {5,9,4,4} , {5,9,14,7} , {5,9,16,8} , {5,9,26,15}\n, {8,3,2,0} , {8,3,8,1} , {8,3,22,8} , {8,3,28,13}\n, {8,5,4,1} , {8,5,14,4} , {8,5,16,5} , {8,5,26,12}\n, {8,7,2,2} , {8,7,8,3} , {8,7,22,10} , {8,7,28,15}\n, {11,1,10,1} , {11,1,20,6} , {11,3,4,0} , {11,3,14,3}\n, {11,3,16,4} , {11,3,26,11} , {11,7,4,2} , {11,7,14,5}\n, {11,7,16,6} , {11,7,26,13} , {11,9,10,5} , {11,9,20,10}\n} ;\n\nstatic const todo for12[] = {\n  {2,2,1,0} , {2,2,11,-2} , {2,2,19,-6} , {2,2,29,-14}\n, {2,3,4,0} , {2,3,14,-3} , {2,3,16,-4} , {2,3,26,-11}\n, {2,5,2,1} , {2,5,8,0} , {2,5,22,-7} , {2,5,28,-12}\n, {2,7,4,2} , {2,7,14,-1} , {2,7,16,-2} , {2,7,26,-9}\n, {2,8,1,3} , {2,8,11,1} , {2,8,19,-3} , {2,8,29,-11}\n, {2,10,7,4} , {2,10,13,2} , {2,10,17,0} , {2,10,23,-4}\n, {6,1,10,-2} , {6,1,20,-7} , {6,2,7,-1} , {6,2,13,-3}\n, {6,2,17,-5} , {6,2,23,-9} , {6,3,2,0} , {6,3,8,-1}\n, {6,3,22,-8} , {6,3,28,-13} , {6,4,5,0} , {6,4,25,-10}\n, {6,6,5,1} , {6,6,25,-9} , {6,7,2,2} , {6,7,8,1}\n, {6,7,22,-6} , {6,7,28,-11} , {6,8,7,2} , {6,8,13,0}\n, {6,8,17,-2} , {6,8,23,-6} , {6,9,10,2} , {6,9,20,-3}\n, {12,1,4,-1} , {12,1,14,-4} , {12,1,16,-5} , {12,1,26,-12}\n, {12,2,5,-1} , {12,2,25,-11} , {12,3,10,-2} , {12,3,20,-7}\n, {12,4,1,0} , {12,4,11,-2} , {12,4,19,-6} , {12,4,29,-14}\n, {12,6,1,1} , {12,6,11,-1} , {12,6,19,-5} , {12,6,29,-13}\n, {12,7,10,0} , {12,7,20,-5} , {12,8,5,2} , {12,8,25,-8}\n, {12,9,4,3} , {12,9,14,0} , {12,9,16,-1} , {12,9,26,-8}\n, {15,1,2,-1} , {15,1,8,-2} , {15,1,22,-9} , {15,1,28,-14}\n, {15,4,7,-1} , {15,4,13,-3} , {15,4,17,-5} , {15,4,23,-9}\n, {15,5,4,0} , {15,5,14,-3} , {15,5,16,-4} , {15,5,26,-11}\n, {15,6,7,0} , {15,6,13,-2} , {15,6,17,-4} , {15,6,23,-8}\n, {15,9,2,3} , {15,9,8,2} , {15,9,22,-5} , {15,9,28,-10}\n, {15,10,1,4} , {15,10,11,2} , {15,10,19,-2} , {15,10,29,-10}\n} ;\n\nvoid primegen_sieve(primegen *pg)\n{\n  uint32_t (*buf)[B32];\n  uint64_t L;\n  int i;\n  uint32_t Lmodqq[49];\n\n  buf = pg->buf;\n  L = pg->L;\n\n  if (L > 2000000000)\n    for (i = 0;i < 49;++i)\n      Lmodqq[i] = L % qqtab[i];\n  else\n    for (i = 0;i < 49;++i)\n      Lmodqq[i] = ((uint32_t) L) % qqtab[i];\n\n  clear(buf);\n\n  for (i = 0;i < 16;++i)\n    doit4(buf[0],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[0],Lmodqq,1);\n  for (;i < 32;++i)\n    doit4(buf[3],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[3],Lmodqq,13);\n  for (;i < 48;++i)\n    doit4(buf[4],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[4],Lmodqq,17);\n  for (;i < 64;++i)\n    doit4(buf[7],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[7],Lmodqq,29);\n  for (;i < 80;++i)\n    doit4(buf[9],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[9],Lmodqq,37);\n  for (;i < 96;++i)\n    doit4(buf[10],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[10],Lmodqq,41);\n  for (;i < 112;++i)\n    doit4(buf[13],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[13],Lmodqq,49);\n  for (;i < 128;++i)\n    doit4(buf[14],for4[i].f,for4[i].g,(int64_t) for4[i].k - L);\n  squarefreetiny(buf[14],Lmodqq,53);\n\n  for (i = 0;i < 12;++i)\n    doit6(buf[1],for6[i].f,for6[i].g,(int64_t) for6[i].k - L);\n  squarefreetiny(buf[1],Lmodqq,7);\n  for (;i < 24;++i)\n    doit6(buf[5],for6[i].f,for6[i].g,(int64_t) for6[i].k - L);\n  squarefreetiny(buf[5],Lmodqq,19);\n  for (;i < 36;++i)\n    doit6(buf[8],for6[i].f,for6[i].g,(int64_t) for6[i].k - L);\n  squarefreetiny(buf[8],Lmodqq,31);\n  for (;i < 48;++i)\n    doit6(buf[11],for6[i].f,for6[i].g,(int64_t) for6[i].k - L);\n  squarefreetiny(buf[11],Lmodqq,43);\n\n  for (i = 0;i < 24;++i)\n    doit12(buf[2],for12[i].f,for12[i].g,(int64_t) for12[i].k - L);\n  squarefreetiny(buf[2],Lmodqq,11);\n  for (;i < 48;++i)\n    doit12(buf[6],for12[i].f,for12[i].g,(int64_t) for12[i].k - L);\n  squarefreetiny(buf[6],Lmodqq,23);\n  for (;i < 72;++i)\n    doit12(buf[12],for12[i].f,for12[i].g,(int64_t) for12[i].k - L);\n  squarefreetiny(buf[12],Lmodqq,47);\n  for (;i < 96;++i)\n    doit12(buf[15],for12[i].f,for12[i].g,(int64_t) for12[i].k - L);\n  squarefreetiny(buf[15],Lmodqq,59);\n\n  squarefree49(buf,L,247);\n  squarefree49(buf,L,253);\n  squarefree49(buf,L,257);\n  squarefree49(buf,L,263);\n  squarefree1(buf,L,241);\n  squarefree1(buf,L,251);\n  squarefree1(buf,L,259);\n  squarefree1(buf,L,269);\n}\n\n\nvoid primegen_fill(primegen *pg)\n{\n  int i;\n  uint32_t mask;\n  uint32_t bits0, bits1, bits2, bits3, bits4, bits5, bits6, bits7;\n  uint32_t bits8, bits9, bits10, bits11, bits12, bits13, bits14, bits15;\n  uint64_t base;\n\n  i = pg->pos;\n  if (i == B32) {\n    primegen_sieve(pg);\n    pg->L += B;\n    i = 0;\n  }\n  pg->pos = i + 1;\n\n  bits0 = ~pg->buf[0][i];\n  bits1 = ~pg->buf[1][i];\n  bits2 = ~pg->buf[2][i];\n  bits3 = ~pg->buf[3][i];\n  bits4 = ~pg->buf[4][i];\n  bits5 = ~pg->buf[5][i];\n  bits6 = ~pg->buf[6][i];\n  bits7 = ~pg->buf[7][i];\n  bits8 = ~pg->buf[8][i];\n  bits9 = ~pg->buf[9][i];\n  bits10 = ~pg->buf[10][i];\n  bits11 = ~pg->buf[11][i];\n  bits12 = ~pg->buf[12][i];\n  bits13 = ~pg->buf[13][i];\n  bits14 = ~pg->buf[14][i];\n  bits15 = ~pg->buf[15][i];\n\n  base = pg->base + 1920;\n  pg->base = base;\n\n  pg->num = 0;\n\n  for (mask = 0x80000000;mask;mask >>= 1) {\n    base -= 60;\n    if (bits15 & mask) pg->p[pg->num++] = base + 59;\n    if (bits14 & mask) pg->p[pg->num++] = base + 53;\n    if (bits13 & mask) pg->p[pg->num++] = base + 49;\n    if (bits12 & mask) pg->p[pg->num++] = base + 47;\n    if (bits11 & mask) pg->p[pg->num++] = base + 43;\n    if (bits10 & mask) pg->p[pg->num++] = base + 41;\n    if (bits9 & mask) pg->p[pg->num++] = base + 37;\n    if (bits8 & mask) pg->p[pg->num++] = base + 31;\n    if (bits7 & mask) pg->p[pg->num++] = base + 29;\n    if (bits6 & mask) pg->p[pg->num++] = base + 23;\n    if (bits5 & mask) pg->p[pg->num++] = base + 19;\n    if (bits4 & mask) pg->p[pg->num++] = base + 17;\n    if (bits3 & mask) pg->p[pg->num++] = base + 13;\n    if (bits2 & mask) pg->p[pg->num++] = base + 11;\n    if (bits1 & mask) pg->p[pg->num++] = base + 7;\n    if (bits0 & mask) pg->p[pg->num++] = base + 1;\n  }\n}\n\nuint64_t primegen_next(primegen *pg)\n{\n  while (!pg->num)\n    primegen_fill(pg);\n\n  return pg->p[--pg->num];\n}\n\nuint64_t primegen_peek(primegen *pg)\n{\n  while (!pg->num)\n    primegen_fill(pg);\n\n  return pg->p[pg->num - 1];\n}\n\nvoid primegen_init(primegen *pg)\n{\n  pg->L = 1;\n  pg->base = 60;\n\n  pg->pos = PRIMEGEN_WORDS;\n\n  pg->p[0] = 59;\n  pg->p[1] = 53;\n  pg->p[2] = 47;\n  pg->p[3] = 43;\n  pg->p[4] = 41;\n  pg->p[5] = 37;\n  pg->p[6] = 31;\n  pg->p[7] = 29;\n  pg->p[8] = 23;\n  pg->p[9] = 19;\n  pg->p[10] = 17;\n  pg->p[11] = 13;\n  pg->p[12] = 11;\n  pg->p[13] = 7;\n  pg->p[14] = 5;\n  pg->p[15] = 3;\n  pg->p[16] = 2;\n\n  pg->num = 17;\n}\n\n\nstatic const unsigned long pop[256] = {\n 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5\n,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6\n,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6\n,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7\n,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6\n,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7\n,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7\n,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8\n};\n\nuint64_t primegen_count(primegen *pg,uint64_t to)\n{\n  uint64_t count = 0;\n  \n  for (;;) {\n    register int pos;\n    register int j;\n    register uint32_t bits;\n    register uint32_t smallcount;\n    while (pg->num) {\n      if (pg->p[pg->num - 1] >= to) return count;\n      ++count;\n      --pg->num;\n    }\n\n    smallcount = 0;\n    pos = pg->pos;\n    while ((pos < B32) && (pg->base + 1920 < to)) {\n      for (j = 0;j < 16;++j) {\n    bits = ~pg->buf[j][pos];\n    smallcount += pop[bits & 255]; bits >>= 8;\n    smallcount += pop[bits & 255]; bits >>= 8;\n    smallcount += pop[bits & 255]; bits >>= 8;\n    smallcount += pop[bits & 255];\n      }\n      pg->base += 1920;\n      ++pos;\n    }\n    pg->pos = pos;\n    count += smallcount;\n\n    if (pos == B32)\n      while (pg->base + B * 60 < to) {\n        primegen_sieve(pg);\n        pg->L += B;\n\n    smallcount = 0;\n        for (j = 0;j < 16;++j)\n      for (pos = 0;pos < B32;++pos) {\n        bits = ~pg->buf[j][pos];\n        smallcount += pop[bits & 255]; bits >>= 8;\n        smallcount += pop[bits & 255]; bits >>= 8;\n        smallcount += pop[bits & 255]; bits >>= 8;\n        smallcount += pop[bits & 255];\n      }\n        count += smallcount;\n        pg->base += B * 60;\n      }\n\n    primegen_fill(pg);\n  }\n}\n\nvoid primegen_skipto(primegen *pg,uint64_t to)\n{\n  for (;;) {\n    int pos;\n    while (pg->num) {\n      if (pg->p[pg->num - 1] >= to) return;\n      --pg->num;\n    }\n\n    pos = pg->pos;\n    while ((pos < B32) && (pg->base + 1920 < to)) {\n      pg->base += 1920;\n      ++pos;\n    }\n    pg->pos = pos;\n    if (pos == B32)\n      while (pg->base + B * 60 < to) {\n        pg->L += B;\n        pg->base += B * 60;\n      }\n\n    primegen_fill(pg);\n  }\n}\n"
  },
  {
    "path": "src/crypto-primegen.h",
    "content": "#ifndef PRIMEGEN_H\n#define PRIMEGEN_H\n\n#include <stdint.h>\n\n/**\n * This is B/32: the number of 32-bit words of space used in the primegen\n * inner loop. This should fit into the CPU's level-1 cache.\n *\n * 2048 works well on a Pentium-100.\n * 3600 works well on a Pentium II-350\n * 4004 works well on an UltraSPARC-I/167\n *\n * 2012-nov (Rob): This code was written 15 years ago. Processor caches\n * haven't really gotten any larger. A number like 8008 works slightly\n * better on an Ivy Bridge CPU, but works noticeably worse on an Atom\n * or ARM processor. The value 4004 seems to be a good compromise for\n * all these processors. In any case, modern CPUs will automatically\n * prefetch the buffers anyway, significantly lessoning the impact of\n * having a poor number defined here. I tried 16016, but it crashed, and\n * I don't know why, but I don't care because I'm not going to use such a\n * large size.\n */\n#define PRIMEGEN_WORDS 4004\n\ntypedef struct {\n  uint32_t buf[16][PRIMEGEN_WORDS];\n  uint64_t p[512]; /* p[num-1] ... p[0], in that order */\n  int num;\n  int pos; /* next entry to use in buf; WORDS to restart */\n  uint64_t base;\n  uint64_t L;\n} primegen;\n\nextern void primegen_sieve(primegen *);\nextern void primegen_fill(primegen *);\n\nextern void primegen_init(primegen *);\nextern uint64_t primegen_next(primegen *);\nextern uint64_t primegen_peek(primegen *);\nextern uint64_t primegen_count(primegen *,uint64_t to);\nextern void primegen_skipto(primegen *,uint64_t to);\n\n#endif\n"
  },
  {
    "path": "src/crypto-siphash24.c",
    "content": "/*\n   SipHash reference C implementation\n\n   Written in 2012 by\n   Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>\n   Daniel J. Bernstein <djb@cr.yp.to>\n\n   To the extent possible under law, the author(s) have dedicated all copyright\n   and related and neighboring rights to this software to the public domain\n   worldwide. This software is distributed without any warranty.\n\n   You should have received a copy of the CC0 Public Domain Dedication along with\n   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n*/\n#include <stdint.h>\n#include <stdio.h>\n#include <string.h>\n#include \"crypto-siphash24.h\"\n\ntypedef uint64_t u64;\ntypedef uint32_t u32;\ntypedef uint8_t u8;\n\n#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )\n\n#define U32TO8_LE(p, v)         \\\n    (p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \\\n    (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);\n\n#define U64TO8_LE(p, v)         \\\n  U32TO8_LE((p),     (u32)((v)      ));   \\\n  U32TO8_LE((p) + 4, (u32)((v) >> 32));\n\n#define U8TO64_LE(p) \\\n  (((u64)((p)[0])      ) | \\\n   ((u64)((p)[1]) <<  8) | \\\n   ((u64)((p)[2]) << 16) | \\\n   ((u64)((p)[3]) << 24) | \\\n   ((u64)((p)[4]) << 32) | \\\n   ((u64)((p)[5]) << 40) | \\\n   ((u64)((p)[6]) << 48) | \\\n   ((u64)((p)[7]) << 56))\n\n#define SIPROUND            \\\n  {              \\\n    v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \\\n    v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \\\n    v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \\\n    v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \\\n  }\n\n/* SipHash-2-4 */\nstatic int crypto_auth( unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k )\n{\n  /* \"somepseudorandomlygeneratedbytes\" */\n  u64 v0 = 0x736f6d6570736575ULL;\n  u64 v1 = 0x646f72616e646f6dULL;\n  u64 v2 = 0x6c7967656e657261ULL;\n  u64 v3 = 0x7465646279746573ULL;\n  u64 b;\n  u64 k0 = U8TO64_LE( k );\n  u64 k1 = U8TO64_LE( k + 8 );\n  const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );\n  const int left = inlen & 7;\n  b = ( ( u64 )inlen ) << 56;\n  v3 ^= k1;\n  v2 ^= k0;\n  v1 ^= k1;\n  v0 ^= k0;\n\n  for ( ; in != end; in += 8 )\n  {\n    u64 m;\n    m = U8TO64_LE( in );\n#ifdef xxxDEBUG\n    printf( \"(%3d) v0 %08x %08x\\n\", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );\n    printf( \"(%3d) v1 %08x %08x\\n\", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );\n    printf( \"(%3d) v2 %08x %08x\\n\", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );\n    printf( \"(%3d) v3 %08x %08x\\n\", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );\n    printf( \"(%3d) compress %08x %08x\\n\", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m );\n#endif\n    v3 ^= m;\n    SIPROUND;\n    SIPROUND;\n    v0 ^= m;\n  }\n\n  switch( left )\n  {\n  case 7: b |= ( ( u64 )in[ 6] )  << 48;\n  case 6: b |= ( ( u64 )in[ 5] )  << 40;\n  case 5: b |= ( ( u64 )in[ 4] )  << 32;\n  case 4: b |= ( ( u64 )in[ 3] )  << 24;\n  case 3: b |= ( ( u64 )in[ 2] )  << 16;\n  case 2: b |= ( ( u64 )in[ 1] )  <<  8;\n  case 1: b |= ( ( u64 )in[ 0] ); break;\n  case 0: break;\n  }\n\n#ifdef xxxDEBUG\n  printf( \"(%3d) v0 %08x %08x\\n\", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );\n  printf( \"(%3d) v1 %08x %08x\\n\", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );\n  printf( \"(%3d) v2 %08x %08x\\n\", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );\n  printf( \"(%3d) v3 %08x %08x\\n\", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );\n  printf( \"(%3d) padding   %08x %08x\\n\", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b );\n#endif\n  v3 ^= b;\n  SIPROUND;\n  SIPROUND;\n  v0 ^= b;\n#ifdef xxxDEBUG\n  printf( \"(%3d) v0 %08x %08x\\n\", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );\n  printf( \"(%3d) v1 %08x %08x\\n\", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );\n  printf( \"(%3d) v2 %08x %08x\\n\", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );\n  printf( \"(%3d) v3 %08x %08x\\n\", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );\n#endif\n  v2 ^= 0xff;\n  SIPROUND;\n  SIPROUND;\n  SIPROUND;\n  SIPROUND;\n  b = v0 ^ v1 ^ v2  ^ v3;\n  U64TO8_LE( out, b );\n  return 0;\n}\n\nuint64_t\nsiphash24(const void *in, size_t inlen, const uint64_t key[2])\n{\n    uint64_t result;\n\n    crypto_auth((unsigned char*)&result,\n                (const unsigned char *)in,\n                inlen,\n                (const unsigned char *)&key[0]);\n\n    return result;\n}\n\n/*\n   SipHash-2-4 output with\n   k = 00 01 02 ...\n   and\n   in = (empty string)\n   in = 00 (1 byte)\n   in = 00 01 (2 bytes)\n   in = 00 01 02 (3 bytes)\n   ...\n   in = 00 01 02 ... 3e (63 bytes)\n*/\nstatic u8 vectors[64][8] =\n{\n  { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },\n  { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },\n  { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },\n  { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },\n  { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },\n  { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },\n  { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },\n  { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },\n  { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },\n  { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },\n  { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },\n  { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },\n  { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },\n  { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },\n  { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },\n  { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },\n  { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },\n  { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },\n  { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },\n  { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },\n  { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },\n  { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },\n  { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },\n  { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },\n  { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },\n  { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },\n  { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },\n  { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },\n  { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },\n  { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },\n  { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },\n  { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },\n  { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },\n  { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },\n  { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },\n  { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },\n  { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },\n  { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },\n  { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },\n  { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },\n  { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },\n  { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },\n  { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },\n  { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },\n  { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },\n  { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },\n  { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },\n  { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },\n  { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },\n  { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },\n  { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },\n  { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },\n  { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },\n  { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },\n  { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },\n  { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },\n  { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },\n  { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },\n  { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },\n  { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },\n  { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },\n  { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },\n  { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },\n  { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }\n};\n\n\nstatic int\ntest_vectors()\n{\n#define MAXLEN 64\n  u8 in[MAXLEN], out[8], k[16];\n  int i;\n  int ok = 1;\n\n  for( i = 0; i < 16; ++i ) k[i] = (u8)i;\n\n  for( i = 0; i < MAXLEN; ++i )\n  {\n    in[i] = (u8)i;\n    crypto_auth( out, in, i, k );\n\n    if ( memcmp( out, vectors[i], 8 ) )\n    {\n      printf( \"test vector failed for %d bytes\\n\", i );\n      ok = 0;\n    }\n  }\n\n  return ok;\n}\n\nint\nsiphash24_selftest(void)\n{\n  if (test_vectors())\n      return 0;\n  else\n      return 1;\n}\n"
  },
  {
    "path": "src/crypto-siphash24.h",
    "content": "#ifndef CRYPTO_SIPHASH24_H\n#define CRYPTO_SIPHASH24_H\n#include <stdint.h>\n\nuint64_t\nsiphash24(const void *in, size_t inlen, const uint64_t key[2]);\n\n/**\n * Regression-test this module.\n * @return\n *      0 on success, a positive integer otherwise.\n */\nint\nsiphash24_selftest(void);\n\n#endif\n\n"
  },
  {
    "path": "src/event-timeout.c",
    "content": "/*\n\n    Event timeout\n\n    This is for the user-mode TCP stack. We need to mark timeouts in the\n    future when we'll re-visit a connection/tcb. For example, when we\n    send a packet, we need to resend it in the future in case we don't\n    get a response.\n\n    This design creates a large \"ring\" of timeouts, and then cycles\n    again and again through the ring. This is a fairly high granularity,\n    just has hundreds, thousands, or 10 thousand entries per second.\n    (I keep adjusting the granularity up and down). Not that at any\n    slot in the ring, there may be entries from the far future.\n\n    NOTE: a big feature of this system is that the structure that tracks\n    the timeout is actually held within the TCB structure. In other\n    words, each TCB can have one-and-only-one timeout.\n\n    NOTE: a recurring bug is that the TCP code removes a TCB from the\n    timeout ring and forgets to put it back somewhere else. Since the\n    TCB is cleaned up on a timeout, such TCBs never get cleaned up,\n    leading to a memory leak. I keep fixing this bug, then changing the\n    code and causing the bug to come back again.\n*/\n#include \"event-timeout.h\"\n#include \"util-logger.h\"\n#include \"util-malloc.h\"\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n\n\n/***************************************************************************\n * The timeout system is a circular ring. We move an index around the \n * ring. At each slot in the ring is a linked-list of all entries at\n * that time index. Because the ring can wrap, not everything at a given\n * entry will be the same timestamp. Therefore, when doing the timeout\n * logic at a slot, we have to doublecheck the actual timestamp, and skip\n * those things that are further in the future.\n ***************************************************************************/\nstruct Timeouts {\n    /**\n     * This index is a monotonically increasing number, modulus the mask.\n     * Every time we check timeouts, we simply move it forward in time.\n     */\n    uint64_t current_index;\n\n    /**\n     * Counts the number of outstanding timeouts. Adding a timeout increments\n     * this number, and removing a timeout decrements this number. The\n     * program shouldn't exit until this number is zero.\n     */\n    uint64_t outstanding_count;\n\n    /**\n     * The number of slots is a power-of-2, so the mask is just this\n     * number minus 1\n     */\n    unsigned mask;\n\n    /**\n     * The ring of entries.\n     */\n    struct TimeoutEntry *slots[1024*1024];\n};\n\n/***************************************************************************\n ***************************************************************************/\nstruct Timeouts *\ntimeouts_create(uint64_t timestamp)\n{\n    struct Timeouts *timeouts;\n\n    /*\n     * Allocate memory and initialize it to zero\n     */\n    timeouts = CALLOC(1, sizeof(*timeouts));\n    \n    /*\n     * We just mask off the low order bits to determine wrap. I'm using\n     * a variable here because one of these days I'm going to make\n     * the size of the ring dynamically adjustable depending upon\n     * the speed of the scan.\n     */\n    timeouts->mask = sizeof(timeouts->slots)/sizeof(timeouts->slots[0]) - 1;\n\n    /*\n     * Set the index to the current time. Note that this timestamp is\n     * the 'time_t' value multiplied by the number of ticks-per-second,\n     * where 'ticks' is something I've defined for scanning. Right now\n     * I hard-code in the size of the ticks, but eventually they'll be\n     * dynamically resized depending upon the speed of the scan.\n     */\n    timeouts->current_index = timestamp;\n\n\n    return timeouts;\n}\n\n/***************************************************************************\n * This inserts the timeout entry into the appropriate place in the\n * timeout ring.\n ***************************************************************************/\nvoid\ntimeouts_add(struct Timeouts *timeouts, struct TimeoutEntry *entry,\n             size_t offset, uint64_t timestamp)\n{\n    unsigned index;\n\n    /* Unlink from wherever the entry came from */\n    if (entry->timestamp)\n        timeouts->outstanding_count--;\n    timeout_unlink(entry);\n\n    if (entry->prev) {\n        LOG(1, \"***CHANGE %d-seconds\\n\", \n                    (int)((timestamp-entry->timestamp)/TICKS_PER_SECOND));\n    }\n\n    /* Initialize the new entry */\n    entry->timestamp = timestamp;\n    entry->offset = (unsigned)offset;\n\n    /* Link it into it's new location */\n    index = timestamp & timeouts->mask;\n    entry->next = timeouts->slots[index];\n    timeouts->slots[index] = entry;\n    entry->prev = &timeouts->slots[index];\n    if (entry->next)\n        entry->next->prev = &entry->next;\n\n    timeouts->outstanding_count++;\n}\n\n/***************************************************************************\n * Remove the next event that it older than the specified timestamp\n ***************************************************************************/\nvoid *\ntimeouts_remove(struct Timeouts *timeouts, uint64_t timestamp)\n{\n    struct TimeoutEntry *entry = NULL;\n\n    /* Search until we find one */\n    while (timeouts->current_index <= timestamp) {\n\n        /* Start at the current slot */\n        entry = timeouts->slots[timeouts->current_index & timeouts->mask];\n\n        /* enumerate through the linked list until we find a used slot */\n        while (entry && entry->timestamp > timestamp)\n            entry = entry->next;\n        if (entry)\n            break;\n\n        /* found nothing at this slot, so move to next slot */\n        timeouts->current_index++;\n    }\n\n    if (entry == NULL) {\n        /* we've caught up to the current time, and there's nothing\n         * left to timeout, so return NULL */\n        return NULL;\n    }\n\n    /* unlink this entry from the timeout system */\n    timeouts--;\n    timeout_unlink(entry);\n\n    /* return a pointer to the structure holding this entry */\n    return ((char*)entry) - entry->offset;\n}\n\n\n"
  },
  {
    "path": "src/event-timeout.h",
    "content": "#ifndef EVENT_TIMEOUT_H\n#define EVENT_TIMEOUT_H\n#include <stdint.h>\n#include <stdio.h>\n#include <stddef.h> /* offsetof*/\n#include \"util-bool.h\" /* <stdbool.h> */\n#if defined(_MSC_VER)\n#undef inline\n#define inline _inline\n#endif\nstruct Timeouts;\n\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstruct TimeoutEntry {\n    /**\n     * In units of 1/16384 of a second. We use power-of-two units here\n     * to make the \"modulus\" operation a simple binary \"and\".\n     * See the TICKS_FROM_TV() macro for getting the timestamp from\n     * the current time.\n     */\n    uint64_t timestamp;\n\n    /** we build a doubly-linked list */\n    struct TimeoutEntry *next;\n    struct TimeoutEntry **prev;\n\n    /** The timeout entry is never allocated by itself, but instead\n     * lives inside another data structure. This stores the value of\n     * 'offsetof()', so given a pointer to this structure, we can find\n     * the original structure that contains it */\n    unsigned offset;\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic inline bool\ntimeout_is_unlinked(const struct TimeoutEntry *entry) {\n    if (entry->prev == 0 || entry->next == 0)\n        return true;\n    else\n        return false;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic inline void\ntimeout_unlink(struct TimeoutEntry *entry)\n{\n    if (entry->prev == 0 && entry->next == 0)\n        return;\n    *(entry->prev) = entry->next;\n    if (entry->next)\n        entry->next->prev = entry->prev;\n    entry->next = 0;\n    entry->prev = 0;\n    entry->timestamp = 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic inline void\ntimeout_init(struct TimeoutEntry *entry)\n{\n    entry->next = 0;\n    entry->prev = 0;\n}\n\n/**\n * Create a timeout subsystem.\n * @param timestamp_now\n *      The current timestamp indicating \"now\" when the thing starts.\n *      This should be 'time(0) * TICKS_PER_SECOND'.\n */\nstruct Timeouts *\ntimeouts_create(uint64_t timestamp_now);\n\n/**\n * Insert the timeout 'entry' into the future location in the timeout\n * ring, as determined by the timestamp.\n * @param timeouts\n *      A ring of timeouts, with each slot corresponding to a specific\n *      time in the future.\n * @param entry\n *      The entry that we are going to insert into the ring. If it's\n *      already in the ring, it'll be removed from the old location\n *      first before inserting into the new location.\n * @param offset\n *      The 'entry' field above is part of an existing structure. This\n *      tells the offset_of() from the beginning of that structure. \n *      In other words, this tells us the pointer to the object that\n *      that is the subject of the timeout.\n * @param timestamp_expires\n *      When this timeout will expire. This is in terms of internal\n *      ticks, which in units of TICKS_PER_SECOND.\n */\nvoid\ntimeouts_add(struct Timeouts *timeouts, struct TimeoutEntry *entry,\n                  size_t offset, uint64_t timestamp_expires);\n\n/**\n * Remove an object from the timestamp system that is older than than\n * the specified timestamp. This function must be called repeatedly\n * until it returns NULL to remove all the objects that are older\n * than the given timestamp.\n * @param timeouts\n *      A ring of timeouts. We'll walk the ring until we've caught\n *      up with the current time.\n * @param timestamp_now\n *      Usually, this timestmap will be \"now\", the current time,\n *      and anything older than this will be aged out.\n * @return\n *      an object older than the specified timestamp, or NULL\n *      if there are no more objects to be found\n */\nvoid *\ntimeouts_remove(struct Timeouts *timeouts, uint64_t timestamp_now);\n\n/*\n * This macros convert a normal \"timeval\" structure into the timestamp\n * that we use for timeouts. The timeval structure probably will come\n * from the packets that we are capturing.\n */\n#define TICKS_PER_SECOND (16384ULL)\n#define TICKS_FROM_SECS(secs) ((secs)*16384ULL)\n#define TICKS_FROM_USECS(usecs) ((usecs)/16384ULL)\n#define TICKS_FROM_TV(secs,usecs) (TICKS_FROM_SECS(secs)+TICKS_FROM_USECS(usecs))\n\n#endif\n"
  },
  {
    "path": "src/in-binary.c",
    "content": "/*\n    Read in the binary file produced by \"out-binary.c\". This allows you to\n    translate the \"binary\" format into any of the other output formats.\n*/\n#include \"massip-addr.h\"\n#include \"in-binary.h\"\n#include \"masscan.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"main-globals.h\"\n#include \"output.h\"\n#include \"util-safefunc.h\"\n#include \"in-filter.h\"\n#include \"in-report.h\"\n#include \"util-malloc.h\"\n#include \"util-logger.h\"\n\n#include <stdlib.h>\n#include <assert.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable:4996)\n#endif\n\nstatic const size_t BUF_MAX = 1024*1024;\n\nstruct MasscanRecord {\n    unsigned timestamp;\n    ipaddress ip;\n    unsigned char ip_proto;\n    unsigned short port;\n    unsigned char reason;\n    unsigned char ttl;\n    unsigned char mac[6];\n    enum ApplicationProtocol app_proto;\n};\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nparse_status(struct Output *out,\n        enum PortStatus status, /* open/closed */\n        const unsigned char *buf, size_t buf_length)\n{\n    struct MasscanRecord record;\n\n    if (buf_length < 12)\n        return;\n\n    /* parse record */\n    record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];\n    record.ip.ipv4   = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];\n    record.ip.version = 4;\n    record.port      = buf[8]<<8 | buf[9];\n    record.reason    = buf[10];\n    record.ttl       = buf[11];\n\n    /* if ARP, then there will be a MAC address */\n    if (record.ip.ipv4 == 0 && buf_length >= 12+6)\n        memcpy(record.mac, buf+12, 6);\n    else\n        memset(record.mac, 0, 6);\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    switch (record.port) {\n    case 53:\n    case 123:\n    case 137:\n    case 161: \n        record.ip_proto = 17;\n        break;\n    case 36422:\n    case 36412:\n    case 2905:\n        record.ip_proto = 132;\n        break;\n    default:\n        record.ip_proto = 6;\n        break;\n    }\n\n    /*\n     * Now report the result\n     */\n    output_report_status(out,\n                    record.timestamp,\n                    status,\n                    record.ip,\n                    record.ip_proto,\n                    record.port,\n                    record.reason,\n                    record.ttl,\n                    record.mac);\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nparse_status2(struct Output *out,\n        enum PortStatus status, /* open/closed */\n        const unsigned char *buf, size_t buf_length,\n        struct MassIP *filter)\n{\n    struct MasscanRecord record;\n\n    if (buf_length < 13)\n        return;\n\n    /* parse record */\n    record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];\n    record.ip.ipv4   = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];\n    record.ip.version = 4;\n    record.ip_proto  = buf[8];\n    record.port      = buf[9]<<8 | buf[10];\n    record.reason    = buf[11];\n    record.ttl       = buf[12];\n\n    /* if ARP, then there will be a MAC address */\n    if (record.ip.ipv4 == 0 && buf_length >= 13+6)\n        memcpy(record.mac, buf+13, 6);\n    else\n        memset(record.mac, 0, 6);\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    /* Filter for known IP/ports, if specified on command-line */\n    if (filter && filter->count_ipv4s) {\n        if (!massip_has_ip(filter, record.ip))\n            return;\n    }\n    if (filter && filter->count_ports) {\n        if (!massip_has_port(filter, record.port))\n            return;\n    }\n\n    /*\n     * Now report the result\n     */\n    output_report_status(out,\n                    record.timestamp,\n                    status,\n                    record.ip,\n                    record.ip_proto,\n                    record.port,\n                    record.reason,\n                    record.ttl,\n                    record.mac);\n\n}\n\nstatic unsigned char\n_get_byte(const unsigned char *buf, size_t length, size_t *offset)\n{\n    unsigned char result;\n    if (*offset < length) {\n        result = buf[*offset];\n    } else {\n        result = 0xFF;\n    }\n    (*offset)++;\n    return result;\n}\nstatic unsigned\n_get_integer(const unsigned char *buf, size_t length, size_t *r_offset)\n{\n    unsigned result;\n    size_t offset = *r_offset;\n    (*r_offset) += 4;\n    \n    if (offset + 4 <= length) {\n        result = buf[offset+0]<<24\n                | buf[offset+1]<<16\n                | buf[offset+2]<<8\n                | buf[offset+3]<<0;\n    } else {\n        result = 0xFFFFFFFF;\n    }\n    return result;\n}\nstatic unsigned short\n_get_short(const unsigned char *buf, size_t length, size_t *r_offset)\n{\n    unsigned short result;\n    size_t offset = *r_offset;\n    (*r_offset) += 2;\n    \n    if (offset + 2 <= length) {\n        result = buf[offset+0]<<8\n        | buf[offset+1]<<0;\n    } else {\n        result = 0xFFFF;\n    }\n    return result;\n}\n\nstatic unsigned long long\n_get_long(const unsigned char *buf, size_t length, size_t *r_offset)\n{\n    unsigned long long result;\n    size_t offset = *r_offset;\n    (*r_offset) += 8;\n    \n    if (offset + 8 <= length) {\n        result =\n          (unsigned long long)buf[offset+0]<<56ULL\n        | (unsigned long long)buf[offset+1]<<48ULL\n        | (unsigned long long)buf[offset+2]<<40ULL\n        | (unsigned long long)buf[offset+3]<<32ULL\n        | (unsigned long long)buf[offset+4]<<24ULL\n        | (unsigned long long)buf[offset+5]<<16ULL\n        | (unsigned long long)buf[offset+6]<<8ULL\n        | (unsigned long long)buf[offset+7]<<0ULL;\n\n    } else {\n        result = 0xFFFFFFFFffffffffULL;\n    }\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nparse_status6(struct Output *out,\n        enum PortStatus status, /* open/closed */\n        const unsigned char *buf, size_t length,\n        struct MassIP *filter)\n{\n    struct MasscanRecord record;\n    size_t offset = 0;\n\n    /* parse record */\n    record.timestamp = _get_integer(buf, length, &offset);\n    record.ip_proto  = _get_byte(buf, length, &offset);\n    record.port      = _get_short(buf, length, &offset);\n    record.reason    = _get_byte(buf, length, &offset);\n    record.ttl       = _get_byte(buf, length, &offset);\n    record.ip.version= _get_byte(buf, length, &offset);\n    if (record.ip.version != 6) {\n        fprintf(stderr, \"[-] corrupt record\\n\");\n        return;\n    }\n    record.ip.ipv6.hi = _get_long(buf, length, &offset);\n    record.ip.ipv6.lo = _get_long(buf, length, &offset);\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    /* Filter for known IP/ports, if specified on command-line */\n    if (filter && filter->count_ipv4s) {\n        if (!massip_has_ip(filter, record.ip))\n            return;\n    }\n    if (filter && filter->count_ports) {\n        if (!massip_has_port(filter, record.port))\n            return;\n    }\n\n    /*\n     * Now report the result\n     */\n    output_report_status(out,\n                    record.timestamp,\n                    status,\n                    record.ip,\n                    record.ip_proto,\n                    record.port,\n                    record.reason,\n                    record.ttl,\n                    record.mac);\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nparse_banner6(struct Output *out, unsigned char *buf, size_t length,\n              const struct MassIP *filter,\n              const struct RangeList *btypes)\n{\n    struct MasscanRecord record;\n    size_t offset = 0;\n\n    /*\n     * Parse the parts that are common to most records\n     */\n    record.timestamp = _get_integer(buf, length, &offset);\n    record.ip_proto  = _get_byte(buf, length, &offset);\n    record.port      = _get_short(buf, length, &offset);\n    record.app_proto = _get_short(buf, length, &offset);\n    record.ttl       = _get_byte(buf, length, &offset);\n    record.ip.version= _get_byte(buf, length, &offset);\n    if (record.ip.version != 6) {\n        fprintf(stderr, \"[-] corrupt record\\n\");\n        return;\n    }\n    record.ip.ipv6.hi = _get_long(buf, length, &offset);\n    record.ip.ipv6.lo = _get_long(buf, length, &offset);\n    \n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    \n    /*\n     * Filter out records if requested\n     */\n    if (!readscan_filter_pass(record.ip, record.port, record.app_proto,\n              filter, btypes))\n          return;\n    \n    /*\n     * Now print the output\n     */\n    if (offset > length)\n        return;\n    output_report_banner(\n                out,\n                record.timestamp,\n                record.ip,\n                record.ip_proto,    /* TCP=6, UDP=17 */\n                record.port,\n                record.app_proto,   /* HTTP, SSL, SNMP, etc. */\n                record.ttl, /* ttl */\n                buf+offset, (unsigned)(length-offset)\n                );\n}\n\n\n/***************************************************************************\n * [OBSOLETE]\n *  This parses an old version of the banner record. I've still got files\n *  hanging around with this version, so I'm keeping it in the code for\n *  now, but eventually I'll get rid of it.\n ***************************************************************************/\nstatic void\nparse_banner3(struct Output *out, unsigned char *buf, size_t buf_length)\n{\n    struct MasscanRecord record;\n\n    /*\n     * Parse the parts that are common to most records\n     */\n    record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];\n    record.ip.ipv4   = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];\n    record.ip.version = 4;\n    record.port      = buf[8]<<8 | buf[9];\n    record.app_proto = buf[10]<<8 | buf[11];\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    /*\n     * Now print the output\n     */\n    output_report_banner(\n                out,\n                record.timestamp,\n                record.ip,\n                6, /* this is always TCP */\n                record.port,\n                record.app_proto,\n                0, /* ttl */\n                buf+12, (unsigned)buf_length-12\n                );\n}\n\n/***************************************************************************\n * Parse the BANNER record, extracting the timestamp, IP address, and port\n * number. We also convert the banner string into a safer form.\n ***************************************************************************/\nstatic void\nparse_banner4(struct Output *out, unsigned char *buf, size_t buf_length)\n{\n    struct MasscanRecord record;\n\n    if (buf_length < 13)\n        return;\n\n    /*\n     * Parse the parts that are common to most records\n     */\n    record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];\n    record.ip.ipv4   = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];\n    record.ip.version = 4;\n    record.ip_proto  = buf[8];\n    record.port      = buf[9]<<8 | buf[10];\n    record.app_proto = buf[11]<<8 | buf[12];\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    /*\n     * Now print the output\n     */\n    output_report_banner(\n                out,\n                record.timestamp,\n                record.ip,\n                record.ip_proto,    /* TCP=6, UDP=17 */\n                record.port,\n                record.app_proto,   /* HTTP, SSL, SNMP, etc. */\n                0, /* ttl */\n                buf+13, (unsigned)buf_length-13\n                );\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nparse_banner9(struct Output *out, unsigned char *buf, size_t buf_length,\n              const struct MassIP *filter,\n              const struct RangeList *btypes)\n{\n    struct MasscanRecord record;\n    unsigned char *data = buf+14;\n    size_t data_length = buf_length-14;\n\n    if (buf_length < 14)\n        return;\n\n    /*\n     * Parse the parts that are common to most records\n     */\n    record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];\n    record.ip.ipv4   = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];\n    record.ip.version = 4;\n    record.ip_proto  = buf[8];\n    record.port      = buf[9]<<8 | buf[10];\n    record.app_proto = buf[11]<<8 | buf[12];\n    record.ttl       = buf[13];\n\n    if (out->when_scan_started == 0)\n        out->when_scan_started = record.timestamp;\n\n    /*\n     * KLUDGE: when doing SSL stuff, add a IP:name pair to a database\n     * so we can annotate [VULN] strings with this information\n     */\n    //readscan_report(record.ip, record.app_proto, &data, &data_length);\n\n\n    /*\n     * Filter out records if requested\n     */\n    if (!readscan_filter_pass(record.ip, record.port, record.app_proto,\n              filter, btypes))\n          return;\n    \n    /*\n     * Now print the output\n     */\n    output_report_banner(\n                out,\n                record.timestamp,\n                record.ip,\n                record.ip_proto,    /* TCP=6, UDP=17 */\n                record.port,\n                record.app_proto,   /* HTTP, SSL, SNMP, etc. */\n                record.ttl, /* ttl */\n                data, (unsigned)data_length\n                );\n}\n\n/***************************************************************************\n * Read in the file, one record at a time.\n ***************************************************************************/\nstatic uint64_t\n_binaryfile_parse(struct Output *out, const char *filename,\n           struct MassIP *filter,\n           const struct RangeList *btypes)\n{\n    FILE *fp = 0;\n    unsigned char *buf = 0;\n    size_t bytes_read;\n    uint64_t total_records = 0;\n\n    /* Allocate a buffer of up to one megabyte per record */\n    buf = MALLOC(BUF_MAX);\n\n    /* Open the file */\n    fp = fopen(filename, \"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"[-] FAIL: --readscan\\n\");\n        fprintf(stderr, \"[-] %s: %s\\n\", filename, strerror(errno));\n        goto end;\n    }\n\n    LOG(0, \"[+] --readscan %s\\n\", filename);\n    \n    if (feof(fp)) {\n        LOG(0, \"[-] %s: file is empty\\n\", filename);\n        goto end;\n    }\n    \n    /* first record is pseudo-record */\n    bytes_read = fread(buf, 1, 'a'+2, fp);\n    if (bytes_read < 'a'+2) {\n        LOG(0, \"[-] %s: %s\\n\", filename, strerror(errno));\n        goto end;\n    }\n\n    /* Make sure it's got the format string */\n    if (memcmp(buf, \"masscan/1.1\", 11) != 0) {\n        LOG(0,\n                \"[-] %s: unknown file format (expeced \\\"masscan/1.1\\\")\\n\",\n                filename);\n        goto end;\n    }\n\n    /*\n     * Look for start time\n     */\n    if (buf[11] == '.' && strtoul((char*)buf+12,0,0) >= 2) {\n        unsigned i;\n\n        /* move to next field */\n        for (i=0; i<'a' && buf[i] && buf[i] != '\\n'; i++)\n            ;\n        i++;\n\n        if (buf[i] == 's')\n            i++;\n        if (buf[i] == ':')\n            i++;\n\n        /* extract timestamp */\n        if (i < 'a')\n            out->when_scan_started = strtoul((char*)buf+i,0,0);\n    }\n\n    /* Now read all records */\n    for (;;) {\n        unsigned type;\n        unsigned length;\n\n\n        /* [TYPE]\n         * This is one or more bytes indicating the type of type of the\n         * record\n         */\n        bytes_read = fread(buf, 1, 1, fp);\n        if (bytes_read != 1)\n            break;\n        type = buf[0] & 0x7F;\n        while (buf[0] & 0x80) {\n            bytes_read = fread(buf, 1, 1, fp);\n            if (bytes_read != 1)\n                break;\n            type = (type << 7) | (buf[0] & 0x7F);\n        }\n\n        /* [LENGTH]\n         * Is one byte for lengths smaller than 127 bytes, or two\n         * bytes for lengths up to 16384.\n         */\n        bytes_read = fread(buf, 1, 1, fp);\n        if (bytes_read != 1)\n            break;\n        length = buf[0] & 0x7F;\n        while (buf[0] & 0x80) {\n            bytes_read = fread(buf, 1, 1, fp);\n            if (bytes_read != 1)\n                break;\n            length = (length << 7) | (buf[0] & 0x7F);\n        }\n        if (length > BUF_MAX) {\n            LOG(0, \"[-] file corrupt\\n\");\n            goto end;\n        }\n\n\n        /* get the remainder of the record */\n        bytes_read = fread(buf, 1, length, fp);\n        if (bytes_read < length)\n            break; /* eof */\n\n        /* Depending on record type, do something different */\n        switch (type) {\n            case 1: /* STATUS: open */\n                if (!btypes->count)\n                    parse_status(out, PortStatus_Open, buf, bytes_read);\n                break;\n            case 2: /* STATUS: closed */\n                if (!btypes->count)\n                    parse_status(out, PortStatus_Closed, buf, bytes_read);\n                break;\n            case 3: /* BANNER */\n                parse_banner3(out, buf, bytes_read);\n                break;\n            case 4:\n                if (fread(buf+bytes_read,1,1,fp) != 1) {\n                    LOG(0, \"[-] read() error\\n\");\n                    exit(1);\n                }\n                bytes_read++;\n                parse_banner4(out, buf, bytes_read);\n                break;\n            case 5:\n                parse_banner4(out, buf, bytes_read);\n                break;\n            case 6: /* STATUS: open */\n                if (!btypes->count)\n                    parse_status2(out, PortStatus_Open, buf, bytes_read, filter);\n                break;\n            case 7: /* STATUS: closed */\n                if (!btypes->count)\n                    parse_status2(out, PortStatus_Closed, buf, bytes_read, filter);\n                break;\n            case 9:\n                parse_banner9(out, buf, bytes_read, filter, btypes);\n                break;\n            case 10: /* Open6 */\n                if (!btypes->count)\n                    parse_status6(out, PortStatus_Open, buf, bytes_read, filter);\n                break;\n            case 11: /* Closed6 */\n                if (!btypes->count)\n                    parse_status6(out, PortStatus_Closed, buf, bytes_read, filter);\n                break;\n            case 13: /* Banner6 */\n                parse_banner6(out, buf, bytes_read, filter, btypes);\n                break;\n            case 'm': /* FILEHEADER */\n                //goto end;\n                break;\n            default:\n                LOG(0, \"[-] file corrupt: unknown type %u\\n\", type);\n                goto end;\n        }\n        total_records++;\n        if ((total_records & 0xFFFF) == 0)\n            LOG(0, \"[+] %s: %8\" PRIu64 \"\\r\", filename, total_records);\n    }\n\nend:\n    if (buf)\n        free(buf);\n    if (fp)\n        fclose(fp);\n    return total_records;\n}\n\n\n/*****************************************************************************\n * When masscan is called with the \"--readscan\" parameter, it doesn't\n * do a scan of the live network, but instead reads scan results from\n * a file. Those scan results can then be written out in any of the\n * other formats. This preserves the original timestamps.\n *****************************************************************************/\nvoid\nreadscan_binary_scanfile(struct Masscan *masscan,\n                     int arg_first, int arg_max, char *argv[])\n{\n    struct Output *out;\n    int i;\n\n    /*\n     * Create the output system, such as XML or JSON output\n     */\n    out = output_create(masscan, 0);\n    \n    /*\n     * Set the start time to zero. We'll read it from the first file\n     * that we parse\n     */\n    out->when_scan_started = 0;\n\n    /*\n     * We don't parse the entire argument list, just a subrange\n     * containing the list of files. The 'arg_first' parameter\n     * points to the first filename after the '--readscan'\n     * parameter, and 'arg_max' is the parameter after\n     * the last filename. For example, consider an argument list that\n     * looks like:\n     *   masscan --foo --readscan file1.scan file2.scan --bar\n     * Then arg_first=3 and arg_max=5.\n     */\n    for (i=arg_first; i<arg_max; i++) {\n        _binaryfile_parse(out, argv[i], &masscan->targets, &masscan->banner_types);\n    }\n\n    /* Done! */\n    output_destroy(out);\n}\n\n\n"
  },
  {
    "path": "src/in-binary.h",
    "content": "#ifndef IN_BINARY_H\n#define IN_BINARY_H\nstruct Masscan;\n\n/**\n * Read that output of previous scans that were saved in the binary format\n * (i.e. using the -oB parameter or the '--output-format binary' parameter).\n * The intent is that the user can then re-output in another format like\n * JSON or XML.\n */\nvoid\nreadscan_binary_scanfile(struct Masscan *masscan, \n                     int arg_first, int arg_max, char *argv[]);\n\n#endif\n\n"
  },
  {
    "path": "src/in-filter.c",
    "content": "#include \"in-filter.h\"\n#include \"massip.h\"\n\n\nint\nreadscan_filter_pass(ipaddress ip, unsigned port, unsigned type,\n              const struct MassIP *filter,\n              const struct RangeList *btypes)\n{\n    if (filter && filter->count_ipv4s) {\n        if (!massip_has_ip(filter, ip))\n            return 0;\n    }\n    if (filter && filter->count_ports) {\n        if (!massip_has_port(filter, port))\n            return 0;\n    }\n    if (btypes && btypes->count) {\n        if (!rangelist_is_contains(btypes, type))\n            return 0;\n    }\n\n    return 1;\n}\n"
  },
  {
    "path": "src/in-filter.h",
    "content": "/*\n    This is for filtering input in the \"--readscan\" feature\n*/\n#ifndef IN_FILTER_H\n#define IN_FILTER_H\n#include \"massip-addr.h\"\nstruct RangeList;\nstruct Range6List;\nstruct MassIP;\n\n/**\n * Filters readscan record by IP address, port number,\n * or banner-type.\n */\nint\nreadscan_filter_pass(ipaddress ip, unsigned port, unsigned type,\n              const struct MassIP *massip,\n              const struct RangeList *btypes);\n\n\n\n#endif\n"
  },
  {
    "path": "src/in-report.c",
    "content": "#include \"in-report.h\"\n#include \"masscan-app.h\"\n#include \"crypto-base64.h\"\n#include \"proto-x509.h\"\n#include \"proto-banout.h\"\n#include \"smack.h\"\n#include \"util-malloc.h\"\n\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n\nstruct CNDB_Entry {\n    unsigned ip;\n    char *name;\n    struct CNDB_Entry *next;\n};\n\nstruct CNDB_Database {\n    struct CNDB_Entry *entries[65536];\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic struct CNDB_Database *db = NULL;\n\n/***************************************************************************\n ***************************************************************************/\nstatic const char *\ncndb_lookup(unsigned ip)\n{\n    const struct CNDB_Entry *entry;\n    \n    if (db == NULL)\n        return 0;\n\n    entry = db->entries[ip&0xFFFF];\n    while (entry && entry->ip != ip)\n        entry = entry->next;\n    if (entry)\n        return entry->name;\n    else {\n        return 0;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ncndb_add(unsigned ip, const unsigned char *name, size_t name_length)\n{\n    struct CNDB_Entry *entry;\n\n    if (name_length == 0)\n        return;\n    \n    if (db == NULL) {\n        db = CALLOC(1, sizeof(*db));\n    }\n        \n    entry = MALLOC(sizeof(*entry));\n    entry->ip =ip;\n    entry->name = MALLOC(name_length+1);\n    memcpy(entry->name, name, name_length+1);\n    entry->name[name_length] = '\\0';\n    entry->next = db->entries[ip&0xFFFF];\n    db->entries[ip&0xFFFF] = entry;\n\n}\n\n/***************************************************************************\n ***************************************************************************/\n#if 0\nstatic void\ncndb_add_cn(unsigned ip, const unsigned char *data, size_t length)\n{\n    size_t offset = 0;\n    size_t name_offset;\n    size_t name_length;\n    \n    if (length < 7)\n        return;\n    \n    /*cipher:0x39 , safe-we1.dyndns.org*/\n    if (memcmp(data+offset, \"cipher:\", 7) != 0)\n        return;\n    offset += 7;\n    \n    /* skip to name */\n    while (offset < length && data[offset] != ',')\n        offset++;\n    if (offset >= length)\n        return;\n    else\n        offset++; /* skip ',' */\n    while (offset < length && data[offset] == ' ')\n        offset++;\n    if (offset >= length)\n        return;\n    \n    /* we should have a good name */\n    name_offset = offset;\n    while (offset < length && data[offset] != ',')\n        offset++;\n    name_length = offset - name_offset;\n    \n    /* now insert into database */\n    cndb_add(ip, data+name_offset, name_length);\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\n#if 0\nstatic unsigned\nfound(const char *str, size_t str_len, const unsigned char *p, size_t length)\n{\n    size_t i;\n  \n    if (str_len > length)\n        return 0;\n\n    for (i=0; i<length; i++) {\n        if (str[0] == p[i] && memcmp(str, p+i, str_len) == 0)\n            return 1;\n    }\n    return 0;\n}\n#endif\n\nenum {\n    XUnknown,\n    XNas,\n    XWiFi,\n    XFW,\n    X509,\n    XCom,\n    XVM,\n    XCam,\n    XVPN,\n    XPBX,\n    Xprint,\n    Xdefault,\n    XMail,\n    Xadmin,\n    Xav,\n    Xpot,\n    Xbox,\n\n    Xend\n};\n\nunsigned counts[32];\n\nstatic void\nprint_counts()\n{\n    unsigned i;\n    const char *count_names[] = {\n        \"Unknown\", \"NAS\", \"WiFi\", \"FW\", \"X509\",\n        \"Conf\", \"VM\", \"Cam\", \"VPN\", \"PBX\", \"Printer\",\n        \"default\", \"mail\", \"admin\", \"AV\", \"honeypot\", \"box\",\n        0, \"\", \"\", \"\"};\n\n    printf(\"----counts----\\n\");\n    for (i=0; i<Xend; i++) {\n        printf(\"%10u %s\\n\", counts[i], count_names[i]);\n    }\n    printf(\"---------------\\n\");\n\n    assert(count_names[i] == NULL);\n}\n\nstruct Names {\n    unsigned code;\n    unsigned length;\n    const char *name;\n\n} mynames[] = {\n\n/* raspberry pi */\n/* issuer[Debian */\n\n    \n    \n    \n\n\n    {XNas,   9, \"nasend~~]\"},\n    {XPBX,  13, \"issuer[iPECS]\"},\n    {Xav,   13, \"issuer[McAfee\"},\n    {Xadmin,14, \"issuer[webmin]\"},\n    {Xadmin,14, \"issuer[Webmin \"},\n    {Xprint,15, \"subject[HP-IPG]\"},\n    {XNas,  16, \"issuer[LaCie SA]\"},\n    {XWiFi, 16, \"subject[OpenWrt]\"},\n    {Xadmin,16, \"issuer[Puppet CA\"},\n    {Xav,   16, \"issuer[Kaspersky\"},\n    {XFW,   17, \"subject[Fortinet]\"},\n    {XFW,   17, \"issuer[ICC-FW CA]\"},\n    {XCam,  17, \"issuer[HIKVISION]\"}, \n    {Xprint,17, \"subject[SHARP MX-\"},\n    {X509,  18, \"issuer[GANDI SAS]\"},\n    {XFW,   18, \"subject[FortiGate]\"},\n    {XFW,   18, \"issuer[watchguard]\"},\n    {XVM,   18, \"issuer[VMware Inc]\"}, \n    {Xbox,  19, \"issuer[eBox Server]\"},\n    {XFW,   19, \"subject[WatchGuard]\"}, \n    {X509,  19, \"issuer[RapidSSL CA]\"},\n    {X509,  19, \"issuer[AddTrust AB]\"},\n    {XCom,  19, \"issuer[Cisco SSCA2]\"},\n    {XCom,  19, \"subject[Cisco SSCA2]\"},\n   {Xdefault,19,\"issuer[v] issuer[v]\"},\n    {X509,  20, \"issuer[Register.com]\"},\n    {X509,  20, \"issuer[Thawte, Inc.]\"},\n    {X509,  20, \"issuer[thawte, Inc.]\"},\n    {XMail, 20, \"issuer[EQ-MT-RAPTOR]\"},\n    {X509,  20, \"issuer[DigiCert Inc]\"},\n    {X509,  21, \"issuer[TERENA SSL CA]\"},\n    {XFW,   21, \"issuer[WatchGuard CA]\"},  \n    {XVPN,  21, \"issuer[OpenVPN Web CA\"},\n    {X509,  21, \"issuer[GeoTrust Inc.]\"},\n    {XNas,  21, \"issuer[TS Series NAS]\"},\n    {XCom,  21, \"subject[Polycom Inc.]\"},\n    {XFW,   21, \"issuer[Fortinet Ltd.]\"},\n    {XNas,  21, \"issuer[Synology Inc.]\"},\n   {Xdefault,21,\"issuer[XX] issuer[XX]\"},\n    {XWiFi, 21, \"2Wire]Gateway Device]\"},\n    {X509,  21, \"subject[DigiCert Inc]\"},\n    {XCam,  22, \"issuer[SamsungTechwin]\"}, \n    {X509,  22, \"issuer[TAIWAN-CA INC.]\"},\n    {X509,  22, \"issuer[GeoTrust, Inc.]\"},    \n    {X509,  22, \"issuer[ValiCert, Inc.]\"},\n    {0,     22, \"issuer[Apache Friends]\"},\n    {X509,  22, \"issuer[VeriSign, Inc.]\"},\n    {X509,  22, \"issuer[Cybertrust Inc]\"},\n    {XCam,  23, \"subject[HiTRON SYSTEMS]\"},\n    {XFW,   23, \"issuer[SonicWALL, Inc.]\"},\n    {XFW,   23, \"issuer[Future Systems.]\"},\n    {XCom,  23, \"issuer[Polycom Root CA]\"},\n    {X509,  24, \"issuer[AlphaSSL CA - G2]\"},\n    {X509,  24, \"issuer[GlobalSign nv-sa]\"},\n    {XVPN,  24, \"SonicWALL, Inc.]SSL-VPN]\"},\n    {X509,  25, \"issuer[Comodo CA Limited]\"},\n    {X509,  25, \"issuer[COMODO CA Limited]\"},    \n    {X509,  25, \"issuer[GoDaddy.com, Inc.]\"},\n    {Xbox,  26, \"subject[Barracuda Networks]\"},\n    {X509,  26, \"issuer[Equifax Secure Inc.]\"},\n    {X509,  28, \"issuer[Gandi Standard SSL CA]\"},\n    {X509,  28, \"issuer[The USERTRUST Network]\"},\n    {XCom,  28, \"subject[Polycom] subject[VSG]\"},\n    {X509,  28, \"issuer[EuropeanSSL Server CA]\"},\n    {0,     28, \"issuer[SuSE Linux Web Server]\"},\n    {XWiFi, 29, \"issuer[CradlePoint Technology]\"},\n    {XVPN,  29, \"SonicWALL]Secure Remote Access]\"},\n    {Xdefault,29,\"subject[SomeOrganizationalUnit]\"},\n    {Xdefault,29,\"issuer[Internet Widgits Pty Ltd]\"},\n    {X509,  30, \"issuer[Network Solutions L.L.C.]\"},\n    {X509,  30, \"issuer[The Go Daddy Group, Inc.]\"},\n    {Xpot,  30, \"issuer[Nepenthes Development Team]\"},\n    {X509,  30, \"issuer[WoSign Class 1 DV Server CA]\"},\n    {XCom,  30, \"issuer[Polycom Equipment Policy CA]\"},\n    {X509,  30, \"issuer[Starfield Technologies, Inc.]\"},\n    {X509,  30, \"issuer[Certum Certification Authority]\"},\n    {XNas,  30, \"subject[Fujitsu CELVIN(R) NAS Server]\"},\n    {XVPN,  35, \"SonicWALL, Inc.]Secure Remote Access]\"},\n    {X509,  40, \"issuer[Secure Digital Certificate Signing]\"},\n    {X509,  40, \"issuer[Equifax Secure Certificate Authority]\"},\n    {XVM,   40, \"subject[VMware ESX Server Default Certificate]\"}, \n    {XCam,  40, \"issuer[Cisco Systems] issuer[Cisco Manufacturing CA]\"},\n    {0,0, 0}\n};\n\nstatic struct SMACK *global_xnames;\nstatic void\nxname_init(void)\n{\n    unsigned i;\n\n    global_xnames = smack_create(\"readscan-x509-names\", 0);\n\n    for (i=0; mynames[i].name; i++) {\n        const char *pattern = mynames[i].name;\n        unsigned len = mynames[i].length;\n        unsigned id = mynames[i].code;\n\n\n        smack_add_pattern(  global_xnames,\n                            pattern,\n                            len,\n                            id,\n                            0\n                            );\n    }\n\n    smack_compile(global_xnames);\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nfound_type(const unsigned char *banner, size_t banner_length)\n{\n    size_t id;\n    unsigned state = 0;\n    unsigned offset = 0;\n\n    /*for (i=0; mynames[i].name; i++) {\n        if (found(mynames[i].name, mynames[i].length, banner, banner_length))\n            return 1;\n    }*/\n\n    id = smack_search_next( global_xnames,\n                                        &state,\n                                        banner,\n                                        &offset,\n                                        (unsigned)banner_length);\n    if (id == SMACK_NOT_FOUND)\n        return 0;\n    \n    counts[id]++;\n\n    return 1;\n}\n\nvoid\nreadscan_report(  unsigned ip,\n                  unsigned app_proto,\n                  unsigned char **r_data,\n                  size_t *r_data_length)\n{\n    size_t data_length = *r_data_length;\n    unsigned char *data = *r_data;\n\n\n    if (app_proto == PROTO_X509_CERT) {\n        unsigned char *der = MALLOC(data_length);\n        struct CertDecode x;\n        size_t der_length;\n        struct BannerOutput banout[1];\n        const unsigned char *banner;\n        size_t banner_length;\n\n        banout_init(banout);\n\n        der_length = base64_decode(der, data_length, data, data_length);\n        \n        x509_decode_init(&x, data_length);\n        x.is_capture_issuer = 1;\n        x.is_capture_subject = 1;\n        x509_decode(&x, der, der_length, banout);\n\n        banner = banout_string(banout, PROTO_SSL3);\n        banner_length = banout_string_length(banout, PROTO_SSL3);\n\n        if (banner_length) {\n            if (!found_type(banner, banner_length))\n                cndb_add(ip, banner, banner_length);\n        }\n\n        banout_release(banout);\n    /*} else if (0 && app_proto == PROTO_SSL3) {\n        cndb_add(ip, data, data_length);*/\n    } else if (app_proto == PROTO_VULN) {\n        const char *name = cndb_lookup(ip);\n        \n        if (data_length == 15 && memcmp(data, \"SSL[heartbeat] \", 15) == 0)\n            return;\n\n        if (name && strlen(name) < 300) {\n            //printf(\"vuln=%s\\n\", name);\n            ((char*)data)[data_length] = ' ';\n            memcpy((char*)data+data_length+1, name, strlen(name)+1);\n            data_length += strlen(name)+1;\n        }\n\n        /* kludge */\n        if (data_length == 31 && memcmp(data, \"SSL[heartbeat] SSL[HEARTBLEED] \", 31) == 0)\n            return;\n    }\n\n}\n\nvoid\nreadscan_report_init(void)\n{\n    if (global_xnames == NULL)\n        xname_init();\n}\n\nvoid\nreadscan_report_print(void)\n{\n  print_counts();\n}\n\n"
  },
  {
    "path": "src/in-report.h",
    "content": "#ifndef IN_REPORT_H\n#define IN_REPORT_H\n#include <stdio.h>\n\nvoid\nreadscan_report(  unsigned ip,\n                  unsigned app_proto,\n                  unsigned char **data,\n                  size_t *data_length);\n\nvoid\nreadscan_report_init(void);\n\nvoid\nreadscan_report_print(void);\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/main-conf.c",
    "content": "/*\n    Read in the configuration for MASSCAN.\n\n    Configuration parameters can be read either from the command-line\n    or a configuration file. Long parameters of the --xxxx variety have\n    the same name in both.\n\n    Most of the code in this module is for 'nmap' options we don't support.\n    That's because we support some 'nmap' options, and I wanted to give\n    more feedback for some of them why they don't work as expected, such\n    as reminding people that this is an asynchronous scanner.\n\n*/\n#include \"masscan.h\"\n#include \"massip-addr.h\"\n#include \"masscan-version.h\"\n#include \"util-safefunc.h\"\n#include \"util-logger.h\"\n#include \"proto-banner1.h\"\n#include \"templ-payloads.h\"\n#include \"crypto-base64.h\"\n#include \"vulncheck.h\"\n#include \"masscan-app.h\"\n#include \"unusedparm.h\"\n#include \"read-service-probes.h\"\n#include \"util-malloc.h\"\n#include \"massip.h\"\n#include \"massip-parse.h\"\n#include \"massip-port.h\"\n#include \"templ-opts.h\"\n#include <ctype.h>\n#include <limits.h>\n\n#ifdef WIN32\n#include <direct.h>\n#define getcwd _getcwd\n#else\n#include <unistd.h>\n#endif\n\n#ifndef min\n#define min(a,b) ((a)<(b)?(a):(b))\n#endif\n\n#if defined(_MSC_VER)\n#define strdup _strdup\n#endif\n\n\n\n/***************************************************************************\n ***************************************************************************/\n/*static struct Range top_ports_tcp[] = {\n    {80, 80},{23, 23}, {443,443},{21,22},{25,25},{3389,3389},{110,110},\n    {445,445},\n};\nstatic struct Range top_ports_udp[] = {\n    {161, 161}, {631, 631}, {137,138},{123,123},{1434},{445,445},{135,135},\n    {67,67},\n};\nstatic struct Range top_ports_sctp[] = {\n    {7, 7},{9, 9},{20,22},{80,80},{179,179},{443,443},{1167,1167},\n};*/\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nmasscan_usage(void)\n{\n    printf(\"usage: masscan [options] [<IP|RANGE>... -pPORT[,PORT...]]\\n\");\n    printf(\"\\n\");\n    printf(\"examples:\\n\");\n    printf(\"    masscan -p80,8000-8100 10.0.0.0/8 --rate=10000\\n\");\n    printf(\"        scan some web ports on 10.x.x.x at 10kpps\\n\");\n    printf(\"\\n\");\n    printf(\"    masscan --nmap\\n\");\n    printf(\"        list those options that are compatible with nmap\\n\");\n    printf(\"\\n\");\n    printf(\"    masscan -p80 10.0.0.0/8 --banners -oB <filename>\\n\");\n    printf(\"        save results of scan in binary format to <filename>\\n\");\n    printf(\"\\n\");\n    printf(\"    masscan --open --banners --readscan <filename> -oX <savefile>\\n\");\n    printf(\"        read binary scan results in <filename> and save them as xml in <savefile>\\n\");\n    exit(1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nprint_version()\n{\n    const char *cpu = \"unknown\";\n    const char *compiler = \"unknown\";\n    const char *compiler_version = \"unknown\";\n    const char *os = \"unknown\";\n    printf(\"\\n\");\n    printf(\"Masscan version %s ( %s )\\n\", \n        MASSCAN_VERSION,\n        \"https://github.com/robertdavidgraham/masscan\"\n        );\n    printf(\"Compiled on: %s %s\\n\", __DATE__, __TIME__);\n\n#if defined(__x86_64) || defined(__x86_64__)\n    cpu = \"x86\";\n#endif\n\n#if defined(_MSC_VER)\n    #if defined(_M_AMD64) || defined(_M_X64)\n        cpu = \"x86\";\n    #elif defined(_M_IX86)\n        cpu = \"x86\";\n    #elif defined (_M_ARM_FP)\n        cpu = \"arm\";\n    #endif\n\n    {\n        int msc_ver = _MSC_VER;\n\n        compiler = \"VisualStudio\";\n\n        if (msc_ver < 1500)\n            compiler_version = \"pre2008\";\n        else if (msc_ver == 1500)\n            compiler_version = \"2008\";\n        else if (msc_ver == 1600)\n            compiler_version = \"2010\";\n        else if (msc_ver == 1700)\n            compiler_version = \"2012\";\n        else if (msc_ver == 1800)\n            compiler_version = \"2013\";\n        else\n            compiler_version = \"post-2013\";\n    }\n\n    \n#elif defined(__GNUC__)\n# if defined(__clang__)\n    compiler = \"clang\";\n# else\n    compiler = \"gcc\";\n# endif\n    compiler_version = __VERSION__;\n\n#if defined(i386) || defined(__i386) || defined(__i386__)\n    cpu = \"x86\";\n#endif\n\n#if defined(__corei7) || defined(__corei7__)\n    cpu = \"x86-Corei7\";\n#endif\n\n#endif\n\n#if defined(WIN32)\n    os = \"Windows\";\n#elif defined(__linux__)\n    os = \"Linux\";\n#elif defined(__APPLE__)\n    os = \"Apple\";\n#elif defined(__MACH__)\n    os = \"MACH\";\n#elif defined(__FreeBSD__)\n    os = \"FreeBSD\";\n#elif defined(__NetBSD__)\n    os = \"NetBSD\";\n#elif defined(unix) || defined(__unix) || defined(__unix__)\n    os = \"Unix\";\n#endif\n\n    printf(\"Compiler: %s %s\\n\", compiler, compiler_version);\n    printf(\"OS: %s\\n\", os);\n    printf(\"CPU: %s (%u bits)\\n\", cpu, (unsigned)(sizeof(void*))*8);\n\n#if defined(GIT)\n    printf(\"GIT version: %s\\n\", GIT);\n#endif\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nprint_nmap_help(void)\n{\n    printf(\"Masscan (https://github.com/robertdavidgraham/masscan)\\n\"\n\"Usage: masscan [Options] -p{Target-Ports} {Target-IP-Ranges}\\n\"\n\"TARGET SPECIFICATION:\\n\"\n\"  Can pass only IPv4/IPv6 address, CIDR networks, or ranges (non-nmap style)\\n\"\n\"  Ex: 10.0.0.0/8, 192.168.0.1, 10.0.0.1-10.0.0.254\\n\"\n\"  -iL <inputfilename>: Input from list of hosts/networks\\n\"\n\"  --exclude <host1[,host2][,host3],...>: Exclude hosts/networks\\n\"\n\"  --excludefile <exclude_file>: Exclude list from file\\n\"\n\"  --randomize-hosts: Randomize order of hosts (default)\\n\"\n\"HOST DISCOVERY:\\n\"\n\"  -Pn: Treat all hosts as online (default)\\n\"\n\"  -n: Never do DNS resolution (default)\\n\"\n\"SCAN TECHNIQUES:\\n\"\n\"  -sS: TCP SYN (always on, default)\\n\"\n\"SERVICE/VERSION DETECTION:\\n\"\n\"  --banners: get the banners of the listening service if available. The\\n\"\n\"    default timeout for waiting to receive data is 30 seconds.\\n\"\n\"PORT SPECIFICATION AND SCAN ORDER:\\n\"\n\"  -p <port ranges>: Only scan specified ports\\n\"\n\"    Ex: -p22; -p1-65535; -p 111,137,80,139,8080\\n\"\n\"TIMING AND PERFORMANCE:\\n\"\n\"  --max-rate <number>: Send packets no faster than <number> per second\\n\"\n\"  --connection-timeout <number>: time in seconds a TCP connection will\\n\"\n\"    timeout while waiting for banner data from a port.\\n\"\n\"FIREWALL/IDS EVASION AND SPOOFING:\\n\"\n\"  -S/--source-ip <IP_Address>: Spoof source address\\n\"\n\"  -e <iface>: Use specified interface\\n\"\n\"  -g/--source-port <portnum>: Use given port number\\n\"\n\"  --ttl <val>: Set IP time-to-live field\\n\"\n\"  --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address\\n\"\n\"OUTPUT:\\n\"\n\"  --output-format <format>: Sets output to binary/list/unicornscan/json/ndjson/grepable/xml\\n\"\n\"  --output-file <file>: Write scan results to file. If --output-format is\\n\"\n\"     not given default is xml\\n\"\n\"  -oL/-oJ/-oD/-oG/-oB/-oX/-oU <file>: Output scan in List/JSON/nDjson/Grepable/Binary/XML/Unicornscan format,\\n\"\n\"     respectively, to the given filename. Shortcut for\\n\"\n\"     --output-format <format> --output-file <file>\\n\"\n\"  -v: Increase verbosity level (use -vv or more for greater effect)\\n\"\n\"  -d: Increase debugging level (use -dd or more for greater effect)\\n\"\n\"  --open: Only show open (or possibly open) ports\\n\"\n\"  --packet-trace: Show all packets sent and received\\n\"\n\"  --iflist: Print host interfaces and routes (for debugging)\\n\"\n\"  --append-output: Append to rather than clobber specified output files\\n\"\n\"  --resume <filename>: Resume an aborted scan\\n\"\n\"MISC:\\n\"\n\"  --send-eth: Send using raw ethernet frames (default)\\n\"\n\"  -V: Print version number\\n\"\n\"  -h: Print this help summary page.\\n\"\n\"EXAMPLES:\\n\"\n\"  masscan -v -sS 192.168.0.0/16 10.0.0.0/8 -p 80\\n\"\n\"  masscan 23.0.0.0/0 -p80 --banners -output-format binary --output-filename internet.scan\\n\"\n\"  masscan --open --banners --readscan internet.scan -oG internet_scan.grepable\\n\"\n\"SEE (https://github.com/robertdavidgraham/masscan) FOR MORE HELP\\n\"\n\"\\n\");\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ncount_cidr6_bits(struct Range6 *range, bool *exact)\n{\n    uint64_t i;\n\n    /* for the comments of this function, see  count_cidr_bits */\n    *exact = false;\n    \n    for (i=0; i<128; i++) {\n        uint64_t mask_hi;\n        uint64_t mask_lo;\n        if (i < 64) {\n            mask_hi = 0xFFFFFFFFffffffffull >> i;\n            mask_lo = 0xFFFFFFFFffffffffull;\n        } else {\n            mask_hi = 0;\n            mask_lo = 0xFFFFFFFFffffffffull >> (i - 64);\n        }\n        if ((range->begin.hi & mask_hi) != 0 || (range->begin.lo & mask_lo) != 0) {\n            continue;\n        }\n        if ((range->begin.hi & ~mask_hi) == (range->end.hi & ~mask_hi) &&\n                (range->begin.lo & ~mask_lo) == (range->end.lo & ~mask_lo)) {\n            if (((range->end.hi & mask_hi) == mask_hi) && ((range->end.lo & mask_lo) == mask_lo)) {\n                *exact = true;\n                return (unsigned) i;\n            }\n        } else {\n            *exact = false;\n            range->begin.hi = range->begin.hi + mask_hi;\n            if (range->begin.lo >= 0xffffffffffffffff - 1 - mask_lo) {\n                range->begin.hi += 1;\n            }\n            range->begin.lo = range->begin.lo + mask_lo + 1;\n            return (unsigned) i;\n        }\n    }\n    range->begin.lo = range->begin.lo + 1;\n    if (range->begin.lo == 0) {\n        range->begin.hi = range->begin.hi + 1;\n    }\n    return 128;\n}\n\n\n\n/***************************************************************************\n * Echoes the configuration for one NIC\n ***************************************************************************/\nstatic void\nmasscan_echo_nic(struct Masscan *masscan, FILE *fp, unsigned i)\n{\n    char idx_str[64];\n\n    /* If we have only one adapter, then don't print the array indexes.\n     * Otherwise, we need to print the array indexes to distinguish\n     * the NICs from each other */\n    if (masscan->nic_count <= 1)\n        idx_str[0] = '\\0';\n    else\n        snprintf(idx_str, sizeof(idx_str), \"[%u]\", i);\n\n    if (masscan->nic[i].ifname[0])\n        fprintf(fp, \"adapter%s = %s\\n\", idx_str, masscan->nic[i].ifname);\n    \n    if (masscan->nic[i].src.ipv4.first != 0 || masscan->nic[i].src.ipv4.last != 0) {\n\n        /**\n         * FIX 495.1 for issue #495: Single adapter-ip is not saved at all\n         *\n         * The else case handles a simple invocation of one adapter-ip:\n         *\n         * 1. masscan ... --adapter-ip 1.2.3.1 ...   [BROKEN]\n         *\n         * This looks like it was just copy pasta/typo. If the first ip is the same\n         * as the last ip, it is a single adapter-ip\n         *\n         * This never worked as it was before so paused.conf would never save the\n         * adapter-ip as it fell through this if/else if into nowhere. It probably\n         * went undetected because in simple environments and/or in simple scans,\n         * masscan is able to intelligently determine the adapter-ip and only\n         * advanced usage requires overriding the chosen value. In addition to\n         * that, it is probably relatively uncommon to interrupt a scan as not many\n         * users are doing multi-hour / multi-day scans, having them paused and\n         * then resuming them (apparently)\n         */\n        if (masscan->nic[i].src.ipv4.first == masscan->nic[i].src.ipv4.last) {\n            ipaddress_formatted_t fmt = ipv4address_fmt(masscan->nic[i].src.ipv4.first);\n            fprintf(fp, \"adapter-ip%s = %s\\n\", idx_str, fmt.string);\n        }\n\n        /**\n         * FIX 495.2 for issue #495: Ranges of size two don't print. When 495.1 is\n         * added, ranges of size two print as only the first value in the range\n         * Before 495.1, they didn't print at all, so this is not a bug that is\n         * introduced by 495.1, just noticed while applying that fix\n         *\n         * The first if case here is for handling when adapter-ip is a range\n         *\n         * Examples of the multiple/range case:\n         *\n         * 1. masscan ... --adapter-ip 1.2.3.1-1.2.3.2 ...   [BROKEN]\n         * 2. masscan ... --adapter-ip 1.2.3.1-1.2.3.4 ...   [OK]\n         *\n         * If the range spans exactly two adapter-ips, it will not hit the range\n         * printing logic case here because of an off-by-one\n         *\n         * Changing it from < to <= fixes that issue and both of the above cases\n         * now print the correct range as expected\n         */\n        else if (masscan->nic[i].src.ipv4.first < masscan->nic[i].src.ipv4.last) {\n            ipaddress_formatted_t fmt1 = ipv4address_fmt(masscan->nic[i].src.ipv4.first);\n            ipaddress_formatted_t fmt2 = ipv4address_fmt(masscan->nic[i].src.ipv4.last);\n            fprintf(fp, \"adapter-ip%s = %s-%s\\n\", idx_str, fmt1.string, fmt2.string);\n        }\n    }\n\n    if (masscan->nic[i].src.ipv6.range) {\n        if (ipv6address_is_lessthan(masscan->nic[i].src.ipv6.first, masscan->nic[i].src.ipv6.last)) {\n            ipaddress_formatted_t fmt1 = ipv6address_fmt(masscan->nic[i].src.ipv6.first);\n            ipaddress_formatted_t fmt2 = ipv6address_fmt(masscan->nic[i].src.ipv6.last);\n            fprintf(fp, \"adapter-ip%s = %s-%s\\n\", idx_str, fmt1.string, fmt2.string);\n        } else {\n            ipaddress_formatted_t fmt = ipv6address_fmt(masscan->nic[i].src.ipv6.first);\n            fprintf(fp, \"adapter-ip%s = %s\\n\", idx_str, fmt.string);\n        }\n    }\n\n    if (masscan->nic[i].my_mac_count) {\n        ipaddress_formatted_t fmt = macaddress_fmt(masscan->nic[i].source_mac);\n        fprintf(fp, \"adapter-mac%s = %s\\n\", idx_str, fmt.string);\n    }\n    if (masscan->nic[i].router_ip) {\n        ipaddress_formatted_t fmt = ipv4address_fmt(masscan->nic[i].router_ip);\n        fprintf(fp, \"router-ip%s = %s\\n\", idx_str, fmt.string);\n    }\n    if (!macaddress_is_zero(masscan->nic[i].router_mac_ipv4)) {\n        ipaddress_formatted_t fmt =  macaddress_fmt(masscan->nic[i].router_mac_ipv4);\n        fprintf(fp, \"router-mac-ipv4%s = %s\\n\", idx_str, fmt.string);\n    }\n    if (!macaddress_is_zero(masscan->nic[i].router_mac_ipv6)) {\n        ipaddress_formatted_t fmt = macaddress_fmt(masscan->nic[i].router_mac_ipv6);\n        fprintf(fp, \"router-mac-ipv6%s = %s\\n\", idx_str, fmt.string);\n    }\n\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nmasscan_save_state(struct Masscan *masscan)\n{\n    char filename[512];\n    FILE *fp;\n\n    safe_strcpy(filename, sizeof(filename), \"paused.conf\");\n    fprintf(stderr, \"                                   \"\n                    \"                                   \\r\");\n    fprintf(stderr, \"saving resume file to: %s\\n\", filename);\n\n    fp = fopen(filename, \"wt\");\n    if (fp == NULL) {\n        fprintf(stderr, \"[-] FAIL: saving resume file\\n\");\n        fprintf(stderr, \"[-] %s: %s\\n\", filename, strerror(errno));\n        return;\n    }\n\n    \n    masscan_echo(masscan, fp, 0);\n\n    fclose(fp);\n}\n\n\n#if 0\n/*****************************************************************************\n * Read in ranges from a file\n *\n * There can be multiple ranges on a line, delimited by spaces. In fact,\n * millions of ranges can be on a line: there is limit to the line length.\n * That makes reading the file a little bit squirrelly. From one perspective\n * this parser doesn't treat the new-line '\\n' any different than other\n * space. But, from another perspective, it has to, because things like\n * comments are terminated by a newline. Also, it has to count the number\n * of lines correctly to print error messages.\n *****************************************************************************/\nstatic void\nranges_from_file(struct RangeList *ranges, const char *filename)\n{\n    FILE *fp;\n    unsigned line_number = 0;\n\n    fp = fopen(filename, \"rt\");\n    if (fp) {\n        perror(filename);\n        exit(1); /* HARD EXIT: because if it's an exclusion file, we don't\n                  * want to continue. We don't want ANY chance of\n                  * accidentally scanning somebody */\n    }\n\n    while (!feof(fp)) {\n        int c = '\\n';\n\n        /* remove leading whitespace */\n        while (!feof(fp)) {\n            c = getc(fp);\n            line_number += (c == '\\n');\n            if (!isspace(c&0xFF))\n                break;\n        }\n\n        /* If this is a punctuation, like '#', then it's a comment */\n        if (ispunct(c&0xFF)) {\n            while (!feof(fp)) {\n                c = getc(fp);\n                line_number += (c == '\\n');\n                if (c == '\\n') {\n                    break;\n                }\n            }\n            /* Loop back to the begining state at the start of a line */\n            continue;\n        }\n\n        if (c == '\\n') {\n            continue;\n        }\n\n        /*\n         * Read in a single entry\n         */\n        if (!feof(fp)) {\n            char address[64];\n            size_t i;\n            struct Range range;\n            unsigned offset = 0;\n\n\n            /* Grab all bytes until the next space or comma */\n            address[0] = (char)c;\n            i = 1;\n            while (!feof(fp)) {\n                c = getc(fp);\n                if (c == EOF)\n                    break;\n                line_number += (c == '\\n');\n                if (isspace(c&0xFF) || c == ',') {\n                    break;\n                }\n                if (i+1 >= sizeof(address)) {\n                    LOG(0, \"%s:%u:%u: bad address spec: \\\"%.*s\\\"\\n\",\n                            filename, line_number, offset, (int)i, address);\n                    exit(1);\n                } else\n                    address[i] = (char)c;\n                i++;\n            }\n            address[i] = '\\0';\n\n            /* parse the address range */\n            range = range_parse_ipv4(address, &offset, (unsigned)i);\n            if (range.begin == 0xFFFFFFFF && range.end == 0) {\n                LOG(0, \"%s:%u:%u: bad range spec: \\\"%.*s\\\"\\n\",\n                        filename, line_number, offset, (int)i, address);\n                exit(1);\n            } else {\n                rangelist_add_range(ranges, range.begin, range.end);\n            }\n        }\n    }\n\n    fclose(fp);\n\n    /* Target list must be sorted every time it's been changed, \n     * before it can be used */\n    rangelist_sort(ranges);\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nhexval(char c)\n{\n    if ('0' <= c && c <= '9')\n        return (unsigned)(c - '0');\n    if ('a' <= c && c <= 'f')\n        return (unsigned)(c - 'a' + 10);\n    if ('A' <= c && c <= 'F')\n        return (unsigned)(c - 'A' + 10);\n    return 0xFF;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nparse_mac_address(const char *text, macaddress_t *mac)\n{\n    unsigned i;\n\n    for (i=0; i<6; i++) {\n        unsigned x;\n        char c;\n\n        while (isspace(*text & 0xFF) && ispunct(*text & 0xFF))\n            text++;\n\n        c = *text;\n        if (!isxdigit(c&0xFF))\n            return -1;\n        x = hexval(c)<<4;\n        text++;\n\n        c = *text;\n        if (!isxdigit(c&0xFF))\n            return -1;\n        x |= hexval(c);\n        text++;\n\n        mac->addr[i] = (unsigned char)x;\n\n        if (ispunct(*text & 0xFF))\n            text++;\n    }\n\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic uint64_t\nparseInt(const char *str)\n{\n    uint64_t result = 0;\n\n    while (*str && isdigit(*str & 0xFF)) {\n        result = result * 10 + (*str - '0');\n        str++;\n    }\n    return result;\n}\n\n/**\n * a stricter function for determining if something is boolean.\n */\nstatic bool\nisBoolean(const char *str) {\n    size_t length = str?strlen(str):0;\n\n    if (length == 0)\n        return false;\n\n    /* \"0\" or \"1\" is boolean */\n    if (isdigit(str[0])) {\n        if (strtoul(str,0,0) == 0)\n            return true;\n        else if (strtoul(str,0,0) == 1)\n            return true;\n        else\n            return false;\n    }\n\n    switch (str[0]) {\n        case 'e':\n        case 'E':\n            if (memcasecmp(\"enable\", str, length)==0)\n                return true;\n            if (memcasecmp(\"enabled\", str, length)==0)\n                return true;\n            return false;\n        case 'd':\n        case 'D':\n            if (memcasecmp(\"disable\", str, length)==0)\n                return true;\n            if (memcasecmp(\"disabled\", str, length)==0)\n                return true;\n            return false;\n\n        case 't':\n        case 'T':\n            if (memcasecmp(\"true\", str, length)==0)\n                return true;\n            return false;\n        case 'f':\n        case 'F':\n            if (memcasecmp(\"false\", str, length)==0)\n                return true;\n            return false;\n\n        case 'o':\n        case 'O':\n            if (memcasecmp(\"on\", str, length)==0)\n                return true;\n            if (memcasecmp(\"off\", str, length)==0)\n                return true;\n            return false;\n        case 'Y':\n        case 'y':\n            if (memcasecmp(\"yes\", str, length)==0)\n                return true;\n            return false;\n        case 'n':\n        case 'N':\n            if (memcasecmp(\"no\", str, length)==0)\n                return true;\n            return false;\n        default:\n            return false;\n    }\n}\n\nstatic unsigned\nparseBoolean(const char *str)\n{\n    if (str == NULL || str[0] == 0)\n        return 1;\n    if (isdigit(str[0])) {\n        if (strtoul(str,0,0) == 0)\n            return 0;\n        else\n            return 1;\n    }\n    switch (str[0]) {\n    case 'e': /* enable */\n    case 'E':\n        return 1;\n    case 'd': /* disable */\n    case 'D':\n        return 0;\n\n    case 't': /* true */\n    case 'T':\n        return 1;\n    case 'f': /* false */\n    case 'F':\n        return 0;\n\n    case 'o': /* on or off */\n    case 'O':\n        if (str[1] == 'f' || str[1] == 'F')\n            return 0;\n        else\n            return 1;\n        break;\n\n    case 'Y': /* yes */\n    case 'y':\n        return 1;\n    case 'n': /* no */\n    case 'N':\n        return 0;\n    }\n    return 1;\n}\n\n/***************************************************************************\n * Parses the number of seconds (for rotating files mostly). We do a little\n * more than just parse an integer. We support strings like:\n *\n * hourly\n * daily\n * Week\n * 5days\n * 10-months\n * 3600\n ***************************************************************************/\nstatic uint64_t\nparseTime(const char *value)\n{\n    uint64_t num = 0;\n    unsigned is_negative = 0;\n\n    while (*value == '-') {\n        is_negative = 1;\n        value++;\n    }\n\n    while (isdigit(value[0]&0xFF)) {\n        num = num*10 + (value[0] - '0');\n        value++;\n    }\n    while (ispunct(value[0]) || isspace(value[0]))\n        value++;\n\n    if (isalpha(value[0]) && num == 0)\n        num = 1;\n\n    if (value[0] == '\\0')\n        return num;\n\n    switch (tolower(value[0])) {\n    case 's':\n        num *= 1;\n        break;\n    case 'm':\n        num *= 60;\n        break;\n    case 'h':\n        num *= 60*60;\n        break;\n    case 'd':\n        num *= 24*60*60;\n        break;\n    case 'w':\n        num *= 24*60*60*7;\n        break;\n    default:\n        fprintf(stderr, \"--rotate-offset: unknown character\\n\");\n        exit(1);\n    }\n    if (num >= 24*60*60) {\n        fprintf(stderr, \"--rotate-offset: value is greater than 1 day\\n\");\n        exit(1);\n    }\n    if (is_negative)\n        num = 24*60*60 - num;\n\n    return num;\n}\n\n/***************************************************************************\n * Parses a size integer, which can be suffixed with \"tera\", \"giga\", \n * \"mega\", and \"kilo\". These numbers are in units of 1024 so suck it.\n ***************************************************************************/\nstatic uint64_t\nparseSize(const char *value)\n{\n    uint64_t num = 0;\n\n    while (isdigit(value[0]&0xFF)) {\n        num = num*10 + (value[0] - '0');\n        value++;\n    }\n    while (ispunct(value[0]) || isspace(value[0]))\n        value++;\n\n    if (isalpha(value[0]) && num == 0)\n        num = 1;\n\n    if (value[0] == '\\0')\n        return num;\n\n    switch (tolower(value[0])) {\n    case 'k': /* kilobyte */\n        num *= 1024ULL;\n        break;\n    case 'm': /* megabyte */\n        num *= 1024ULL * 1024ULL;\n        break;\n    case 'g': /* gigabyte */\n        num *= 1024ULL * 1024ULL * 1024ULL;\n        break;\n    case 't': /* terabyte, 'cause we roll that way */\n        num *=  1024ULL * 1024ULL * 1024ULL * 1024ULL;\n        break;\n    case 'p': /* petabyte, 'cause we are awesome */\n        num *=  1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL;\n        break;\n    case 'e': /* exabyte, now that's just silly */\n        num *=  1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL;\n        break;\n    default:\n        fprintf(stderr, \"--rotate-size: unknown character\\n\");\n        exit(1);\n    }\n    return num;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nis_power_of_two(uint64_t x)\n{\n    while ((x&1) == 0)\n        x >>= 1;\n    return x == 1;\n}\n\n\n/***************************************************************************\n * Tests if the named parameter on the command-line. We do a little\n * more than a straight string compare, because I get confused\n * whether parameter have punctuation. Is it \"--excludefile\" or\n * \"--exclude-file\"? I don't know if it's got that dash. Screw it,\n * I'll just make the code so it don't care.\n ***************************************************************************/\nstatic int\nEQUALS(const char *lhs, const char *rhs)\n{\n    for (;;) {\n        while (*lhs == '-' || *lhs == '.' || *lhs == '_')\n            lhs++;\n        while (*rhs == '-' || *rhs == '.' || *rhs == '_')\n            rhs++;\n        if (*lhs == '\\0' && *rhs == '[')\n            return 1; /*arrays*/\n        if (tolower(*lhs & 0xFF) != tolower(*rhs & 0xFF))\n            return 0;\n        if (*lhs == '\\0')\n            return 1;\n        lhs++;\n        rhs++;\n    }\n}\n\nstatic int\nEQUALSx(const char *lhs, const char *rhs, size_t rhs_length)\n{\n    for (;;) {\n        while (*lhs == '-' || *lhs == '.' || *lhs == '_')\n            lhs++;\n        while (*rhs == '-' || *rhs == '.' || *rhs == '_')\n            rhs++;\n        if (*lhs == '\\0' && *rhs == '[')\n            return 1; /*arrays*/\n        if (tolower(*lhs & 0xFF) != tolower(*rhs & 0xFF))\n            return 0;\n        if (*lhs == '\\0')\n            return 1;\n        lhs++;\n        rhs++;\n        if (--rhs_length == 0)\n            return 1;\n    }\n}\n\nstatic unsigned\nINDEX_OF(const char *str, char c)\n{\n    unsigned i;\n    for (i=0; str[i] && str[i] != c; i++)\n        ;\n    return i;\n}\n\nstatic unsigned\nARRAY(const char *rhs)\n{\n    const char *p = strchr(rhs, '[');\n    if (p == NULL)\n        return 0;\n    else\n        p++;\n    return (unsigned)parseInt(p);\n}\n\n/**\n * Called if user specified `--top-ports` on the command-line.\n */\nstatic void\nconfig_top_ports(struct Masscan *masscan, unsigned maxports)\n{\n    unsigned i;\n    static const unsigned short top_udp_ports[] = {\n        161, /* SNMP - should be found on all network equipment */\n        135, /* MS-RPC - should be found on all modern Windows */\n        500, /* ISAKMP - for establishing IPsec tunnels */\n        137, /* NetBIOS-NameService - should be found on old Windows */\n        138, /* NetBIOS-Datagram - should be found on old Windows */\n        445, /* SMB datagram service */\n        67, /* DHCP */\n        53, /* DNS */\n        1900, /* UPnP - Microsoft-focused local discovery */\n        5353, /* mDNS - Apple-focused local discovery */\n        4500, /* nat-t-ike - IPsec NAT traversal */\n        514, /* syslog - all Unix machiens */\n        69, /* TFTP */\n        49152, /* first of modern ephemeral ports */\n        631, /* IPP - printing protocol for Linux */\n        123, /* NTP network time protocol */\n        1434, /* MS-SQL server*/\n        520, /* RIP - routers use this protocol sometimes */\n        7, /* Echo */\n        111, /* SunRPC portmapper */\n        2049, /* SunRPC NFS */\n        5683, /* COAP */\n        11211, /* memcached */\n        1701, /* L2TP */\n        27960, /* quaked amplifier */\n        1645, /* RADIUS */\n        1812, /* RADIUS */\n        1646, /* RADIUS */\n        1813, /* RADIUS */\n        3343, /* Microsoft Cluster Services */\n        2535, /* MADCAP rfc2730 TODO FIXME */\n        \n    };\n\n    static const unsigned short top_tcp_ports[] = {\n        80, 443, 8080,   /* also web */\n        21, 990,     /* FTP, oldie but goodie */\n        22,     /* SSH, so much infrastructure */\n        23, 992,     /* Telnet, oldie but still around*/\n        24,     /* people put things here instead of TelnetSSH*/\n        25, 465, 587, 2525,     /* SMTP email*/\n        5800, 5900, 5901, /* VNC */\n        111,    /* SunRPC */\n        139, 445, /* Microsoft Windows networking */\n        135,    /* DCEPRC, more Microsoft Windows */\n        3389,   /* Microsoft Windows RDP */\n        88,     /* Kerberos, also Microsoft windows */\n        389, 636,    /* LDAP and MS Win */\n        1433,   /* MS SQL */\n        53,     /* DNS */\n        2083, 2096,   /* cPanel */\n        9050,   /* ToR */\n        8140,   /* Puppet */\n        11211,  /* memcached */\n        1098, 1099, /* Java RMI */\n        6000, 6001, /* XWindows */\n        5060, 5061, /* SIP - session initiation protocool */\n        554,    /* RTSP */\n        548,    /* AFP */\n        \n\n        1,3,4,6,7,9,13,17,19,20,26,30,32,33,37,42,43,49,70,\n        79,81,82,83,84,85,89,90,99,100,106,109,110,113,119,125,\n        143,144,146,161,163,179,199,211,212,222,254,255,256,259,264,280,\n        301,306,311,340,366,406,407,416,417,425,427,444,458,464,\n        465,481,497,500,512,513,514,515,524,541,543,544,545,554,555,563,\n        593,616,617,625,631,646,648,666,667,668,683,687,691,700,705,\n        711,714,720,722,726,749,765,777,783,787,800,801,808,843,873,880,888,\n        898,900,901,902,903,911,912,981,987,993,995,999,1000,1001,\n        1002,1007,1009,1010,1011,1021,1022,1023,1024,1025,1026,1027,1028,\n        1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,\n        1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,\n        1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,\n        1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,\n        1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,\n        1094,1095,1096,1097,1100,1102,1104,1105,1106,1107,1108,\n        1110,1111,1112,1113,1114,1117,1119,1121,1122,1123,1124,1126,1130,\n        1131,1132,1137,1138,1141,1145,1147,1148,1149,1151,1152,1154,1163,\n        1164,1165,1166,1169,1174,1175,1183,1185,1186,1187,1192,1198,1199,\n        1201,1213,1216,1217,1218,1233,1234,1236,1244,1247,1248,1259,1271,\n        1272,1277,1287,1296,1300,1301,1309,1310,1311,1322,1328,1334,1352,\n        1417,1434,1443,1455,1461,1494,1500,1501,1503,1521,1524,1533,\n        1556,1580,1583,1594,1600,1641,1658,1666,1687,1688,1700,1717,1718,\n        1719,1720,1721,1723,1755,1761,1782,1783,1801,1805,1812,1839,1840,\n        1862,1863,1864,1875,1900,1914,1935,1947,1971,1972,1974,1984,1998,\n        1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,\n        2020,2021,2022,2030,2033,2034,2035,2038,2040,2041,2042,2043,2045,\n        2046,2047,2048,2049,2065,2068,2099,2100,2103,2105,2106,2107,2111,\n        2119,2121,2126,2135,2144,2160,2161,2170,2179,2190,2191,2196,2200,\n        2222,2251,2260,2288,2301,2323,2366,2381,2382,2383,2393,2394,2399,\n        2401,2492,2500,2522,2557,2601,2602,2604,2605,2607,2608,2638,\n        2701,2702,2710,2717,2718,2725,2800,2809,2811,2869,2875,2909,2910,\n        2920,2967,2968,2998,3000,3001,3003,3005,3006,3007,3011,3013,3017,\n        3030,3031,3052,3071,3077,3128,3168,3211,3221,3260,3261,3268,3269,\n        3283,3300,3301,3306,3322,3323,3324,3325,3333,3351,3367,3369,3370,\n        3371,3372,3389,3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,\n        3689,3690,3703,3737,3766,3784,3800,3801,3809,3814,3826,3827,3828,\n        3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,\n        3995,3998,4000,4001,4002,4003,4004,4005,4006,4045,4111,4125,4126,\n        4129,4224,4242,4279,4321,4343,4443,4444,4445,4446,4449,4550,4567,\n        4662,4848,4899,4900,4998,5000,5001,5002,5003,5004,5009,5030,5033,\n        5050,5051,5054,5080,5087,5100,5101,5102,5120,5190,5200,\n        5214,5221,5222,5225,5226,5269,5280,5298,5357,5405,5414,5431,5432,\n        5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678,5679,\n        5718,5730,5801,5802,5810,5811,5815,5822,5825,5850,5859,5862,\n        5877,5902,5903,5904,5906,5907,5910,5911,5915,5922,5925,\n        5950,5952,5959,5960,5961,5962,5963,5987,5988,5989,5998,5999,\n        6002,6003,6004,6005,6006,6007,6009,6025,6059,6100,6101,6106,\n        6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565,6566,6567,\n        6580,6646,6666,6667,6668,6669,6689,6692,6699,6779,6788,6789,6792,\n        6839,6881,6901,6969,7000,7001,7002,7004,7007,7019,7025,7070,7100,\n        7103,7106,7200,7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,\n        7777,7778,7800,7911,7920,7921,7937,7938,7999,8000,8001,8002,8007,\n        8008,8009,8010,8011,8021,8022,8031,8042,8045,8080,8081,8082,8083,\n        8084,8085,8086,8087,8088,8089,8090,8093,8099,8100,8180,8181,8192,\n        8193,8194,8200,8222,8254,8290,8291,8292,8300,8333,8383,8400,8402,\n        8443,8500,8600,8649,8651,8652,8654,8701,8800,8873,8888,8899,8994,\n        9000,9001,9002,9003,9009,9010,9011,9040,9071,9080,9081,9090,\n        9091,9099,9100,9101,9102,9103,9110,9111,9200,9207,9220,9290,9415,\n        9418,9485,9500,9502,9503,9535,9575,9593,9594,9595,9618,9666,9876,\n        9877,9878,9898,9900,9917,9929,9943,9944,9968,9998,9999,10000,10001,\n        10002,10003,10004,10009,10010,10012,10024,10025,10082,10180,10215,\n        10243,10566,10616,10617,10621,10626,10628,10629,10778,11110,11111,\n        11967,12000,12174,12265,12345,13456,13722,13782,13783,14000,14238,\n        14441,14442,15000,15002,15003,15004,15660,15742,16000,16001,16012,\n        16016,16018,16080,16113,16992,16993,17877,17988,18040,18101,18988,\n        19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221,\n        20222,20828,21571,22939,23502,24444,24800,25734,25735,26214,27000,\n        27352,27353,27355,27356,27715,28201,30000,30718,30951,31038,31337,\n        32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,\n        32779,32780,32781,32782,32783,32784,32785,33354,33899,34571,34572,\n        34573,35500,38292,40193,40911,41511,42510,44176,44442,44443,44501,\n        45100,48080,49152,49153,49154,49155,49156,49157,49158,49159,49160,\n        49161,49163,49165,49167,49175,49176,49400,49999,50000,50001,50002,\n        50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,\n        52848,52869,54045,54328,55055,55056,55555,55600,56737,56738,57294,\n        57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,\n        65129,65389};\n    struct RangeList *ports = &masscan->targets.ports;\n    static const unsigned max_tcp_ports = sizeof(top_tcp_ports)/sizeof(top_tcp_ports[0]);\n    static const unsigned max_udp_ports = sizeof(top_udp_ports)/sizeof(top_udp_ports[0]);\n\n\n    if (masscan->scan_type.tcp) {\n        LOG(2, \"[+] adding TCP top-ports = %u\\n\", maxports);\n        for (i=0; i<maxports && i<max_tcp_ports; i++)\n            rangelist_add_range_tcp(ports,\n                                top_tcp_ports[i],\n                                top_tcp_ports[i]);\n    }\n\n    if (masscan->scan_type.udp) {\n        LOG(2, \"[+] adding UDP top-ports = %u\\n\", maxports);\n        for (i=0; i<maxports && i<max_udp_ports; i++)\n            rangelist_add_range_udp(ports,\n                                top_udp_ports[i],\n                                top_udp_ports[i]);\n    }\n\n    /* Targets must be sorted after every change, before being used */\n    rangelist_sort(ports);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nisInteger(const char *value)\n{\n    size_t i;\n    \n    if (value == NULL)\n        return 0;\n    \n    for (i=0; value[i]; i++)\n        if (!isdigit(value[i]&0xFF))\n            return 0;\n    return 1;\n}\n\n/***************************************************************************\n ***************************************************************************/\ntypedef int (*SET_PARAMETER)(struct Masscan *masscan, const char *name, const char *value);\nenum {CONF_OK, CONF_WARN, CONF_ERR};\n\nstatic int SET_arpscan(struct Masscan *masscan, const char *name, const char *value)\n{\n    struct Range range;\n\n    UNUSEDPARM(name);\n    UNUSEDPARM(value);\n\n    if (masscan->echo) {\n        if (masscan->scan_type.arp || masscan->echo_all)\n            fprintf(masscan->echo, \"arpscan = %s\\n\", masscan->scan_type.arp?\"true\":\"false\");\n        return 0;\n    }\n    range.begin = Templ_ARP;\n    range.end = Templ_ARP;\n    rangelist_add_range(&masscan->targets.ports, range.begin, range.end);\n    rangelist_sort(&masscan->targets.ports);\n    masscan_set_parameter(masscan, \"router-mac\", \"ff-ff-ff-ff-ff-ff\");\n    masscan->scan_type.arp = 1;\n    LOG(5, \"--arpscan\\n\");\n    return CONF_OK;\n}\n\nstatic int SET_banners(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->is_banners || masscan->echo_all)\n            fprintf(masscan->echo, \"banners = %s\\n\", masscan->is_banners?\"true\":\"false\");\n       return 0;\n    }\n    masscan->is_banners = parseBoolean(value);\n    return CONF_OK;\n}\n\nstatic int SET_banners_rawudp(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->is_banners_rawudp || masscan->echo_all)\n            fprintf(masscan->echo, \"rawudp = %s\\n\", masscan->is_banners_rawudp?\"true\":\"false\");\n       return 0;\n    }\n    masscan->is_banners_rawudp = parseBoolean(value);\n    if (masscan->is_banners_rawudp)\n        masscan->is_banners = true;\n    return CONF_OK;\n}\n\nstatic int SET_capture(struct Masscan *masscan, const char *name, const char *value)\n{\n    if (masscan->echo) {\n        if (!masscan->is_capture_cert || masscan->echo_all)\n            fprintf(masscan->echo, \"%scapture = cert\\n\", masscan->is_capture_cert?\"\":\"no\");\n        if (!masscan->is_capture_servername || masscan->echo_all)\n            fprintf(masscan->echo, \"%scapture = servername\\n\", masscan->is_capture_servername?\"\":\"no\");\n        if (masscan->is_capture_html || masscan->echo_all)\n            fprintf(masscan->echo, \"%scapture = html\\n\", masscan->is_capture_html?\"\":\"no\");\n        if (masscan->is_capture_heartbleed || masscan->echo_all)\n            fprintf(masscan->echo, \"%scapture = heartbleed\\n\", masscan->is_capture_heartbleed?\"\":\"no\");\n        if (masscan->is_capture_ticketbleed || masscan->echo_all)\n            fprintf(masscan->echo, \"%scapture = ticketbleed\\n\", masscan->is_capture_ticketbleed?\"\":\"no\");\n        return 0;\n    }\n    if (EQUALS(\"capture\", name)) {\n        if (EQUALS(\"cert\", value))\n            masscan->is_capture_cert = 1;\n        else if (EQUALS(\"servername\", value))\n            masscan->is_capture_servername = 1;\n        else if (EQUALS(\"html\", value))\n            masscan->is_capture_html = 1;\n        else if (EQUALS(\"heartbleed\", value))\n            masscan->is_capture_heartbleed = 1;\n        else if (EQUALS(\"ticketbleed\", value))\n            masscan->is_capture_ticketbleed = 1;\n        else {\n            fprintf(stderr, \"FAIL: %s: unknown capture type\\n\", value);\n            return CONF_ERR;\n        }\n    } else if (EQUALS(\"nocapture\", name)) {\n        if (EQUALS(\"cert\", value))\n            masscan->is_capture_cert = 0;\n        else if (EQUALS(\"servername\", value))\n            masscan->is_capture_servername = 0;\n        else if (EQUALS(\"html\", value))\n            masscan->is_capture_html = 0;\n        else if (EQUALS(\"heartbleed\", value))\n            masscan->is_capture_heartbleed = 0;\n        else if (EQUALS(\"ticketbleed\", value))\n            masscan->is_capture_ticketbleed = 0;\n        else {\n            fprintf(stderr, \"FAIL: %s: unknown nocapture type\\n\", value);\n            return CONF_ERR;\n        }\n    }\n    return CONF_OK;\n}\n\nstatic int SET_hello(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->is_hello_ssl) {\n            fprintf(masscan->echo, \"hello = ssl\\n\");\n        } else if (masscan->is_hello_smbv1) {\n            fprintf(masscan->echo, \"hello = smbv1\\n\");\n        } else if (masscan->is_hello_http) {\n            fprintf(masscan->echo, \"hello = http\\n\");\n        }\n        return 0;\n    }\n    if (EQUALS(\"ssl\", value))\n        masscan->is_hello_ssl = 1;\n    else if (EQUALS(\"smbv1\", value))\n        masscan->is_hello_smbv1 = 1;\n    else if (EQUALS(\"http\", value))\n        masscan->is_hello_http = 1;\n    else {\n        fprintf(stderr, \"FAIL: %s: unknown hello type\\n\", value);\n        return CONF_ERR;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_hello_file(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned index;\n    FILE *fp;\n    char buf[16384];\n    char buf2[16384];\n    size_t bytes_read;\n    size_t bytes_encoded;\n    char foo[64];\n\n    if (masscan->echo) {\n        //Echoed as a string \"hello-string\" that was originally read\n        //from a file, not the \"hello-filename\"\n        return 0;\n    }\n    \n    index = ARRAY(name);\n    if (index >= 65536) {\n        fprintf(stderr, \"%s: bad index\\n\", name);\n        return CONF_ERR;\n    }\n\n    /* When connecting via TCP, send this file */\n    fp = fopen(value, \"rb\");\n    if (fp == NULL) {\n        LOG(0, \"[-] [FAILED] --hello-file\\n\");\n        LOG(0, \"[-] %s: %s\\n\", value, strerror(errno));\n        return CONF_ERR;\n    }\n    \n    bytes_read = fread(buf, 1, sizeof(buf), fp);\n    if (bytes_read == 0) {\n        LOG(0, \"[FAILED] could not read hello file\\n\");\n        perror(value);\n        fclose(fp);\n        return CONF_ERR;\n    }\n    fclose(fp);\n    \n    bytes_encoded = base64_encode(buf2, sizeof(buf2)-1, buf, bytes_read);\n    buf2[bytes_encoded] = '\\0';\n    \n    snprintf(foo, sizeof(foo), \"hello-string[%u]\", (unsigned)index);\n    \n    masscan_set_parameter(masscan, foo, buf2);\n\n    return CONF_OK;\n}\n\nstatic int SET_hello_string(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned index;\n    char *value2;\n    struct TcpCfgPayloads *pay;\n\n    if (masscan->echo) {\n        for (pay = masscan->payloads.tcp; pay; pay = pay->next) {\n            fprintf(masscan->echo, \"hello-string[%u] = %s\\n\",\n                    pay->port, pay->payload_base64);\n        }\n        return 0;\n    }\n    \n    index = ARRAY(name);\n    if (index >= 65536) {\n        fprintf(stderr, \"%s: bad index\\n\", name);\n        exit(1);\n    }\n\n    \n    value2 = STRDUP(value);\n\n    pay = MALLOC(sizeof(*pay));\n    \n    pay->payload_base64 = value2;\n    pay->port = index;\n    pay->next = masscan->payloads.tcp;\n    masscan->payloads.tcp = pay;\n    return CONF_OK;\n}\n\nstatic int SET_hello_timeout(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->tcp_hello_timeout || masscan->echo_all)\n            fprintf(masscan->echo, \"hello-timeout = %u\\n\", masscan->tcp_hello_timeout);\n        return 0;\n    }\n    masscan->tcp_hello_timeout = (unsigned)parseInt(value);\n    return CONF_OK;\n}\n\nstatic int SET_http_cookie(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned char *newvalue;\n    size_t value_length;\n\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.cookies_count || masscan->echo_all) {\n            size_t i;\n            for (i=0; i<masscan->http.cookies_count; i++) {\n                fprintf(masscan->echo,\n                        \"http-cookie = %.*s\\n\",\n                        (unsigned)masscan->http.cookies[i].value_length,\n                        masscan->http.cookies[i].value);\n            }\n        }\n        return 0;\n    }\n\n    /* allocate new value */\n    value_length = strlen(value);\n    newvalue = MALLOC(value_length+1);\n    memcpy(newvalue, value, value_length+1);\n    newvalue[value_length] = '\\0';\n\n    /* Add to our list of headers */\n    if (masscan->http.cookies_count < sizeof(masscan->http.cookies)/sizeof(masscan->http.cookies[0])) {\n        size_t x = masscan->http.cookies_count;\n        masscan->http.cookies[x].value = newvalue;\n        masscan->http.cookies[x].value_length = value_length;\n        masscan->http.cookies_count++;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_http_header(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned name_length;\n    char *newname;\n    unsigned char *newvalue;\n    size_t value_length;\n\n    if (masscan->echo) {\n        if (masscan->http.headers_count || masscan->echo_all) {\n            size_t i;\n            for (i=0; i<masscan->http.headers_count; i++) {\n                if (masscan->http.headers[i].name == 0)\n                    continue;\n                fprintf(masscan->echo,\n                        \"http-header = %s:%.*s\\n\",\n                        masscan->http.headers[i].name,\n                        (unsigned)masscan->http.headers[i].value_length,\n                        masscan->http.headers[i].value);\n            }\n        }\n        return 0;\n    }\n\n    /* \n     * allocate a new name \n     */\n    name += 11;\n    if (*name == '[') {\n        /* Specified as: \"--http-header[name] value\" */\n        while (ispunct(*name))\n            name++;\n        name_length = (unsigned)strlen(name);\n        while (name_length && ispunct(name[name_length-1]))\n            name_length--;\n        newname = MALLOC(name_length+1);\n        memcpy(newname, name, name_length+1);\n        newname[name_length] = '\\0';\n    } else if (strchr(value, ':')) {\n        /* Specified as: \"--http-header Name:value\" */\n        name_length = INDEX_OF(value, ':');\n        newname = MALLOC(name_length + 1);\n        memcpy(newname, value, name_length + 1);\n            \n        /* Trim the value */\n        value = value + name_length + 1;\n        while (*value && isspace(*value & 0xFF))\n            value++;\n\n        /* Trim the name */\n        while (name_length && isspace(newname[name_length-1]&0xFF))\n            name_length--;\n        newname[name_length] = '\\0';\n    } else {\n        fprintf(stderr, \"[-] --http-header needs both a name and value\\n\");\n        fprintf(stderr, \"    hint: \\\"--http-header Name:value\\\"\\n\");\n        exit(1);\n    }\n\n    /* allocate new value */\n    value_length = strlen(value);\n    newvalue = MALLOC(value_length+1);\n    memcpy(newvalue, value, value_length+1);\n    newvalue[value_length] = '\\0';\n\n    /* Add to our list of headers */\n    if (masscan->http.headers_count < sizeof(masscan->http.headers)/sizeof(masscan->http.headers[0])) {\n        size_t x = masscan->http.headers_count;\n        masscan->http.headers[x].name = newname;\n        masscan->http.headers[x].value = newvalue;\n        masscan->http.headers[x].value_length = value_length;\n        masscan->http.headers_count++;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_http_method(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.method || masscan->echo_all)\n            fprintf(masscan->echo, \"http-method = %.*s\\n\", (unsigned)masscan->http.method_length, masscan->http.method);\n        return 0;\n    }\n    if (masscan->http.method)\n        free(masscan->http.method);\n    masscan->http.method_length = strlen(value);\n    masscan->http.method = MALLOC(masscan->http.method_length+1);\n    memcpy(masscan->http.method, value, masscan->http.method_length+1);\n    return CONF_OK;\n}\nstatic int SET_http_url(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.url || masscan->echo_all)\n            fprintf(masscan->echo, \"http-url = %.*s\\n\", (unsigned)masscan->http.url_length, masscan->http.url);\n        return 0;\n    }\n    if (masscan->http.url)\n        free(masscan->http.url);\n    masscan->http.url_length = strlen(value);\n    masscan->http.url = MALLOC(masscan->http.url_length+1);\n    memcpy(masscan->http.url, value, masscan->http.url_length+1);\n    return CONF_OK;\n}\nstatic int SET_http_version(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.version || masscan->echo_all)\n            fprintf(masscan->echo, \"http-version = %.*s\\n\", (unsigned)masscan->http.version_length, masscan->http.version);\n        return 0;\n    }\n    if (masscan->http.version)\n        free(masscan->http.version);\n    masscan->http.version_length = strlen(value);\n    masscan->http.version = MALLOC(masscan->http.version_length+1);\n    memcpy(masscan->http.version, value, masscan->http.version_length+1);\n    return CONF_OK;\n}\nstatic int SET_http_host(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.host || masscan->echo_all)\n            fprintf(masscan->echo, \"http-host = %.*s\\n\", (unsigned)masscan->http.host_length, masscan->http.host);\n        return 0;\n    }\n    if (masscan->http.host)\n        free(masscan->http.host);\n    masscan->http.host_length = strlen(value);\n    masscan->http.host = MALLOC(masscan->http.host_length+1);\n    memcpy(masscan->http.host, value, masscan->http.host_length+1);\n    return CONF_OK;\n}\n\nstatic int SET_http_user_agent(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.user_agent || masscan->echo_all)\n            fprintf(masscan->echo, \"http-user-agent = %.*s\\n\", (unsigned)masscan->http.user_agent_length, masscan->http.user_agent);\n        return 0;\n    }\n    if (masscan->http.user_agent)\n        free(masscan->http.user_agent);\n    masscan->http.user_agent_length = strlen(value);\n    masscan->http.user_agent = MALLOC(masscan->http.user_agent_length+1);\n    memcpy( masscan->http.user_agent,\n            value,\n            masscan->http.user_agent_length+1\n            );\n    return CONF_OK;\n}\n\nstatic int SET_http_payload(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->http.payload || masscan->echo_all)\n            fprintf(masscan->echo, \"http-payload = %.*s\\n\", (unsigned)masscan->http.payload_length, masscan->http.payload);\n        return 0;\n    }\n    masscan->http.payload_length = strlen(value);\n    masscan->http.payload = REALLOC(masscan->http.payload, masscan->http.payload_length+1);\n    memcpy( masscan->http.payload,\n            value,\n            masscan->http.payload_length+1\n            );\n    return CONF_OK;\n}\n\nstatic int SET_status_ndjson(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n\n    if (masscan->echo) {\n        if (masscan->output.is_status_ndjson || masscan->echo_all)\n            fprintf(masscan->echo, \"ndjson-status = %s\\n\", masscan->output.is_status_ndjson?\"true\":\"false\");\n        return 0;\n    }\n    masscan->output.is_status_ndjson = parseBoolean(value);\n    return CONF_OK;\n}\nstatic int SET_status_json(struct Masscan *masscan, const char *name, const char *value)\n{\n    /* NOTE: this is here just to warn people they mistyped it */\n    UNUSEDPARM(name);\n    UNUSEDPARM(value);\n\n    if (masscan->echo) {\n        return 0;\n    }\n    fprintf(stderr, \"[-] FAIL: %s not supported, use --status-ndjson\\n\", name);\n    fprintf(stderr, \"    hint: new-line delimited JSON status is what we use\\n\");\n    return CONF_ERR;\n}\n\nstatic int SET_min_packet(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->min_packet_size != 60 || masscan->echo_all)\n            fprintf(masscan->echo, \"min-packet = %u\\n\", masscan->min_packet_size);\n        return 0;\n    }\n    masscan->min_packet_size = (unsigned)parseInt(value);\n    return CONF_OK;\n}\n\n\nstatic int SET_nobanners(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        return 0;\n    }\n    masscan->is_banners = !parseBoolean(value);\n    return CONF_OK;\n}\n\nstatic int SET_noreset(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->is_noreset || masscan->echo_all)\n            fprintf(masscan->echo, \"noreset = %s\\n\", masscan->is_noreset?\"true\":\"false\");\n        return 0;\n    }\n    masscan->is_noreset = parseBoolean(value);\n    return CONF_OK;\n}\n\nstatic int SET_nmap_payloads(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    \n    if (masscan->echo) {\n        if ((masscan->payloads.nmap_payloads_filename && masscan->payloads.nmap_payloads_filename[0]) || masscan->echo_all)\n            fprintf(masscan->echo, \"nmap-payloads = %s\\n\", masscan->payloads.nmap_payloads_filename);\n        return 0;\n    }\n    \n    if (masscan->payloads.nmap_payloads_filename)\n        free(masscan->payloads.nmap_payloads_filename);\n    masscan->payloads.nmap_payloads_filename = strdup(value);\n\n    return CONF_OK;\n}\n\nstatic int SET_nmap_service_probes(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    \n    if (masscan->echo) {\n        if ((masscan->payloads.nmap_service_probes_filename && masscan->payloads.nmap_service_probes_filename[0]) || masscan->echo_all)\n            fprintf(masscan->echo, \"nmap-service-probes = %s\\n\", masscan->payloads.nmap_service_probes_filename);\n        return 0;\n    }\n    \n    if (masscan->payloads.nmap_service_probes_filename)\n        free(masscan->payloads.nmap_service_probes_filename);\n    masscan->payloads.nmap_service_probes_filename = strdup(value);\n    \n    \n    return CONF_OK;\n}\n\nstatic int SET_offline(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n\n    if (masscan->echo) {\n        if (masscan->is_offline || masscan->echo_all)\n            fprintf(masscan->echo, \"offline = %s\\n\", masscan->is_offline?\"true\":\"false\");\n        return 0;\n    }\n    masscan->is_offline = parseBoolean(value);\n    return CONF_OK;\n}\n\nstatic int SET_output_append(struct Masscan *masscan, const char *name, const char *value)\n{\n    if (masscan->echo) {\n        if (masscan->output.is_append || masscan->echo_all)\n            fprintf(masscan->echo, \"output-append = %s\\n\",\n                    masscan->output.is_append?\"true\":\"false\");\n        return 0;\n    }\n    if (EQUALS(\"overwrite\", name) || !parseBoolean(value))\n        masscan->output.is_append = 0;\n    else\n        masscan->output.is_append = 1;\n    return CONF_OK;\n}\n\nstatic int SET_output_filename(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->output.filename[0] || masscan->echo_all)\n            fprintf(masscan->echo, \"output-filename = %s\\n\", masscan->output.filename);\n        return 0;\n    }\n    if (masscan->output.format == 0)\n        masscan->output.format = Output_XML; /*TODO: Why is the default XML?*/\n    safe_strcpy(masscan->output.filename,\n             sizeof(masscan->output.filename),\n             value);\n    return CONF_OK;\n}\n\nstatic int SET_output_format(struct Masscan *masscan, const char *name, const char *value)\n{\n    enum OutputFormat x = 0;\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        FILE *fp = masscan->echo;\n        ipaddress_formatted_t fmt;\n        switch (masscan->output.format) {\n            case Output_Default:    if (masscan->echo_all) fprintf(fp, \"output-format = interactive\\n\"); break;\n            case Output_Interactive:fprintf(fp, \"output-format = interactive\\n\"); break;\n            case Output_List:       fprintf(fp, \"output-format = list\\n\"); break;\n            case Output_Unicornscan:fprintf(fp, \"output-format = unicornscan\\n\"); break;\n            case Output_XML:        fprintf(fp, \"output-format = xml\\n\"); break;\n            case Output_Binary:     fprintf(fp, \"output-format = binary\\n\"); break;\n            case Output_Grepable:   fprintf(fp, \"output-format = grepable\\n\"); break;\n            case Output_JSON:       fprintf(fp, \"output-format = json\\n\"); break;\n            case Output_NDJSON:     fprintf(fp, \"output-format = ndjson\\n\"); break;\n            case Output_Certs:      fprintf(fp, \"output-format = certs\\n\"); break;\n            case Output_None:       fprintf(fp, \"output-format = none\\n\"); break;\n            case Output_Hostonly:   fprintf(fp, \"output-format = hostonly\\n\"); break;\n            case Output_Redis:\n                fmt = ipaddress_fmt(masscan->redis.ip);\n                fprintf(fp, \"output-format = redis\\n\");\n                fprintf(fp, \"redis = %s %u\\n\", fmt.string, masscan->redis.port);\n                break;\n                \n            default:\n                fprintf(fp, \"output-format = unknown(%u)\\n\", masscan->output.format);\n                break;\n        }\n        return 0;\n    }\n    if (EQUALS(\"unknown(0)\", value))        x = Output_Interactive;\n    else if (EQUALS(\"interactive\", value))  x = Output_Interactive;\n    else if (EQUALS(\"list\", value))         x = Output_List;\n    else if (EQUALS(\"unicornscan\", value))  x = Output_Unicornscan;\n    else if (EQUALS(\"xml\", value))          x = Output_XML;\n    else if (EQUALS(\"binary\", value))       x = Output_Binary;\n    else if (EQUALS(\"greppable\", value))    x = Output_Grepable;\n    else if (EQUALS(\"grepable\", value))     x = Output_Grepable;\n    else if (EQUALS(\"json\", value))         x = Output_JSON;\n    else if (EQUALS(\"ndjson\", value))       x = Output_NDJSON;\n    else if (EQUALS(\"certs\", value))        x = Output_Certs;\n    else if (EQUALS(\"none\", value))         x = Output_None;\n    else if (EQUALS(\"redis\", value))        x = Output_Redis;\n    else if (EQUALS(\"hostonly\", value))     x = Output_Hostonly;\n    else {\n        LOG(0, \"FAIL: unknown output-format: %s\\n\", value);\n        LOG(0, \"  hint: 'binary', 'xml', 'grepable', ...\\n\");\n        return CONF_ERR;\n    }\n    masscan->output.format = x;\n\n    return CONF_OK;\n}\n\nstatic int SET_output_noshow(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->echo_all) {\n            fprintf(masscan->echo, \"output-noshow = %s%s%s\\n\",\n                    (!masscan->output.is_show_open)?\"open,\":\"\",\n                    (!masscan->output.is_show_closed)?\"closed,\":\"\",\n                    (!masscan->output.is_show_host)?\"host,\":\"\"\n                    );\n        }\n        return 0;\n    }\n    for (;;) {\n        const char *val2 = value;\n        unsigned val2_len = INDEX_OF(val2, ',');\n        if (val2_len == 0)\n            break;\n        if (EQUALSx(\"open\", val2, val2_len))\n            masscan->output.is_show_open = 0;\n        else if (EQUALSx(\"closed\", val2, val2_len) || EQUALSx(\"close\", val2, val2_len))\n            masscan->output.is_show_closed = 0;\n        else if (EQUALSx(\"open\", val2, val2_len))\n            masscan->output.is_show_host = 0;\n        else if (EQUALSx(\"all\",val2,val2_len)) {\n            masscan->output.is_show_open = 0;\n            masscan->output.is_show_host = 0;\n            masscan->output.is_show_closed = 0;\n        }\n        else {\n            LOG(0, \"FAIL: unknown 'noshow' spec: %.*s\\n\", val2_len, val2);\n            exit(1);\n        }\n        value += val2_len;\n        while (*value == ',')\n            value++;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_output_show(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->echo_all) {\n            fprintf(masscan->echo, \"output-show = %s%s%s\\n\",\n                    masscan->output.is_show_open?\"open,\":\"\",\n                    masscan->output.is_show_closed?\"closed,\":\"\",\n                    masscan->output.is_show_host?\"host,\":\"\"\n                    );\n        }\n        return 0;\n    }\n    for (;;) {\n        const char *val2 = value;\n        unsigned val2_len = INDEX_OF(val2, ',');\n        if (val2_len == 0)\n            break;\n        if (EQUALSx(\"open\", val2, val2_len))\n            masscan->output.is_show_open = 1;\n        else if (EQUALSx(\"closed\", val2, val2_len) || EQUALSx(\"close\", val2, val2_len))\n            masscan->output.is_show_closed = 1;\n        else if (EQUALSx(\"open\", val2, val2_len))\n            masscan->output.is_show_host = 1;\n        else if (EQUALSx(\"all\",val2,val2_len)) {\n            masscan->output.is_show_open = 1;\n            masscan->output.is_show_host = 1;\n            masscan->output.is_show_closed = 1;\n        }\n        else {\n            LOG(0, \"FAIL: unknown 'show' spec: %.*s\\n\", val2_len, val2);\n            exit(1);\n        }\n        value += val2_len;\n        while (*value == ',')\n            value++;\n    }\n    return CONF_OK;\n}\nstatic int SET_output_show_open(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    UNUSEDPARM(value);\n    if (masscan->echo) {\n        return 0;\n    }\n    /* \"open\" \"open-only\" */\n    masscan->output.is_show_open = 1;\n    masscan->output.is_show_closed = 0;\n    masscan->output.is_show_host = 0;\n    return CONF_OK;\n}\n\n/* Specifies a 'libpcap' file where the received packets will be written.\n * This is useful while debugging so that we can see what exactly is\n * going on. It's also an alternate mode for getting output from this\n * program. Instead of relying upon this program's determination of what\n * ports are open or closed, you can instead simply parse this capture\n * file yourself and make your own determination */\nstatic int SET_pcap_filename(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->pcap_filename[0])\n            fprintf(masscan->echo, \"pcap-filename = %s\\n\", masscan->pcap_filename);\n        return 0;\n    }\n    if (value)\n        safe_strcpy(masscan->pcap_filename, sizeof(masscan->pcap_filename), value);\n    return CONF_OK;\n}\n\n/* Specifies a 'libpcap' file from which to read packet-payloads. The payloads found\n * in this file will serve as the template for spewing out custom packets. There are\n * other options that can set payloads as well, like \"--nmap-payloads\" for reading\n * their custom payload file, as well as the various \"hello\" options for specifying\n * the string sent to the server once a TCP connection has been established. */\nstatic int SET_pcap_payloads(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if ((masscan->payloads.pcap_payloads_filename && masscan->payloads.pcap_payloads_filename[0]) || masscan->echo_all)\n            fprintf(masscan->echo, \"pcap-payloads = %s\\n\", masscan->payloads.pcap_payloads_filename);\n        return 0;\n    }\n    \n    if (masscan->payloads.pcap_payloads_filename)\n        free(masscan->payloads.pcap_payloads_filename);\n    masscan->payloads.pcap_payloads_filename = strdup(value);\n    \n    /* file will be loaded in \"masscan_load_database_files()\" */\n    \n    return CONF_OK;\n}\n\n\nstatic int SET_randomize_hosts(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    UNUSEDPARM(value);\n    if (masscan->echo) {\n        //fprintf(masscan->echo, \"randomize-hosts = true\\n\");\n        return 0;\n    }\n    return CONF_OK;\n}\n\n\nstatic int SET_rate(struct Masscan *masscan, const char *name, const char *value)\n{\n    double rate = 0.0;\n    double point = 10.0;\n    unsigned i;\n    \n    if (masscan->echo) {\n        if ((unsigned)(masscan->max_rate * 100000) % 100000) {\n            /* print as floating point number, which is rare */\n            fprintf(masscan->echo, \"rate = %f\\n\", masscan->max_rate);\n        } else {\n            /* pretty print as just an integer, which is what most people\n             * expect */\n            fprintf(masscan->echo, \"rate = %-10.0f\\n\", masscan->max_rate);\n        }\n        return 0;\n    }\n    \n    for (i=0; value[i] && value[i] != '.'; i++) {\n        char c = value[i];\n        if (c < '0' || '9' < c) {\n            fprintf(stderr, \"CONF: non-digit in rate spec: %s=%s\\n\", name, value);\n            return CONF_ERR;\n        }\n        rate = rate * 10.0 + (c - '0');\n    }\n    \n    if (value[i] == '.') {\n        i++;\n        while (value[i]) {\n            char c = value[i];\n            if (c < '0' || '9' < c) {\n                fprintf(stderr, \"CONF: non-digit in rate spec: %s=%s\\n\",\n                        name, value);\n                return CONF_ERR;\n            }\n            rate += (c - '0')/point;\n            point *= 10.0;\n            value++;\n        }\n    }\n    \n    masscan->max_rate = rate;\n    return CONF_OK;\n}\n\nstatic int SET_resume_count(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->resume.count || masscan->echo_all) {\n            fprintf(masscan->echo, \"resume-count = %\" PRIu64 \"\\n\", masscan->resume.count);\n        }\n        return 0;\n    }\n    masscan->resume.count = parseInt(value);\n    return CONF_OK;\n}\n\nstatic int SET_resume_index(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->resume.index  || masscan->echo_all) {\n            fprintf(masscan->echo, \"\\n# resume information\\n\");\n            fprintf(masscan->echo, \"resume-index = %\" PRIu64 \"\\n\", masscan->resume.index);\n        }\n        return 0;\n    }\n    masscan->resume.index = parseInt(value);\n    return CONF_OK;\n}\n\nstatic int SET_retries(struct Masscan *masscan, const char *name, const char *value)\n{\n    uint64_t x;\n    \n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->retries || masscan->echo_all)\n            fprintf(masscan->echo, \"retries = %u\\n\", masscan->retries);\n        return 0;\n    }\n    x = strtoul(value, 0, 0);\n    if (x >= 1000) {\n        fprintf(stderr, \"FAIL: retries=<n>: expected number less than 1000\\n\");\n        return CONF_ERR;\n    }\n    masscan->retries = (unsigned)x;\n    return CONF_OK;\n    \n}\n\nstatic int SET_rotate_time(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->output.rotate.timeout || masscan->echo_all)\n            fprintf(masscan->echo, \"rotate = %u\\n\", masscan->output.rotate.timeout);\n        return 0;\n    }\n    masscan->output.rotate.timeout = (unsigned)parseTime(value);\n    return CONF_OK;\n}\nstatic int SET_rotate_directory(struct Masscan *masscan, const char *name, const char *value)\n{\n    char *p;\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (memcmp(masscan->output.rotate.directory, \".\",2) != 0 || masscan->echo_all) {\n            fprintf(masscan->echo, \"rotate-dir = %s\\n\", masscan->output.rotate.directory);\n        }\n        return 0;\n    }\n    safe_strcpy(   masscan->output.rotate.directory,\n             sizeof(masscan->output.rotate.directory),\n             value);\n    /* strip trailing slashes */\n    p = masscan->output.rotate.directory;\n    while (*p && (p[strlen(p)-1] == '/' || p[strlen(p)-1] == '\\\\')) /* Fix for #561 */\n        p[strlen(p)-1] = '\\0';\n    return CONF_OK;\n}\nstatic int SET_rotate_offset(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    /* Time offset, otherwise output files are aligned to nearest time\n     * interval, e.g. at the start of the hour for \"hourly\" */\n    if (masscan->echo) {\n        if (masscan->output.rotate.offset || masscan->echo_all)\n            fprintf(masscan->echo, \"rotate-offset = %u\\n\", masscan->output.rotate.offset);\n        return 0;\n    }\n    masscan->output.rotate.offset = (unsigned)parseTime(value);\n    return CONF_OK;\n}\nstatic int SET_rotate_filesize(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->output.rotate.filesize || masscan->echo_all)\n            fprintf(masscan->echo, \"rotate-size = %\" PRIu64 \"\\n\", masscan->output.rotate.filesize);\n        return 0;\n    }\n    masscan->output.rotate.filesize = parseSize(value);\n    return CONF_OK;\n    \n}\n\nstatic int SET_script(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if ((masscan->scripting.name && masscan->scripting.name[0]) || masscan->echo_all)\n            fprintf(masscan->echo, \"script = %s\\n\", masscan->scripting.name);\n        return 0;\n    }\n    if (value && value[0])\n        masscan->is_scripting = 1;\n    else\n        masscan->is_scripting = 0;\n    \n    if (masscan->scripting.name)\n        free(masscan->scripting.name);\n    \n    masscan->scripting.name = strdup(value);\n    \n    return CONF_OK;\n}\n\n\nstatic int SET_seed(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        fprintf(masscan->echo, \"seed = %\" PRIu64 \"\\n\", masscan->seed);\n        return 0;\n    }\n    if (EQUALS(\"time\", value))\n        masscan->seed = time(0);\n    else\n        masscan->seed = parseInt(value);\n    return CONF_OK;\n}\n\nstatic int SET_space(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    UNUSEDPARM(value);\n    if (masscan->echo) {\n        fprintf(masscan->echo, \"\\n\");\n        return 0;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_shard(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned one = 0;\n    unsigned of = 0;\n\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->shard.of > 0  || masscan->echo_all)\n            fprintf(masscan->echo, \"shard = %u/%u\\n\", masscan->shard.one, masscan->shard.of);\n        return 0;\n    }\n    while (isdigit(*value))\n        one = one*10 + (*(value++)) - '0';\n    while (ispunct(*value))\n        value++;\n    while (isdigit(*value))\n        of = of*10 + (*(value++)) - '0';\n    \n    if (one < 1) {\n        LOG(0, \"FAIL: shard index can't be zero\\n\");\n        LOG(0, \"hint   it goes like 1/4 2/4 3/4 4/4\\n\");\n        return CONF_ERR;\n    }\n    if (one > of) {\n        LOG(0, \"FAIL: shard spec is wrong\\n\");\n        LOG(0, \"hint   it goes like 1/4 2/4 3/4 4/4\\n\");\n        return CONF_ERR;\n    }\n    masscan->shard.one = one;\n    masscan->shard.of = of;\n    return CONF_OK;\n}\n\nstatic int SET_output_stylesheet(struct Masscan *masscan, const char *name, const char *value)\n{\n    UNUSEDPARM(name);\n    if (masscan->echo) {\n        if (masscan->output.stylesheet[0] || masscan->echo_all)\n            fprintf(masscan->echo, \"stylesheet = %s\\n\", masscan->output.stylesheet);\n        return 0;\n    }\n    \n    if (masscan->output.format == 0)\n        masscan->output.format = Output_XML;\n    \n    safe_strcpy(masscan->output.stylesheet, sizeof(masscan->output.stylesheet), value);\n    return CONF_OK;\n}\n\nstatic int SET_topports(struct Masscan *masscan, const char *name, const char *value)\n{\n    unsigned default_value = 20;\n\n    if (masscan->echo) {\n        /* don't echo: this instead triggers filling the `--port`\n         * list, so the ports themselves will be echoed, not this\n         * parameter */\n        return 0;\n    }\n\n    if (value == 0 || value[0] == '\\0') {\n        /* can be specified by itself on the command-line, alone\n         * without a following parameter */\n        /* ex: `--top-ports` */\n        masscan->top_ports = default_value;\n    } else if (isBoolean(value)) {\n        /* ex: `--top-ports enable` */\n        if (parseBoolean(value))\n            masscan->top_ports = default_value;\n        else\n            masscan->top_ports = 0;\n    } else if (isInteger(value)) {\n        /* ex: `--top-ports 5` */\n        uint64_t num = parseInt(value);\n        masscan->top_ports = (unsigned)num;\n    } else {\n        fprintf(stderr, \"[-] %s: bad value: %s\\n\", name, value);\n        return CONF_ERR;\n    }\n    return CONF_OK;\n}\n\nstatic int SET_tcp_mss(struct Masscan *masscan, const char *name, const char *value)\n{\n    /* h/t @IvreRocks */\n    static const unsigned default_mss = 1460;\n\n    if (masscan->echo) {\n        if (masscan->templ_opts) {\n            switch (masscan->templ_opts->tcp.is_mss) {\n                case Default:\n                    break;\n                case Add:\n                    if (masscan->templ_opts->tcp.mss == default_mss)\n                        fprintf(masscan->echo, \"tcp-mss = %s\\n\", \"enable\");\n                    else\n                        fprintf(masscan->echo, \"tcp-mss = %u\\n\",\n                                masscan->templ_opts->tcp.mss);\n                    break;\n                case Remove:\n                    fprintf(masscan->echo, \"tcp-mss = %s\\n\", \"disable\");\n                    break;\n                default:\n                    break;\n            }\n        }\n        return 0;\n    }\n\n    if (masscan->templ_opts == NULL)\n        masscan->templ_opts = calloc(1, sizeof(*masscan->templ_opts));\n\n    if (value == 0 || value[0] == '\\0') {\n        /* no following parameter, so interpret this to mean \"enable\" */\n        masscan->templ_opts->tcp.is_mss = Add;\n        masscan->templ_opts->tcp.mss = default_mss; /* 1460 */\n    } else if (isBoolean(value)) {\n        /* looking for \"enable\" or \"disable\", but any boolean works,\n         * like \"true/false\" or \"off/on\" */\n        if (parseBoolean(value)) {\n            masscan->templ_opts->tcp.is_mss = Add;\n            masscan->templ_opts->tcp.mss = default_mss; /* 1460 */\n        } else\n            masscan->templ_opts->tcp.is_mss = Remove;\n    } else if (isInteger(value)) {\n        /* A specific number was specified */\n        uint64_t num = parseInt(value);\n        if (num >= 0x10000)\n            goto fail;\n        masscan->templ_opts->tcp.is_mss = Add;\n        masscan->templ_opts->tcp.mss = (unsigned)num;\n    } else\n        goto fail;\n\n    return CONF_OK;\nfail:\n    fprintf(stderr, \"[-] %s: bad value: %s\\n\", name, value);\n    return CONF_ERR;\n}\n\nstatic int SET_tcp_wscale(struct Masscan *masscan, const char *name, const char *value)\n{\n    static const unsigned default_value = 3;\n\n    if (masscan->echo) {\n        if (masscan->templ_opts) {\n            switch (masscan->templ_opts->tcp.is_wscale) {\n                case Default:\n                    break;\n                case Add:\n                    if (masscan->templ_opts->tcp.wscale == default_value)\n                        fprintf(masscan->echo, \"tcp-wscale = %s\\n\", \"enable\");\n                    else\n                        fprintf(masscan->echo, \"tcp-wscale = %u\\n\",\n                                masscan->templ_opts->tcp.wscale);\n                    break;\n                case Remove:\n                    fprintf(masscan->echo, \"tcp-wscale = %s\\n\", \"disable\");\n                    break;\n                default:\n                    break;\n            }\n        }\n        return 0;\n    }\n\n    if (masscan->templ_opts == NULL)\n        masscan->templ_opts = calloc(1, sizeof(*masscan->templ_opts));\n\n    if (value == 0 || value[0] == '\\0') {\n        masscan->templ_opts->tcp.is_wscale = Add;\n        masscan->templ_opts->tcp.wscale = default_value;\n    } else if (isBoolean(value)) {\n        if (parseBoolean(value)) {\n            masscan->templ_opts->tcp.is_wscale = Add;\n            masscan->templ_opts->tcp.wscale = default_value;\n        } else\n            masscan->templ_opts->tcp.is_wscale = Remove;\n    } else if (isInteger(value)) {\n        uint64_t num = parseInt(value);\n        if (num >= 255)\n            goto fail;\n        masscan->templ_opts->tcp.is_wscale = Add;\n        masscan->templ_opts->tcp.wscale = (unsigned)num;\n    } else\n        goto fail;\n\n    return CONF_OK;\nfail:\n    fprintf(stderr, \"[-] %s: bad value: %s\\n\", name, value);\n    return CONF_ERR;\n}\n\nstatic int SET_tcp_tsecho(struct Masscan *masscan, const char *name, const char *value)\n{\n    static const unsigned default_value = 0x12345678;\n\n    if (masscan->echo) {\n        if (masscan->templ_opts) {\n            switch (masscan->templ_opts->tcp.is_tsecho) {\n                case Default:\n                    break;\n                case Add:\n                    if (masscan->templ_opts->tcp.tsecho == default_value)\n                        fprintf(masscan->echo, \"tcp-tsecho = %s\\n\", \"enable\");\n                    else\n                        fprintf(masscan->echo, \"tcp-tsecho = %u\\n\",\n                                masscan->templ_opts->tcp.tsecho);\n                    break;\n                case Remove:\n                    fprintf(masscan->echo, \"tcp-tsecho = %s\\n\", \"disable\");\n                    break;\n                default:\n                    break;\n            }\n        }\n        return 0;\n    }\n\n    if (masscan->templ_opts == NULL)\n        masscan->templ_opts = calloc(1, sizeof(*masscan->templ_opts));\n\n    if (value == 0 || value[0] == '\\0') {\n        masscan->templ_opts->tcp.is_tsecho = Add;\n        masscan->templ_opts->tcp.tsecho = default_value;\n    } else if (isBoolean(value)) {\n        if (parseBoolean(value)) {\n            masscan->templ_opts->tcp.is_tsecho = Add;\n            masscan->templ_opts->tcp.tsecho = default_value;\n        } else\n            masscan->templ_opts->tcp.is_tsecho = Remove;\n    } else if (isInteger(value)) {\n        uint64_t num = parseInt(value);\n        if (num >= 255)\n            goto fail;\n        masscan->templ_opts->tcp.is_tsecho = Add;\n        masscan->templ_opts->tcp.tsecho = (unsigned)num;\n    } else\n        goto fail;\n\n    return CONF_OK;\nfail:\n    fprintf(stderr, \"[-] %s: bad value: %s\\n\", name, value);\n    return CONF_ERR;\n}\n\nstatic int SET_tcp_sackok(struct Masscan *masscan, const char *name, const char *value)\n{\n    if (masscan->echo) {\n        if (masscan->templ_opts) {\n            switch (masscan->templ_opts->tcp.is_sackok) {\n                case Default:\n                    break;\n                case Add:\n                    fprintf(masscan->echo, \"tcp-sackok = %s\\n\", \"enable\");\n                    break;\n                case Remove:\n                    fprintf(masscan->echo, \"tcp-sackok = %s\\n\", \"disable\");\n                    break;\n                default:\n                    break;\n            }\n        }\n        return 0;\n    }\n\n    if (masscan->templ_opts == NULL)\n        masscan->templ_opts = calloc(1, sizeof(*masscan->templ_opts));\n\n    if (value == 0 || value[0] == '\\0') {\n        masscan->templ_opts->tcp.is_sackok = Add;\n    } else if (isBoolean(value)) {\n        if (parseBoolean(value)) {\n            masscan->templ_opts->tcp.is_sackok = Add;\n        } else\n            masscan->templ_opts->tcp.is_sackok = Remove;\n    } else if (isInteger(value)) {\n        if (parseInt(value) != 0)\n            masscan->templ_opts->tcp.is_sackok = Add;\n    } else\n        goto fail;\n\n    return CONF_OK;\nfail:\n    fprintf(stderr, \"[-] %s: bad value: %s\\n\", name, value);\n    return CONF_ERR;\n}\n\n\nstatic int SET_debug_tcp(struct Masscan *masscan, const char *name, const char *value) {\n    extern int is_tcp_debug; /* global */\n    UNUSEDPARM(name);\n    UNUSEDPARM(masscan);\n\n    if (value == 0 || value[0] == '\\0')\n        is_tcp_debug = 1;\n    else\n        is_tcp_debug = parseBoolean(value);\n    return CONF_OK;\n}\n\n\n\nstruct ConfigParameter {\n    const char *name;\n    SET_PARAMETER set;\n    unsigned flags;\n    const char *alts[6];\n};\nenum {F_NONE, F_BOOL=1, F_NUMABLE=2};\nstruct ConfigParameter config_parameters[] = {\n    {\"resume-index\",    SET_resume_index,       0,      {0}},\n    {\"resume-count\",    SET_resume_count,       0,      {0}},\n    {\"seed\",            SET_seed,               0,      {0}},\n    {\"arpscan\",         SET_arpscan,            F_BOOL, {\"arp\",0}},\n    {\"randomize-hosts\", SET_randomize_hosts,    F_BOOL, {0}},\n    {\"rate\",            SET_rate,               0,      {\"max-rate\",0}},\n    {\"shard\",           SET_shard,              0,      {\"shards\",0}},\n    {\"banners\",         SET_banners,            F_BOOL, {\"banner\",0}}, /* --banners */\n    {\"rawudp\",          SET_banners_rawudp,     F_BOOL, {\"rawudp\",0}}, /* --rawudp */\n    {\"nobanners\",       SET_nobanners,          F_BOOL, {\"nobanner\",0}},\n    {\"retries\",         SET_retries,            0,      {\"retry\", \"max-retries\", \"max-retry\", 0}},\n    {\"noreset\",         SET_noreset,            F_BOOL, {0}},\n    {\"nmap-payloads\",   SET_nmap_payloads,      0,      {\"nmap-payload\",0}},\n    {\"nmap-service-probes\",SET_nmap_service_probes, 0,  {\"nmap-service-probe\",0}},\n    {\"offline\",         SET_offline,            F_BOOL, {\"notransmit\", \"nosend\", \"dry-run\", 0}},\n    {\"pcap-filename\",   SET_pcap_filename,      0,      {\"pcap\",0}},\n    {\"pcap-payloads\",   SET_pcap_payloads,      0,      {\"pcap-payload\",0}},\n    {\"hello\",           SET_hello,              0,      {0}},\n    {\"hello-file\",      SET_hello_file,         0,      {\"hello-filename\",0}},\n    {\"hello-string\",    SET_hello_string,       0,      {0}},\n    {\"hello-timeout\",   SET_hello_timeout,      0,      {0}},\n    {\"http-cookie\",     SET_http_cookie,        0,      {0}},\n    {\"http-header\",     SET_http_header,        0,      {\"http-field\", 0}},\n    {\"http-method\",     SET_http_method,        0,      {0}},\n    {\"http-version\",    SET_http_version,       0,      {0}},\n    {\"http-url\",        SET_http_url,           0,      {\"http-uri\",0}},\n    {\"http-user-agent\", SET_http_user_agent,    0,      {\"http-useragent\",0}},\n    {\"http-host\",       SET_http_host,          0,      {0}},\n    {\"http-payload\",    SET_http_payload,       0,      {0}},\n    {\"ndjson-status\",   SET_status_ndjson,      F_BOOL, {\"status-ndjson\", 0}},\n    {\"json-status\",     SET_status_json,        F_BOOL, {\"status-json\", 0}},\n    {\"min-packet\",      SET_min_packet,         0,      {\"min-pkt\",0}},\n    {\"capture\",         SET_capture,            0,      {0}},\n    {\"nocapture\",       SET_capture,            0,      {\"no-capture\", 0}},\n    {\"SPACE\",           SET_space,              0,      {0}},\n    {\"output-filename\", SET_output_filename,    0,      {\"output-file\",0}},\n    {\"output-format\",   SET_output_format,      0,      {0}},\n    {\"output-show\",     SET_output_show,        0,      {\"output-status\", \"show\",0}},\n    {\"output-noshow\",   SET_output_noshow,      0,      {\"noshow\",0}},\n    {\"output-show-open\",SET_output_show_open,   F_BOOL, {\"open\", \"open-only\", 0}},\n    {\"output-append\",   SET_output_append,      0,      {\"append-output\",0}},\n    {\"rotate\",          SET_rotate_time,        0,      {\"output-rotate\", \"rotate-output\", \"rotate-time\", 0}},\n    {\"rotate-dir\",      SET_rotate_directory,   0,      {\"output-rotate-dir\", \"rotate-directory\", 0}},\n    {\"rotate-offset\",   SET_rotate_offset,      0,      {\"output-rotate-offset\", 0}},\n    {\"rotate-size\",     SET_rotate_filesize,    0,      {\"output-rotate-filesize\", \"rotate-filesize\", 0}},\n    {\"stylesheet\",      SET_output_stylesheet,  0,      {0}},\n    {\"script\",          SET_script,             0,      {0}},\n    {\"SPACE\",           SET_space,              0,      {0}},\n    {\"tcp-mss\",         SET_tcp_mss,            F_NUMABLE, {\"tcpmss\",0}},\n    {\"tcp-wscale\",      SET_tcp_wscale,         F_NUMABLE, {0}},\n    {\"tcp-tsecho\",      SET_tcp_tsecho,         F_NUMABLE, {0}},\n    {\"tcp-sackok\",      SET_tcp_sackok,         F_BOOL, {0}},\n    {\"top-ports\",       SET_topports,           F_NUMABLE, {\"top-port\",0}},\n\n    {\"debug-tcp\",       SET_debug_tcp,          F_BOOL, {\"tcp-debug\", 0}},\n    {0}\n};\n\n/***************************************************************************\n * Called either from the \"command-line\" parser when it sees a --param,\n * or from the \"config-file\" parser for normal options.\n ***************************************************************************/\nvoid\nmasscan_set_parameter(struct Masscan *masscan,\n                      const char *name, const char *value)\n{\n    unsigned index = ARRAY(name);\n    if (index >= 65536) {\n        fprintf(stderr, \"%s: bad index\\n\", name);\n        exit(1);\n    }\n    \n    /*\n     * NEW:\n     * Go through configured list of parameters\n     */\n    {\n        size_t i;\n        \n        for (i=0; config_parameters[i].name; i++) {\n            if (EQUALS(config_parameters[i].name, name)) {\n                config_parameters[i].set(masscan, name, value);\n                return;\n            } else {\n                size_t j;\n                for (j=0; config_parameters[i].alts[j]; j++) {\n                    if (EQUALS(config_parameters[i].alts[j], name)) {\n                        config_parameters[i].set(masscan, name, value);\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    /*\n     * OLD:\n     * Configure the old parameters, the ones we don't have in the new config\n     * system yet (see the NEW part above).\n     * TODO: transition all these old params to the new system\n     */\n    if (EQUALS(\"conf\", name) || EQUALS(\"config\", name)) {\n        masscan_read_config_file(masscan, value);\n    } else if (EQUALS(\"adapter\", name) || EQUALS(\"if\", name) || EQUALS(\"interface\", name)) {\n        if (masscan->nic[index].ifname[0]) {\n            fprintf(stderr, \"CONF: overwriting \\\"adapter=%s\\\"\\n\", masscan->nic[index].ifname);\n        }\n        if (masscan->nic_count < index + 1)\n            masscan->nic_count = index + 1;\n        snprintf(  masscan->nic[index].ifname,\n                    sizeof(masscan->nic[index].ifname),\n                    \"%s\",\n                    value);\n\n    }\n    else if (EQUALS(\"adapter-ip\", name) || EQUALS(\"source-ip\", name)\n             || EQUALS(\"source-address\", name) || EQUALS(\"spoof-ip\", name)\n             || EQUALS(\"spoof-address\", name) || EQUALS(\"src-ip\", name)) {\n        /* Send packets FROM this IP address */\n        struct Range range;\n        struct Range6 range6;\n        int err;\n\n        /* Grab the next IPv4 or IPv6 range */\n        err = massip_parse_range(value, 0, 0, &range, &range6);\n        switch (err) {\n        case Ipv4_Address:\n            /* If more than one IP address given, make the range is\n             * an even power of two (1, 2, 4, 8, 16, ...) */\n            if (!is_power_of_two((uint64_t)range.end - range.begin + 1)) {\n                LOG(0, \"FAIL: range must be even power of two: %s=%s\\n\",\n                        name, value);\n                exit(1);\n            }\n            masscan->nic[index].src.ipv4.first = range.begin;\n            masscan->nic[index].src.ipv4.last = range.end;\n            masscan->nic[index].src.ipv4.range = range.end - range.begin + 1;\n            break;\n        case Ipv6_Address:\n            masscan->nic[index].src.ipv6.first = range6.begin;\n            masscan->nic[index].src.ipv6.last = range6.end;\n            masscan->nic[index].src.ipv6.range = 1; /* TODO: add support for more than one source */\n            break;\n        default:\n            LOG(0, \"FAIL: bad source IP address: %s=%s\\n\",\n                    name, value);\n            LOG(0, \"hint   addresses look like \\\"192.168.1.23\\\" or \\\"2001:db8:1::1ce9\\\".\\n\");\n            exit(1);\n        }\n\n\n\n    } else if (EQUALS(\"adapter-port\", name) || EQUALS(\"source-port\", name)\n               || EQUALS(\"src-port\", name)) {\n        /* Send packets FROM this port number */\n        unsigned is_error = 0;\n        struct RangeList ports = {0};\n        memset(&ports, 0, sizeof(ports));\n\n        rangelist_parse_ports(&ports, value, &is_error, 0);\n\n        /* Check if there was an error in parsing */\n        if (is_error) {\n            LOG(0, \"FAIL: bad source port specification: %s\\n\",\n                    name);\n            exit(1);\n        }\n\n        /* Only allow one range of ports */\n        if (ports.count != 1) {\n            LOG(0, \"FAIL: only one '%s' range may be specified, found %u ranges\\n\",\n                    name, ports.count);\n            exit(1);\n        }\n\n        /* verify range is even power of 2 (1, 2, 4, 8, 16, ...) */\n        if (!is_power_of_two(ports.list[0].end - ports.list[0].begin + 1)) {\n            LOG(0, \"FAIL: source port range must be even power of two: %s=%s\\n\",\n                    name, value);\n            exit(1);\n        }\n\n        masscan->nic[index].src.port.first = ports.list[0].begin;\n        masscan->nic[index].src.port.last = ports.list[0].end;\n        masscan->nic[index].src.port.range = ports.list[0].end - ports.list[0].begin + 1;\n    } else if (EQUALS(\"adapter-mac\", name) || EQUALS(\"spoof-mac\", name)\n               || EQUALS(\"source-mac\", name) || EQUALS(\"src-mac\", name)) {\n        /* Send packets FROM this MAC address */\n        macaddress_t source_mac;\n        int err;\n\n        err = parse_mac_address(value, &source_mac);\n        if (err) {\n            LOG(0, \"[-] CONF: bad MAC address: %s = %s\\n\", name, value);\n            return;\n        }\n\n        /* Check for duplicates */\n        if (macaddress_is_equal(masscan->nic[index].source_mac, source_mac)) {\n            /* suppresses warning message about duplicate MAC addresses if\n             * they are in fact the same */\n            return;\n        }\n\n        /* Warn if we are overwriting a Mac address */\n        if (masscan->nic[index].my_mac_count != 0) {\n            ipaddress_formatted_t fmt1 = macaddress_fmt(masscan->nic[index].source_mac);\n            ipaddress_formatted_t fmt2 = macaddress_fmt(source_mac);\n            LOG(0, \"[-] WARNING: overwriting MAC address, was %s, now %s\\n\",\n                fmt1.string,\n                fmt2.string);\n        }\n\n        masscan->nic[index].source_mac = source_mac;\n        masscan->nic[index].my_mac_count = 1;\n    }\n    else if (EQUALS(\"router-mac\", name) || EQUALS(\"router\", name)\n             || EQUALS(\"dest-mac\", name) || EQUALS(\"destination-mac\", name)\n             || EQUALS(\"dst-mac\", name) || EQUALS(\"target-mac\", name)) {\n        macaddress_t router_mac;\n        int err;\n        \n        err = parse_mac_address(value, &router_mac);\n        if (err) {\n            fprintf(stderr, \"[-] CONF: bad MAC address: %s = %s\\n\", name, value);\n            return;\n        }\n\n        masscan->nic[index].router_mac_ipv4 = router_mac;\n        masscan->nic[index].router_mac_ipv6 = router_mac;\n    }\n    else if (EQUALS(\"router-mac-ipv4\", name) || EQUALS(\"router-ipv4\", name)) {\n        macaddress_t router_mac;\n        int err;\n        \n        err = parse_mac_address(value, &router_mac);\n        if (err) {\n            fprintf(stderr, \"[-] CONF: bad MAC address: %s = %s\\n\", name, value);\n            return;\n        }\n\n        masscan->nic[index].router_mac_ipv4 = router_mac;\n    }\n    else if (EQUALS(\"router-mac-ipv6\", name) || EQUALS(\"router-ipv6\", name)) {\n        macaddress_t router_mac;\n        int err;\n        \n        err = parse_mac_address(value, &router_mac);\n        if (err) {\n            fprintf(stderr, \"[-] CONF: bad MAC address: %s = %s\\n\", name, value);\n            return;\n        }\n\n        masscan->nic[index].router_mac_ipv6 = router_mac;\n    }\n    else if (EQUALS(\"router-ip\", name)) {\n        /* Send packets FROM this IP address */\n        struct Range range;\n\n        range = range_parse_ipv4(value, 0, 0);\n\n        /* Check for bad format */\n        if (range.begin != range.end) {\n            LOG(0, \"FAIL: bad source IPv4 address: %s=%s\\n\",\n                    name, value);\n            LOG(0, \"hint   addresses look like \\\"19.168.1.23\\\"\\n\");\n            exit(1);\n        }\n\n        masscan->nic[index].router_ip = range.begin;\n    }\n    else if (EQUALS(\"udp-ports\", name) || EQUALS(\"udp-port\", name)) {\n        unsigned is_error = 0;\n        masscan->scan_type.udp = 1;\n        rangelist_parse_ports(&masscan->targets.ports, value, &is_error, Templ_UDP);\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    }\n    else if (EQUALS(\"oprotos\", name) || EQUALS(\"oproto\", name)) {\n        unsigned is_error = 0;\n        masscan->scan_type.oproto = 1;\n        rangelist_parse_ports(&masscan->targets.ports, value, &is_error, Templ_Oproto_first);\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    }\n    else if (EQUALS(\"tcp-ports\", name) || EQUALS(\"tcp-port\", name)) {\n        unsigned is_error = 0;\n        masscan->scan_type.tcp = 1;\n        rangelist_parse_ports(&masscan->targets.ports, value, &is_error, Templ_TCP);\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    }\n    else if (EQUALS(\"ports\", name) || EQUALS(\"port\", name)\n             || EQUALS(\"dst-port\", name) || EQUALS(\"dest-port\", name)\n             || EQUALS(\"destination-port\", name)\n             || EQUALS(\"target-port\", name)) {\n        unsigned defaultrange = 0;\n        int err;\n\n        if (masscan->scan_type.udp)\n            defaultrange = Templ_UDP;\n        else if (masscan->scan_type.sctp)\n            defaultrange = Templ_SCTP;\n        \n        err = massip_add_port_string(&masscan->targets, value, defaultrange);\n        if (err) {\n            fprintf(stderr, \"[-] FAIL: bad target port: %s\\n\", value);\n            fprintf(stderr, \"    Hint: a port is a number [0..65535]\\n\");\n            exit(1);\n        }\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;    }\n    else if (EQUALS(\"banner-types\", name) || EQUALS(\"banner-type\", name)\n             || EQUALS(\"banner-apps\", name) || EQUALS(\"banner-app\", name)\n           ) {\n        enum ApplicationProtocol app;\n        \n        app = masscan_string_to_app(value);\n        \n        if (app) {\n            rangelist_add_range(&masscan->banner_types, app, app);\n            rangelist_sort(&masscan->banner_types);\n        } else {\n            LOG(0, \"FAIL: bad banner app: %s\\n\", value);\n            fprintf(stderr, \"err\\n\");\n            exit(1);\n        }\n    } else if (EQUALS(\"exclude-ports\", name) || EQUALS(\"exclude-port\", name)) {\n        unsigned defaultrange = 0;\n        int err;\n\n        if (masscan->scan_type.udp)\n            defaultrange = Templ_UDP;\n        else if (masscan->scan_type.sctp)\n            defaultrange = Templ_SCTP;\n        \n        err = massip_add_port_string(&masscan->exclude, value, defaultrange);\n        if (err) {\n            fprintf(stderr, \"[-] FAIL: bad exclude port: %s\\n\", value);\n            fprintf(stderr, \"    Hint: a port is a number [0..65535]\\n\");\n            exit(1);\n        }\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    } else if (EQUALS(\"bpf\", name)) {\n        size_t len = strlen(value) + 1;\n        if (masscan->bpf_filter)\n            free(masscan->bpf_filter);\n        masscan->bpf_filter = MALLOC(len);\n        memcpy(masscan->bpf_filter, value, len);\n    } else if (EQUALS(\"ping\", name) || EQUALS(\"ping-sweep\", name)) {\n        /* Add ICMP ping request */\n        struct Range range;\n        range.begin = Templ_ICMP_echo;\n        range.end = Templ_ICMP_echo;\n        rangelist_add_range(&masscan->targets.ports, range.begin, range.end);\n        rangelist_sort(&masscan->targets.ports);\n        masscan->scan_type.ping = 1;\n        LOG(5, \"--ping\\n\");\n    } else if (EQUALS(\"range\", name) || EQUALS(\"ranges\", name)\n               || EQUALS(\"ip\", name) || EQUALS(\"ipv4\", name)\n               || EQUALS(\"dst-ip\", name) || EQUALS(\"dest-ip\", name)\n               || EQUALS(\"destination-ip\", name)\n               || EQUALS(\"target-ip\", name)) {\n        int err;\n        err = massip_add_target_string(&masscan->targets, value);\n        if (err) {\n            fprintf(stderr, \"ERROR: bad IP address/range: %s\\n\", value);\n        }\n\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    }\n    else if (\n                EQUALS(\"exclude\", name) ||\n                EQUALS(\"exclude-range\", name) ||\n                EQUALS(\"exclude-ranges\", name) ||\n                EQUALS(\"exclude-ip\", name) ||\n                EQUALS(\"exclude-ipv4\", name)\n                ) {\n        int err;\n        err = massip_add_target_string(&masscan->exclude, value);\n        if (err) {\n            fprintf(stderr, \"ERROR: bad exclude address/range: %s\\n\", value);\n        }\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    } else if (EQUALS(\"badsum\", name)) {\n        masscan->nmap.badsum = 1;\n    } else if (EQUALS(\"banner1\", name)) {\n        banner1_test(value);\n        exit(1);\n    } else if (EQUALS(\"blackrock-rounds\", name)) {\n        masscan->blackrock_rounds = (unsigned)parseInt(value);\n    } else if (EQUALS(\"connection-timeout\", name) || EQUALS(\"tcp-timeout\", name)) {\n        /* The timeout for banners TCP connections */\n        masscan->tcp_connection_timeout = (unsigned)parseInt(value);\n    } else if (EQUALS(\"datadir\", name)) {\n        safe_strcpy(masscan->nmap.datadir, sizeof(masscan->nmap.datadir), value);\n    } else if (EQUALS(\"data-length\", name)) {\n        unsigned x = (unsigned)strtoul(value, 0, 0);\n        if (x >= 1514 - 14 - 40) {\n            fprintf(stderr, \"error: %s=<n>: expected number less than 1500\\n\", name);\n        } else {\n            masscan->nmap.data_length = x;\n        }\n    } else if (EQUALS(\"debug\", name)) {\n        if (EQUALS(\"if\", value)) {\n            masscan->op = Operation_DebugIF;\n        }\n    } else if (EQUALS(\"dns-servers\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: DNS lookups too synchronous\\n\",\n                name);\n        exit(1);\n    } else if (EQUALS(\"echo\", name)) {\n        masscan->op = Operation_Echo;\n    } else if (EQUALS(\"echo-all\", name)) {\n        masscan->op = Operation_EchoAll;\n    } else if (EQUALS(\"echo-cidr\", name)) {\n        masscan->op = Operation_EchoCidr;\n    } else if (EQUALS(\"excludefile\", name)) {\n        unsigned count1 = masscan->exclude.ipv4.count;\n        unsigned count2;\n        int err;\n        const char *filename = value;\n\n        LOG(1, \"EXCLUDING: %s\\n\", value);\n        err = massip_parse_file(&masscan->exclude, filename);\n        if (err) {\n            LOG(0, \"[-] FAIL: error reading from exclude file\\n\");\n            exit(1);\n        }\n\n        /* Detect if this file has made any change, otherwise don't print\n         * a message */\n        count2 = masscan->exclude.ipv4.count;\n        if (count2 - count1)\n            fprintf(stderr, \"%s: excluding %u ranges from file\\n\",\n                value, count2 - count1);\n    } else if (EQUALS(\"heartbleed\", name)) {\n        masscan->is_heartbleed = 1;\n        masscan_set_parameter(masscan, \"no-capture\", \"cert\");\n        masscan_set_parameter(masscan, \"no-capture\", \"heartbleed\");\n        masscan_set_parameter(masscan, \"banners\", \"true\");\n    } else if (EQUALS(\"ticketbleed\", name)) {\n        masscan->is_ticketbleed = 1;\n        masscan_set_parameter(masscan, \"no-capture\", \"cert\");\n        masscan_set_parameter(masscan, \"no-capture\", \"ticketbleed\");\n        masscan_set_parameter(masscan, \"banners\", \"true\");\n    } else if (EQUALS(\"host-timeout\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: this is an asynchronous tool, so no timeouts\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"iflist\", name)) {\n        masscan->op = Operation_List_Adapters;\n    } else if (EQUALS(\"includefile\", name)) {\n        int err;\n        const char *filename = value;\n\n        err = massip_parse_file(&masscan->targets, filename);\n        if (err) {\n            LOG(0, \"[-] FAIL: error reading from include file\\n\");\n            exit(1);\n        }\n        if (masscan->op == 0)\n            masscan->op = Operation_Scan;\n    } else if (EQUALS(\"infinite\", name)) {\n        masscan->is_infinite = 1;\n    } else if (EQUALS(\"interactive\", name)) {\n        masscan->output.is_interactive = 1;\n    } else if (EQUALS(\"nointeractive\", name)) {\n        masscan->output.is_interactive = 0;\n    } else if (EQUALS(\"status\", name)) {\n        masscan->output.is_status_updates = 1;\n    } else if (EQUALS(\"nostatus\", name)) {\n        masscan->output.is_status_updates = 0;\n    } else if (EQUALS(\"ip-options\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: maybe soon\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"log-errors\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: maybe soon\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"min-hostgroup\", name) || EQUALS(\"max-hostgroup\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: we randomize all the groups!\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"min-parallelism\", name) || EQUALS(\"max-parallelism\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: we all the parallel!\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"min-rtt-timeout\", name) || EQUALS(\"max-rtt-timeout\", name) || EQUALS(\"initial-rtt-timeout\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: we are asynchronous, so no timeouts, no RTT tracking!\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"min-rate\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported, we go as fast as --max-rate allows\\n\", name);\n        /* no exit here, since it's just info */\n    } else if (EQUALS(\"mtu\", name)) {\n        fprintf(stderr, \"nmap(%s): fragmentation not yet supported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"nmap\", name)) {\n        print_nmap_help();\n        exit(1);\n    } else if (EQUALS(\"osscan-limit\", name)) {\n        fprintf(stderr, \"nmap(%s): OS scanning unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"osscan-guess\", name)) {\n        fprintf(stderr, \"nmap(%s): OS scanning unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"packet-trace\", name) || EQUALS(\"trace-packet\", name)) {\n        masscan->nmap.packet_trace = 1;\n    } else if (EQUALS(\"privileged\", name) || EQUALS(\"unprivileged\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"pfring\", name)) {\n        masscan->is_pfring = 1;\n    } else if (EQUALS(\"port-ratio\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"readrange\", name) || EQUALS(\"readranges\", name)) {\n        masscan->op = Operation_ReadRange;\n    } else if (EQUALS(\"reason\", name)) {\n        masscan->output.is_reason = 1;\n    } else if (EQUALS(\"redis\", name)) {\n        struct Range range;\n        unsigned offset = 0;\n        unsigned max_offset = (unsigned)strlen(value);\n        unsigned port = 6379;\n\n        range = range_parse_ipv4(value, &offset, max_offset);\n        if ((range.begin == 0 && range.end == 0) || range.begin != range.end) {\n            LOG(0, \"FAIL:  bad redis IP address: %s\\n\", value);\n            exit(1);\n        }\n        if (offset < max_offset) {\n            while (offset < max_offset && isspace(value[offset]))\n                offset++;\n            if (offset+1 < max_offset && value[offset] == ':' && isdigit(value[offset+1]&0xFF)) {\n                port = (unsigned)strtoul(value+offset+1, 0, 0);\n                if (port > 65535 || port == 0) {\n                    LOG(0, \"FAIL: bad redis port: %s\\n\", value+offset+1);\n                    exit(1);\n                }\n            }\n        }\n\n        /* TODO: add support for connecting to IPv6 addresses here */\n        masscan->redis.ip.ipv4 = range.begin;\n        masscan->redis.ip.version = 4;\n\n        masscan->redis.port = port;\n        masscan->output.format = Output_Redis;\n        safe_strcpy(masscan->output.filename, \n                 sizeof(masscan->output.filename), \n                 \"<redis>\");\n    } else if(EQUALS(\"redis-pwd\", name)) {\n        masscan->redis.password = strdup(value);\n    } else if (EQUALS(\"release-memory\", name)) {\n        fprintf(stderr, \"nmap(%s): this is our default option\\n\", name);\n    } else if (EQUALS(\"resume\", name)) {\n        masscan_read_config_file(masscan, value);\n        masscan_set_parameter(masscan, \"output-append\", \"true\");\n    } else if (EQUALS(\"vuln\", name)) {\n        if (EQUALS(\"heartbleed\", value)) {\n            masscan_set_parameter(masscan, \"heartbleed\", \"true\");\n            return;\n\t\t} else if (EQUALS(\"ticketbleed\", value)) {\n            masscan_set_parameter(masscan, \"ticketbleed\", \"true\");\n            return;\n        } else if (EQUALS(\"poodle\", value) || EQUALS(\"sslv3\", value)) {\n            masscan->is_poodle_sslv3 = 1;\n            masscan_set_parameter(masscan, \"no-capture\", \"cert\");\n            masscan_set_parameter(masscan, \"banners\", \"true\");\n            return;\n        }\n        \n        if (!vulncheck_lookup(value)) {\n            fprintf(stderr, \"FAIL: vuln check '%s' does not exist\\n\", value);\n            fprintf(stderr, \"  hint: use '--vuln list' to list available scripts\\n\");\n            exit(1);\n        }\n        if (masscan->vuln_name != NULL) {\n            if (strcmp(masscan->vuln_name, value) == 0)\n                return; /* ok */\n            else {\n                fprintf(stderr, \"FAIL: only one vuln check supported at a time\\n\");\n                fprintf(stderr, \"  hint: '%s' is existing vuln check, '%s' is new vuln check\\n\",\n                        masscan->vuln_name, value);\n                exit(1);\n            }\n        }\n        \n        masscan->vuln_name = vulncheck_lookup(value)->name;\n    } else if (EQUALS(\"scan-delay\", name) || EQUALS(\"max-scan-delay\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported: we do timing VASTLY differently!\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"scanflags\", name)) {\n        fprintf(stderr, \"nmap(%s): TCP scan flags not yet supported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"sendq\", name) || EQUALS(\"sendqueue\", name)) {\n        masscan->is_sendq = 1;\n    } else if (EQUALS(\"send-eth\", name)) {\n        fprintf(stderr, \"nmap(%s): unnecessary, we always do --send-eth\\n\", name);\n    } else if (EQUALS(\"send-ip\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported, we only do --send-eth\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"selftest\", name) || EQUALS(\"self-test\", name) || EQUALS(\"regress\", name)) {\n        masscan->op = Operation_Selftest;\n        return;\n    } else if (EQUALS(\"benchmark\", name)) {\n        masscan->op = Operation_Benchmark;\n        return;\n    } else if (EQUALS(\"source-port\", name) || EQUALS(\"sourceport\", name)) {\n        masscan_set_parameter(masscan, \"adapter-port\", value);\n    } else if (EQUALS(\"nobacktrace\", name) || EQUALS(\"backtrace\", name)) {\n        ;\n    } else if (EQUALS(\"no-stylesheet\", name)) {\n        masscan->output.stylesheet[0] = '\\0';\n    } else if (EQUALS(\"system-dns\", name)) {\n        fprintf(stderr, \"nmap(%s): DNS lookups will never be supported by this code\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"top-ports\", name)) {\n        unsigned n = (unsigned)parseInt(value);\n        if (!isInteger(value))\n            n = 100;\n        LOG(2, \"top-ports = %u\\n\", n);\n        masscan->top_ports = n;\n    } else if (EQUALS(\"traceroute\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"test\", name)) {\n        if (EQUALS(\"csv\", value))\n            masscan->is_test_csv = 1;\n    } else if (EQUALS(\"notest\", name)) {\n        if (EQUALS(\"csv\", value))\n            masscan->is_test_csv = 0;\n    } else if (EQUALS(\"ttl\", name)) {\n        unsigned x = (unsigned)strtoul(value, 0, 0);\n        if (x >= 256) {\n            fprintf(stderr, \"error: %s=<n>: expected number less than 256\\n\", name);\n        } else {\n            masscan->nmap.ttl = x;\n        }\n    } else if (EQUALS(\"version\", name)) {\n        print_version();\n        exit(1);\n    } else if (EQUALS(\"version-intensity\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"version-light\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"version-all\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"version-trace\", name)) {\n        fprintf(stderr, \"nmap(%s): unsupported\\n\", name);\n        exit(1);\n    } else if (EQUALS(\"vlan\", name) || EQUALS(\"adapter-vlan\", name)) {\n        masscan->nic[index].is_vlan = 1;\n        masscan->nic[index].vlan_id = (unsigned)parseInt(value);\n    } else if (EQUALS(\"wait\", name)) {\n        if (EQUALS(\"forever\", value))\n            masscan->wait =  INT_MAX;\n        else\n            masscan->wait = (unsigned)parseInt(value);\n    } else if (EQUALS(\"webxml\", name)) {\n        masscan_set_parameter(masscan, \"stylesheet\", \"http://nmap.org/svn/docs/nmap.xsl\");\n    } else {\n        fprintf(stderr, \"CONF: unknown config option: %s=%s\\n\", name, value);\n        exit(1);\n    }\n}\n\nstatic bool\nis_numable(const char *name) {\n    size_t i;\n\n    for (i=0; config_parameters[i].name; i++) {\n        if (EQUALS(config_parameters[i].name, name)) {\n            return (config_parameters[i].flags & F_NUMABLE) == F_NUMABLE;\n        } else {\n            size_t j;\n            for (j=0; config_parameters[i].alts[j]; j++) {\n                if (EQUALS(config_parameters[i].alts[j], name)) {\n                    return (config_parameters[i].flags & F_NUMABLE) == F_NUMABLE;\n                }\n            }\n        }\n    }\n    return false;\n}\n\n/***************************************************************************\n * Command-line parsing code assumes every --parm is followed by a value.\n * This is a list of the parameters that don't follow the default.\n ***************************************************************************/\nstatic int\nis_singleton(const char *name)\n{\n    static const char *singletons[] = {\n        \"echo\", \"echo-all\", \"echo-cidr\", \"selftest\", \"self-test\", \"regress\",\n        \"benchmark\",\n        \"system-dns\", \"traceroute\", \"version\",\n        \"version-light\",\n        \"version-all\", \"version-trace\",\n        \"osscan-limit\", \"osscan-guess\",\n        \"badsum\", \"reason\", \"open\", \"open-only\",\n        \"packet-trace\", \"release-memory\",\n        \"log-errors\", \"append-output\", \"webxml\",\n        \"no-stylesheet\", \"heartbleed\", \"ticketbleed\",\n        \"send-eth\", \"send-ip\", \"iflist\",\n        \"nmap\", \"trace-packet\", \"pfring\", \"sendq\",\n        \"ping\", \"ping-sweep\", \"nobacktrace\", \"backtrace\",\n        \"infinite\", \"nointeractive\", \"interactive\", \"status\", \"nostatus\",\n        \"read-range\", \"read-ranges\", \"readrange\", \"read-ranges\",\n        0};\n    size_t i;\n\n    for (i=0; singletons[i]; i++) {\n        if (EQUALS(singletons[i], name))\n            return 1;\n    }\n    \n    for (i=0; config_parameters[i].name; i++) {\n        if (EQUALS(config_parameters[i].name, name)) {\n            return (config_parameters[i].flags & F_BOOL) == F_BOOL;\n        } else {\n            size_t j;\n            for (j=0; config_parameters[i].alts[j]; j++) {\n                if (EQUALS(config_parameters[i].alts[j], name)) {\n                    return (config_parameters[i].flags & F_BOOL) == F_BOOL;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nmasscan_help()\n{\n    printf(\n\"usage: masscan [options] [<IP|RANGE>... -pPORT[,PORT...]]\\n\"\n\"MASSCAN is a fast port scanner. The primary input parameters are the\\n\"\n\"IP addresses/ranges you want to scan, and the port numbers. An example\\n\"\n\"is the following, which scans the 10.x.x.x network for web servers:\\n\"\n\"\\n\"\n\"    masscan 10.0.0.0/8 -p80\\n\"\n\"\\n\"\n\"The program auto-detects network interface/adapter settings. If this\\n\"\n\"fails, you'll have to set these manually. The following is an\\n\"\n\"example of all the parameters that are needed:\\n\"\n\"\\n\"\n\"    --adapter-ip 192.168.10.123\\n\"\n\"    --adapter-mac 00-11-22-33-44-55\\n\"\n\"    --router-mac 66-55-44-33-22-11\\n\"\n\"\\n\"\n\"Parameters can be set either via the command-line or config-file. The\\n\"\n\"names are the same for both. Thus, the above adapter settings would\\n\"\n\"appear as follows in a configuration file:\\n\"\n\"\\n\"\n\"    adapter-ip = 192.168.10.123\\n\"\n\"    adapter-mac = 00-11-22-33-44-55\\n\"\n\"    router-mac = 66-55-44-33-22-11\\n\"\n\"\\n\"\n\"All single-dash parameters have a spelled out double-dash equivalent,\\n\"\n\"so '-p80' is the same as '--ports 80' (or 'ports = 80' in config file).\\n\"\n\"To use the config file, type:\\n\"\n\"\\n\"\n\"    masscan -c <filename>\\n\"\n\"\\n\"\n\"To generate a config-file from the current settings, use the --echo\\n\"\n\"option. This stops the program from actually running, and just echoes\\n\"\n\"the current configuration instead. This is a useful way to generate\\n\"\n\"your first config file, or see a list of parameters you didn't know\\n\"\n\"about. I suggest you try it now:\\n\"\n\"\\n\"\n\"    masscan -p1234 --echo\\n\"\n\"\\n\");\n    exit(1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nmasscan_load_database_files(struct Masscan *masscan)\n{\n    const char *filename;\n    \n    /*\n     * \"pcap-payloads\"\n     */\n    filename = masscan->payloads.pcap_payloads_filename;\n    if (filename) {\n        if (masscan->payloads.udp == NULL)\n            masscan->payloads.udp = payloads_udp_create();\n        if (masscan->payloads.oproto == NULL)\n            masscan->payloads.oproto = payloads_udp_create();\n\n        payloads_read_pcap(filename, masscan->payloads.udp, masscan->payloads.oproto);\n    }\n\n    /*\n     * `--nmap-payloads`\n     */\n    filename = masscan->payloads.nmap_payloads_filename;\n    if (filename) {\n        FILE *fp;\n        \n        fp = fopen(filename, \"rt\");\n        if (fp == NULL) {\n            fprintf(stderr, \"[-] FAIL: --nmap-payloads\\n\");\n            fprintf(stderr, \"[-] %s:%s\\n\", filename, strerror(errno));\n        } else {\n            if (masscan->payloads.udp == NULL)\n                masscan->payloads.udp = payloads_udp_create();\n            \n            payloads_udp_readfile(fp, filename, masscan->payloads.udp);\n            \n            fclose(fp);\n        }\n    }\n    \n    /*\n     * \"nmap-service-probes\"\n     */\n    filename = masscan->payloads.nmap_service_probes_filename;\n    if (filename) {\n        if (masscan->payloads.probes)\n            nmapserviceprobes_free(masscan->payloads.probes);\n        \n        masscan->payloads.probes = nmapserviceprobes_read_file(filename);\n    }\n}\n\n/***************************************************************************\n * Read the configuration from the command-line.\n * Called by 'main()' when starting up.\n ***************************************************************************/\nvoid\nmasscan_command_line(struct Masscan *masscan, int argc, char *argv[])\n{\n    int i;\n\n    for (i=1; i<argc; i++) {\n\n        /*\n         * --name=value\n         * --name:value\n         * --name value\n         */\n        if (argv[i][0] == '-' && argv[i][1] == '-') {\n            const char *argname = argv[i] + 2;\n\n            if (EQUALS(\"help\", argname)) {\n                masscan_help();\n                exit(1);\n            } else if (is_numable(argname)) {\n                /* May exist by itself like a bool or take an additional\n                 * numeric argument */\n                char name2[64];\n                const char *name = argname;\n                unsigned name_length;\n                const char *value;\n\n                /* Look for:\n                 * --name=value\n                 * --name:value */\n                value = strchr(argname, '=');\n                if (value == NULL)\n                    value = strchr(&argv[i][2], ':');\n                if (value) {\n                    name_length = (unsigned)(value - name);\n                } else {\n                    /* The next parameter contains the name */\n                    if (i+1 < argc) {\n                        value = argv[i+1];\n                        if (isInteger(value) || isBoolean(value))\n                            i++;\n                        else\n                            value = \"\";\n                    } else\n                        value = \"\";\n                    name_length = (unsigned)strlen(argname);\n                }\n\n                /* create a copy of the name */\n                if (name_length > sizeof(name2) - 1) {\n                    fprintf(stderr, \"%.*s: name too long\\n\", name_length, name);\n                    name_length = sizeof(name2) - 1;\n                }\n                memcpy(name2, name, name_length);\n                name2[name_length] = '\\0';\n\n                masscan_set_parameter(masscan, name2, value);\n            } else if (EQUALS(\"readscan\", argv[i]+2)) {\n                /* Read in a binary file instead of scanning the network*/\n                masscan->op = Operation_ReadScan;\n                \n                /* Default to reading banners */\n                masscan->is_banners = true;\n                masscan->is_banners_rawudp = true;\n\n                /* This option may be followed by many filenames, therefore,\n                 * skip forward in the argument list until the next\n                 * argument */\n                while (i+1 < argc && argv[i+1][0] != '-')\n                    i++;\n                continue;\n            } else {\n                char name2[64];\n                char *name = argv[i] + 2;\n                unsigned name_length;\n                const char *value;\n\n                value = strchr(&argv[i][2], '=');\n                if (value == NULL)\n                    value = strchr(&argv[i][2], ':');\n                if (value == NULL) {\n                    if (is_singleton(name))\n                        value = \"\";\n                    else\n                        value = argv[++i];\n                    name_length = (unsigned)strlen(name);\n                } else {\n                    name_length = (unsigned)(value - name);\n                    value++;\n                }\n\n                if (i >= argc) {\n                    fprintf(stderr, \"%.*s: empty parameter\\n\", name_length, name);\n                    break;\n                }\n\n                if (name_length > sizeof(name2) - 1) {\n                    fprintf(stderr, \"%.*s: name too long\\n\", name_length, name);\n                    name_length = sizeof(name2) - 1;\n                }\n\n                memcpy(name2, name, name_length);\n                name2[name_length] = '\\0';\n\n                masscan_set_parameter(masscan, name2, value);\n            }\n            continue;\n        }\n\n        /* For for a single-dash parameter */\n        if (argv[i][0] == '-') {\n            const char *arg;\n\n            switch (argv[i][1]) {\n            case '6':\n                /* Silently ignore this: IPv6 features enabled all the time */\n                break;\n            case 'A':\n                fprintf(stderr, \"nmap(%s): unsupported: this tool only does SYN scan\\n\", argv[i]);\n                exit(1);\n            case 'b':\n                fprintf(stderr, \"nmap(%s): FTP bounce scans will never be supported\\n\", argv[i]);\n                exit(1);\n            case 'c':\n                if (argv[i][2])\n                    arg = argv[i]+2;\n                else\n                    arg = argv[++i];\n                masscan_read_config_file(masscan, arg);\n                break;\n            case 'd': /* just do same as verbosity level */\n                {\n                    int v;\n                    for (v=1; argv[i][v] == 'd'; v++) {\n                        LOG_add_level(1);\n                    }\n                }\n                break;\n            case 'e':\n                if (argv[i][2])\n                    arg = argv[i]+2;\n                else\n                    arg = argv[++i];\n                masscan_set_parameter(masscan, \"adapter\", arg);\n                break;\n            case 'f':\n                fprintf(stderr, \"nmap(%s): fragmentation not yet supported\\n\", argv[i]);\n                exit(1);\n            case 'F':\n                fprintf(stderr, \"nmap(%s): unsupported, no slow/fast mode\\n\", argv[i]);\n                exit(1);\n            case 'g':\n                if (argv[i][2])\n                    arg = argv[i]+2;\n                else\n                    arg = argv[++i];\n                masscan_set_parameter(masscan, \"adapter-port\", arg);\n                break;\n            case 'h':\n            case '?':\n                masscan_usage();\n                break;\n            case 'i':\n                if (argv[i][3] == '\\0' && !isdigit(argv[i][2]&0xFF)) {\n                    /* This looks like an nmap option*/\n                    switch (argv[i][2]) {\n                    case 'L':\n                        masscan_set_parameter(masscan, \"includefile\", argv[++i]);\n                        break;\n                    case 'R':\n                        /* -iR in nmap makes it randomize addresses completely. Thus,\n                         * it's nearest equivalent is scanning the entire Internet range */\n                        masscan_set_parameter(masscan, \"include\", \"0.0.0.0/0\");\n                        break;\n                    default:\n                        fprintf(stderr, \"nmap(%s): unsupported option\\n\", argv[i]);\n                        exit(1);\n                    }\n\n                } else {\n                    if (argv[i][2])\n                        arg = argv[i]+2;\n                    else\n                        arg = argv[++i];\n\n                    masscan_set_parameter(masscan, \"adapter\", arg);\n                }\n                break;\n            case 'n':\n                /* This looks like an nmap option*/\n                /* Do nothing: this code never does DNS lookups anyway */\n                break;\n            case 'o': /* nmap output format */\n                switch (argv[i][2]) {\n                case 'A':\n                    masscan->output.format = Output_All;\n                    fprintf(stderr, \"nmap(%s): unsupported output format\\n\", argv[i]);\n                    exit(1);\n                    break;\n                case 'B':\n                    masscan->output.format = Output_Binary;\n                    break;\n                case 'D':\n                    masscan->output.format = Output_NDJSON;\n                    break;\n                case 'J':\n                    masscan->output.format = Output_JSON;\n                    break;\n                case 'N':\n                    masscan->output.format = Output_Nmap;\n                    fprintf(stderr, \"nmap(%s): unsupported output format\\n\", argv[i]);\n                    exit(1);\n                    break;\n                case 'X':\n                    masscan->output.format = Output_XML;\n                    break;\n                case 'R':\n                    masscan->output.format = Output_Redis;\n                    if (i+1 < argc && argv[i+1][0] != '-')\n                        masscan_set_parameter(masscan, \"redis\", argv[i+1]);\n                    break;\n                case 'S':\n                    masscan->output.format = Output_ScriptKiddie;\n                    fprintf(stderr, \"nmap(%s): unsupported output format\\n\", argv[i]);\n                    exit(1);\n                    break;\n                case 'G':\n                    masscan->output.format = Output_Grepable;\n                    break;\n                case 'L':\n                    masscan_set_parameter(masscan, \"output-format\", \"list\");\n                    break;\n                case 'U':\n                    masscan_set_parameter(masscan, \"output-format\", \"unicornscan\");\n                    break;\n                case 'H':\n                    masscan_set_parameter(masscan, \"output-format\", \"hostonly\");\n                    break;\n                default:\n                    fprintf(stderr, \"nmap(%s): unknown output format\\n\", argv[i]);\n                    exit(1);\n                }\n\n                ++i;\n                if (i >= argc || (argv[i][0] == '-' && argv[i][1] != '\\0')) {\n                    fprintf(stderr, \"missing output filename\\n\");\n                    exit(1);\n                }\n\n                masscan_set_parameter(masscan, \"output-filename\", argv[i]);\n                break;\n            case 'O':\n                fprintf(stderr, \"nmap(%s): unsupported, OS detection is too complex\\n\", argv[i]);\n                exit(1);\n                break;\n            case 'p':\n                if (argv[i][2])\n                    arg = argv[i]+2;\n                else\n                    arg = argv[++i];\n                if (i >= argc || arg[0] == 0) { // if string is empty\n                    fprintf(stderr, \"%s: empty parameter\\n\", argv[i]);\n                } else\n                    masscan_set_parameter(masscan, \"ports\", arg);\n                break;\n            case 'P':\n                switch (argv[i][2]) {\n                case 'n':\n                    /* we already do this */\n                    break;\n                default:\n                    fprintf(stderr, \"nmap(%s): unsupported option, maybe in future\\n\", argv[i]);\n                    exit(1);\n                }\n                break;\n            case 'r':\n                /* This looks like an nmap option*/\n                fprintf(stderr, \"nmap(%s): wat? randomization is our raison d'etre!! rethink prease\\n\", argv[i]);\n                exit(1);\n                break;\n            case 'R':\n                /* This looks like an nmap option*/\n                fprintf(stderr, \"nmap(%s): unsupported. This code will never do DNS lookups.\\n\", argv[i]);\n                exit(1);\n                break;\n            case 's': /* NMAP: scan type */\n                if (argv[i][3] == '\\0' && !isdigit(argv[i][2]&0xFF)) {\n                    unsigned j;\n\n                    for (j=2; argv[i][j]; j++)\n                    switch (argv[i][j]) {\n                    case 'A':\n                        fprintf(stderr, \"nmap(%s): ACK scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'C':\n                        fprintf(stderr, \"nmap(%s): unsupported\\n\", argv[i]);\n                        exit(1);\n                    case 'F':\n                        fprintf(stderr, \"nmap(%s): FIN scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'I':\n                        fprintf(stderr, \"nmap(%s): Zombie scans will never be supported\\n\", argv[i]);\n                        exit(1);\n                    case 'L': /* List Scan - simply list targets to scan */\n                        masscan->op = Operation_ListScan;\n                        break;\n                    case 'M':\n                        fprintf(stderr, \"nmap(%s): Maimon scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'n': /* Ping Scan - disable port scan */\n                        fprintf(stderr, \"nmap(%s): ping-sweeps not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'N':\n                        fprintf(stderr, \"nmap(%s): NULL scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'O': /* Other IP protocols (not ICMP, UDP, TCP, or SCTP) */\n                        masscan->scan_type.oproto = 1;\n                        break;\n                    case 'S': /* TCP SYN scan - THIS IS WHAT WE DO! */\n                        masscan->scan_type.tcp = 1;\n                        break;\n                    case 'T': /* TCP connect scan */\n                        fprintf(stderr, \"nmap(%s): connect() is too synchronous for cool kids\\n\", argv[i]);\n                        fprintf(stderr, \"WARNING: doing SYN scan (-sS) anyway, ignoring (-sT)\\n\");\n                        break;\n                    case 'U': /* UDP scan */\n                        masscan->scan_type.udp = 1;\n                        break;\n                    case 'V':\n                        fprintf(stderr, \"nmap(%s): unlikely this will be supported\\n\", argv[i]);\n                        exit(1);\n                    case 'W':\n                        fprintf(stderr, \"nmap(%s): Windows scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'X':\n                        fprintf(stderr, \"nmap(%s): Xmas scan not yet supported\\n\", argv[i]);\n                        exit(1);\n                    case 'Y':\n                        break;\n                    case 'Z':\n                        masscan->scan_type.sctp = 1;\n                        break;\n                    default:\n                        fprintf(stderr, \"nmap(%s): unsupported option\\n\", argv[i]);\n                        exit(1);\n                    }\n\n                } else {\n                    fprintf(stderr, \"%s: unknown parameter\\n\", argv[i]);\n                    exit(1);\n                }\n                break;\n            case 'S':\n                if (argv[i][2])\n                    arg = argv[i]+2;\n                else\n                    arg = argv[++i];\n                masscan_set_parameter(masscan, \"adapter-ip\", arg);\n                break;\n            case 'v':\n                {\n                    int v;\n                    for (v=1; argv[i][v] == 'v'; v++)\n                        LOG_add_level(1);\n                }\n                break;\n            case 'V': /* print version and exit */\n                masscan_set_parameter(masscan, \"version\", \"\");\n                break;\n            case 'W':\n                masscan->op = Operation_List_Adapters;\n                return;\n            case 'T':\n                fprintf(stderr, \"nmap(%s): unsupported, we do timing WAY different than nmap\\n\", argv[i]);\n                exit(1);\n                return;\n            default:\n                LOG(0, \"FAIL: unknown option: -%s\\n\", argv[i]);\n                LOG(0, \" [hint] try \\\"--help\\\"\\n\");\n                LOG(0, \" [hint] ...or, to list nmap-compatible options, try \\\"--nmap\\\"\\n\");\n                exit(1);\n            }\n            continue;\n        }\n\n        if (!isdigit(argv[i][0]) && argv[i][0] != ':' && argv[i][0] != '[') {\n            fprintf(stderr, \"FAIL: unknown command-line parameter \\\"%s\\\"\\n\", argv[i]);\n            fprintf(stderr, \" [hint] did you want \\\"--%s\\\"?\\n\", argv[i]);\n            exit(1);\n        }\n\n        /* If parameter doesn't start with '-', assume it's an\n         * IPv4 range\n         */\n        masscan_set_parameter(masscan, \"range\", argv[i]);\n    }\n\n    /*\n     * If no other \"scan type\" found, then default to TCP\n     */\n    if (masscan->scan_type.udp == 0 && masscan->scan_type.sctp == 0\n        && masscan->scan_type.ping == 0 && masscan->scan_type.arp == 0\n        && masscan->scan_type.oproto == 0)\n        masscan->scan_type.tcp = 1;\n    \n    /*\n     * If \"top-ports\" specified, then add all those ports. This may be in\n     * addition to any other ports\n     */\n    if (masscan->top_ports) {\n        config_top_ports(masscan, masscan->top_ports);\n    }\n    if (masscan->shard.of < masscan->shard.one) {\n        fprintf(stderr, \"[-] WARNING: the shard number must be less than the total shard count: %u/%u\\n\",\n            masscan->shard.one, masscan->shard.of);\n    }\n    if (masscan->shard.of > 1 && masscan->seed == 0) {\n        fprintf(stderr, \"[-] WARNING: --seed <num> is not specified\\n    HINT: all shards must share the same seed\\n\");\n    }\n}\n\n/***************************************************************************\n * Prints the current configuration to the command-line then exits.\n * Use#1: create a template file of all settable parameters.\n * Use#2: make sure your configuration was interpreted correctly.\n ***************************************************************************/\nvoid\nmasscan_echo(struct Masscan *masscan, FILE *fp, unsigned is_echo_all)\n{\n    unsigned i;\n    unsigned l = 0;\n    \n    /*\n     * NEW:\n     * Print all configuration parameters\n     */\n    masscan->echo = fp;\n    masscan->echo_all = is_echo_all;\n    for (i=0; config_parameters[i].name; i++) {\n        config_parameters[i].set(masscan, 0, 0);\n    }\n    masscan->echo = 0;\n    masscan->echo_all = 0;\n    \n    /*\n     * OLD:\n     * Things here below are the old way of echoing parameters.\n     * TODO: cleanup this code, replacing with the new way.\n     */\n    if (masscan->nic_count == 0)\n        masscan_echo_nic(masscan, fp, 0);\n    else {\n        for (i=0; i<masscan->nic_count; i++)\n            masscan_echo_nic(masscan, fp, i);\n    }\n\n    /**\n     * Fix for #737, save adapter-port/source-port value or range\n     */\n    if (masscan->nic[0].src.port.first != 0) {\n        fprintf(fp, \"adapter-port = %d\", masscan->nic[0].src.port.first);\n        if (masscan->nic[0].src.port.first != masscan->nic[0].src.port.last) {\n            /* --adapter-port <first>-<last> */\n            fprintf(fp, \"-%d\", masscan->nic[0].src.port.last);\n        }\n        fprintf(fp, \"\\n\");\n    }\n\n    /*\n     * Targets\n     */\n    fprintf(fp, \"# TARGET SELECTION (IP, PORTS, EXCLUDES)\\n\");\n    fprintf(fp, \"ports = \");\n    /* Disable comma generation for the first element */\n    l = 0;\n    for (i=0; i<masscan->targets.ports.count; i++) {\n        struct Range range = masscan->targets.ports.list[i];\n        do {\n            struct Range rrange = range;\n            unsigned done = 0;\n            if (l)\n                fprintf(fp, \",\");\n            l = 1;\n            if (rrange.begin >= Templ_ICMP_echo) {\n                rrange.begin -= Templ_ICMP_echo;\n                rrange.end -= Templ_ICMP_echo;\n                fprintf(fp,\"I:\");\n                done = 1;\n            } else if (rrange.begin >= Templ_SCTP) {\n                rrange.begin -= Templ_SCTP;\n                rrange.end -= Templ_SCTP;\n                fprintf(fp,\"S:\");\n                range.begin = Templ_ICMP_echo;\n            } else if (rrange.begin >= Templ_UDP) {\n                rrange.begin -= Templ_UDP;\n                rrange.end -= Templ_UDP;\n                fprintf(fp,\"U:\");\n                range.begin = Templ_SCTP;\n            } else if (Templ_Oproto_first <= rrange.begin && rrange.begin <= Templ_Oproto_last) {\n                rrange.begin -= Templ_Oproto_first;\n                rrange.end -= Templ_Oproto_first;\n                fprintf(fp, \"O:\");\n                range.begin = Templ_Oproto_first;\n            } else\n                range.begin = Templ_UDP;\n            rrange.end = min(rrange.end, 65535);\n            if (rrange.begin == rrange.end)\n                fprintf(fp, \"%u\", rrange.begin);\n            else\n                fprintf(fp, \"%u-%u\", rrange.begin, rrange.end);\n            if (done)\n                break;\n        } while (range.begin <= range.end);\n    }\n    fprintf(fp, \"\\n\");\n\n    /*\n     * IPv4 address targets\n     */\n    for (i=0; i<masscan->targets.ipv4.count; i++) {\n        unsigned prefix_bits;\n        struct Range range = masscan->targets.ipv4.list[i];\n\n        if (range.begin == range.end) {\n            fprintf(fp, \"range = %u.%u.%u.%u\",\n                    (range.begin>>24)&0xFF,\n                    (range.begin>>16)&0xFF,\n                    (range.begin>> 8)&0xFF,\n                    (range.begin>> 0)&0xFF\n                    );\n        } else if (range_is_cidr(range, &prefix_bits)) {\n            fprintf(fp, \"range = %u.%u.%u.%u/%u\",\n                    (range.begin>>24)&0xFF,\n                    (range.begin>>16)&0xFF,\n                    (range.begin>> 8)&0xFF,\n                    (range.begin>> 0)&0xFF,\n                    prefix_bits\n                    );\n\n        } else {\n            fprintf(fp, \"range = %u.%u.%u.%u-%u.%u.%u.%u\",\n                    (range.begin>>24)&0xFF,\n                    (range.begin>>16)&0xFF,\n                    (range.begin>> 8)&0xFF,\n                    (range.begin>> 0)&0xFF,\n                    (range.end>>24)&0xFF,\n                    (range.end>>16)&0xFF,\n                    (range.end>> 8)&0xFF,\n                    (range.end>> 0)&0xFF\n                    );\n        }\n        fprintf(fp, \"\\n\");\n    }\n    for (i=0; i<masscan->targets.ipv6.count; i++) {\n        bool exact = false;\n        struct Range6 range = masscan->targets.ipv6.list[i];\n        ipaddress_formatted_t fmt = ipv6address_fmt(range.begin);\n        \n        fprintf(fp, \"range = %s\", fmt.string);\n        if (!ipv6address_is_equal(range.begin, range.end)) {\n            unsigned cidr_bits = count_cidr6_bits(&range, &exact);\n            \n            if (exact && cidr_bits) {\n                fprintf(fp, \"/%u\", cidr_bits);\n            } else {\n                fmt = ipv6address_fmt(range.end);\n                fprintf(fp, \"-%s\", fmt.string);\n            }\n        }\n        fprintf(fp, \"\\n\");\n    }\n}\n\n\n/***************************************************************************\n * Prints the list of CIDR to scan to the command-line then exits.\n * Use: provide this list to other tools. Unlike masscan -sL, it keeps\n * the CIDR aggretated format, and does not randomize the order of output.\n * For example, given the starting range of [10.0.0.1-10.0.0.255], this will\n * print all the CIDR ranges that make this up:\n *  10.0.0.1/32\n *  10.0.0.2/31\n *  10.0.0.4/30\n *  10.0.0.8/29\n *  10.0.0.16/28\n *  10.0.0.32/27\n *  10.0.0.64/26\n *  10.0.0.128/25\n ***************************************************************************/\nvoid\nmasscan_echo_cidr(struct Masscan *masscan, FILE *fp, unsigned is_echo_all)\n{\n    unsigned i;\n    UNUSEDPARM(is_echo_all);\n\n    masscan->echo = fp;\n\n    /*\n     * For all IPv4 ranges ...\n     */\n    for (i=0; i<masscan->targets.ipv4.count; i++) {\n\n        /* Get the next range in the list */\n        struct Range range = masscan->targets.ipv4.list[i];\n\n        /* If not a single CIDR range, print all the CIDR ranges\n         * needed to completely represent this addres */\n        for (;;) {\n            unsigned prefix_length;\n            struct Range cidr;\n\n            /* Find the largest CIDR range (one that can be specified\n             * with a /prefix) at the start of this range. */\n            cidr = range_first_cidr(range, &prefix_length);\n            fprintf(fp, \"%u.%u.%u.%u/%u\\n\",\n                    (cidr.begin>>24)&0xFF,\n                    (cidr.begin>>16)&0xFF,\n                    (cidr.begin>> 8)&0xFF,\n                    (cidr.begin>> 0)&0xFF,\n                    prefix_length\n                    );\n\n            /* If this is the last range, then stop. There are multiple\n             * ways to gets to see if we get to the end, but I think\n             * this is the best. */\n            if (cidr.end >= range.end)\n                break;\n\n            /* If the CIDR range didn't cover the entire range,\n             * then remove it from the beginning of the range\n             * and process the remainder */\n            range.begin = cidr.end+1;\n        }\n    }\n\n    /*\n     * For all IPv6 ranges...\n     */\n    for (i=0; i<masscan->targets.ipv6.count; i++) {\n        struct Range6 range = masscan->targets.ipv6.list[i];\n        bool exact = false;\n        while (!exact) {\n            ipaddress_formatted_t fmt = ipv6address_fmt(range.begin);\n            fprintf(fp, \"%s\", fmt.string);\n            if (range.begin.hi == range.end.hi && range.begin.lo == range.end.lo) {\n                fprintf(fp, \"/128\");\n                exact = true;\n            } else {\n                unsigned cidr_bits = count_cidr6_bits(&range, &exact);\n                fprintf(fp, \"/%u\", cidr_bits);\n            }\n            fprintf(fp, \"\\n\");\n        }\n    }\n}\n\n/***************************************************************************\n * remove leading/trailing whitespace\n ***************************************************************************/\nstatic void\ntrim(char *line, size_t sizeof_line)\n{\n    if (sizeof_line > strlen(line))\n        sizeof_line = strlen(line);\n\n    while (isspace(*line & 0xFF))\n        memmove(line, line+1, sizeof_line--);\n    while (*line && isspace(line[sizeof_line-1] & 0xFF))\n        line[--sizeof_line] = '\\0';\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nmasscan_read_config_file(struct Masscan *masscan, const char *filename)\n{\n    FILE *fp;\n    char line[65536];\n\n    fp = fopen(filename, \"rt\");\n    if (fp == NULL) {\n        char dir[512];\n        char *x;\n        \n        fprintf(stderr, \"[-] FAIL: reading configuration file\\n\");\n        fprintf(stderr, \"[-] %s: %s\\n\", filename, strerror(errno));\n\n        x = getcwd(dir, sizeof(dir));\n        if (x)\n            fprintf(stderr, \"[-] cwd = %s\\n\", dir);\n        return;\n    }\n\n    while (fgets(line, sizeof(line), fp)) {\n        char *name;\n        char *value;\n\n        trim(line, sizeof(line));\n\n        if (ispunct(line[0] & 0xFF) || line[0] == '\\0')\n            continue;\n\n        name = line;\n        value = strchr(line, '=');\n        if (value == NULL)\n            continue;\n        *value = '\\0';\n        value++;\n        trim(name, sizeof(line));\n        trim(value, sizeof(line));\n\n        masscan_set_parameter(masscan, name, value);\n    }\n\n    fclose(fp);\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nint masscan_conf_contains(const char *x, int argc, char **argv)\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        if (strcmp(argv[i], x) == 0)\n            return 1;\n    }\n\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nmainconf_selftest()\n{\n    char test[] = \" test 1 \";\n\n    trim(test, sizeof(test));\n    if (strcmp(test, \"test 1\") != 0) {\n        goto failure;\n    }\n\n\n    /* */\n    {\n        int argc = 6;\n        char *argv[] = { \"foo\", \"bar\", \"-ddd\", \"--readscan\", \"xxx\", \"--something\" };\n    \n        if (masscan_conf_contains(\"--nothing\", argc, argv))\n            goto failure;\n\n        if (!masscan_conf_contains(\"--readscan\", argc, argv))\n            goto failure;\n    }\n\n    return 0;\nfailure:\n    fprintf(stderr, \"[+] selftest failure: config subsystem\\n\");\n    return 1;\n}\n\n"
  },
  {
    "path": "src/main-dedup.c",
    "content": "/*\n\n    Filters duplicate responses\n\n    This is an asynchronous and \"stateless\" scanner that spews out probes\n    without having holding \"state\" for the probes. This means that when\n    a response comes back, we have no \"state\" to associate with it.\n \n    This means when two responses come back, we still don't have any\n    \"state\" to remember that the first one came back. This will cause\n    us to report two results instead of one.\n \n    We could create a large table holding a record for EVERY response\n    that we've seen. But this would require a lot of memory for large\n    scans.\n \n    Instead, we remember a small hashtable of recent responses. This\n    takes advantage of the fact that multiple responses are likely\n    to be recent and eventually age out.\n \n    We call this \"deduplication\" as it's simply removing duplicate\n    responses.\n*/\n#include \"main-dedup.h\"\n#include \"util-malloc.h\"\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include \"syn-cookie.h\"\n\n/**\n * This is the number of entries in our table. More entries does a better job at the\n * cost of using more memory.\n */\n#define DEDUP_ENTRIES 65536\n\nstruct DedupEntry_IPv4\n{\n    unsigned ip_them;\n    unsigned port_them;\n    unsigned ip_me;\n    unsigned port_me;\n};\n\nstruct DedupEntry_IPv6\n{\n    ipv6address ip_them;\n    ipv6address ip_me;\n    unsigned short port_them;\n    unsigned short port_me;\n};\n\n/**\n * This is simply the array of entries. We have two arrays, one for IPv4\n * and another for IPv6.\n */\nstruct DedupTable\n{\n    struct DedupEntry_IPv4 entries[DEDUP_ENTRIES][4];\n    struct DedupEntry_IPv6 entries6[DEDUP_ENTRIES][4];\n};\n\n/**\n * We use the FNv1a hash algorithm, which starts with this seed value.\n */\nconst unsigned fnv1a_seed  = 0x811C9DC5; /* 2166136261 */\n\n/**\n * Hash one byte, the other hash functions of multiple bytes call this function.\n * @param hash\n *      The current hash value that we keep updating as we repeatedly\n *      call this function, or the `fnv1a_seed   value on the first call to\n *      this function.\n */\nstatic inline unsigned fnv1a(unsigned char c, unsigned hash)\n{\n  const unsigned prime = 0x01000193; /* 16777619 */\n  return (c ^ hash) * prime;\n}\n\nstatic unsigned fnv1a_string(const void *v_buf, size_t length, unsigned hash)\n{\n    const unsigned char *buf = (const unsigned char *)v_buf;\n    size_t i;\n    for (i=0; i<length; i++)\n        hash = fnv1a(buf[i], hash);\n    return hash;\n}\n\nstatic inline unsigned fnv1a_short(unsigned data, unsigned hash)\n{\n    hash = fnv1a((data>>0)&0xFF, hash);\n    hash = fnv1a((data>>8)&0xFF, hash);\n    return hash;\n}\nstatic inline unsigned fnv1a_longlong(unsigned long long data, unsigned hash)\n{\n    return fnv1a_string(&data, 8, hash);\n}\n\n/**\n * Create a new table, which means simply allocating the object\n * and setting it to zero.\n */\nstruct DedupTable *\ndedup_create(void)\n{\n    struct DedupTable *dedup;\n\n    dedup = CALLOC(1, sizeof(*dedup));\n\n    return dedup;\n}\n\n/**\n * There's nothing special we need to do to free the structure\n * since it's all contained in the single allocation.\n */\nvoid\ndedup_destroy(struct DedupTable *dedup)\n{\n    free(dedup);\n}\n\n/**\n * Create a hash of the IPv6 socket. This doesn't have to be\n * cryptographically secure, so we are going to use the FNv1a algorithm.\n */\nstatic inline unsigned\ndedup_hash_ipv6(ipaddress ip_them, unsigned port_them, ipaddress ip_me, unsigned port_me)\n{\n    unsigned hash = fnv1a_seed;\n    hash = fnv1a_longlong(ip_them.ipv6.hi, hash);\n    hash = fnv1a_longlong(ip_them.ipv6.lo, hash);\n    hash = fnv1a_short(port_them, hash);\n    hash = fnv1a_longlong(ip_me.ipv6.hi, hash);\n    hash = fnv1a_longlong(ip_me.ipv6.lo, hash);\n    hash = fnv1a_short(port_me, hash);\n    return hash;\n}\n\n/**\n * If two IPv6 addresses are equal.\n */\nstatic inline int\nis_equal6(ipv6address lhs, ipv6address rhs)\n{\n    return lhs.hi == rhs.hi && lhs.lo == rhs.lo;\n}\n\n/**\n * Swap two addresses in the table. This uses the classic XOR trick\n * rather than using a swap variable.\n */\nstatic inline void\nswap6(struct DedupEntry_IPv6 *lhs, struct DedupEntry_IPv6 *rhs)\n{\n    lhs->ip_them.hi ^= rhs->ip_them.hi;\n    lhs->ip_them.lo ^= rhs->ip_them.lo;\n    lhs->port_them ^= rhs->port_them;\n    lhs->ip_me.hi ^= rhs->ip_me.hi;\n    lhs->ip_me.lo ^= rhs->ip_me.lo;\n    lhs->port_me ^= rhs->port_me;\n\n    rhs->ip_them.hi ^= lhs->ip_them.hi;\n    rhs->ip_them.lo ^= lhs->ip_them.lo;\n    rhs->port_them ^= lhs->port_them;\n    rhs->ip_me.hi ^= lhs->ip_me.hi;\n    rhs->ip_me.lo ^= lhs->ip_me.lo;\n    rhs->port_me ^= lhs->port_me;\n\n    lhs->ip_them.hi ^= rhs->ip_them.hi;\n    lhs->ip_them.lo ^= rhs->ip_them.lo;\n    lhs->port_them ^= rhs->port_them;\n    lhs->ip_me.hi ^= rhs->ip_me.hi;\n    lhs->ip_me.lo ^= rhs->ip_me.lo;\n    lhs->port_me ^= rhs->port_me;\n}\n\n/**\n * This implements the same algorithm as for IPv4 addresses, but for\n * IPv6 addresses instead.\n */\nstatic unsigned\ndedup_is_duplicate_ipv6(struct DedupTable *dedup,\n                   ipaddress ip_them, unsigned port_them,\n                   ipaddress ip_me, unsigned port_me)\n{\n    unsigned hash;\n    struct DedupEntry_IPv6 *bucket;\n    unsigned i;\n\n    /* THREAT: probably need to secure this hash, though the syn-cookies\n     * provides some protection */\n    hash = dedup_hash_ipv6(ip_them, port_them, ip_me, port_me);\n    hash &= DEDUP_ENTRIES-1;\n\n    /* Search in this bucket */\n    bucket = dedup->entries6[hash];\n\n    /* If we find the entry in our table, move it to the front, so\n     * that it won't be aged out as quickly. We keep prepending new\n     * addresses to front, aging older addresses that haven't been\n     * seen in a while. */\n    for (i = 0; i < 4; i++) {\n        if (is_equal6(bucket[i].ip_them, ip_them.ipv6) && bucket[i].port_them == port_them\n            && is_equal6(bucket[i].ip_me, ip_me.ipv6) && bucket[i].port_me == port_me) {\n            /* move to end of list so constant repeats get ignored */\n            if (i > 0) {\n                swap6(&bucket[0], &bucket[i]);\n            }\n            return 1;\n        }\n    }\n\n    /* We didn't find it, so add it to our list. This will push\n     * older entries at this bucket off the list */\n    memmove(bucket, bucket+1, 3*sizeof(*bucket));\n    bucket[0].ip_them.hi = ip_them.ipv6.hi;\n    bucket[0].ip_them.lo = ip_them.ipv6.lo;\n    bucket[0].port_them = (unsigned short)port_them;\n    bucket[0].ip_me.hi = ip_me.ipv6.hi;\n    bucket[0].ip_me.lo = ip_me.ipv6.lo;\n    bucket[0].port_me = (unsigned short)port_me;\n\n    return 0;\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ndedup_is_duplicate_ipv4(struct DedupTable *dedup,\n                   ipaddress ip_them, unsigned port_them,\n                   ipaddress ip_me, unsigned port_me)\n{\n    unsigned hash;\n    struct DedupEntry_IPv4 *bucket;\n    unsigned i;\n\n    /* THREAT: probably need to secure this hash, though the syn-cookies\n     * provides some protection */\n    hash = (ip_them.ipv4 + port_them) ^ ((ip_me.ipv4) + (ip_them.ipv4>>16)) ^ (ip_them.ipv4>>24) ^ port_me;\n    hash &= DEDUP_ENTRIES-1;\n\n    /* Search in this bucket */\n    bucket = dedup->entries[hash];\n\n    /* If we find the entry in our table, move it to the front, so\n     * that it won't be aged out as quickly. We keep prepending new\n     * addresses to front, aging older addresses that haven't been\n     * seen in a while. */\n    for (i = 0; i < 4; i++) {\n        if (bucket[i].ip_them == ip_them.ipv4 && bucket[i].port_them == port_them\n            && bucket[i].ip_me == ip_me.ipv4 && bucket[i].port_me == port_me) {\n            /* move to end of list so constant repeats get ignored */\n            if (i > 0) {\n                bucket[i].ip_them ^= bucket[0].ip_them;\n                bucket[i].port_them ^= bucket[0].port_them;\n                bucket[i].ip_me ^= bucket[0].ip_me;\n                bucket[i].port_me ^= bucket[0].port_me;\n\n                bucket[0].ip_them ^= bucket[i].ip_them;\n                bucket[0].port_them ^= bucket[i].port_them;\n                bucket[0].ip_me ^= bucket[i].ip_me;\n                bucket[0].port_me ^= bucket[i].port_me;\n\n                bucket[i].ip_them ^= bucket[0].ip_them;\n                bucket[i].port_them ^= bucket[0].port_them;\n                bucket[i].ip_me ^= bucket[0].ip_me;\n                bucket[i].port_me ^= bucket[0].port_me;\n            }\n            return 1;\n        }\n    }\n\n    /* We didn't find it, so add it to our list. This will push\n     * older entries at this bucket off the list */\n    memmove(bucket, bucket+1, 3*sizeof(*bucket));\n    bucket[0].ip_them = ip_them.ipv4;\n    bucket[0].port_them = port_them;\n    bucket[0].ip_me = ip_me.ipv4;\n    bucket[0].port_me = port_me;\n\n    return 0;\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\ndedup_is_duplicate(struct DedupTable *dedup,\n                   ipaddress ip_them, unsigned port_them,\n                   ipaddress ip_me, unsigned port_me)\n{\n    if (ip_them.version == 6)\n        return dedup_is_duplicate_ipv6(dedup, ip_them, port_them, ip_me, port_me);\n    else\n        return dedup_is_duplicate_ipv4(dedup, ip_them, port_them, ip_me, port_me);\n}\n\n\n/**\n * My own deterministic rand() function for testing this module\n */\nstatic unsigned\n_rand(unsigned *seed)\n{\n    static const unsigned a = 214013;\n    static const unsigned c = 2531011;\n\n    *seed = (*seed) * a + c;\n    return (*seed)>>16 & 0x7fff;\n}\n\n/*\n * Provide a simple unit test for this module.\n *\n * This is a pretty lame test. I'm going to generate\n * a set of random addresses, tweaked so that they aren't\n * too random, so that I get around 30 to 50 expected\n * duplicates. If I get zero duplicates, or if I get too\n * many duplicates in the test, then I know it's failed.\n *\n * This is in no way a reliable test that deterministically\n * tests the functionality. It's a crappy non-deterministic\n * test.\n *\n * We also do a simple deterministic test, but this still\n * is insufficient testing how duplicates age out and such.\n */\nint\ndedup_selftest(void)\n{\n    struct DedupTable *dedup;\n    unsigned seed = 0;\n    size_t i;\n    unsigned found_match = 0;\n    unsigned line = 0;\n    \n    dedup = dedup_create();\n    \n    /* Deterministic test.\n     *\n     * The first time we check on a socket combo, there should\n     * be no duplicate. The second time we check, however, there should\n     * be a duplicate.\n     */\n    {\n        ipaddress ip_me;\n        ipaddress ip_them;\n        unsigned port_me;\n        unsigned port_them;\n        \n        ip_me.version = 4;\n        ip_them.version = 4;\n        ip_me.ipv4 = 0x12345678;\n        ip_them.ipv4 = 0xabcdef0;\n        port_me = 0x1234;\n        port_them = 0xfedc;\n        \n        if (dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            line = __LINE__;\n            goto fail;\n        }\n        if (!dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            line = __LINE__;\n            goto fail;\n        }\n        \n        ip_me.version = 6;\n        ip_them.version = 6;\n        ip_me.ipv6.hi = 0x12345678;\n\t    ip_me.ipv6.lo = 0x12345678;\n        ip_them.ipv6.hi = 0xabcdef0;\n        ip_them.ipv6.lo = 0xabcdef0;\n\n        if (dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            line = __LINE__;\n            goto fail;\n        }\n        if (!dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            ipaddress_formatted_t fmt1 = ipaddress_fmt(ip_them);\n            ipaddress_formatted_t fmt2 = ipaddress_fmt(ip_me);\n            fprintf(stderr, \"[-] [%s]:%u -> [%s]:%u\\n\", \n\t\t\t    fmt1.string, port_them,\n\t\t\t    fmt2.string, port_me);\n            line = __LINE__;\n            goto fail;\n        }\n        \n    }\n    \n    /* Test IPv4 addresses */\n    for (i=0; i<100000; i++) {\n        ipaddress ip_me;\n        ipaddress ip_them;\n        unsigned port_me;\n        unsigned port_them;\n        \n        ip_me.version = 4;\n        ip_them.version = 4;\n        \n        /* Instead of completely random numbers over the entire\n         * range, each port/IP is restricted to just 512\n         * random combinations. This should statistically\n         * give us around 10 matches*/\n        ip_me.ipv4 = _rand(&seed) & 0xFF800000;\n        ip_them.ipv4 = _rand(&seed) & 0x1FF;\n        port_me = _rand(&seed) & 0xFF80;\n        port_them = _rand(&seed) & 0x1FF;\n        \n        if (dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            found_match++;\n        }\n    }\n    \n    /* Approximately 30 matches should be found. If we couldn't\n     * find any, or if we've found too many, then the test has\n     * failed. */\n    if (found_match == 0 || found_match > 200) {\n        line = __LINE__;\n        goto fail;\n    }\n    \n    /* Now do IPv6 */\n    found_match = 0;\n    seed = 0;\n    \n    /* Test IPv4 addresses */\n    for (i=0; i<100000; i++) {\n        ipaddress ip_me;\n        ipaddress ip_them;\n        unsigned port_me;\n        unsigned port_them;\n        \n        ip_me.version = 6;\n        ip_them.version = 6;\n        \n        /* Instead of completely random numbers over the entire\n         * range, each port/IP is restricted to just 512\n         * random combinations. This should statistically\n         * give us around 10 matches*/\n        ip_me.ipv6.hi = _rand(&seed) & 0xFF800000;\n        ip_them.ipv6.lo = _rand(&seed) & 0x1FF;\n        port_me = _rand(&seed) & 0xFF80;\n        port_them = _rand(&seed) & 0x1FF;\n        \n        if (dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me)) {\n            found_match++;\n        }\n    }\n\n    /* The result should be same as for IPv4, around 30 matches found. */\n    if (found_match == 0 || found_match > 200) {\n        line = __LINE__;\n        goto fail;\n    }\n    \n    /* All tests have passed */\n    return 0; /* success :) */\n\nfail:\n    fprintf(stderr, \"[-] selftest: 'dedup' failed, file=%s, line=%u\\n\", __FILE__, line);\n    return 1;\n}\n"
  },
  {
    "path": "src/main-dedup.h",
    "content": "#ifndef MAIN_DEDUP_H\n#define MAIN_DEDUP_H\n#include \"massip-addr.h\"\n\nstruct DedupTable *\ndedup_create(void);\n\nvoid\ndedup_destroy(struct DedupTable *table);\n\nunsigned\ndedup_is_duplicate(         struct DedupTable *dedup,\n                            ipaddress ip_them, unsigned port_them,\n                            ipaddress ip_me, unsigned port_me);\n\n/**\n * Simple unit test\n * @return 0 on success, 1 on failure.\n */\nint dedup_selftest(void);\n\n\n#endif\n"
  },
  {
    "path": "src/main-globals.h",
    "content": "#ifndef MAIN_GLOBALS_H\n#define MAIN_GLOBALS_H\n#include <time.h>\n\nextern unsigned volatile is_tx_done;\nextern unsigned volatile is_rx_done;\nextern time_t global_now;\n\n\n#endif\n"
  },
  {
    "path": "src/main-initadapter.c",
    "content": "#include \"masscan.h\"\n#include \"util-logger.h\"\n#include \"rawsock.h\"\n#include \"rawsock-adapter.h\"\n#include \"stack-arpv4.h\"\n#include \"stack-ndpv6.h\"\n#include \"stub-pcap-dlt.h\"\n\n\n/***************************************************************************\n * Initialize the network adapter.\n *\n * This requires finding things like our IP address, MAC address, and router\n * MAC address. The user could configure these things manually instead.\n *\n * Note that we don't update the \"static\" configuration with the discovered\n * values, but instead return them as the \"running\" configuration. That's\n * so if we pause and resume a scan, auto discovered values don't get saved\n * in the configuration file.\n ***************************************************************************/\nint\nmasscan_initialize_adapter(\n    struct Masscan *masscan,\n    unsigned index,\n    macaddress_t *source_mac,\n    macaddress_t *router_mac_ipv4,\n    macaddress_t *router_mac_ipv6\n    )\n{\n    char *ifname;\n    char ifname2[256];\n    unsigned adapter_ip = 0;\n    unsigned is_usable_ipv4 = !massip_has_ipv4_targets(&masscan->targets); /* I don't understand this line, seems opposite */\n    unsigned is_usable_ipv6 = !massip_has_ipv6_targets(&masscan->targets); /* I don't understand this line, seems opposite */\n    ipaddress_formatted_t fmt;\n\n    /*\n     * ADAPTER/NETWORK-INTERFACE\n     *\n     * If no network interface was configured, we need to go hunt down\n     * the best Interface to use. We do this by choosing the first\n     * interface with a \"default route\" (aka. \"gateway\") defined\n     */\n    if (masscan->nic[index].ifname[0])\n        ifname = masscan->nic[index].ifname;\n    else {\n        /* no adapter specified, so find a default one */\n        int err;\n        ifname2[0] = '\\0';\n        err = rawsock_get_default_interface(ifname2, sizeof(ifname2));\n        if (err || ifname2[0] == '\\0') {\n            LOG(0, \"[-] FAIL: could not determine default interface\\n\");\n            LOG(0, \"    [hint] try \\\"--interface ethX\\\"\\n\");\n            return -1;\n        }\n        ifname = ifname2;\n    }\n    LOG(1, \"[+] interface = %s\\n\", ifname);\n\n    /*\n     * START ADAPTER\n     *\n     * Once we've figured out which adapter to use, we now need to\n     * turn it on.\n     */\n    masscan->nic[index].adapter = rawsock_init_adapter(\n                                            ifname,\n                                            masscan->is_pfring,\n                                            masscan->is_sendq,\n                                            masscan->nmap.packet_trace,\n                                            masscan->is_offline,\n                                            (void*)masscan->bpf_filter,\n                                            masscan->nic[index].is_vlan,\n                                            masscan->nic[index].vlan_id);\n    if (masscan->nic[index].adapter == 0) {\n        LOG(0, \"[-] if:%s:init: failed\\n\", ifname);\n        return -1;\n    }\n    masscan->nic[index].link_type = masscan->nic[index].adapter->link_type;\n    LOG(1, \"[+] interface-type = %u\\n\", masscan->nic[index].link_type);\n    rawsock_ignore_transmits(masscan->nic[index].adapter, ifname);\n\n    /*\n     * MAC ADDRESS\n     *\n     * This is the address we send packets from. It actually doesn't really\n     * matter what this address is, but to be a \"responsible\" citizen we\n     * try to use the hardware address in the network card.\n     */\n    if (masscan->nic[index].link_type == PCAP_DLT_NULL) {\n        LOG(1, \"[+] source-mac = %s\\n\", \"none\");\n    } else if (masscan->nic[index].link_type == PCAP_DLT_RAW) {\n        LOG(1, \"[+] source-mac = %s\\n\", \"none\");\n    } else {\n        *source_mac = masscan->nic[index].source_mac;\n        if (masscan->nic[index].my_mac_count == 0) {\n            if (macaddress_is_zero(*source_mac)) {\n                rawsock_get_adapter_mac(ifname, source_mac->addr);\n            }\n            /* If still zero, then print error message */\n            if (macaddress_is_zero(*source_mac)) {\n                fprintf(stderr, \"[-] FAIL: failed to detect MAC address of interface:\"\n                        \" \\\"%s\\\"\\n\", ifname);\n                fprintf(stderr, \" [hint] try something like \"\n                        \"\\\"--source-mac 00-11-22-33-44-55\\\"\\n\");\n                return -1;\n            }\n        }\n        \n        fmt = macaddress_fmt(*source_mac);\n        LOG(1, \"[+] source-mac = %s\\n\", fmt.string);\n    }\n    \n\n    /*\n     * IPv4 ADDRESS\n     *\n     * We need to figure out that IP address to send packets from. This\n     * is done by querying the adapter (or configured by user). If the\n     * adapter doesn't have one, then the user must configure one.\n     */\n    if (massip_has_ipv4_targets(&masscan->targets)) {\n        adapter_ip = masscan->nic[index].src.ipv4.first;\n        if (adapter_ip == 0) {\n            adapter_ip = rawsock_get_adapter_ip(ifname);\n            masscan->nic[index].src.ipv4.first = adapter_ip;\n            masscan->nic[index].src.ipv4.last = adapter_ip;\n            masscan->nic[index].src.ipv4.range = 1;\n        }\n        if (adapter_ip == 0) {\n            /* We appear to have IPv4 targets, yet we cannot find an adapter\n             * to use for those targets. We are having trouble querying the\n             * operating system stack. */\n            LOG(0, \"[-] FAIL: failed to detect IP of interface \\\"%s\\\"\\n\", ifname);\n            LOG(0, \"    [hint] did you spell the name correctly?\\n\");\n            LOG(0, \"    [hint] if it has no IP address, manually set with something like \"\n                            \"\\\"--source-ip 198.51.100.17\\\"\\n\");\n            if (massip_has_ipv4_targets(&masscan->targets)) {\n                return -1;\n            }\n        }\n        \n        fmt = ipv4address_fmt(adapter_ip);\n        LOG(1, \"[+] source-ip = %s\\n\", fmt.string);\n        \n        if (adapter_ip != 0)\n            is_usable_ipv4 = 1;\n        \n        /*\n         * ROUTER MAC ADDRESS\n         *\n         * NOTE: this is one of the least understood aspects of the code. We must\n         * send packets to the local router, which means the MAC address (not\n         * IP address) of the router.\n         *\n         * Note: in order to ARP the router, we need to first enable the libpcap\n         * code above.\n         */\n        *router_mac_ipv4 = masscan->nic[index].router_mac_ipv4;\n        if (masscan->is_offline) {\n            /* If we are doing offline benchmarking/testing, then create\n             * a fake MAC address fro the router */\n            memcpy(router_mac_ipv4->addr, \"\\x66\\x55\\x44\\x33\\x22\\x11\", 6);\n        } else if (masscan->nic[index].link_type == PCAP_DLT_NULL) {\n            /* If it's a VPN tunnel, then there is no Ethernet MAC address */\n            LOG(1, \"[+] router-mac-ipv4 = %s\\n\", \"implicit\");\n\t} else if (masscan->nic[index].link_type == PCAP_DLT_RAW) {\n            /* If it's a VPN tunnel, then there is no Ethernet MAC address */\n            LOG(1, \"[+] router-mac-ipv4 = %s\\n\", \"implicit\");\n        } else if (macaddress_is_zero(*router_mac_ipv4)) {\n            ipv4address_t router_ipv4 = masscan->nic[index].router_ip;\n            int err = 0;\n\n\n            LOG(2, \"[+] if(%s): looking for default gateway\\n\", ifname);\n            if (router_ipv4 == 0)\n                err = rawsock_get_default_gateway(ifname, &router_ipv4);\n            if (err == 0) {\n                fmt = ipv4address_fmt(router_ipv4);\n                LOG(1, \"[+] router-ip = %s\\n\", fmt.string);\n                LOG(2, \"[+] if(%s):arp: resolving IPv4 address\\n\", ifname);\n                \n                stack_arp_resolve(\n                        masscan->nic[index].adapter,\n                        adapter_ip,\n                        *source_mac,\n                        router_ipv4,\n                        router_mac_ipv4);\n            }\n            \n            fmt = macaddress_fmt(*router_mac_ipv4);\n            LOG(1, \"[+] router-mac-ipv4 = %s\\n\", fmt.string);\n            if (macaddress_is_zero(*router_mac_ipv4)) {\n                fmt = ipv4address_fmt(masscan->nic[index].router_ip);\n                LOG(0, \"[-] FAIL: ARP timed-out resolving MAC address for router %s: \\\"%s\\\"\\n\", ifname, fmt.string);\n                LOG(0, \"    [hint] try \\\"--router ip 192.0.2.1\\\" to specify different router\\n\");\n                LOG(0, \"    [hint] try \\\"--router-mac 66-55-44-33-22-11\\\" instead to bypass ARP\\n\");\n                LOG(0, \"    [hint] try \\\"--interface eth0\\\" to change interface\\n\");\n                return -1;\n            }\n        }\n    }\n        \n\n    /*\n     * IPv6 ADDRESS\n     *\n     * We need to figure out that IPv6 address to send packets from. This\n     * is done by querying the adapter (or configured by user). If the\n     * adapter doesn't have one, then the user must configure one.\n     */\n    if (massip_has_ipv6_targets(&masscan->targets)) {\n        ipv6address adapter_ipv6 = masscan->nic[index].src.ipv6.first;\n        if (ipv6address_is_zero(adapter_ipv6)) {\n            adapter_ipv6 = rawsock_get_adapter_ipv6(ifname);\n            masscan->nic[index].src.ipv6.first = adapter_ipv6;\n            masscan->nic[index].src.ipv6.last = adapter_ipv6;\n            masscan->nic[index].src.ipv6.range = 1;\n        }\n        if (ipv6address_is_zero(adapter_ipv6)) {\n            fprintf(stderr, \"[-] FAIL: failed to detect IPv6 address of interface \\\"%s\\\"\\n\",\n                            ifname);\n            fprintf(stderr, \"    [hint] did you spell the name correctly?\\n\");\n            fprintf(stderr, \"    [hint] if it has no IP address, manually set with something like \"\n                            \"\\\"--source-ip 2001:3b8::1234\\\"\\n\");\n            return -1;\n        }\n        fmt = ipv6address_fmt(adapter_ipv6);\n        LOG(1, \"[+] source-ip = [%s]\\n\", fmt.string);\n        is_usable_ipv6 = 1;\n        \n        /*\n         * ROUTER MAC ADDRESS\n         */\n        *router_mac_ipv6 = masscan->nic[index].router_mac_ipv6;\n        if (masscan->is_offline) {\n            memcpy(router_mac_ipv6->addr, \"\\x66\\x55\\x44\\x33\\x22\\x11\", 6);\n        }\n        if (macaddress_is_zero(*router_mac_ipv6)) {\n            /* [synchronous]\n             * Wait for router neighbor notification. This may take\n             * some time */\n            stack_ndpv6_resolve(\n                    masscan->nic[index].adapter,\n                    adapter_ipv6,\n                    *source_mac,\n                    router_mac_ipv6);\n        }\n        \n        fmt = macaddress_fmt(*router_mac_ipv6);\n        LOG(1, \"[+] router-mac-ipv6 = %s\\n\", fmt.string);\n        if (macaddress_is_zero(*router_mac_ipv6)) {\n            fmt = ipv4address_fmt(masscan->nic[index].router_ip);\n            LOG(0, \"[-] FAIL: NDP timed-out resolving MAC address for router %s: \\\"%s\\\"\\n\", ifname, fmt.string);\n            LOG(0, \"    [hint] try \\\"--router-mac-ipv6 66-55-44-33-22-11\\\" instead to bypass ARP\\n\");\n            LOG(0, \"    [hint] try \\\"--interface eth0\\\" to change interface\\n\");\n            return -1;\n        }\n\n\n    }\n\n    masscan->nic[index].is_usable = (is_usable_ipv4 & is_usable_ipv6);\n\n\n\n    LOG(2, \"[+] if(%s): initialization done.\\n\", ifname);\n    return 0;\n}\n"
  },
  {
    "path": "src/main-listscan.c",
    "content": "#include \"masscan.h\"\n#include \"util-logger.h\"\n#include \"crypto-blackrock.h\"\n\n\nvoid\nmain_listscan(struct Masscan *masscan)\n{\n    uint64_t i;\n    uint64_t range;\n    uint64_t start;\n    uint64_t end;\n    struct BlackRock blackrock;\n    unsigned increment = masscan->shard.of;\n    uint64_t seed = masscan->seed;\n\n    /* If called with no ports, then create a pseudo-port needed\n     * for the internal algorithm. */\n    if (!massip_has_target_ports(&masscan->targets))\n        rangelist_add_range(&masscan->targets.ports, 80, 80);\n    massip_optimize(&masscan->targets);\n\n    /* The \"range\" is the total number of IP/port combinations that\n     * the scan can produce */\n    range = massip_range(&masscan->targets).lo;\n\n\ninfinite:\n    blackrock_init(&blackrock, range, seed, masscan->blackrock_rounds);\n\n    start = masscan->resume.index + (masscan->shard.one-1);\n    end = range;\n    if (masscan->resume.count && end > start + masscan->resume.count)\n        end = start + masscan->resume.count;\n    end += (uint64_t)(masscan->retries * masscan->max_rate);\n\n    for (i=start; i<end; ) {\n        uint64_t xXx;\n        unsigned port;\n        ipaddress addr;\n\n        xXx = blackrock_shuffle(&blackrock,  i);\n\n        massip_pick(&masscan->targets, xXx, &addr, &port);\n        \n\n        if (masscan->is_test_csv) {\n            /* [KLUDGE] [TEST]\n             * For testing randomness output, prints last two bytes of\n             * IP address as CSV format for import into spreadsheet\n             */\n            printf(\"%u,%u\\n\",(addr.ipv4>>8)&0xFF, (addr.ipv4>>0)&0xFF);\n        } else if (masscan->targets.count_ports == 1) {\n            ipaddress_formatted_t fmt = ipaddress_fmt(addr);\n            /* This is the normal case */\n            printf(\"%s\\n\", fmt.string);\n        } else {\n            ipaddress_formatted_t fmt = ipaddress_fmt(addr);\n            if (addr.version == 6)\n                printf(\"[%s]:%u\\n\", fmt.string, port);\n            else\n                printf(\"%s:%u\\n\", fmt.string, port);\n        }\n\n        i += increment; /* <------ increment by 1 normally, more with shards/NICs */\n    }\n\n    if (masscan->is_infinite) {\n        seed++;\n        goto infinite;\n    }\n}\n"
  },
  {
    "path": "src/main-ptrace.c",
    "content": "#include \"main-ptrace.h\"\n#include \"proto-preprocess.h\"\n#include \"pixie-timer.h\"\n#include \"util-safefunc.h\"\n\n\n/***************************************************************************\n * Print packet info, when using nmap-style --packet-trace option\n ***************************************************************************/\nvoid\npacket_trace(FILE *fp, double pt_start, const unsigned char *px, size_t length, unsigned is_sent)\n{\n    unsigned x;\n    struct PreprocessedInfo parsed;\n    char from[64];\n    char to[64];\n    char sz_type[32];\n    unsigned type;\n    double timestamp = 1.0 * pixie_gettime() / 1000000.0;\n    unsigned offset;\n    const char *direction;\n    ipaddress_formatted_t fmt;\n\n    if (is_sent)\n        direction = \"SENT\";\n    else\n        direction = \"RCVD\";\n\n    /* parse the packet */\n    x = preprocess_frame(px, (unsigned)length, 1, &parsed);\n    if (!x)\n        return;\n    offset = parsed.found_offset;\n\n\n    /* format the IP addresses into fixed-width fields */\n    fmt = ipaddress_fmt(parsed.src_ip);\n    snprintf(from, sizeof(from), \"[%s]:%u\", fmt.string, parsed.port_src);\n\n    fmt = ipaddress_fmt(parsed.dst_ip);\n    snprintf(to, sizeof(to), \"[%s]:%u\", fmt.string, parsed.port_dst);\n\n    switch (parsed.found) {\n        case FOUND_ARP:\n            type = px[offset+6]<<8 | px[offset+7];\n            *strchr(to, ':') = '\\0';\n            *strchr(from, ':') = '\\0';\n            switch (type) {\n                case 1:safe_strcpy(sz_type, sizeof(sz_type), \"request\"); break;\n                case 2:safe_strcpy(sz_type, sizeof(sz_type), \"response\"); break;\n                default: snprintf(sz_type, sizeof(sz_type), \"unknown(%u)\", type); break;\n            }\n            fprintf(fp, \"%s (%5.4f) ARP  %-21s > %-21s %s\\n\", direction,\n                    timestamp - pt_start, from, to, sz_type);\n            break;\n        case FOUND_DNS:\n        case FOUND_UDP:\n            fprintf(fp, \"%s (%5.4f) UDP  %-21s > %-21s \\n\", direction,\n                    timestamp - pt_start, from, to);\n            break;\n        case FOUND_ICMP:\n            fprintf(fp, \"%s (%5.4f) ICMP %-21s > %-21s \\n\", direction,\n                    timestamp - pt_start, from, to);\n            break;\n        case FOUND_TCP:\n            type = px[offset+13];\n            switch (type) {\n                case 0x00: safe_strcpy(sz_type, sizeof(sz_type), \"NULL\"); break;\n                case 0x01: safe_strcpy(sz_type, sizeof(sz_type), \"FIN\"); break;\n                case 0x11: safe_strcpy(sz_type, sizeof(sz_type), \"FIN-ACK\"); break;\n                case 0x19: safe_strcpy(sz_type, sizeof(sz_type), \"FIN-ACK-PSH\"); break;\n                case 0x02: safe_strcpy(sz_type, sizeof(sz_type), \"SYN\"); break;\n                case 0x12: safe_strcpy(sz_type, sizeof(sz_type), \"SYN-ACK\"); break;\n                case 0x04: safe_strcpy(sz_type, sizeof(sz_type), \"RST\"); break;\n                case 0x14: safe_strcpy(sz_type, sizeof(sz_type), \"RST-ACK\"); break;\n                case 0x15: safe_strcpy(sz_type, sizeof(sz_type), \"RST-FIN-ACK\"); break;\n                case 0x10: safe_strcpy(sz_type, sizeof(sz_type), \"ACK\"); break;\n                case 0x18: safe_strcpy(sz_type, sizeof(sz_type), \"ACK-PSH\"); break;\n                default:\n                    snprintf(sz_type, sizeof(sz_type),\n                              \"%s%s%s%s%s%s%s%s\",\n                              (type&0x01)?\"FIN\":\"\",\n                              (type&0x02)?\"SYN\":\"\",\n                              (type&0x04)?\"RST\":\"\",\n                              (type&0x08)?\"PSH\":\"\",\n                              (type&0x10)?\"ACK\":\"\",\n                              (type&0x20)?\"URG\":\"\",\n                              (type&0x40)?\"ECE\":\"\",\n                              (type&0x80)?\"CWR\":\"\"\n                              );\n                    break;\n            }\n            if (parsed.app_length)\n            fprintf(fp, \"%s (%5.4f) TCP  %-21s > %-21s %s %u-bytes\\n\", direction,\n                    timestamp - pt_start, from, to, sz_type, parsed.app_length);\n            else\n            fprintf(fp, \"%s (%5.4f) TCP  %-21s > %-21s %s\\n\", direction,\n                    timestamp - pt_start, from, to, sz_type);\n            break;\n        case FOUND_IPV6:\n            break;\n        default:\n            fprintf(fp, \"%s (%5.4f) UNK  %-21s > %-21s [%u]\\n\", direction,\n                    timestamp - pt_start, from, to, parsed.found);\n            break;\n    }\n\n\n}\n"
  },
  {
    "path": "src/main-ptrace.h",
    "content": "#ifndef masscan_main_ptrace_h\n#define masscan_main_ptrace_h\n#include <stdio.h>\n#include <stdint.h>\n\n\nvoid packet_trace(FILE *fp, double pt_trace, const unsigned char *px, size_t length, unsigned is_sent);\n\n\n#endif\n"
  },
  {
    "path": "src/main-readrange.c",
    "content": "#include \"main-readrange.h\"\n#include \"masscan.h\"\n#include <assert.h>\n\n/***************************************************************************\n ***************************************************************************/\n/*static unsigned\ncount_cidr_bits(struct Range range)\n{\n    unsigned i;\n\n    for (i=0; i<32; i++) {\n        unsigned mask = 0xFFFFFFFF >> i;\n\n        if ((range.begin & ~mask) == (range.end & ~mask)) {\n            if ((range.begin & mask) == 0 && (range.end & mask) == mask)\n                return i;\n        }\n    }\n\n    return 0;\n}*/\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ncount_cidr6_bits(struct Range6 range)\n{\n    uint64_t i;\n\n    /* Kludge: can't handle more than 64-bits of CIDR ranges */\n    if (range.begin.hi != range.begin.lo)\n        return 0;\n\n    for (i=0; i<64; i++) {\n        uint64_t mask = 0xFFFFFFFFffffffffull >> i;\n\n        if ((range.begin.lo & ~mask) == (range.end.lo & ~mask)) {\n            if ((range.begin.lo & mask) == 0 && (range.end.lo & mask) == mask)\n                return (unsigned)i;\n        }\n    }\n\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nmain_readrange(struct Masscan *masscan)\n{\n    struct RangeList *list4 = &masscan->targets.ipv4;\n    struct Range6List *list6 = &masscan->targets.ipv6;\n    unsigned i;\n    FILE *fp = stdout;\n\n    for (i=0; i<list4->count; i++) {\n        unsigned prefix_length;\n        struct Range range = list4->list[i];\n\n        if (range.begin == range.end) {\n            fprintf(fp, \"%u.%u.%u.%u\\n\",\n                (range.begin>>24)&0xFF,\n                (range.begin>>16)&0xFF,\n                (range.begin>> 8)&0xFF,\n                (range.begin>> 0)&0xFF\n                );\n        } else if (range_is_cidr(range, &prefix_length)) {\n            fprintf(fp, \"%u.%u.%u.%u/%u\\n\",\n                    (range.begin>>24)&0xFF,\n                    (range.begin>>16)&0xFF,\n                    (range.begin>> 8)&0xFF,\n                    (range.begin>> 0)&0xFF,\n                    prefix_length\n                    );\n        } else {\n            fprintf(fp, \"%u.%u.%u.%u-%u.%u.%u.%u\\n\",\n                    (range.begin>>24)&0xFF,\n                    (range.begin>>16)&0xFF,\n                    (range.begin>> 8)&0xFF,\n                    (range.begin>> 0)&0xFF,\n                    (range.end>>24)&0xFF,\n                    (range.end>>16)&0xFF,\n                    (range.end>> 8)&0xFF,\n                    (range.end>> 0)&0xFF\n                    );\n        }\n    }\n\n    for (i=0; i<list6->count; i++) {\n        struct Range6 range = list6->list[i];\n        ipaddress_formatted_t fmt = ipv6address_fmt(range.begin);\n        fprintf(fp, \"%s\", fmt.string);\n        if (!ipv6address_is_equal(range.begin, range.end)) {\n            unsigned cidr_bits = count_cidr6_bits(range);\n            if (cidr_bits) {\n                fprintf(fp, \"/%u\", cidr_bits);\n            } else {\n                fmt = ipv6address_fmt(range.end);\n                fprintf(fp, \"-%s\", fmt.string);\n            }\n        }\n        fprintf(fp, \"\\n\");\n    }\n\n}\n"
  },
  {
    "path": "src/main-readrange.h",
    "content": "#ifndef MAIN_READRANGE_H\n#define MAIN_READRANGE_H\nstruct Masscan;\n\nvoid\nmain_readrange(struct Masscan *masscan);\n\n#endif\n"
  },
  {
    "path": "src/main-status.c",
    "content": "/*\n    prints \"status\" message once per second to the commandline\n\n    The status message indicates:\n    - the rate in packets-per-second\n    - %done\n    - estimated time remaining of the scan\n    - number of 'tcbs' (TCP control blocks) of active TCP connections\n\n*/\n#include \"main-status.h\"\n#include \"pixie-timer.h\"\n#include \"unusedparm.h\"\n#include \"main-globals.h\"\n#include \"util-safefunc.h\"\n#include \"util-bool.h\"\n#include <stdio.h>\n\n\n/***************************************************************************\n * Print a status message about once-per-second to the command-line. This\n * algorithm is a little funky because checking the timestamp on EVERY\n * packet is slow.\n ***************************************************************************/\nvoid\nstatus_print(\n    struct Status *status,\n    uint64_t count,\n    uint64_t max_count,\n    double pps,\n    uint64_t total_tcbs,\n    uint64_t total_synacks,\n    uint64_t total_syns,\n    uint64_t exiting,\n    bool json_status)\n{\n    double elapsed_time;\n    double rate;\n    double now;\n    double percent_done;\n    double time_remaining;\n    uint64_t current_tcbs = 0;\n    uint64_t current_synacks = 0;\n    uint64_t current_syns = 0;\n    double tcb_rate = 0.0;\n    double synack_rate = 0.0;\n    double syn_rate = 0.0;\n    double kpps = pps / 1000;\n    const char *fmt;\n\n    /* Support for --json-status; does not impact legacy/default output */\n    \n    /**\n     * {\"state\":\"*\",\"rate\":{\"kpps\":24.99,\"pps\":24985.49,\"synps\": 27763,\"ackps\":4,\"tcbps\":4},\"tcb\": 33,\"syn\":246648}\n     */\n    const char* json_fmt_infinite =\n    \"{\"\n        \"\\\"state\\\":\\\"*\\\",\"\n        \"\\\"rate\\\":\"\n        \"{\"\n            \"\\\"kpps\\\":%.2f,\"\n            \"\\\"pps\\\":%6$.2f,\"\n            \"\\\"synps\\\":%.0f,\"\n            \"\\\"ackps\\\":%.0f,\"\n            \"\\\"tcbps\\\":%.0f\"\n        \"},\"\n        \"\\\"tcb\\\":%5$\" PRIu64 \",\"\n        \"\\\"syn\\\":%7$\" PRIu64\n    \"}\\n\";\n    \n    /**\n     * {\"state\":\"waiting\",\"rate\":{\"kpps\":0.00,\"pps\":0.00},\"progress\":{\"percent\":21.87,\"seconds\":4,\"found\":56,\"syn\":{\"sent\": 341436,\"total\":1561528,\"remaining\":1220092}}}\n     */\n    const char *json_fmt_waiting = \n    \"{\"\n        \"\\\"state\\\":\\\"waiting\\\",\"\n        \"\\\"rate\\\":\"\n        \"{\"\n            \"\\\"kpps\\\":%.2f,\"\n            \"\\\"pps\\\":%5$.2f\"\n        \"},\"\n        \"\\\"progress\\\":\"\n        \"{\"\n            \"\\\"percent\\\":%.2f,\"\n            \"\\\"seconds\\\":%d,\"\n            \"\\\"found\\\":%\" PRIu64 \",\"\n            \"\\\"syn\\\":\"\n            \"{\"\n                \"\\\"sent\\\":%6$\" PRIu64 \",\"\n                \"\\\"total\\\":%7$\" PRIu64 \",\"\n                \"\\\"remaining\\\":%8$\" PRIu64\n            \"}\" \n        \"}\"\n    \"}\\n\";\n\n    /**\n     * {\"state\":\"running\",\"rate\":{\"kpps\":24.92,\"pps\":24923.07},\"progress\":{\"percent\":9.77,\"eta\":{\n     *      \"hours\":0,\"mins\":0,\"seconds\":55},\"syn\":{\"sent\": 152510,\"total\": 1561528,\"remaining\": 1409018},\"found\": 27}}\n     */\n    const char *json_fmt_running = \n    \"{\"\n        \"\\\"state\\\":\\\"running\\\",\"\n        \"\\\"rate\\\":\"\n        \"{\"\n            \"\\\"kpps\\\":%.2f,\"\n            \"\\\"pps\\\":%7$.2f\"\n        \"},\"\n        \"\\\"progress\\\":\"\n        \"{\"\n            \"\\\"percent\\\":%.2f,\"\n            \"\\\"eta\\\":\"\n            \"{\"\n                \"\\\"hours\\\":%u,\"\n                \"\\\"mins\\\":%u,\"\n                \"\\\"seconds\\\":%u\"\n            \"},\"\n            \"\\\"syn\\\":\"\n            \"{\"\n                \"\\\"sent\\\":%8$\" PRIu64 \",\"\n                \"\\\"total\\\":%9$\" PRIu64 \",\"\n                \"\\\"remaining\\\":%10$\" PRIu64\n            \"},\" \n            \"\\\"found\\\":%6$\" PRIu64\n        \"}\"\n    \"}\\n\";\n\n    /*\n     * ####  FUGGLY TIME HACK  ####\n     *\n     * PF_RING doesn't timestamp packets well, so we can't base time from\n     * incoming packets. Checking the time ourself is too ugly on per-packet\n     * basis. Therefore, we are going to create a global variable that keeps\n     * the time, and update that variable whenever it's convenient. This\n     * is one of those convenient places.\n     */\n    global_now = time(0);\n\n\n    /* Get the time. NOTE: this is CLOCK_MONOTONIC_RAW on Linux, not\n     * wall-clock time. */\n    now = (double)pixie_gettime();\n\n    /* Figure how many SECONDS have elapsed, in a floating point value.\n     * Since the above timestamp is in microseconds, we need to\n     * shift it by 1-million\n     */\n    elapsed_time = (now - status->last.clock)/1000000.0;\n    if (elapsed_time <= 0)\n        return;\n\n    /* Figure out the \"packets-per-second\" number, which is just:\n     *\n     *  rate = packets_sent / elapsed_time;\n     */\n    rate = (count - status->last.count)*1.0/elapsed_time;\n\n    /*\n     * Smooth the number by averaging over the last 8 seconds\n     */\n     status->last_rates[status->last_count++ & 0x7] = rate;\n     rate =     status->last_rates[0]\n                + status->last_rates[1]\n                + status->last_rates[2]\n                + status->last_rates[3]\n                + status->last_rates[4]\n                + status->last_rates[5]\n                + status->last_rates[6]\n                + status->last_rates[7]\n                ;\n    rate /= 8;\n    /*if (rate == 0)\n        return;*/\n\n    /*\n     * Calculate \"percent-done\", which is just the total number of\n     * packets sent divided by the number we need to send.\n     */\n    percent_done = (double)(count*100.0/max_count);\n\n\n    /*\n     * Calculate the time remaining in the scan\n     */\n    time_remaining  = (1.0 - percent_done/100.0) * (max_count / rate);\n\n    /*\n     * some other stats\n     */\n    if (total_tcbs) {\n        current_tcbs = total_tcbs - status->total_tcbs;\n        status->total_tcbs = total_tcbs;\n        tcb_rate = (1.0*current_tcbs)/elapsed_time;\n    }\n    if (total_synacks) {\n        current_synacks = total_synacks - status->total_synacks;\n        status->total_synacks = total_synacks;\n        synack_rate = (1.0*current_synacks)/elapsed_time;\n    }\n    if (total_syns) {\n        current_syns = total_syns - status->total_syns;\n        status->total_syns = total_syns;\n        syn_rate = (1.0*current_syns)/elapsed_time;\n    }\n\n    /*\n     * Print the message to <stderr> so that <stdout> can be redirected\n     * to a file (<stdout> reports what systems were found).\n     */\n\n    if (status->is_infinite) {\n        if (json_status == 1)\n            fmt = json_fmt_infinite;\n        else\n            fmt = \"rate:%6.2f-kpps, syn/s=%.0f ack/s=%.0f tcb-rate=%.0f, %\" PRIu64 \"-tcbs,         \\r\";\n\n        fprintf(stderr,\n            fmt,\n                kpps,\n                syn_rate,\n                synack_rate,\n                tcb_rate,\n                total_tcbs,\n                pps,\n                count);\n    } else {\n        if (is_tx_done) {\n            if (json_status == 1)\n                fmt = json_fmt_waiting;\n            else\n                fmt = \"rate:%6.2f-kpps, %5.2f%% done, waiting %d-secs, found=%\" PRIu64 \"       \\r\";\n\n            fprintf(stderr,\n                    fmt,\n                    pps/1000.0,\n                    percent_done,\n                    (int)exiting,\n                    total_synacks,\n                    pps,\n                    count,\n                    max_count,\n                    max_count-count);\n            \n        } else {\n            if (json_status == 1)\n                fmt = json_fmt_running;\n            else\n                fmt = \"rate:%6.2f-kpps, %5.2f%% done,%4u:%02u:%02u remaining, found=%\" PRIu64 \"       \\r\";\n\n            fprintf(stderr,\n                fmt,\n                pps/1000.0,\n                percent_done,\n                (unsigned)(time_remaining/60/60),\n                (unsigned)(time_remaining/60)%60,\n                (unsigned)(time_remaining)%60,\n                total_synacks,\n                pps,\n                count,\n                max_count,\n                max_count-count);\n        }\n    }\n    fflush(stderr);\n\n    /*\n     * Remember the values to be diffed against the next time around\n     */\n    status->last.clock = now;\n    status->last.count = count;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nstatus_finish(struct Status *status)\n{\n    UNUSEDPARM(status);\n    fprintf(stderr,\n\"                                                                             \\r\");\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nstatus_start(struct Status *status)\n{\n    memset(status, 0, sizeof(*status));\n    status->last.clock = clock();\n    status->last.time = time(0);\n    status->last.count = 0;\n    status->timer = 0x1;\n}\n"
  },
  {
    "path": "src/main-status.h",
    "content": "#ifndef MAIN_STATUS_H\n#define MAIN_STATUS_H\n#include <stdint.h>\n#include <time.h>\n#include \"util-bool.h\"\n\nstruct Status\n{\n    struct {\n        double clock;\n        time_t time;\n        uint64_t count;\n    } last;\n    uint64_t timer;\n    unsigned charcount;\n\n    double last_rates[8];\n    unsigned last_count;\n\n    unsigned is_infinite:1;\n\n    uint64_t total_tcbs;\n    uint64_t total_synacks;\n    uint64_t total_syns;\n};\n\n\nvoid status_print(struct Status *status, uint64_t count, uint64_t max_count, double x, uint64_t total_tcbs, uint64_t total_synacks, uint64_t total_syns, uint64_t exiting, bool json_status);\nvoid status_finish(struct Status *status);\nvoid status_start(struct Status *status);\n\n\n#endif\n"
  },
  {
    "path": "src/main-throttle.c",
    "content": "/*\n\n    Rate-limit/throttler: stops us from transmitting too fast.\n\n    We can send packets at millions of packets/second. This will\n    melt most networks. Therefore, we need to throttle or rate-limit\n    how fast we go.\n\n    Since we are sending packet at a rate of 10-million-per-second, we\n    the calculations need to be done in a light-weight manner. For one\n    thing, we can't do a system-call per packet.\n\n    NOTE: one complication to watch for is the difference between clock\n    time and elapsed time, and that they change. We have to avoid a problem\n    where somebody suspends the computer for a few days, then wake it up,\n    at which point the system tries sending a million packets/second instead\n    of the desired thousand packets/second.\n*/\n#include \"main-throttle.h\"\n#include \"pixie-timer.h\"\n#include \"util-logger.h\"\n#include <string.h>\n#include <stdio.h>\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nthrottler_start(struct Throttler *throttler, double max_rate)\n{\n    unsigned i;\n\n    memset(throttler, 0, sizeof(*throttler));\n\n    throttler->max_rate = max_rate;\n\n    for (i=0; i<sizeof(throttler->buckets)/sizeof(throttler->buckets[0]); i++) {\n        throttler->buckets[i].timestamp = pixie_gettime();\n        throttler->buckets[i].packet_count = 0;\n    }\n\n    throttler->batch_size = 1;\n\n    LOG(1, \"[+] starting throttler: rate = %0.2f-pps\\n\", throttler->max_rate);\n}\n\n\n/***************************************************************************\n * We return the number of packets that can be sent in a batch. Thus,\n * instead of trying to throttle each packet individually, which has a\n * high per-packet cost, we try to throttle a bunch at a time. Normally,\n * this function will return 1, only at high rates does it return larger\n * numbers.\n *\n * NOTE: The minimum value this returns is 1. When it's less than that,\n * it'll pause and wait until it's ready to send a packet.\n ***************************************************************************/\nuint64_t\nthrottler_next_batch(struct Throttler *throttler, uint64_t packet_count)\n{\n    uint64_t timestamp;\n    uint64_t index;\n    uint64_t old_timestamp;\n    uint64_t old_packet_count;\n    double current_rate;\n    double max_rate = throttler->max_rate;\n\nagain:\n\n    /* NOTE: this uses CLOCK_MONOTONIC_RAW on Linux, so the timstamp doesn't\n     * move forward when the machine is suspended */\n    timestamp = pixie_gettime();\n\n    /*\n     * We record that last 256 buckets, and average the rate over all of\n     * them.\n     */\n    index = (throttler->index) & 0xFF;\n    throttler->buckets[index].timestamp = timestamp;\n    throttler->buckets[index].packet_count = packet_count;\n\n    index = (++throttler->index) & 0xFF;\n    old_timestamp = throttler->buckets[index].timestamp;\n    old_packet_count = throttler->buckets[index].packet_count;\n\n    /*\n     * If the delay is more than 1-second, then we should reset the system\n     * in order to avoid transmitting too fast.\n     */\n    if (timestamp - old_timestamp > 1000000) {\n        //throttler_start(throttler, throttler->max_rate);\n        throttler->batch_size = 1;\n        goto again;\n    }\n\n    /*\n     * Calculate the recent rate.\n     * NOTE: this isn't the rate \"since start\", but only the \"recent\" rate.\n     * That's so that if the system pauses for a while, we don't flood the\n     * network trying to catch up.\n     */\n    current_rate = 1.0*(packet_count - old_packet_count)/((timestamp - old_timestamp)/1000000.0);\n\n\n    /*\n     * If we've been going too fast, then <pause> for a moment, then\n     * try again.\n     */\n    if (current_rate > max_rate) {\n        double waittime;\n\n        /* calculate waittime, in seconds */\n        waittime = (current_rate - max_rate) / throttler->max_rate;\n\n        /* At higher rates of speed, we don't actually need to wait the full\n         * interval. It's better to have a much smaller interval, so that\n         * we converge back on the true rate faster */\n        waittime *= 0.1;\n\n        /* This is in case of gross failure of the system. This should never\n         * actually happen, unless there is a bug. Really, I ought to make\n         * this an 'assert()' instead to fail and fix the bug rather than\n         * silently continuing, but I'm too lazy */\n        if (waittime > 0.1)\n            waittime = 0.1;\n\n        /* Since we've exceeded the speed limit, we should reduce the\n         * batch size slightly. We don't do it only by a little bit to\n         * avoid over-correcting. We want to converge on the correct\n         * speed gradually. Note that since this happens hundreds or\n         * thousands of times a second, the convergence is very fast\n         * even with 0.1% adjustment */\n        throttler->batch_size *= 0.999;\n\n        /* Now we wait for a bit */\n        pixie_usleep((uint64_t)(waittime * 1000000.0));\n\n        /* There are two choices here. We could either return immediately,\n         * or we can loop around again. Right now, the code loops around\n         * again in order to support very slow rates, such as 0.5 packets\n         * per second. Nobody would want to run a scanner that slowly of\n         * course, but it's great for testing */\n        //return (uint64_t)throttler->batch_size;\n        goto again;\n    }\n\n    /*\n     * Calculate how many packets are needed to catch up again to the current\n     * rate, and return that.\n     *\n     * NOTE: this is almost always going to have the value of 1 (one). Only at\n     * very high speeds (above 100,000 packets/second) will this value get\n     * larger.\n     */\n    throttler->batch_size *= 1.005;\n    if (throttler->batch_size > 10000)\n        throttler->batch_size = 10000;\n    throttler->current_rate = current_rate;\n\n    throttler->test_timestamp = timestamp;\n    throttler->test_packet_count = packet_count;\n    return (uint64_t)throttler->batch_size;\n}\n"
  },
  {
    "path": "src/main-throttle.h",
    "content": "#ifndef MAIN_THROTTLE_H\n#define MAIN_THROTTLE_H\n#include <stdint.h>\n\nstruct Throttler\n{\n    double max_rate;\n    double current_rate;\n    double batch_size;\n\n    unsigned index;\n\n    struct {\n        uint64_t timestamp;\n        uint64_t packet_count;\n    } buckets[256];\n\n    uint64_t test_timestamp;\n    uint64_t test_packet_count;\n\n};\n\n\nuint64_t throttler_next_batch(struct Throttler *throttler, uint64_t count);\nvoid throttler_start(struct Throttler *status, double max_rate);\n\n#endif\n"
  },
  {
    "path": "src/main.c",
    "content": "/*\n\n    main\n\n    This includes:\n\n    * main()\n    * transmit_thread() - transmits probe packets\n    * receive_thread() - receives response packets\n\n    You'll be wanting to study the transmit/receive threads, because that's\n    where all the action is.\n\n    This is the lynch-pin of the entire program, so it includes a heckuva lot\n    of headers, and the functions have a lot of local variables. I'm trying\n    to make this file relative \"flat\" this way so that everything is visible.\n*/\n#include \"masscan.h\"\n#include \"masscan-version.h\"\n#include \"masscan-status.h\"     /* open or closed */\n#include \"massip-parse.h\"\n#include \"massip-port.h\"\n#include \"main-status.h\"        /* printf() regular status updates */\n#include \"main-throttle.h\"      /* rate limit */\n#include \"main-dedup.h\"         /* ignore duplicate responses */\n#include \"main-ptrace.h\"        /* for nmap --packet-trace feature */\n#include \"main-globals.h\"       /* all the global variables in the program */\n#include \"main-readrange.h\"\n#include \"crypto-siphash24.h\"   /* hash function, for hash tables */\n#include \"crypto-blackrock.h\"   /* the BlackRock shuffling func */\n#include \"crypto-lcg.h\"         /* the LCG randomization func */\n#include \"crypto-base64.h\"      /* base64 encode/decode */\n#include \"templ-pkt.h\"          /* packet template, that we use to send */\n#include \"util-logger.h\"             /* adjust with -v command-line opt */\n#include \"stack-ndpv6.h\"        /* IPv6 Neighbor Discovery Protocol */\n#include \"stack-arpv4.h\"        /* Handle ARP resolution and requests */\n#include \"rawsock.h\"            /* API on top of Linux, Windows, Mac OS X*/\n#include \"rawsock-adapter.h\"    /* Get Ethernet adapter configuration */\n#include \"rawsock-pcapfile.h\"   /* for saving pcap files w/ raw packets */\n#include \"syn-cookie.h\"         /* for SYN-cookies on send */\n#include \"output.h\"             /* for outputting results */\n#include \"rte-ring.h\"           /* producer/consumer ring buffer */\n#include \"stub-pcap.h\"          /* dynamically load libpcap library */\n#include \"smack.h\"              /* Aho-corasick state-machine pattern-matcher */\n#include \"pixie-timer.h\"        /* portable time functions */\n#include \"pixie-threads.h\"      /* portable threads */\n#include \"pixie-backtrace.h\"    /* maybe print backtrace on crash */\n#include \"templ-payloads.h\"     /* UDP packet payloads */\n#include \"in-binary.h\"          /* convert binary output to XML/JSON */\n#include \"vulncheck.h\"          /* checking vulns like monlist, poodle, heartblee */\n#include \"scripting.h\"\n#include \"read-service-probes.h\"\n#include \"misc-rstfilter.h\"\n#include \"proto-x509.h\"\n#include \"proto-arp.h\"          /* for responding to ARP requests */\n#include \"proto-banner1.h\"      /* for snatching banners from systems */\n#include \"stack-tcp-core.h\"          /* for TCP/IP connection table */\n#include \"proto-preprocess.h\"   /* quick parse of packets */\n#include \"proto-icmp.h\"         /* handle ICMP responses */\n#include \"proto-udp.h\"          /* handle UDP responses */\n#include \"proto-snmp.h\"         /* parse SNMP responses */\n#include \"proto-ntp.h\"          /* parse NTP responses */\n#include \"proto-coap.h\"         /* CoAP selftest */\n#include \"proto-zeroaccess.h\"\n#include \"proto-sctp.h\"\n#include \"proto-oproto.h\"       /* Other protocols on top of IP */\n#include \"util-malloc.h\"\n#include \"util-checksum.h\"\n\n#include <assert.h>\n#include <limits.h>\n#include <string.h>\n#include <time.h>\n#include <stdlib.h>\n#include <signal.h>\n#include <stdint.h>\n\n#if defined(WIN32)\n#include <WinSock.h>\n#if defined(_MSC_VER)\n#pragma comment(lib, \"Ws2_32.lib\")\n#endif\n#else\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <unistd.h>\n#endif\n\n/*\n * yea I know globals suck\n */\nunsigned volatile is_tx_done = 0;\nunsigned volatile is_rx_done = 0;\ntime_t global_now;\n\nuint64_t usec_start;\n\n\n/***************************************************************************\n * We create a pair of transmit/receive threads for each network adapter.\n * This structure contains the parameters we send to each pair.\n ***************************************************************************/\nstruct ThreadPair {\n    /** This points to the central configuration. Note that it's 'const',\n     * meaning that the thread cannot change the contents. That'd be\n     * unsafe */\n    const struct Masscan *masscan;\n\n    /** The adapter used by the thread-pair. Normally, thread-pairs have\n     * their own network adapter, especially when doing PF_RING\n     * clustering. */\n    struct Adapter *adapter;\n\n    struct stack_t *stack;\n\n    /**\n     * The index of the network adapter that we are using for this\n     * thread-pair. This is an index into the \"masscan->nic[]\"\n     * array.\n     *\n     * NOTE: this is also the \"thread-id\", because we create one\n     * transmit/receive thread pair per NIC.\n     */\n    unsigned nic_index;\n\n    /**\n     * A copy of the master 'index' variable. This is just advisory for\n     * other threads, to tell them how far we've gotten.\n     */\n    volatile uint64_t my_index;\n\n\n    /* This is used both by the transmit and receive thread for\n     * formatting packets */\n    struct TemplateSet tmplset[1];\n\n    /**\n     * The current IP address we are using for transmit/receive.\n     */\n    struct stack_src_t _src_;\n\n    macaddress_t source_mac;\n    macaddress_t router_mac_ipv4;\n    macaddress_t router_mac_ipv6;\n\n    unsigned done_transmitting;\n    unsigned done_receiving;\n\n    double pt_start;\n\n    struct Throttler throttler[1];\n\n    uint64_t *total_synacks;\n    uint64_t *total_tcbs;\n    uint64_t *total_syns;\n\n    size_t thread_handle_xmit;\n    size_t thread_handle_recv;\n};\n\nstruct source_t {\n    unsigned ipv4;\n    unsigned ipv4_mask;\n    unsigned port;\n    unsigned port_mask;\n    ipv6address ipv6;\n    ipv6address ipv6_mask;\n};\n\n/***************************************************************************\n * We support a range of source IP/port. This function converts that\n * range into useful variables we can use to pick things form that range.\n ***************************************************************************/\nstatic void\nadapter_get_source_addresses(const struct Masscan *masscan,\n            unsigned nic_index,\n            struct source_t *src)\n{\n    const struct stack_src_t *ifsrc = &masscan->nic[nic_index].src;\n    static ipv6address mask = {~0ULL, ~0ULL};\n\n    src->ipv4 = ifsrc->ipv4.first;\n    src->ipv4_mask = ifsrc->ipv4.last - ifsrc->ipv4.first;\n\n    src->port = ifsrc->port.first;\n    src->port_mask = ifsrc->port.last - ifsrc->port.first;\n\n    src->ipv6 = ifsrc->ipv6.first;\n\n    /* TODO: currently supports only a single address. This needs to\n     * be fixed to support a list of addresses */\n    src->ipv6_mask = mask;\n}\n\n\n/***************************************************************************\n * This thread spews packets as fast as it can\n *\n *      THIS IS WHERE ALL THE EXCITEMENT HAPPENS!!!!\n *      90% of CPU cycles are in the function.\n *\n ***************************************************************************/\nstatic void\ntransmit_thread(void *v) /*aka. scanning_thread() */\n{\n    struct ThreadPair *parms = (struct ThreadPair *)v;\n    uint64_t i;\n    uint64_t start;\n    uint64_t end;\n    const struct Masscan *masscan = parms->masscan;\n    uint64_t retries = masscan->retries;\n    uint64_t rate = (uint64_t)masscan->max_rate;\n    unsigned r = (unsigned)retries + 1;\n    uint64_t range;\n    uint64_t range_ipv6;\n    struct BlackRock blackrock;\n    uint64_t count_ipv4 = rangelist_count(&masscan->targets.ipv4);\n    uint64_t count_ipv6 = range6list_count(&masscan->targets.ipv6).lo;\n    struct Throttler *throttler = parms->throttler;\n    struct TemplateSet pkt_template = templ_copy(parms->tmplset);\n    struct Adapter *adapter = parms->adapter;\n    uint64_t packets_sent = 0;\n    unsigned increment = masscan->shard.of * masscan->nic_count;\n    struct source_t src;\n    uint64_t seed = masscan->seed;\n    uint64_t repeats = 0; /* --infinite repeats */\n    uint64_t *status_syn_count;\n    uint64_t entropy = masscan->seed;\n\n    /* Wait to make sure receive_thread is ready */\n    pixie_usleep(1000000);\n    LOG(1, \"[+] starting transmit thread #%u\\n\", parms->nic_index);\n\n    /* export a pointer to this variable outside this threads so\n     * that the 'status' system can print the rate of syns we are\n     * sending */\n    status_syn_count = MALLOC(sizeof(uint64_t));\n    *status_syn_count = 0;\n    parms->total_syns = status_syn_count;\n\n\n    /* Normally, we have just one source address. In special cases, though\n     * we can have multiple. */\n    adapter_get_source_addresses(masscan, parms->nic_index, &src);\n\n\n    /* \"THROTTLER\" rate-limits how fast we transmit, set with the\n     * --max-rate parameter */\n    throttler_start(throttler, masscan->max_rate/masscan->nic_count);\n\ninfinite:\n    \n    /* Create the shuffler/randomizer. This creates the 'range' variable,\n     * which is simply the number of IP addresses times the number of\n     * ports.\n     * IPv6: low index will pick addresses from the IPv6 ranges, and high\n     * indexes will pick addresses from the IPv4 ranges. */\n    range = count_ipv4 * rangelist_count(&masscan->targets.ports)\n            + count_ipv6 * rangelist_count(&masscan->targets.ports);\n    range_ipv6 = count_ipv6 * rangelist_count(&masscan->targets.ports);\n    blackrock_init(&blackrock, range, seed, masscan->blackrock_rounds);\n\n    /* Calculate the 'start' and 'end' of a scan. One reason to do this is\n     * to support --shard, so that multiple machines can co-operate on\n     * the same scan. Another reason to do this is so that we can bleed\n     * a little bit past the end when we have --retries. Yet another\n     * thing to do here is deal with multiple network adapters, which\n     * is essentially the same logic as shards. */\n    start = masscan->resume.index + (masscan->shard.one-1) * masscan->nic_count + parms->nic_index;\n    end = range;\n    if (masscan->resume.count && end > start + masscan->resume.count)\n        end = start + masscan->resume.count;\n    end += retries * range;\n\n\n    /* -----------------\n     * the main loop\n     * -----------------*/\n    LOG(3, \"THREAD: xmit: starting main loop: [%llu..%llu]\\n\", start, end);\n    for (i=start; i<end; ) {\n        uint64_t batch_size;\n\n        /*\n         * Do a batch of many packets at a time. That because per-packet\n         * throttling is expensive at 10-million pps, so we reduce the\n         * per-packet cost by doing batches. At slower rates, the batch\n         * size will always be one. (--max-rate)\n         */\n        batch_size = throttler_next_batch(throttler, packets_sent);\n\n        /*\n         * Transmit packets from other thread, when doing --banners. This\n         * takes priority over sending SYN packets. If there is so much\n         * activity grabbing banners that we cannot transmit more SYN packets,\n         * then \"batch_size\" will get decremented to zero, and we won't be\n         * able to transmit SYN packets.\n         */\n        stack_flush_packets(parms->stack, adapter,\n                        &packets_sent, &batch_size);\n\n\n        /*\n         * Transmit a bunch of packets. At any rate slower than 100,000\n         * packets/second, the 'batch_size' is likely to be 1. At higher\n         * rates, we can't afford to throttle on a per-packet basis and \n         * instead throttle on a per-batch basis. In other words, throttle\n         * based on 2-at-a-time, 3-at-time, and so on, with the batch\n         * size increasing as the packet rate increases. This gives us\n         * very precise packet-timing for low rates below 100,000 pps,\n         * while not incurring the overhead for high packet rates.\n         */\n        while (batch_size && i < end) {\n            uint64_t xXx;\n            uint64_t cookie;\n            \n\n\n            /*\n             * RANDOMIZE THE TARGET:\n             *  This is kinda a tricky bit that picks a random IP and port\n             *  number in order to scan. We monotonically increment the\n             *  index 'i' from [0..range]. We then shuffle (randomly transmog)\n             *  that index into some other, but unique/1-to-1, number in the\n             *  same range. That way we visit all targets, but in a random\n             *  order. Then, once we've shuffled the index, we \"pick\" the\n             *  IP address and port that the index refers to.\n             */\n            xXx = (i + (r--) * rate);\n            if (rate > range)\n                xXx %= range;\n            else\n                while (xXx >= range)\n                    xXx -= range;\n            xXx = blackrock_shuffle(&blackrock,  xXx);\n            \n            if (xXx < range_ipv6) {\n                ipv6address ip_them;\n                unsigned port_them;\n                ipv6address ip_me;\n                unsigned port_me;\n\n                ip_them = range6list_pick(&masscan->targets.ipv6, xXx % count_ipv6);\n                port_them = rangelist_pick(&masscan->targets.ports, xXx / count_ipv6);\n\n                ip_me = src.ipv6;\n                port_me = src.port;\n                \n                cookie = syn_cookie_ipv6(ip_them, port_them, ip_me, port_me, entropy);\n\n                rawsock_send_probe_ipv6(\n                        adapter,\n                        ip_them, port_them,\n                        ip_me, port_me,\n                        (unsigned)cookie,\n                        !batch_size, /* flush queue on last packet in batch */\n                        &pkt_template\n                        );\n\n                /* Our index selects an IPv6 target */\n            } else {\n                /* Our index selects an IPv4 target. In other words, low numbers\n                 * index into the IPv6 ranges, and high numbers index into the\n                 * IPv4 ranges. */\n                ipv4address ip_them;\n                ipv4address port_them;\n                unsigned ip_me;\n                unsigned port_me;\n\n                xXx -= range_ipv6;\n\n                ip_them = rangelist_pick(&masscan->targets.ipv4, xXx % count_ipv4);\n                port_them = rangelist_pick(&masscan->targets.ports, xXx / count_ipv4);\n\n                /*\n                 * SYN-COOKIE LOGIC\n                 *  Figure out the source IP/port, and the SYN cookie\n                 */\n                if (src.ipv4_mask > 1 || src.port_mask > 1) {\n                    uint64_t ck = syn_cookie_ipv4((unsigned)(i+repeats),\n                                            (unsigned)((i+repeats)>>32),\n                                            (unsigned)xXx, (unsigned)(xXx>>32),\n                                            entropy);\n                    port_me = src.port + (ck & src.port_mask);\n                    ip_me = src.ipv4 + ((ck>>16) & src.ipv4_mask);\n                } else {\n                    ip_me = src.ipv4;\n                    port_me = src.port;\n                }\n                cookie = syn_cookie_ipv4(ip_them, port_them, ip_me, port_me, entropy);\n\n                /*\n                 * SEND THE PROBE\n                 *  This is sorta the entire point of the program, but little\n                 *  exciting happens here. The thing to note that this may\n                 *  be a \"raw\" transmit that bypasses the kernel, meaning\n                 *  we can call this function millions of times a second.\n                 */\n                rawsock_send_probe_ipv4(\n                        adapter,\n                        ip_them, port_them,\n                        ip_me, port_me,\n                        (unsigned)cookie,\n                        !batch_size, /* flush queue on last packet in batch */\n                        &pkt_template\n                        );\n            }\n\n            batch_size--;\n            packets_sent++;\n            (*status_syn_count)++;\n\n            /*\n             * SEQUENTIALLY INCREMENT THROUGH THE RANGE\n             *  Yea, I know this is a puny 'i++' here, but it's a core feature\n             *  of the system that is linearly increments through the range,\n             *  but produces from that a shuffled sequence of targets (as\n             *  described above). Because we are linearly incrementing this\n             *  number, we can do lots of creative stuff, like doing clever\n             *  retransmits and sharding.\n             */\n            if (r == 0) {\n                i += increment; /* <------ increment by 1 normally, more with shards/nics */\n                r = (unsigned)retries + 1;\n            }\n\n        } /* end of batch */\n\n\n        /* save our current location for resuming, if the user pressed\n         * <ctrl-c> to exit early */\n        parms->my_index = i;\n\n        /* If the user pressed <ctrl-c>, then we need to exit. In case\n         * the user wants to --resume the scan later, we save the current\n         * state in a file */\n        if (is_tx_done) {\n            break;\n        }\n    }\n\n    /*\n     * --infinite\n     *  For load testing, go around and do this again\n     */\n    if (masscan->is_infinite && !is_tx_done) {\n        seed++;\n        repeats++;\n        goto infinite;\n    }\n\n    /*\n     * Flush any untransmitted packets. High-speed mechanisms like Windows\n     * \"sendq\" and Linux's \"PF_RING\" queue packets and transmit many together,\n     * so there may be some packets that we've queued but not yet transmitted.\n     * This call makes sure they are transmitted.\n     */\n    rawsock_flush(adapter);\n\n    /*\n     * Wait until the receive thread realizes the scan is over\n     */\n    LOG(1, \"[+] transmit thread #%u complete\\n\", parms->nic_index);\n\n    /*\n     * We are done transmitting. However, response packets will take several\n     * seconds to arrive. Therefore, sit in short loop waiting for those\n     * packets to arrive. Pressing <ctrl-c> a second time will exit this\n     * prematurely.\n     */\n    while (!is_rx_done) {\n        unsigned k;\n        uint64_t batch_size;\n\n        for (k=0; k<1000; k++) {\n            \n            /*\n             * Only send a few packets at a time, throttled according to the max\n             * --max-rate set by the user\n             */\n            batch_size = throttler_next_batch(throttler, packets_sent);\n\n\n            /* Transmit packets from the receive thread */\n            stack_flush_packets(  parms->stack, adapter,\n                            &packets_sent,\n                            &batch_size);\n\n            /* Make sure they've actually been transmitted, not just queued up for\n             * transmit */\n            rawsock_flush(adapter);\n\n            pixie_usleep(100);\n        }\n    }\n\n    /* Thread is about to exit */\n    parms->done_transmitting = 1;\n    LOG(1, \"[+] exiting transmit thread #%u                    \\n\", parms->nic_index);\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nis_nic_port(const struct Masscan *masscan, unsigned ip)\n{\n    unsigned i;\n    for (i=0; i<masscan->nic_count; i++)\n        if (is_my_port(&masscan->nic[i].src, ip))\n            return 1;\n    return 0;\n}\n\nstatic unsigned\nis_ipv6_multicast(ipaddress ip_me)\n{\n    /* If this is an IPv6 multicast packet, one sent to the IPv6\n     * address with a prefix of FF02::/16 */\n    return ip_me.version == 6 && (ip_me.ipv6.hi>>48ULL) == 0xFF02;\n}\n\n\n/***************************************************************************\n *\n * Asynchronous receive thread\n *\n * The transmit and receive threads run independently of each other. There\n * is no record what was transmitted. Instead, the transmit thread sets a\n * \"SYN-cookie\" in transmitted packets, which the receive thread will then\n * use to match up requests with responses.\n ***************************************************************************/\nstatic void\nreceive_thread(void *v)\n{\n    struct ThreadPair *parms = (struct ThreadPair *)v;\n    const struct Masscan *masscan = parms->masscan;\n    struct Adapter *adapter = parms->adapter;\n    int data_link = stack_if_datalink(adapter);\n    struct Output *out;\n    struct DedupTable *dedup;\n    struct PcapFile *pcapfile = NULL;\n    struct TCP_ConnectionTable *tcpcon = 0;\n    uint64_t *status_synack_count;\n    uint64_t *status_tcb_count;\n    uint64_t entropy = masscan->seed;\n    struct ResetFilter *rf;\n    struct stack_t *stack = parms->stack;\n    struct source_t src = {0};\n\n    \n    \n    /* For reducing RST responses, see rstfilter_is_filter() below */\n    rf = rstfilter_create(entropy, 16384);\n\n    /* some status variables */\n    status_synack_count = MALLOC(sizeof(uint64_t));\n    *status_synack_count = 0;\n    parms->total_synacks = status_synack_count;\n\n    status_tcb_count = MALLOC(sizeof(uint64_t));\n    *status_tcb_count = 0;\n    parms->total_tcbs = status_tcb_count;\n\n    LOG(1, \"[+] starting receive thread #%u\\n\", parms->nic_index);\n    \n    /* Lock this thread to a CPU. Transmit threads are on even CPUs,\n     * receive threads on odd CPUs */\n    if (pixie_cpu_get_count() > 1) {\n        unsigned cpu_count = pixie_cpu_get_count();\n        unsigned cpu = parms->nic_index * 2 + 1;\n        while (cpu >= cpu_count) {\n            cpu -= cpu_count;\n            cpu++;\n        }\n        //TODO:\n        //pixie_cpu_set_affinity(cpu);\n    }\n\n    /*\n     * If configured, open a --pcap file for saving raw packets. This is\n     * so that we can debug scans, but also so that we can look at the\n     * strange things people send us. Note that we don't record transmitted\n     * packets, just the packets we've received.\n     */\n    if (masscan->pcap_filename[0]) {\n        pcapfile = pcapfile_openwrite(masscan->pcap_filename, 1);\n    }\n\n    /*\n     * Open output. This is where results are reported when saving\n     * the --output-format to the --output-filename\n     */\n    out = output_create(masscan, parms->nic_index);\n\n    /*\n     * Create deduplication table. This is so when somebody sends us\n     * multiple responses, we only record the first one.\n     */\n    dedup = dedup_create();\n\n    /*\n     * Create a TCP connection table (per thread pair) for interacting with live\n     * connections when doing --banners\n     */\n    if (masscan->is_banners) {\n        struct TcpCfgPayloads *pay;\n        size_t i;\n\n        /*\n         * Create TCP connection table\n         */\n        tcpcon = tcpcon_create_table(\n            (size_t)((masscan->max_rate/5) / masscan->nic_count),\n            parms->stack,\n            &parms->tmplset->pkts[Proto_TCP],\n            output_report_banner,\n            out,\n            masscan->tcb.timeout,\n            masscan->seed\n            );\n        \n        /*\n         * Initialize TCP scripting\n         */\n        scripting_init_tcp(tcpcon, masscan->scripting.L);\n\n        /*\n         * Get the possible source IP addresses and ports that masscan\n         * might be using to transmit from.\n         */\n        adapter_get_source_addresses(masscan, parms->nic_index, &src);\n                               \n\n        /*\n         * Set some flags [kludge]\n         */\n        tcpcon_set_banner_flags(tcpcon,\n                masscan->is_capture_cert,\n                masscan->is_capture_servername,\n                masscan->is_capture_html,\n                masscan->is_capture_heartbleed,\n\t\t\t\tmasscan->is_capture_ticketbleed);\n        if (masscan->is_hello_smbv1)\n            tcpcon_set_parameter(tcpcon, \"hello\", 1, \"smbv1\");\n        if (masscan->is_hello_http)\n            tcpcon_set_parameter(tcpcon, \"hello\", 1, \"http\");\n        if (masscan->is_hello_ssl)\n            tcpcon_set_parameter(tcpcon, \"hello\", 1, \"ssl\");\n        if (masscan->is_heartbleed)\n            tcpcon_set_parameter(tcpcon, \"heartbleed\", 1, \"1\");\n        if (masscan->is_ticketbleed)\n            tcpcon_set_parameter(tcpcon, \"ticketbleed\", 1, \"1\");\n        if (masscan->is_poodle_sslv3)\n            tcpcon_set_parameter(tcpcon, \"sslv3\", 1, \"1\");\n\n        if (masscan->http.payload)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-payload\",\n                                    masscan->http.payload_length,\n                                    masscan->http.payload);\n        if (masscan->http.user_agent)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-user-agent\",\n                                    masscan->http.user_agent_length,\n                                    masscan->http.user_agent);\n        if (masscan->http.host)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-host\",\n                                    masscan->http.host_length,\n                                    masscan->http.host);\n        if (masscan->http.method)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-method\",\n                                    masscan->http.method_length,\n                                    masscan->http.method);\n        if (masscan->http.url)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-url\",\n                                    masscan->http.url_length,\n                                    masscan->http.url);\n        if (masscan->http.version)\n            tcpcon_set_parameter(   tcpcon,\n                                    \"http-version\",\n                                    masscan->http.version_length,\n                                    masscan->http.version);\n\n\n        if (masscan->tcp_connection_timeout) {\n            char foo[64];\n            snprintf(foo, sizeof(foo), \"%u\", masscan->tcp_connection_timeout);\n            tcpcon_set_parameter(   tcpcon,\n                                 \"timeout\",\n                                 strlen(foo),\n                                 foo);\n        }\n        if (masscan->tcp_hello_timeout) {\n            char foo[64];\n            snprintf(foo, sizeof(foo), \"%u\", masscan->tcp_hello_timeout);\n            tcpcon_set_parameter(   tcpcon,\n                                 \"hello-timeout\",\n                                 strlen(foo),\n                                 foo);\n        }\n        \n        for (i=0; i<masscan->http.headers_count; i++) {\n            tcpcon_set_http_header(tcpcon,\n                        masscan->http.headers[i].name,\n                        masscan->http.headers[i].value_length,\n                        masscan->http.headers[i].value,\n                        http_field_replace);\n        }\n        for (i=0; i<masscan->http.cookies_count; i++) {\n            tcpcon_set_http_header(tcpcon,\n                        \"Cookie\",\n                        masscan->http.cookies[i].value_length,\n                        masscan->http.cookies[i].value,\n                        http_field_add);\n        }\n        for (i=0; i<masscan->http.remove_count; i++) {\n            tcpcon_set_http_header(tcpcon,\n                        masscan->http.headers[i].name,\n                        0,\n                        0,\n                        http_field_remove);\n        }\n\n        for (pay = masscan->payloads.tcp; pay; pay = pay->next) {\n            char name[64];\n            snprintf(name, sizeof(name), \"hello-string[%u]\", pay->port);\n            tcpcon_set_parameter(   tcpcon, \n                                    name, \n                                    strlen(pay->payload_base64), \n                                    pay->payload_base64);\n        }\n\n    }\n\n    /*\n     * In \"offline\" mode, we don't have any receive threads, so simply\n     * wait until transmitter thread is done then go to the end\n     */\n    if (masscan->is_offline) {\n        while (!is_rx_done)\n            pixie_usleep(10000);\n        parms->done_receiving = 1;\n        goto end;\n    }\n\n    /*\n     * Receive packets. This is where we catch any responses and print\n     * them to the terminal.\n     */\n    LOG(2, \"[+] THREAD: recv: starting main loop\\n\");\n    while (!is_rx_done) {\n        int status;\n        unsigned length;\n        unsigned secs;\n        unsigned usecs;\n        const unsigned char *px;\n        int err;\n        unsigned x;\n        struct PreprocessedInfo parsed;\n        ipaddress ip_me;\n        unsigned port_me;\n        ipaddress ip_them;\n        unsigned port_them;\n        unsigned seqno_me;\n        unsigned seqno_them;\n        unsigned cookie;\n        unsigned Q = 0;\n\n        /*\n         * RECEIVE\n         *\n         * This is the boring part of actually receiving a packet\n         */\n        err = rawsock_recv_packet(\n                    adapter,\n                    &length,\n                    &secs,\n                    &usecs,\n                    &px);\n        if (err != 0) {\n            if (tcpcon)\n                tcpcon_timeouts(tcpcon, (unsigned)time(0), 0);\n            continue;\n        }\n        \n\n        /*\n         * Do any TCP event timeouts based on the current timestamp from\n         * the packet. For example, if the connection has been open for\n         * around 10 seconds, we'll close the connection. (--banners)\n         */\n        if (tcpcon) {\n            tcpcon_timeouts(tcpcon, secs, usecs);\n        }\n\n        if (length > 1514)\n            continue;\n\n        /*\n         * \"Preprocess\" the response packet. This means to go through and\n         * figure out where the TCP/IP headers are and the locations of\n         * some fields, like IP address and port numbers.\n         */\n        x = preprocess_frame(px, length, data_link, &parsed);\n        if (!x)\n            continue; /* corrupt packet */\n        ip_me = parsed.dst_ip;\n        ip_them = parsed.src_ip;\n        port_me = parsed.port_dst;\n        port_them = parsed.port_src;\n        seqno_them = TCP_SEQNO(px, parsed.transport_offset);\n        seqno_me = TCP_ACKNO(px, parsed.transport_offset);\n        \n        assert(ip_me.version != 0);\n        assert(ip_them.version != 0);\n\n        switch (parsed.ip_protocol) {\n        case 132: /* SCTP */\n            cookie = syn_cookie(ip_them, port_them | (Proto_SCTP<<16), ip_me, port_me, entropy) & 0xFFFFFFFF;\n            break;\n        default:\n            cookie = syn_cookie(ip_them, port_them, ip_me, port_me, entropy) & 0xFFFFFFFF;\n        }\n\n        /* verify: my IP address */\n        if (!is_my_ip(stack->src, ip_me)) {\n            /* NDP Neighbor Solicitations don't come to our IP address, but to\n             * a multicast address */\n            if (is_ipv6_multicast(ip_me)) {\n                if (parsed.found == FOUND_NDPv6 && parsed.opcode == 135) {\n                    stack_ndpv6_incoming_request(stack, &parsed, px, length);\n                }\n            }\n            continue;\n        }\n\n        /*\n         * Handle non-TCP protocols\n         */\n        switch (parsed.found) {\n            case FOUND_NDPv6:\n                switch (parsed.opcode) {\n                case 133: /* Router Solicitation */\n                    /* Ignore router solicitations, since we aren't a router */\n                    continue;\n                case 134: /* Router advertisement */\n                    /* TODO: We need to process router advertisements while scanning\n                     * so that we can print warning messages if router information\n                     * changes while scanning. */\n                    continue;\n                case 135: /* Neighbor Solicitation */\n                    /* When responses come back from our scans, the router will send us\n                     * these packets. We need to respond to them, so that the router\n                     * can then forward the packets to us. If we don't respond, we'll\n                     * get no responses. */\n                    stack_ndpv6_incoming_request(stack, &parsed, px, length);\n                    continue;\n                case 136: /* Neighbor Advertisement */\n                    /* TODO: If doing an --ndpscan, the scanner subsystem needs to deal\n                     * with these */\n                    continue;\n                case 137: /* Redirect */\n                    /* We ignore these, since we really don't have the capability to send\n                     * packets to one router for some destinations and to another router\n                     * for other destinations */\n                    continue;\n                default:\n                    break;\n                }\n                continue;\n            case FOUND_ARP:\n                LOGip(2, ip_them, 0, \"-> ARP [%u] \\n\", px[parsed.found_offset]);\n\n                switch (parsed.opcode) {\n                case 1: /* request */\n                    /* This function will transmit a \"reply\" to somebody's ARP request\n                     * for our IP address (as part of our user-mode TCP/IP).\n                     * Since we completely bypass the TCP/IP stack, we  have to handle ARPs\n                     * ourself, or the router will lose track of us.*/\n                     stack_arp_incoming_request(stack,\n                                      ip_me.ipv4,\n                                      parms->source_mac,\n                                      px, length);\n                    break;\n                case 2: /* response */\n                    /* This is for \"arp scan\" mode, where we are ARPing targets rather\n                     * than port scanning them */\n\n                    /* If we aren't doing an ARP scan, then ignore ARP responses */\n                    if (!masscan->scan_type.arp)\n                        break;\n\n                    /* If this response isn't in our range, then ignore it */\n                    if (!rangelist_is_contains(&masscan->targets.ipv4, ip_them.ipv4))\n                        break;\n\n                    /* Ignore duplicates */\n                    if (dedup_is_duplicate(dedup, ip_them, 0, ip_me, 0))\n                        continue;\n\n                    /* ...everything good, so now report this response */\n                    arp_recv_response(out, secs, px, length, &parsed);\n                    break;\n                }\n                continue;\n            case FOUND_UDP:\n            case FOUND_DNS:\n                if (!is_nic_port(masscan, port_me))\n                    continue;\n                if (parms->masscan->nmap.packet_trace)\n                    packet_trace(stdout, parms->pt_start, px, length, 0);\n                handle_udp(out, secs, px, length, &parsed, entropy);\n                continue;\n            case FOUND_ICMP:\n                handle_icmp(out, secs, px, length, &parsed, entropy);\n                continue;\n            case FOUND_SCTP:\n                handle_sctp(out, secs, px, length, cookie, &parsed, entropy);\n                break;\n            case FOUND_OPROTO: /* other IP proto */\n                handle_oproto(out, secs, px, length, &parsed, entropy);\n                break;\n            case FOUND_TCP:\n                /* fall down to below */\n                break;\n            default:\n                continue;\n        }\n\n\n        /* verify: my port number */\n        if (!is_my_port(stack->src, port_me))\n            continue;\n        if (parms->masscan->nmap.packet_trace)\n            packet_trace(stdout, parms->pt_start, px, length, 0);\n\n        Q = 0;\n\n        /* Save raw packet in --pcap file */\n        if (pcapfile) {\n            pcapfile_writeframe(\n                pcapfile,\n                px,\n                length,\n                length,\n                secs,\n                usecs);\n        }\n\n        {\n            char buf[64];\n            LOGip(5, ip_them, port_them, \"-> TCP ackno=0x%08x flags=0x%02x(%s)\\n\",\n                seqno_me,\n                TCP_FLAGS(px, parsed.transport_offset),\n                reason_string(TCP_FLAGS(px, parsed.transport_offset), buf, sizeof(buf)));\n        }\n\n        /* If recording --banners, create a new \"TCP Control Block (TCB)\" */\n        if (tcpcon) {\n            struct TCP_Control_Block *tcb;\n\n            /* does a TCB already exist for this connection? */\n            tcb = tcpcon_lookup_tcb(tcpcon,\n                            ip_me, ip_them,\n                            port_me, port_them);\n\n            if (TCP_IS_SYNACK(px, parsed.transport_offset)) {\n                if (cookie != seqno_me - 1) {\n                    ipaddress_formatted_t fmt = ipaddress_fmt(ip_them);\n                    LOG(0, \"%s - bad cookie: ackno=0x%08x expected=0x%08x\\n\",\n                        fmt.string, seqno_me-1, cookie);\n                    continue;\n                }\n                if (tcb == NULL) {\n                    tcb = tcpcon_create_tcb(tcpcon,\n                                    ip_me, ip_them,\n                                    port_me, port_them,\n                                    seqno_me, seqno_them+1,\n                                    parsed.ip_ttl, NULL,\n                                    secs, usecs);\n                    (*status_tcb_count)++;\n                }\n                Q += stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_SYNACK,\n                    0, 0, secs, usecs, seqno_them+1, seqno_me);\n\n            } else if (tcb) {\n                /* If this is an ACK, then handle that first */\n                if (TCP_IS_ACK(px, parsed.transport_offset)) {\n                    Q += stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_ACK,\n                        0, 0, secs, usecs, seqno_them, seqno_me);\n                }\n\n                /* If this contains payload, handle that second */\n                if (parsed.app_length) {\n                    Q += stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_DATA,\n                        px + parsed.app_offset, parsed.app_length,\n                        secs, usecs, seqno_them, seqno_me);\n                }\n\n                /* If this is a FIN, handle that. Note that ACK +\n                 * payload + FIN can come together */\n                if (TCP_IS_FIN(px, parsed.transport_offset)\n                    && !TCP_IS_RST(px, parsed.transport_offset)) {\n                    Q += stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_FIN,\n                            0, 0, \n                            secs, usecs, \n                            seqno_them + parsed.app_length, /* the FIN comes after any data in the packet */\n                            seqno_me);\n                }\n\n                /* If this is a RST, then we'll be closing the connection */\n                if (TCP_IS_RST(px, parsed.transport_offset)) {\n                    Q += stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_RST,\n                        0, 0, secs, usecs, seqno_them, seqno_me);\n                }\n            } else if (TCP_IS_FIN(px, parsed.transport_offset)) {\n                ipaddress_formatted_t fmt;\n                /*\n                 * NO TCB!\n                 *  This happens when we've sent a FIN, deleted our connection,\n                 *  but the other side didn't get the packet.\n                 */\n                fmt = ipaddress_fmt(ip_them);\n                LOG(4, \"%s: received FIN but no TCB\\n\", fmt.string);\n                if (TCP_IS_RST(px, parsed.transport_offset))\n                    ; /* ignore if it's own TCP flag is set */\n                else {\n                    int is_suppress;\n                    \n                    is_suppress = rstfilter_is_filter(rf, ip_me, port_me, ip_them, port_them);\n                    if (!is_suppress)\n                        tcpcon_send_RST(\n                            tcpcon,\n                            ip_me, ip_them,\n                            port_me, port_them,\n                            seqno_them, seqno_me);\n                }\n            }\n\n        }\n\n        if (Q == 0)\n            ; //printf(\"\\nerr\\n\");\n   \n        if (TCP_IS_SYNACK(px, parsed.transport_offset)\n            || TCP_IS_RST(px, parsed.transport_offset)) {\n            /* figure out the status */\n            status = PortStatus_Unknown;\n            if (TCP_IS_SYNACK(px, parsed.transport_offset))\n                status = PortStatus_Open;\n            if (TCP_IS_RST(px, parsed.transport_offset)) {\n                status = PortStatus_Closed;\n            }\n\n            /* verify: syn-cookies */\n            if (cookie != seqno_me - 1) {\n                ipaddress_formatted_t fmt = ipaddress_fmt(ip_them);\n                LOG(2, \"%s - bad cookie: ackno=0x%08x expected=0x%08x\\n\",\n                    fmt.string, seqno_me-1, cookie);\n                continue;\n            }\n\n            /* verify: ignore duplicates */\n            if (dedup_is_duplicate(dedup, ip_them, port_them, ip_me, port_me))\n                continue;\n\n            /* keep statistics on number received */\n            if (TCP_IS_SYNACK(px, parsed.transport_offset))\n                (*status_synack_count)++;\n\n            /*\n             * This is where we do the output\n             */\n            output_report_status(\n                        out,\n                        global_now,\n                        status,\n                        ip_them,\n                        6, /* ip proto = tcp */\n                        port_them,\n                        px[parsed.transport_offset + 13], /* tcp flags */\n                        parsed.ip_ttl,\n                        parsed.mac_src\n                        );\n            \n\n            /*\n             * Send RST so other side isn't left hanging (only doing this in\n             * complete stateless mode where we aren't tracking banners)\n             */\n            if (tcpcon == NULL && !masscan->is_noreset)\n                tcp_send_RST(\n                    &parms->tmplset->pkts[Proto_TCP],\n                    parms->stack,\n                    ip_them, ip_me,\n                    port_them, port_me,\n                    0, seqno_me);\n\n        }\n    }\n\n\n    LOG(1, \"[+] exiting receive thread #%u                    \\n\", parms->nic_index);\n    \n    /*\n     * cleanup\n     */\nend:\n    if (tcpcon)\n        tcpcon_destroy_table(tcpcon);\n    dedup_destroy(dedup);\n    output_destroy(out);\n    if (pcapfile)\n        pcapfile_close(pcapfile);\n\n    /*TODO: free stack packet buffers */\n\n    /* Thread is about to exit */\n    parms->done_receiving = 1;\n}\n\n\n/***************************************************************************\n * We trap the <ctrl-c> so that instead of exiting immediately, we sit in\n * a loop for a few seconds waiting for any late response. But, the user\n * can press <ctrl-c> a second time to exit that waiting.\n ***************************************************************************/\nstatic void control_c_handler(int x)\n{\n    static unsigned control_c_pressed = 0;\n    static unsigned control_c_pressed_again = 0;\n    if (control_c_pressed == 0) {\n        fprintf(stderr,\n                \"waiting several seconds to exit...\"\n                \"                                            \\n\"\n                );\n        fflush(stderr);\n        control_c_pressed = 1+x;\n        is_tx_done = control_c_pressed;\n    } else {\n        if (is_rx_done) {\n            fprintf(stderr, \"\\nERROR: threads not exiting %d\\n\", is_rx_done);\n            if (is_rx_done++ > 1)\n                exit(1);\n        } else {\n            control_c_pressed_again = 1;\n            is_rx_done = control_c_pressed_again;\n        }\n    }\n\n}\n\n\n\n\n/***************************************************************************\n * Called from main() to initiate the scan.\n * Launches the 'transmit_thread()' and 'receive_thread()' and waits for\n * them to exit.\n ***************************************************************************/\nstatic int\nmain_scan(struct Masscan *masscan)\n{\n    struct ThreadPair parms_array[8];\n    uint64_t count_ips;\n    uint64_t count_ports;\n    uint64_t range;\n    unsigned index;\n    time_t now = time(0);\n    struct Status status;\n    uint64_t min_index = UINT64_MAX;\n    struct MassVulnCheck *vulncheck = NULL;\n    struct stack_t *stack;\n\n    memset(parms_array, 0, sizeof(parms_array));\n\n    /*\n     * Vuln check initialization\n     */\n    if (masscan->vuln_name) {\n        unsigned i;\n\t\tunsigned is_error;\n        vulncheck = vulncheck_lookup(masscan->vuln_name);\n        \n        /* If no ports specified on command-line, grab default ports */\n        is_error = 0;\n        if (rangelist_count(&masscan->targets.ports) == 0)\n            rangelist_parse_ports(&masscan->targets.ports, vulncheck->ports, &is_error, 0);\n        \n        /* Kludge: change normal port range to vulncheck range */\n        for (i=0; i<masscan->targets.ports.count; i++) {\n            struct Range *r = &masscan->targets.ports.list[i];\n            r->begin = (r->begin&0xFFFF) | Templ_VulnCheck;\n            r->end = (r->end & 0xFFFF) | Templ_VulnCheck;\n        }\n    }\n    \n    /*\n     * Initialize the task size\n     */\n    count_ips = rangelist_count(&masscan->targets.ipv4) + range6list_count(&masscan->targets.ipv6).lo;\n    if (count_ips == 0) {\n        LOG(0, \"FAIL: target IP address list empty\\n\");\n        LOG(0, \" [hint] try something like \\\"--range 10.0.0.0/8\\\"\\n\");\n        LOG(0, \" [hint] try something like \\\"--range 192.168.0.100-192.168.0.200\\\"\\n\");\n        return 1;\n    }\n    count_ports = rangelist_count(&masscan->targets.ports);\n    if (count_ports == 0) {\n        LOG(0, \"FAIL: no ports were specified\\n\");\n        LOG(0, \" [hint] try something like \\\"-p80,8000-9000\\\"\\n\");\n        LOG(0, \" [hint] try something like \\\"--ports 0-65535\\\"\\n\");\n        return 1;\n    }\n    range = count_ips * count_ports;\n    range += (uint64_t)(masscan->retries * range);\n\n    /*\n     * If doing an ARP scan, then don't allow port scanning\n     */\n    if (rangelist_is_contains(&masscan->targets.ports, Templ_ARP)) {\n        if (masscan->targets.ports.count != 1) {\n            LOG(0, \"FAIL: cannot arpscan and portscan at the same time\\n\");\n            return 1;\n        }\n    }\n\n    /*\n     * If the IP address range is very big, then require that that the\n     * user apply an exclude range\n     */\n    if (count_ips > 1000000000ULL && rangelist_count(&masscan->exclude.ipv4) == 0) {\n        LOG(0, \"FAIL: range too big, need confirmation\\n\");\n        LOG(0, \" [hint] to prevent accidents, at least one --exclude must be specified\\n\");\n        LOG(0, \" [hint] use \\\"--exclude 255.255.255.255\\\" as a simple confirmation\\n\");\n        exit(1);\n    }\n\n    /*\n     * trim the nmap UDP payloads down to only those ports we are using. This\n     * makes lookups faster at high packet rates.\n     */\n    payloads_udp_trim(masscan->payloads.udp, &masscan->targets);\n    payloads_oproto_trim(masscan->payloads.oproto, &masscan->targets);\n\n\n#ifdef __AFL_HAVE_MANUAL_CONTROL\n  __AFL_INIT();\n#endif\n\n    /*\n     * Start scanning threats for each adapter\n     */\n    for (index=0; index<masscan->nic_count; index++) {\n        struct ThreadPair *parms = &parms_array[index];\n        int err;\n\n        parms->masscan = masscan;\n        parms->nic_index = index;\n        parms->my_index = masscan->resume.index;\n        parms->done_transmitting = 0;\n        parms->done_receiving = 0;\n\n        /* needed for --packet-trace option so that we know when we started\n         * the scan */\n        parms->pt_start = 1.0 * pixie_gettime() / 1000000.0;\n\n\n        /*\n         * Turn the adapter on, and get the running configuration\n         */\n        err = masscan_initialize_adapter(\n                            masscan,\n                            index,\n                            &parms->source_mac,\n                            &parms->router_mac_ipv4,\n                            &parms->router_mac_ipv6\n                            );\n        if (err != 0)\n            exit(1);\n        parms->adapter = masscan->nic[index].adapter;\n        if (!masscan->nic[index].is_usable) {\n            LOG(0, \"FAIL: failed to detect IP of interface\\n\");\n            LOG(0, \" [hint] did you spell the name correctly?\\n\");\n            LOG(0, \" [hint] if it has no IP address, \"\n                    \"manually set with \\\"--adapter-ip 192.168.100.5\\\"\\n\");\n            exit(1);\n        }\n\n\n        /*\n         * Initialize the TCP packet template. The way this works is that\n         * we parse an existing TCP packet, and use that as the template for\n         * scanning. Then, we adjust the template with additional features,\n         * such as the IP address and so on.\n         */\n        parms->tmplset->vulncheck = vulncheck;\n        template_packet_init(\n                    parms->tmplset,\n                    parms->source_mac,\n                    parms->router_mac_ipv4,\n                    parms->router_mac_ipv6,\n                    masscan->payloads.udp,\n                    masscan->payloads.oproto,\n                    stack_if_datalink(masscan->nic[index].adapter),\n                    masscan->seed,\n                    masscan->templ_opts);\n\n        /*\n         * Set the \"source port\" of everything we transmit.\n         */\n        if (masscan->nic[index].src.port.range == 0) {\n            unsigned port = 40000 + now % 20000;\n            masscan->nic[index].src.port.first = port;\n            masscan->nic[index].src.port.last = port + 16;\n            masscan->nic[index].src.port.range = 16;\n        }\n\n        stack = stack_create(parms->source_mac, &masscan->nic[index].src);\n        parms->stack = stack;\n\n        /*\n         * Set the \"TTL\" (IP time-to-live) of everything we send.\n         */\n        if (masscan->nmap.ttl)\n            template_set_ttl(parms->tmplset, masscan->nmap.ttl);\n\n        if (masscan->nic[0].is_vlan)\n            template_set_vlan(parms->tmplset, masscan->nic[0].vlan_id);\n\n\n        /*\n         * trap <ctrl-c> to pause\n         */\n        signal(SIGINT, control_c_handler);\n\n    }\n\n    /*\n     * Print helpful text\n     */\n    {\n        char buffer[80];\n        struct tm x;\n\n        now = time(0);\n        safe_gmtime(&x, &now);\n        strftime(buffer, sizeof(buffer), \"%Y-%m-%d %H:%M:%S GMT\", &x);\n        LOG(0, \"Starting masscan \" MASSCAN_VERSION \" (http://bit.ly/14GZzcT) at %s\\n\",\n            buffer);\n\n        if (count_ports == 1 && \\\n            masscan->targets.ports.list->begin == Templ_ICMP_echo && \\\n            masscan->targets.ports.list->end == Templ_ICMP_echo)\n            { /* ICMP only */\n                //LOG(0, \" -- forced options: -sn -n --randomize-hosts -v --send-eth\\n\");\n                LOG(0, \"Initiating ICMP Echo Scan\\n\");\n                LOG(0, \"Scanning %u hosts\\n\",(unsigned)count_ips);\n             }\n        else /* This could actually also be a UDP only or mixed UDP/TCP/ICMP scan */\n            {\n                //LOG(0, \" -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth\\n\");\n                LOG(0, \"Initiating SYN Stealth Scan\\n\");\n                LOG(0, \"Scanning %u hosts [%u port%s/host]\\n\",\n                    (unsigned)count_ips, (unsigned)count_ports, (count_ports==1)?\"\":\"s\");\n            }\n    }\n    \n    /*\n     * Start all the threads\n     */\n    for (index=0; index<masscan->nic_count; index++) {\n        struct ThreadPair *parms = &parms_array[index];\n        \n        /*\n         * Start the scanning thread.\n         * THIS IS WHERE THE PROGRAM STARTS SPEWING OUT PACKETS AT A HIGH\n         * RATE OF SPEED.\n         */\n        parms->thread_handle_xmit = pixie_begin_thread(transmit_thread, 0, parms);\n\n        /*\n         * Start the MATCHING receive thread. Transmit and receive threads\n         * come in matching pairs.\n         */\n        parms->thread_handle_recv = pixie_begin_thread(receive_thread, 0, parms);\n    }\n\n    /*\n     * Now wait for <ctrl-c> to be pressed OR for threads to exit\n     */\n    pixie_usleep(1000 * 100);\n    LOG(1, \"[+] waiting for threads to finish\\n\");\n    status_start(&status);\n    status.is_infinite = masscan->is_infinite;\n    while (!is_tx_done && masscan->output.is_status_updates) {\n        unsigned i;\n        double rate = 0;\n        uint64_t total_tcbs = 0;\n        uint64_t total_synacks = 0;\n        uint64_t total_syns = 0;\n\n\n        /* Find the minimum index of all the threads */\n        min_index = UINT64_MAX;\n        for (i=0; i<masscan->nic_count; i++) {\n            struct ThreadPair *parms = &parms_array[i];\n\n            if (min_index > parms->my_index)\n                min_index = parms->my_index;\n\n            rate += parms->throttler->current_rate;\n\n            if (parms->total_tcbs)\n                total_tcbs += *parms->total_tcbs;\n            if (parms->total_synacks)\n                total_synacks += *parms->total_synacks;\n            if (parms->total_syns)\n                total_syns += *parms->total_syns;\n        }\n\n        if (min_index >= range && !masscan->is_infinite) {\n            /* Note: This is how we can tell the scan has ended */\n            is_tx_done = 1;\n        }\n\n        /*\n         * update screen about once per second with statistics,\n         * namely packets/second.\n         */\n        if (masscan->output.is_status_updates)\n            status_print(&status, min_index, range, rate,\n                total_tcbs, total_synacks, total_syns,\n                0, masscan->output.is_status_ndjson);\n\n        /* Sleep for almost a second */\n        pixie_mssleep(750);\n    }\n\n    /*\n     * If we haven't completed the scan, then save the resume\n     * information.\n     */\n    if (min_index < count_ips * count_ports) {\n        masscan->resume.index = min_index;\n\n        /* Write current settings to \"paused.conf\" so that the scan can be restarted */\n        masscan_save_state(masscan);\n    }\n\n\n\n    /*\n     * Now wait for all threads to exit\n     */\n    now = time(0);\n    for (;;) {\n        unsigned transmit_count = 0;\n        unsigned receive_count = 0;\n        unsigned i;\n        double rate = 0;\n        uint64_t total_tcbs = 0;\n        uint64_t total_synacks = 0;\n        uint64_t total_syns = 0;\n\n\n        /* Find the minimum index of all the threads */\n        min_index = UINT64_MAX;\n        for (i=0; i<masscan->nic_count; i++) {\n            struct ThreadPair *parms = &parms_array[i];\n\n            if (min_index > parms->my_index)\n                min_index = parms->my_index;\n\n            rate += parms->throttler->current_rate;\n\n            if (parms->total_tcbs)\n                total_tcbs += *parms->total_tcbs;\n            if (parms->total_synacks)\n                total_synacks += *parms->total_synacks;\n            if (parms->total_syns)\n                total_syns += *parms->total_syns;\n        }\n\n\n\n        if (time(0) - now >= masscan->wait) {\n            is_rx_done = 1;\n        }\n\n        if (time(0) - now - 10 > masscan->wait) {\n            LOG(0, \"[-] Passed the wait window but still running, forcing exit...\\n\");\n            exit(0);\n        }\n\n        if (masscan->output.is_status_updates) {\n            status_print(&status, min_index, range, rate,\n                total_tcbs, total_synacks, total_syns,\n                masscan->wait - (time(0) - now),\n                masscan->output.is_status_ndjson);\n\n            for (i=0; i<masscan->nic_count; i++) {\n                struct ThreadPair *parms = &parms_array[i];\n\n                transmit_count += parms->done_transmitting;\n                receive_count += parms->done_receiving;\n\n            }\n\n            pixie_mssleep(250);\n\n            if (transmit_count < masscan->nic_count)\n                continue;\n            is_tx_done = 1;\n            is_rx_done = 1;\n            if (receive_count < masscan->nic_count)\n                continue;\n\n        } else {\n            /* [AFL-fuzz]\n             * Join the threads, which doesn't allow us to print out \n             * status messages, but allows us to exit cleanly without\n             * any waiting */\n            for (i=0; i<masscan->nic_count; i++) {\n                struct ThreadPair *parms = &parms_array[i];\n\n                pixie_thread_join(parms->thread_handle_xmit);\n                parms->thread_handle_xmit = 0;\n                pixie_thread_join(parms->thread_handle_recv);\n                parms->thread_handle_recv = 0;\n            }\n            is_tx_done = 1;\n            is_rx_done = 1;\n        }\n\n        break;\n    }\n\n\n    /*\n     * Now cleanup everything\n     */\n    status_finish(&status);\n\n    if (!masscan->output.is_status_updates) {\n        uint64_t usec_now = pixie_gettime();\n\n        printf(\"%u milliseconds elapsed\\n\", (unsigned)((usec_now - usec_start)/1000));\n    }\n    \n    LOG(1, \"[+] all threads have exited                    \\n\");\n\n    return 0;\n}\n\n\n\n\n/***************************************************************************\n ***************************************************************************/\nint main(int argc, char *argv[])\n{\n    struct Masscan masscan[1];\n    unsigned i;\n    int has_target_addresses = 0;\n    int has_target_ports = 0;\n    \n    usec_start = pixie_gettime();\n#if defined(WIN32)\n    {WSADATA x; WSAStartup(0x101, &x);}\n#endif\n\n    global_now = time(0);\n\n    /* Set system to report debug information on crash */\n    {\n        int is_backtrace = 1;\n        for (i=1; i<(unsigned)argc; i++) {\n            if (strcmp(argv[i], \"--nobacktrace\") == 0)\n                is_backtrace = 0;\n        }\n        if (is_backtrace)\n            pixie_backtrace_init(argv[0]);\n    }\n    \n    /*\n     * Initialize those defaults that aren't zero\n     */\n    memset(masscan, 0, sizeof(*masscan));\n    /* 14 rounds seem to give way better statistical distribution than 4 with a \n    very low impact on scan rate */\n    masscan->blackrock_rounds = 14;\n    masscan->output.is_show_open = 1; /* default: show syn-ack, not rst */\n    masscan->output.is_status_updates = 1; /* default: show status updates */\n    masscan->wait = 10; /* how long to wait for responses when done */\n    masscan->max_rate = 100.0; /* max rate = hundred packets-per-second */\n    masscan->nic_count = 1;\n    masscan->shard.one = 1;\n    masscan->shard.of = 1;\n    masscan->min_packet_size = 60;\n    masscan->redis.password = NULL;\n    masscan->payloads.udp = payloads_udp_create();\n    masscan->payloads.oproto = payloads_oproto_create();\n    safe_strcpy(   masscan->output.rotate.directory,\n                sizeof(masscan->output.rotate.directory),\n                \".\");\n    masscan->is_capture_cert = 1;\n\n    /*\n     * Pre-parse the command-line\n     */\n    if (masscan_conf_contains(\"--readscan\", argc, argv)) {\n        masscan->is_readscan = 1;\n    }\n\n    /*\n     * On non-Windows systems, read the defaults from the file in\n     * the /etc directory. These defaults will contain things\n     * like the output directory, max packet rates, and so on. Most\n     * importantly, the master \"--excludefile\" might be placed here,\n     * so that blacklisted ranges won't be scanned, even if the user\n     * makes a mistake\n     */\n#if !defined(WIN32)\n    if (!masscan->is_readscan) {\n        if (access(\"/etc/masscan/masscan.conf\", 0) == 0) {\n            masscan_read_config_file(masscan, \"/etc/masscan/masscan.conf\");\n        }\n    }\n#endif\n\n    /*\n     * Read in the configuration from the command-line. We are looking for\n     * either options or a list of IPv4 address ranges.\n     */\n    masscan_command_line(masscan, argc, argv);\n    if (masscan->seed == 0)\n        masscan->seed = get_entropy(); /* entropy for randomness */\n\n    /*\n     * Load database files like \"nmap-payloads\" and \"nmap-service-probes\"\n     */\n    masscan_load_database_files(masscan);\n\n    /*\n     * Load the scripting engine if needed and run those that were\n     * specified.\n     */\n    if (masscan->is_scripting)\n        scripting_init(masscan);\n\n    /* We need to do a separate \"raw socket\" initialization step. This is\n     * for Windows and PF_RING. */\n    if (pcap_init() != 0)\n        LOG(2, \"libpcap: failed to load\\n\");\n    rawsock_init();\n\n    /* Init some protocol parser data structures */\n    snmp_init();\n    x509_init();\n\n\n    /*\n     * Apply excludes. People ask us not to scan them, so we maintain a list\n     * of their ranges, and when doing wide scans, add the exclude list to\n     * prevent them from being scanned.\n     */\n    has_target_addresses = massip_has_ipv4_targets(&masscan->targets) || massip_has_ipv6_targets(&masscan->targets);\n    has_target_ports = massip_has_target_ports(&masscan->targets);\n    massip_apply_excludes(&masscan->targets, &masscan->exclude);\n    if (!has_target_ports && masscan->op == Operation_ListScan)\n        massip_add_port_string(&masscan->targets, \"80\", 0);\n\n\n\n\n    /* Optimize target selection so it's a quick binary search instead\n     * of walking large memory tables. When we scan the entire Internet\n     * our --excludefile will chop up our pristine 0.0.0.0/0 range into\n     * hundreds of subranges. This allows us to grab addresses faster. */\n    massip_optimize(&masscan->targets);\n    \n    /* FIXME: we only support 63-bit scans at the current time.\n     * This is big enough for the IPv4 Internet, where scanning\n     * for all TCP ports on all IPv4 addresses results in a 48-bit\n     * scan, but this isn't big enough even for a single port on\n     * an IPv6 subnet (which are 64-bits in size, usually). However,\n     * even at millions of packets per second scanning rate, you still\n     * can't complete a 64-bit scan in a reasonable amount of time.\n     * Nor would you want to attempt the feat, as it would overload\n     * the target IPv6 subnet. Since implementing this would be\n     * difficult for 32-bit processors, for now, I'm going to stick\n     * to a simple 63-bit scan.\n     */\n    if (massint128_bitcount(massip_range(&masscan->targets)) > 63) {\n        fprintf(stderr, \"[-] FAIL: scan range too large, max is 63-bits, requested is %u bits\\n\",\n                massint128_bitcount(massip_range(&masscan->targets)));\n        fprintf(stderr, \"    Hint: scan range is number of IP addresses times number of ports\\n\");\n        fprintf(stderr, \"    Hint: IPv6 subnet must be at least /66 \\n\");\n        exit(1);\n    }\n\n    /*\n     * Once we've read in the configuration, do the operation that was\n     * specified\n     */\n    switch (masscan->op) {\n    case Operation_Default:\n        /* Print usage info and exit */\n        masscan_usage();\n        break;\n\n    case Operation_Scan:\n        /*\n         * THIS IS THE NORMAL THING\n         */\n        if (rangelist_count(&masscan->targets.ipv4) == 0 && massint128_is_zero(range6list_count(&masscan->targets.ipv6))) {\n            /* We check for an empty target list here first, before the excludes,\n             * so that we can differentiate error messages after excludes, in case\n             * the user specified addresses, but they were removed by excludes. */\n            LOG(0, \"FAIL: target IP address list empty\\n\");\n            if (has_target_addresses) {\n                LOG(0, \" [hint] all addresses were removed by exclusion ranges\\n\");\n            } else {\n                LOG(0, \" [hint] try something like \\\"--range 10.0.0.0/8\\\"\\n\");\n                LOG(0, \" [hint] try something like \\\"--range 192.168.0.100-192.168.0.200\\\"\\n\");\n            }\n            exit(1);\n        }\n        if (rangelist_count(&masscan->targets.ports) == 0) {\n            if (has_target_ports) {\n                LOG(0, \" [hint] all ports were removed by exclusion ranges\\n\");\n            } else {\n                LOG(0, \"FAIL: no ports were specified\\n\");\n                LOG(0, \" [hint] try something like \\\"-p80,8000-9000\\\"\\n\");\n                LOG(0, \" [hint] try something like \\\"--ports 0-65535\\\"\\n\");\n            }\n            return 1;\n        }\n        return main_scan(masscan);\n\n    case Operation_ListScan:\n        /* Create a randomized list of IP addresses */\n        main_listscan(masscan);\n        return 0;\n\n    case Operation_List_Adapters:\n        /* List the network adapters we might want to use for scanning */\n        rawsock_list_adapters();\n        break;\n\n    case Operation_DebugIF:\n        for (i=0; i<masscan->nic_count; i++)\n            rawsock_selftest_if(masscan->nic[i].ifname);\n        return 0;\n\n    case Operation_ReadRange:\n        main_readrange(masscan);\n        return 0;\n\n    case Operation_ReadScan:\n        {\n            unsigned start;\n            unsigned stop;\n\n            /* find first file */\n            for (start=1; start<(unsigned)argc; start++) {\n                if (memcmp(argv[start], \"--readscan\", 10) == 0) {\n                    start++;\n                    break;\n                }\n            }\n\n            /* find last file */\n            for (stop=start+1; stop<(unsigned)argc && argv[stop][0] != '-'; stop++)\n                ;\n\n            /*\n             * read the binary files, and output them again depending upon\n             * the output parameters\n             */\n            readscan_binary_scanfile(masscan, start, stop, argv);\n\n        }\n        break;\n\n    case Operation_Benchmark:\n        printf(\"=== benchmarking (%u-bits) ===\\n\\n\", (unsigned)sizeof(void*)*8);\n        blackrock_benchmark(masscan->blackrock_rounds);\n        blackrock2_benchmark(masscan->blackrock_rounds);\n        smack_benchmark();\n        exit(1);\n        break;\n\n    case Operation_Echo:\n        masscan_echo(masscan, stdout, 0);\n        exit(0);\n        break;\n\n    case Operation_EchoAll:\n        masscan_echo(masscan, stdout, 0);\n        exit(0);\n        break;\n\n    case Operation_EchoCidr:\n        masscan_echo_cidr(masscan, stdout, 0);\n        exit(0);\n        break;\n\n    case Operation_Selftest:\n        /*\n         * Do a regression test of all the significant units\n         */\n        {\n            int x = 0;\n            extern int proto_isakmp_selftest(void);\n            \n            x += massip_selftest();\n            x += ranges6_selftest();\n            x += dedup_selftest();\n            x += checksum_selftest();\n            x += ipv4address_selftest();\n            x += ipv6address_selftest();\n            x += proto_coap_selftest();\n            x += smack_selftest();\n            x += sctp_selftest();\n            x += base64_selftest();\n            x += banner1_selftest();\n            x += output_selftest();\n            x += siphash24_selftest();\n            x += ntp_selftest();\n            x += snmp_selftest();\n            x += proto_isakmp_selftest();\n            x += templ_payloads_selftest();\n            x += blackrock_selftest();\n            x += rawsock_selftest();\n            x += lcg_selftest();\n            x += template_selftest();\n            x += ranges_selftest();\n            x += massip_parse_selftest();\n            x += pixie_time_selftest();\n            x += rte_ring_selftest();\n            x += mainconf_selftest();\n            x += zeroaccess_selftest();\n            x += nmapserviceprobes_selftest();\n            x += rstfilter_selftest();\n            x += masscan_app_selftest();\n\n\n            if (x != 0) {\n                /* one of the selftests failed, so return error */\n                fprintf(stderr, \"regression test: failed :( \\n\");\n                return 1;\n            } else {\n                fprintf(stderr, \"regression test: success!\\n\");\n                return 0;\n            }\n        }\n        break;\n    }\n\n\n    return 0;\n}\n\n\n"
  },
  {
    "path": "src/masscan-app.c",
    "content": "#include \"masscan-app.h\"\n#include \"util-safefunc.h\"\n\n/******************************************************************************\n * When outputting results, we call this function to print out the type of \n * banner that we've collected\n ******************************************************************************/\nconst char *\nmasscan_app_to_string(enum ApplicationProtocol proto)\n{\n    static char tmp[64];\n\n    switch (proto) {\n    case PROTO_NONE: return \"unknown\";\n    case PROTO_HEUR: return \"unknown\";\n    case PROTO_SSH1: return \"ssh\";\n    case PROTO_SSH2: return \"ssh\";\n    case PROTO_HTTP: return \"http\";\n    case PROTO_FTP: return \"ftp\";\n    case PROTO_DNS_VERSIONBIND: return \"dns-ver\";\n    case PROTO_SNMP: return \"snmp\";\n    case PROTO_NBTSTAT: return \"nbtstat\";\n    case PROTO_SSL3:    return \"ssl\";\n    case PROTO_SMB:     return \"smb\";\n    case PROTO_SMTP:    return \"smtp\";\n    case PROTO_POP3:    return \"pop\";\n    case PROTO_IMAP4:   return \"imap\";\n    case PROTO_UDP_ZEROACCESS: return \"zeroaccess\";\n    case PROTO_X509_CERT: return \"X509\";\n    case PROTO_X509_CACERT: return \"X509CA\";\n    case PROTO_HTML_TITLE: return \"title\";\n    case PROTO_HTML_FULL: return \"html\";\n    case PROTO_NTP:     return \"ntp\";\n    case PROTO_VULN:    return \"vuln\";\n    case PROTO_HEARTBLEED:    return \"heartbleed\";\n    case PROTO_TICKETBLEED:    return \"ticketbleed\";\n    case PROTO_VNC_OLD: return \"vnc\";\n    case PROTO_SAFE:    return \"safe\";\n    case PROTO_MEMCACHED: return \"memcached\";\n    case PROTO_SCRIPTING:      return \"scripting\";\n    case PROTO_VERSIONING:     return \"versioning\";\n    case PROTO_COAP:           return \"coap\";\n    case PROTO_TELNET:         return \"telnet\";\n    case PROTO_RDP:            return \"rdp\";\n    case PROTO_HTTP_SERVER:     return \"http.server\";\n    case PROTO_MC:              return \"minecraft\";\n    case PROTO_VNC_RFB:         return \"vnc\";\n    case PROTO_VNC_INFO:        return \"vnc-info\";\n    case PROTO_ISAKMP:          return \"isakmp\";\n        \n    case PROTO_ERROR:           return \"error\";\n            \n    default:\n        snprintf(tmp, sizeof(tmp), \"(%u)\", proto);\n        return tmp;\n    }\n}\n\n/******************************************************************************\n ******************************************************************************/\nenum ApplicationProtocol\nmasscan_string_to_app(const char *str)\n{\n    const static struct {\n        const char *name;\n        enum ApplicationProtocol value;\n    } list[] = {\n        {\"ssh1\",    PROTO_SSH1},\n        {\"ssh2\",    PROTO_SSH2},\n        {\"ssh\",     PROTO_SSH2},\n        {\"http\",    PROTO_HTTP},\n        {\"ftp\",     PROTO_FTP},\n        {\"dns-ver\", PROTO_DNS_VERSIONBIND},\n        {\"snmp\",    PROTO_SNMP},\n        {\"nbtstat\", PROTO_NBTSTAT},\n        {\"ssl\",     PROTO_SSL3},\n        {\"smtp\",    PROTO_SMTP},\n        {\"smb\",     PROTO_SMB},\n        {\"pop\",     PROTO_POP3},\n        {\"imap\",    PROTO_IMAP4},\n        {\"x509\",    PROTO_X509_CERT},\n        {\"x509ca\",  PROTO_X509_CACERT},\n        {\"zeroaccess\",  PROTO_UDP_ZEROACCESS},\n        {\"title\",       PROTO_HTML_TITLE},\n        {\"html\",        PROTO_HTML_FULL},\n        {\"ntp\",         PROTO_NTP},\n        {\"vuln\",        PROTO_VULN},\n        {\"heartbleed\",  PROTO_HEARTBLEED},\n        {\"ticketbleed\", PROTO_TICKETBLEED},\n        {\"vnc-old\",     PROTO_VNC_OLD},\n        {\"safe\",        PROTO_SAFE},\n        {\"memcached\",   PROTO_MEMCACHED},\n        {\"scripting\",   PROTO_SCRIPTING},\n        {\"versioning\",  PROTO_VERSIONING},\n        {\"coap\",        PROTO_COAP},\n        {\"telnet\",      PROTO_TELNET},\n        {\"rdp\",         PROTO_RDP},\n        {\"http.server\", PROTO_HTTP_SERVER},\n        {\"minecraft\",   PROTO_MC},\n        {\"vnc\",         PROTO_VNC_RFB},\n        {\"vnc-info\",    PROTO_VNC_INFO},\n        {\"isakmp\",      PROTO_ISAKMP},\n        {0,0}\n    };\n    size_t i;\n\n    for (i=0; list[i].name; i++) {\n        if (strcmp(str, list[i].name) == 0)\n            return list[i].value;\n    }\n    return 0;\n}\n\nint\nmasscan_app_selftest(void) {\n    static const struct {\n        unsigned enumid;\n        unsigned expected;\n    } tests[] = {\n        {PROTO_SNMP, 7},\n        {PROTO_X509_CERT, 15},\n        {PROTO_HTTP_SERVER, 31},\n        {0,0}\n    };\n    size_t i;\n    \n    /* The ENUM contains fixed values in external files,\n     * so programmers should only add onto its end, not\n     * the middle. This self-test will verify that\n     * a programmer hasn't made this mistake.\n     */\n    for (i=0; tests[i].enumid != 0; i++) {\n        unsigned enumid = tests[i].enumid;\n        unsigned expected = tests[i].expected;\n        \n        /* YOU ADDED AN ENUM IN THE MIDDLE INSTEAD ON THE END OF THE LIST */\n        if (enumid != expected) {\n            fprintf(stderr, \"[-] %s:%u fail\\n\", __FILE__, (unsigned)__LINE__);\n            fprintf(stderr, \"[-] enum expected=%u, found=%u\\n\", 30, PROTO_HTTP_SERVER);\n            return 1;\n        }\n    }\n    \n    return 0;\n}\n"
  },
  {
    "path": "src/masscan-app.h",
    "content": "#ifndef MASSCAN_APP_H\n#define MASSCAN_APP_H\n\n/*\n * WARNING: these constants are used in files, so don't change the values.\n * Add new ones onto the end\n */\nenum ApplicationProtocol {\n    PROTO_NONE,\n    PROTO_HEUR,\n    PROTO_SSH1,\n    PROTO_SSH2,\n    PROTO_HTTP,\n    PROTO_FTP,\n    PROTO_DNS_VERSIONBIND,\n    PROTO_SNMP,             /* 7 - simple network management protocol, udp/161 */\n    PROTO_NBTSTAT,          /* 8 - netbios, udp/137 */\n    PROTO_SSL3,\n    PROTO_SMB,              /* 10 - SMB tcp/139 and tcp/445 */\n    PROTO_SMTP,             /* 11 - transfering email */\n    PROTO_POP3,             /* 12 - fetching email */\n    PROTO_IMAP4,            /* 13 - fetching email */\n    PROTO_UDP_ZEROACCESS,\n    PROTO_X509_CERT,        /* 15 - just the cert */\n    PROTO_X509_CACERT,\n    PROTO_HTML_TITLE,\n    PROTO_HTML_FULL,\n    PROTO_NTP,              /* 19 - network time protocol, udp/123 */\n    PROTO_VULN,\n    PROTO_HEARTBLEED,\n    PROTO_TICKETBLEED,\n    PROTO_VNC_OLD,\n    PROTO_SAFE,\n    PROTO_MEMCACHED,        /* 25 - memcached */\n    PROTO_SCRIPTING,\n    PROTO_VERSIONING,\n    PROTO_COAP,             /* 28 - constrained app proto, udp/5683, RFC7252 */\n    PROTO_TELNET,           /* 29 - ye old remote terminal */\n    PROTO_RDP,              /* 30 - Microsoft Remote Desktop Protocol tcp/3389 */\n    PROTO_HTTP_SERVER,      /* 31 - HTTP \"Server:\" field */\n    PROTO_MC,               /* 32 - Minecraft server */\n    PROTO_VNC_RFB,\n    PROTO_VNC_INFO,\n    PROTO_ISAKMP,           /* 35 - IPsec key exchange */\n    \n    PROTO_ERROR,\n\n    PROTO_end_of_list /* must be last one */\n};\n\nconst char *\nmasscan_app_to_string(enum ApplicationProtocol proto);\n\nenum ApplicationProtocol\nmasscan_string_to_app(const char *str);\n\nint\nmasscan_app_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/masscan-status.h",
    "content": "#ifndef MASSCAN_STATUS_H\n#define MASSCAN_STATUS_H\n\n#if 0\nenum PortStatus {\n    Port_Unknown,\n    Port_Open,\n    Port_Closed,\n    Port_IcmpEchoResponse,\n    Port_UdpOpen,\n    Port_UdpClosed,\n    Port_SctpOpen,\n    Port_SctpClosed,\n    Port_ArpOpen,\n};\n#endif\n\nenum PortStatus {\n    PortStatus_Unknown,\n    PortStatus_Open,\n    PortStatus_Closed,\n    PortStatus_Arp,\n    PortStatus_Count\n\n};\n\n\n\n#endif\n"
  },
  {
    "path": "src/masscan-version.h",
    "content": "#ifndef MASSCAN_VERSION\n\n#define MASSCAN_VERSION \"1.3.9-integration\"\n\n#endif\n\n"
  },
  {
    "path": "src/masscan.h",
    "content": "#ifndef MASSCAN_H\n#define MASSCAN_H\n#include \"massip-addr.h\"\n#include \"util-safefunc.h\"\n#include \"stack-src.h\"\n#include \"massip.h\"\n#include \"util-bool.h\"\n#include <string.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <time.h>\n\n#include \"massip.h\"\n#include \"stack-queue.h\"\n\nstruct Adapter;\nstruct TemplateSet;\nstruct Banner1;\nstruct TemplateOptions;\n\n/**\n * This is the \"operation\" to be performed by masscan, which is almost always\n * to \"scan\" the network. However, there are some lesser operations to do\n * instead, like run a \"regression self test\", or \"debug\", or something else\n * instead of scanning. We parse the command-line in order to figure out the\n * proper operation\n */\nenum Operation {\n    Operation_Default = 0,          /* nothing specified, so print usage */\n    Operation_List_Adapters = 1,    /* --listif */\n    Operation_Selftest = 2,         /* --selftest or --regress */\n    Operation_Scan = 3,         /* this is what you expect */\n    Operation_DebugIF = 4,          /* --debug if */\n    Operation_ListScan = 5,         /* -sL */\n    Operation_ReadScan = 6,         /* --readscan <binary-output> */\n    Operation_ReadRange = 7,        /* --readrange */\n    Operation_Benchmark = 8,        /* --benchmark */\n    Operation_Echo = 9,             /* --echo */\n    Operation_EchoAll = 10,         /* --echo-all */\n    Operation_EchoCidr = 11,        /* --echo-cidr */\n};\n\n/**\n * The format of the output. If nothing is specified, then the default will\n * be \"--interactive\", meaning that we'll print to the command-line live as\n * results come in. Only one output format can be specified, except that\n * \"--interactive\" can be specified alongside any of the other ones.\n */\nenum OutputFormat {\n    Output_Default      = 0x0000,\n    Output_Interactive  = 0x0001,   /* --interactive, print to cmdline */\n    Output_List         = 0x0002,\n    Output_Binary       = 0x0004,   /* -oB, \"binary\", the primary format */\n    Output_XML          = 0x0008,   /* -oX, \"xml\" */\n    Output_JSON         = 0x0010,   /* -oJ, \"json\" */\n    Output_NDJSON       = 0x0011,   /* -oD, \"ndjson\" */\n    Output_Nmap         = 0x0020,\n    Output_ScriptKiddie = 0x0040,\n    Output_Grepable     = 0x0080,   /* -oG, \"grepable\" */\n    Output_Redis        = 0x0100, \n    Output_Unicornscan  = 0x0200,   /* -oU, \"unicornscan\" */\n    Output_None         = 0x0400,\n    Output_Certs        = 0x0800,\n    Output_Hostonly     = 0x1000,   /* -oH, \"hostonly\" */\n    Output_All          = 0xFFBF,   /* not supported */\n};\n\n\n/**\n * Holds the list of TCP \"hello\" payloads, specified with the \"--hello-file\"\n * or \"--hello-string\" options\n */\nstruct TcpCfgPayloads\n{\n    /** The \"hello\" data in base64 format. This is either the base64 string\n     * specified in the cmdline/cfgfile with \"--hello-string\", or the \n     * contents of a file specified with \"--hello-file\" that we've converted\n     * into base64 */\n    char *payload_base64;\n    \n    /** The TCP port that this hello belongs to */\n    unsigned port;\n    \n    /** These configuration options are stored as a linked-list */\n    struct TcpCfgPayloads *next;\n};\n\n\n\n\n/**\n * This is the master MASSCAN configuration structure. It is created on startup\n * by reading the command-line and parsing configuration files.\n *\n * Once read in at the start, this structure doesn't change. The transmit\n * and receive threads have only a \"const\" pointer to this structure.\n */\nstruct Masscan\n{\n    /**\n     * What this program is doing, which is normally \"Operation_Scan\", but\n     * which can be other things, like \"Operation_SelfTest\"\n     */\n    enum Operation op;\n    \n    struct {\n        unsigned tcp:1;\n        unsigned udp:1;     /* -sU */\n        unsigned sctp:1;\n        unsigned ping:1;    /* --ping, ICMP echo */\n        unsigned arp:1;     /* --arp, local ARP scan */\n        unsigned oproto:1;  /* -sO */\n    } scan_type;\n    \n    /**\n     * After scan type has been configured, add these ports. In other words,\n     * the user may specify `-sU` or `-sT` after the `--top-ports` parameter,\n     * so we have to wait until after parsing arguments to fill in the ports.\n     */\n    unsigned top_ports;\n    \n    /**\n     * Temporary file to echo parameters to, used for saving configuration\n     * to a file\n     */\n    FILE *echo;\n    unsigned echo_all;\n\n    /**\n     * One or more network adapters that we'll use for scanning. Each adapter\n     * should have a separate set of IP source addresses, except in the case\n     * of PF_RING dnaX:Y adapters.\n     */\n    struct {\n        char ifname[256];\n        struct Adapter *adapter;\n        struct stack_src_t src;\n        macaddress_t source_mac;\n        macaddress_t router_mac_ipv4;\n        macaddress_t router_mac_ipv6;\n        ipv4address_t router_ip;\n        int link_type; /* libpcap definitions */\n        unsigned char my_mac_count; /*is there a MAC address? */\n        unsigned vlan_id;\n        unsigned is_vlan:1;\n        unsigned is_usable:1;\n    } nic[8];\n    unsigned nic_count;\n\n    /**\n     * The target ranges of IPv4 addresses that are included in the scan.\n     * The user can specify anything here, and we'll resolve all overlaps\n     * and such, and sort the target ranges.\n     */\n    struct MassIP targets;\n    \n    /**\n     * IPv4 addresses/ranges that are to be excluded from the scan. This takes\n     * precedence over any 'include' statement. What happens is this: after\n     * all the configuration has been read, we then apply the exclude/blacklist\n     * on top of the target/whitelist, leaving only a target/whitelist left.\n     * Thus, during the scan, we only choose from the target/whitelist and\n     * don't consult the exclude/blacklist.\n     */\n    struct MassIP exclude;\n\n    /**\n     * Only output these types of banners\n     */\n    struct RangeList banner_types;\n\n\n    /**\n     * Maximum rate, in packets-per-second (--rate parameter). This can be\n     * a fraction of a packet-per-second, or be as high as 30000000.0 (or\n     * more actually, but I've only tested to 30megapps).\n     */\n    double max_rate;\n\n    /**\n     * Number of retries (--retries or --max-retries parameter). Retries\n     * happen a few seconds apart.\n     */\n    unsigned retries;\n\n    \n    unsigned is_pfring:1;       /* --pfring */\n    unsigned is_sendq:1;        /* --sendq */\n    unsigned is_banners:1;      /* --banners */\n    unsigned is_banners_rawudp:1; /* --rawudp */\n    unsigned is_offline:1;      /* --offline */\n    unsigned is_noreset:1;      /* --noreset, don't transmit RST */\n    unsigned is_gmt:1;          /* --gmt, all times in GMT */\n    unsigned is_capture_cert:1; /* --capture cert */\n    unsigned is_capture_html:1; /* --capture html */\n    unsigned is_capture_heartbleed:1; /* --capture heartbleed */\n    unsigned is_capture_ticketbleed:1; /* --capture ticket */\n    unsigned is_test_csv:1;     /* (temporary testing feature) */\n    unsigned is_infinite:1;     /* -infinite */\n    unsigned is_readscan:1;     /* --readscan, Operation_Readscan */\n    unsigned is_heartbleed:1;   /* --heartbleed, scan for this vuln */\n    unsigned is_ticketbleed:1;  /* --ticketbleed, scan for this vuln */\n    unsigned is_poodle_sslv3:1; /* --vuln poodle, scan for this vuln */\n    unsigned is_hello_ssl:1;    /* --ssl, use SSL HELLO on all ports */\n    unsigned is_hello_smbv1:1;  /* --smbv1, use SMBv1 hello, instead of v1/v2 hello */\n    unsigned is_hello_http:1;    /* --hello=http, use HTTP on all ports */\n    unsigned is_scripting:1;    /* whether scripting is needed */\n    unsigned is_capture_servername:1; /* --capture servername */\n\n    /** Packet template options, such as whether we should add a TCP MSS\n     * value, or remove it from the packet */\n    struct TemplateOptions *templ_opts; /* e.g. --tcpmss */\n\n    /**\n     * Wait forever for responses, instead of the default 10 seconds\n     */\n    unsigned wait;\n\n    /**\n     * --resume\n     * This structure contains options for pausing the scan (by exiting the\n     * program) and restarting it later.\n     */\n    struct {\n        /** --resume-index */\n        uint64_t index;\n        \n        /** --resume-count */\n        uint64_t count;\n        \n        /** Derives the --resume-index from the target ip:port */\n        struct {\n            unsigned ip;\n            unsigned port;\n        } target;\n    } resume;\n\n    /**\n     * --shard n/m\n     * This is used for distributing a scan across multiple \"shards\". Every\n     * shard in the scan must know the total number of shards, and must also\n     * know which of those shards is it's identity. Thus, shard 1/5 scans\n     * a different range than 2/5. These numbers start at 1, so it's\n     * 1/3 (#1 out of three), 2/3, and 3/3 (but not 0/3).\n     */\n    struct {\n        unsigned one;\n        unsigned of;\n    } shard;\n\n    /**\n     * The packet template set we are current using. We store a binary template\n     * for TCP, UDP, SCTP, ICMP, and so on. All the scans using that protocol\n     * are then scanned using that basic template. IP and TCP options can be\n     * added to the basic template without affecting any other component\n     * of the system.\n     */\n    struct TemplateSet *pkt_template;\n\n    /**\n     * A random seed for randomization if zero, otherwise we'll use\n     * the configured seed for repeatable tests.\n     */\n    uint64_t seed;\n    \n    /**\n     * This block configures what we do for the output files\n     */\n    struct OutputStuff {\n        \n        /**\n         * --output-format\n         * Examples are \"xml\", \"binary\", \"json\", \"ndjson\", \"grepable\", and so on.\n         */\n        enum OutputFormat format;\n        \n        /**\n         * --output-filename\n         * The name of the file where we are storing scan results.\n         * Note: the filename \"-\" means that we should send the file to\n         * <stdout> rather than to a file.\n         */\n        char filename[256];\n        \n        /**\n         * A feature of the XML output where we can insert an optional \n         * stylesheet into the file for better rendering on web browsers\n         */\n        char stylesheet[256];\n\n        /**\n         * --append\n         * We should append to the output file rather than overwriting it.\n         */\n        unsigned is_append:1;\n        \n        /**\n         * --json-status\n         * Print each status update line to stderr as JSON ending with a newline\n         *\n         * This only applies to the three types of status lines that are printed\n         * in status_print(); it does *not* apply to things like startup messages,\n         * error messages or discovery of individual ports\n         *\n         */\n        bool is_status_ndjson;\n\n        /**\n         * --open\n         * --open-only\n         * --show open\n         * Whether to show open ports\n         */\n        unsigned is_show_open:1;\n        \n        /**\n         * --show closed\n         * Whether to show closed ports (i.e. RSTs)\n         */\n        unsigned is_show_closed:1;\n        \n        /**\n         * --show host\n         * Whether to show host messages other than closed ports\n         */\n        unsigned is_show_host:1;\n        \n        /**\n         * print reason port is open, which is redundant for us \n         */\n        unsigned is_reason:1;\n    \n        /**\n         * --interactive\n         * Print to command-line while also writing to output file. This isn't\n         * needed if the output format is already 'interactive' (the default),\n         * but only if the default output format is anything else, and the\n         * user also wants interactivity.\n         */\n        unsigned is_interactive:1;\n        \n        /**\n        * Print state updates\n        */\n        unsigned is_status_updates:1;\n\n        struct {\n            /**\n             * When we should rotate output into the target directory\n             */\n            unsigned timeout;\n            \n            /**\n             * When doing \"--rotate daily\", the rotation is done at GMT. In \n             * order to fix this, add an offset.\n             */\n            unsigned offset;\n            \n            /**\n             * Instead of rotating by timeout, we can rotate by filesize \n             */\n            uint64_t filesize;\n            \n            /**\n             * The directory to which we store rotated files\n             */\n            char directory[256];\n        } rotate;\n    } output;\n\n    struct {\n        unsigned data_length; /* number of bytes to randomly append */\n        unsigned ttl; /* starting IP TTL field */\n        unsigned badsum; /* bad TCP/UDP/SCTP checksum */\n\n        unsigned packet_trace:1; /* print transmit messages */\n        \n        char datadir[256];\n    } nmap;\n\n    char pcap_filename[256];\n\n    struct {\n        unsigned timeout;\n    } tcb;\n\n    struct {\n        char *pcap_payloads_filename;\n        char *nmap_payloads_filename;\n        char *nmap_service_probes_filename;\n    \n        struct PayloadsUDP *udp;\n        struct PayloadsUDP *oproto;\n        struct TcpCfgPayloads *tcp;\n        struct NmapServiceProbeList *probes;\n    } payloads;\n    \n    /** Reconfigure the HTTP header */\n    struct {\n        /* Method */\n        unsigned char *method;\n        size_t method_length;\n\n        /* URL */\n        unsigned char *url;\n        size_t url_length;\n\n        /* Version */\n        unsigned char *version;\n        size_t version_length;\n\n        /* Host */\n        unsigned char *host;\n        size_t host_length;\n\n        /* User-Agent */\n        unsigned char *user_agent;\n        size_t user_agent_length;\n\n        /* Payload after the header*/\n        unsigned char *payload;\n        size_t payload_length;\n\n        /* Headers */\n        struct {\n            const char *name;\n            unsigned char *value;\n            size_t value_length;\n        } headers[16];\n        size_t headers_count;\n\n        /* Cookies */\n        struct {\n            unsigned char *value;\n            size_t value_length;\n        } cookies[16];\n        size_t cookies_count;\n\n        /* Remove */\n        struct {\n            unsigned char *name;\n        } remove[16];\n        size_t remove_count;\n    } http;\n\n    unsigned tcp_connection_timeout;\n    \n    /** Number of seconds to wait for a 'hello' from the server before\n     * giving up and sending a 'hello' from the client. Should be a small\n     * value when doing scans that expect client-side hellos, like HTTP or\n     * SSL, but should be a longer value when doing scans that expect server\n     * hellos, such as FTP or VNC */\n    unsigned tcp_hello_timeout;\n\n\n    char *bpf_filter;\n\n    struct {\n        ipaddress ip;\n        char    *password;\n        unsigned port;\n    } redis;\n\n\n\n    /**\n     * --min-packet\n     */\n    unsigned min_packet_size;\n\n    /**\n     * Number of rounds for randomization\n     * --blackrock-rounds\n     */\n    unsigned blackrock_rounds;\n    \n    /**\n     * --script <name>\n     */\n    struct {\n        /* The name (filename) of the script to run */\n        char *name;\n        \n        /* The script VM */\n        struct lua_State *L;\n    } scripting;\n\n    \n    /**\n     * --vuln <name>\n     * The name of a vuln to check, like \"poodle\"\n     */\n    const char *vuln_name;\n\n};\n\n\nint mainconf_selftest(void);\nvoid masscan_read_config_file(struct Masscan *masscan, const char *filename);\nvoid masscan_command_line(struct Masscan *masscan, int argc, char *argv[]);\nvoid masscan_usage(void);\nvoid masscan_save_state(struct Masscan *masscan);\nvoid main_listscan(struct Masscan *masscan);\n\n/**\n * Load databases, such as:\n *  - nmap-payloads\n *  - nmap-service-probes\n *  - pcap-payloads\n */\nvoid masscan_load_database_files(struct Masscan *masscan);\n\n/**\n * Pre-scan the command-line looking for options that may affect how\n * previous options are handled. This is a bit of a kludge, really.\n */\nint masscan_conf_contains(const char *x, int argc, char **argv);\n\n/**\n * Called to set a <name=value> pair.\n */\nvoid\nmasscan_set_parameter(struct Masscan *masscan,\n                      const char *name, const char *value);\n\n\n\n/**\n * Discover the local network adapter parameters, such as which\n * MAC address we are using and the MAC addresses of the\n * local routers.\n */\nint\nmasscan_initialize_adapter(\n    struct Masscan *masscan,\n    unsigned index,\n    macaddress_t *source_mac,\n    macaddress_t *router_mac_ipv4,\n    macaddress_t *router_mac_ipv6);\n\n/**\n * Echoes the settings to the command-line. By default, echoes only\n * non-default values. With \"echo-all\", everything is echoed.\n */\nvoid\nmasscan_echo(struct Masscan *masscan, FILE *fp, unsigned is_echo_all);\n\n/**\n * Echoes the list of CIDR ranges to scan.\n */\nvoid\nmasscan_echo_cidr(struct Masscan *masscan, FILE *fp, unsigned is_echo_all);\n\n#endif\n"
  },
  {
    "path": "src/massip-addr.c",
    "content": "#include \"massip-addr.h\"\n#include <string.h>\n\n\n/**\n * Holds the output string, so that we can append to it without\n * overflowing buffers. The _append_xxx() functions below append\n * to this string.\n */\ntypedef struct stream_t {\n    char *buf;\n    size_t offset;\n    size_t length;\n} stream_t;\n\n/**\n * Append a character to the output string. All the other _append_xxx()\n * functions call this one, so this is the only one where a\n * buffer-overflow can occur.\n */\nstatic void\n_append_char(stream_t *out, char c)\n{\n    if (out->offset < out->length)\n        out->buf[out->offset++] = c;\n\n    /* keep the string nul terminated as we build it */\n    if (out->offset < out->length)\n        out->buf[out->offset] = '\\0';\n}\n\nstatic void\n_append_ipv6(stream_t *out, const unsigned char *ipv6)\n{\n    static const char hex[] = \"0123456789abcdef\";\n    size_t i;\n    int is_ellision = 0;\n\n    /* An IPv6 address is printed as a series of 2-byte hex words\n     * separated by colons :, for a total of 16-bytes */\n    for (i = 0; i < 16; i += 2) {\n        unsigned n = ipv6[i] << 8 | ipv6[i + 1];\n\n        /* Handle the ellision case. A series of words with a value\n         * of 0 can be removed completely, replaced by an extra colon */\n        if (n == 0 && !is_ellision) {\n            is_ellision = 1;\n            while (i < 13 && ipv6[i + 2] == 0 && ipv6[i + 3] == 0)\n                i += 2;\n            _append_char(out, ':');\n\n            /* test for all-zero address, in which case the output\n             * will be \"::\". */\n            while (i == 14 && ipv6[i] == 0 && ipv6[i + 1] == 0){\n                i=16;\n                _append_char(out, ':');\n            }\n            continue;\n        }\n\n        /* Print the colon between numbers. Fence-post alert: only colons\n         * between numbers are printed, not at the beginning or end of the\n         * string */\n        if (i)\n            _append_char(out, ':');\n\n        /* Print the digits. Leading zeroes are not printed */\n        if (n >> 12)\n            _append_char(out, hex[(n >> 12) & 0xF]);\n        if (n >> 8)\n            _append_char(out, hex[(n >> 8) & 0xF]);\n        if (n >> 4)\n            _append_char(out, hex[(n >> 4) & 0xF]);\n        _append_char(out, hex[(n >> 0) & 0xF]);\n    }\n}\n\nstruct ipaddress_formatted ipv6address_fmt(ipv6address a)\n{\n    struct ipaddress_formatted out;\n    unsigned char tmp[16];\n    size_t i;\n    stream_t s;\n\n    /*\n     * Convert address into a sequence of bytes. Our code\n     * here represents an IPv6 address as two 64-bit numbers, but\n     * the formatting code above that we copied from a different\n     * project represents it as an array of bytes.\n     */\n    for (i=0; i<16; i++) {\n        uint64_t x;\n        if (i<8)\n            x = a.hi;\n        else\n            x = a.lo;\n        x >>= (7 - (i%8)) * 8;\n\n        tmp[i] = (unsigned char)(x & 0xFF);\n    }\n\n    /* Call the formatting function */\n    s.buf = out.string;\n    s.offset = 0;\n    s.length = sizeof(out.string);\n    _append_ipv6(&s, tmp);\n\n    return out;\n}\n\n/**\n * Append a decimal integer.\n */\nstatic void\n_append_decimal(stream_t *out, unsigned long long n)\n{\n    char tmp[64];\n    size_t tmp_offset = 0;\n\n    /* Create temporary string */\n    while (n >= 10) {\n        unsigned digit = n % 10;\n        n /= 10;\n        tmp[tmp_offset++] = (char)('0' + digit);\n    }\n    \n    /* the final digit, may be zero */\n    tmp[tmp_offset++] = (char)('0' + n);\n\n    /* Copy the result backwards */\n    while (tmp_offset)\n        _append_char(out, tmp[--tmp_offset]);\n}\nstatic void\n_append_hex2(stream_t *out, unsigned long long n)\n{\n    static const char hex[17] = \"0123456789abcdef\";\n    \n    _append_char(out, hex[(n>>4)&0xF]);\n    _append_char(out, hex[(n>>0)&0xF]);\n}\n\nstruct ipaddress_formatted ipv4address_fmt(ipv4address ip)\n{\n    struct ipaddress_formatted out;\n    stream_t s;\n\n\n    /* Call the formatting function */\n    s.buf = out.string;\n    s.offset = 0;\n    s.length = sizeof(out.string);\n\n    _append_decimal(&s, (ip >> 24) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 16) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 8) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 0) & 0xFF);\n\n    return out;\n}\n\nstruct ipaddress_formatted macaddress_fmt(macaddress_t mac)\n{\n    struct ipaddress_formatted out;\n    stream_t s;\n\n\n    /* Call the formatting function */\n    s.buf = out.string;\n    s.offset = 0;\n    s.length = sizeof(out.string);\n\n    _append_hex2(&s, mac.addr[0]);\n    _append_char(&s, '-');\n    _append_hex2(&s, mac.addr[1]);\n    _append_char(&s, '-');\n    _append_hex2(&s, mac.addr[2]);\n    _append_char(&s, '-');\n    _append_hex2(&s, mac.addr[3]);\n    _append_char(&s, '-');\n    _append_hex2(&s, mac.addr[4]);\n    _append_char(&s, '-');\n    _append_hex2(&s, mac.addr[5]);\n\n    return out;\n}\n\nstruct ipaddress_formatted ipaddress_fmt(ipaddress a)\n{\n    struct ipaddress_formatted out;\n    stream_t s;\n    ipv4address ip = a.ipv4;\n\n    if (a.version == 6) {\n        return ipv6address_fmt(a.ipv6);\n    }\n\n\n    /* Call the formatting function */\n    s.buf = out.string;\n    s.offset = 0;\n    s.length = sizeof(out.string);\n\n    _append_decimal(&s, (ip >> 24) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 16) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 8) & 0xFF);\n    _append_char(&s, '.');\n    _append_decimal(&s, (ip >> 0) & 0xFF);\n\n    return out;\n}\n\n\nstatic unsigned _count_long(uint64_t number)\n{\n    unsigned i;\n    unsigned count = 0;\n    for (i=0; i<64; i++) {\n        if ((number >> i) & 1)\n            count = i + 1;\n    }\n    return count;\n}\n\n/**\n * Find the number of bits needed to hold the integer. In other words,\n * the number 0x64 would need 7 bits to store it.\n *\n * We use this to count the size of scans. We currently only support\n * scan sizes up to 63 bits.\n */\nunsigned massint128_bitcount(massint128_t number)\n{\n    if (number.hi)\n        return _count_long(number.hi) + 64;\n    else\n        return _count_long(number.lo);\n}\n\nipv6address_t ipv6address_add_uint64(ipv6address_t lhs, uint64_t rhs) {\n    lhs.lo += rhs;\n    if (lhs.lo < rhs) {\n        lhs.hi += 1;\n    }\n    return lhs;\n}\n\nipv6address_t ipv6address_subtract(ipv6address_t lhs, ipv6address_t rhs) {\n    ipv6address_t difference;\n    difference.hi = lhs.hi - rhs.hi;\n    difference.lo = lhs.lo - rhs.lo;\n\n    /* check for underflow */\n    if (difference.lo > lhs.lo)\n        difference.hi -= 1;\n    return difference;\n}\n\nipv6address_t ipv6address_add(ipv6address_t lhs, ipv6address_t rhs) {\n    ipv6address_t sum;\n    sum.hi = lhs.hi + rhs.hi;\n    sum.lo = lhs.lo - rhs.lo;\n\n    /* check for underflow */\n    if (sum.lo > lhs.lo)\n        sum.hi += 1;\n    return sum;\n}\n\n\nint ipv6address_selftest(void)\n{\n  struct test_pair {\n    const char *name;             // Human-readable IPv6 address string\n    struct ipaddress ip_addr;     // IP address (union)\n  };\n  /* Probably overkill, added while investigating issue #796 */\n  struct test_pair tests[] = {\n      {\"2001:db8:ac10:fe01::2\", {.ipv6 = {0x20010db8ac10fe01, 0x0000000000000002}, .version = 6}},\n      {\"2607:f8b0:4000::1\", {.ipv6 = {0x2607f8b040000000, 0x0000000000000001}, .version = 6}},\n      {\"fd12:3456:7890:abcd:ef00::1\", {.ipv6 = {0xfd1234567890abcd, 0xef00000000000001}, .version = 6}},\n      {\"::1\", {.ipv6 = {0x0000000000000000, 0x0000000000000001}, .version = 6}},\n      {\"1::\", {.ipv6 = {0x0001000000000000, 0x0000000000000000}, .version = 6}},\n      {\"1::2\", {.ipv6 = {0x0001000000000000, 0x0000000000000002}, .version = 6}},\n      {\"2::1\", {.ipv6 = {0x0002000000000000, 0x0000000000000001}, .version = 6}},\n      {\"1:2::\", {.ipv6 = {0x0001000200000000, 0x0000000000000000}, .version = 6}},\n      {NULL, {{0, 0}, 0}}\n  };\n\n  int x = 0;\n  ipaddress ip;\n  struct ipaddress_formatted fmt;\n\n  for (int i = 0; tests[i].name != NULL; i++) {\n    fmt = ipaddress_fmt(tests[i].ip_addr);\n    if (strcmp(fmt.string, tests[i].name) != 0)\n      x++;\n  }\n  return x;\n}\n\nint ipv4address_selftest(void)\n{\n    int x = 0;\n    ipaddress ip;\n    struct ipaddress_formatted fmt;\n\n    ip.version = 4;\n    ip.ipv4 = 0x01FF00A3;\n\n    fmt = ipaddress_fmt(ip);\n    if (strcmp(fmt.string, \"1.255.0.163\") != 0)\n        x++;\n\n    return x;\n}\n\nint ipv6address_is_equal_prefixed(ipv6address_t lhs, ipv6address_t rhs, unsigned prefix)\n{\n    ipv6address mask;\n    \n    /* If the prefix is bad, then the answer is 'no'. */\n    if (prefix > 128) {\n        return 0;\n    }\n\n    /* Create the mask from the prefix */\n    if (prefix > 64)\n        mask.hi = ~0ULL;\n    else if (prefix == 0)\n        mask.hi = 0;\n    else\n        mask.hi = ~0ULL << (64 - prefix);\n    \n    if (prefix > 64)\n        mask.lo = ~0ULL << (128 - prefix);\n    else\n        mask.lo = 0;\n\n    /* Mask off any non-zero bits from both addresses */\n    lhs.hi &= mask.hi;\n    lhs.lo &= mask.lo;\n    rhs.hi &= mask.hi;\n    rhs.lo &= mask.lo;\n\n    /* Now do a normal compare */\n    return ipv6address_is_equal(lhs, rhs);\n}\n"
  },
  {
    "path": "src/massip-addr.h",
    "content": "/*\n    Simple module for handling addresses (IPv6, IPv4, MAC).\n    Also implements a 128-bit type for dealing with addresses.\n \n    This is the module that almost all the other code depends\n    upon, because everything else deals with the IP address\n    types defined here.\n    \n*/\n#ifndef MASSIP_ADDR_H\n#define MASSIP_ADDR_H\n#include <stdint.h>\n#include <stddef.h>\n\n#if defined(_MSC_VER) && !defined(inline)\n#define inline __inline\n#endif\n#if defined(_MSC_VER)\n#pragma warning(disable: 4201)\n#endif\n\n/**\n * An IPv6 address is represented as two 64-bit integers instead of a single\n * 128-bit integer. This is because currently (year 2020) most compilers\n * do not support the `uint128_t` type, but all relevant ones do support\n * the `uint64_t` type.\n */\nstruct ipv6address {uint64_t hi; uint64_t lo;};\ntypedef struct ipv6address ipv6address;\ntypedef struct ipv6address ipv6address_t;\n\n/**\n * IPv4 addresses are represented simply with an integer.\n */\ntypedef unsigned ipv4address;\ntypedef ipv4address ipv4address_t;\n\n/**\n * MAC address (layer 2).  Since we have canonical types for IPv4/IPv6\n * addresses, we may as well have a canonical type for MAC addresses,\n * too.\n */\nstruct macaddress_t {unsigned char addr[6];};\ntypedef struct macaddress_t macaddress_t;\n\n/**\n * In many cases we need to do arithmetic on IPv6 addresses, treating\n * them as a large 128-bit integer. Thus, we declare our own 128-bit\n * integer type (and some accompanying math functions). But it's\n * still just the same as a 128-bit integer.\n */\ntypedef ipv6address massint128_t;\n\n\n/**\n * Most of the code in this project is agnostic to the version of IP\n * addresses (IPv4 or IPv6). Therefore, we represent them as a union\n * distinguished by a version number. The `version` is an integer\n * with a value of either 4 or 6.\n */\nstruct ipaddress {\n    union {\n        unsigned ipv4;\n        ipv6address ipv6;\n    };\n    unsigned char version;\n};\ntypedef struct ipaddress ipaddress;\n\n/** @return true if the IPv6 address is zero [::] */\nstatic inline int ipv6address_is_zero(ipv6address_t a) {\n    return a.hi == 0 && a.lo == 0;\n}\n#define massint128_is_zero ipv6address_is_zero\n\n/** The IPv6 address [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]\n * is invalid */\nstatic inline int ipv6address_is_invalid(ipv6address_t a) {\n    return a.hi == ~0ULL && a.lo == ~0ULL;\n}\n\n\n/** Compare two IPv6 addresses */\nstatic inline int ipv6address_is_equal(ipv6address_t a, ipv6address_t b) {\n    return a.hi == b.hi && a.lo == b.lo;\n}\n\nstatic inline int ipaddress_is_equal(ipaddress a, ipaddress b) {\n    if (a.version != b.version)\n        return 0;\n    if (a.version == 4) {\n        return a.ipv4 == b.ipv4;\n    } else if (a.version == 6) {\n        return ipv6address_is_equal(a.ipv6, b.ipv6);\n    } else\n        return 0;\n}\n\n/** Compare two IPv6 addresses, to see which one comes frist. This is used\n * in sorting the addresses\n * @return true if a < b, false otherwise */\nstatic inline int ipv6address_is_lessthan(ipv6address_t a, ipv6address_t b) {\n    return (a.hi == b.hi)?(a.lo < b.lo):(a.hi < b.hi);\n}\n\n/**\n * Mask the lower bits of each address and test if the upper bits are equal\n */\nint ipv6address_is_equal_prefixed(ipv6address_t lhs, ipv6address_t rhs, unsigned prefix);\n\nipv6address_t ipv6address_add_uint64(ipv6address_t lhs, uint64_t rhs);\nipv6address_t ipv6address_subtract(ipv6address_t lhs, ipv6address_t rhs);\nipv6address_t ipv6address_add(ipv6address_t lhs, ipv6address_t rhs);\n\n/**\n * Given a typical EXTERNAL representation of an IPv6 address, which is\n * an array of 16 bytes, convert to the canonical INTERNAL address.\n */\nstatic inline ipv6address ipv6address_from_bytes(const unsigned char *buf) {\n    ipv6address addr;\n    addr.hi = (uint64_t)buf[ 0] << 56\n            | (uint64_t)buf[ 1] << 48\n            | (uint64_t)buf[ 2] << 40\n            | (uint64_t)buf[ 3] << 32\n            | (uint64_t)buf[ 4] << 24\n            | (uint64_t)buf[ 5] << 16\n            | (uint64_t)buf[ 6] <<  8\n            | (uint64_t)buf[ 7] <<  0;\n    addr.lo = (uint64_t)buf[ 8] << 56\n            | (uint64_t)buf[ 9] << 48\n            | (uint64_t)buf[10] << 40\n            | (uint64_t)buf[11] << 32\n            | (uint64_t)buf[12] << 24\n            | (uint64_t)buf[13] << 16\n            | (uint64_t)buf[14] <<  8\n            | (uint64_t)buf[15] <<  0;\n    return addr;\n}\n\n/**\n * Given a typical EXTERNAL representation of an Ethernet MAC address,\n * which is an array of 6 bytes, convert to the canonical INTERNAL address.\n */\nstatic inline macaddress_t macaddress_from_bytes(const void *vbuf)\n{\n    const unsigned char *buf = (const unsigned char *)vbuf;\n    macaddress_t result;\n    result.addr[0] = buf[0];\n    result.addr[1] = buf[1];\n    result.addr[2] = buf[2];\n    result.addr[3] = buf[3];\n    result.addr[4] = buf[4];\n    result.addr[5] = buf[5];\n    return result;\n}\n\n/** Test if the Ethernet MAC address is all zeroes */\nstatic inline int macaddress_is_zero(macaddress_t mac)\n{\n    return mac.addr[0] == 0\n    && mac.addr[1] == 0\n    && mac.addr[2] == 0\n    && mac.addr[3] == 0\n    && mac.addr[4] == 0\n    && mac.addr[5] == 0;\n}\n\n/** Compare two Ethernet MAC addresses to see if they are equal */\nstatic inline int macaddress_is_equal(macaddress_t lhs, macaddress_t rhs)\n{\n    return lhs.addr[0] == rhs.addr[0]\n    && lhs.addr[1] == rhs.addr[1]\n    && lhs.addr[2] == rhs.addr[2]\n    && lhs.addr[3] == rhs.addr[3]\n    && lhs.addr[4] == rhs.addr[4]\n    && lhs.addr[5] == rhs.addr[5];\n}\n\n/**\n * Return a buffer with the formatted address\n */\ntypedef struct ipaddress_formatted {\n    char string[48];\n} ipaddress_formatted_t;\n\nstruct ipaddress_formatted ipv6address_fmt(ipv6address a);\nstruct ipaddress_formatted ipv4address_fmt(ipv4address a);\nstruct ipaddress_formatted ipaddress_fmt(ipaddress a);\nstruct ipaddress_formatted macaddress_fmt(macaddress_t a);\n\nunsigned massint128_bitcount(massint128_t num);\n\n/**\n * @return 0 on success, 1 on failure\n */\nint ipv6address_selftest(void);\nint ipv4address_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/massip-parse.c",
    "content": "/*\n    massip-parse\n\n    This module parses IPv4 and IPv6 addresses.\n\n    It's not a typical parser. It's optimized around parsing large\n    files containing millions of addresses and ranges using a \n    \"state-machine parser\".\n*/\n#include \"massip.h\"\n#include \"massip-parse.h\"\n#include \"massip-rangesv4.h\"\n#include \"massip-rangesv6.h\"\n#include \"util-logger.h\"\n#include \"util-bool.h\"\n#include \"util-malloc.h\"\n#include \"util-safefunc.h\"\n#include \"unusedparm.h\"\n\n#include <string.h>\n\nstruct massip_parser\n{\n    unsigned long long line_number;\n    unsigned long long char_number;\n    unsigned state;\n    unsigned tmp;\n    unsigned char digit_count;\n    unsigned addr;\n    unsigned begin;\n    unsigned end;\n    struct {\n        ipv6address _begin;\n        ipv6address _end;\n        unsigned short tmp[8];\n        unsigned char index;\n        unsigned char ellision_index;\n        unsigned is_bracket:1;\n        unsigned is_second:1;\n    } ipv6;\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic struct massip_parser *\n_parser_init(struct massip_parser *p)\n{\n    memset(p, 0, sizeof(*p));\n    p->line_number = 1;\n    p->ipv6.ellision_index = 8;\n    return p;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_parser_destroy(struct massip_parser *p)\n{\n    UNUSEDPARM(p);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_parser_err(struct massip_parser *p, unsigned long long *line_number, unsigned long long *charindex)\n{\n    *line_number = p->line_number;\n    *charindex = p->char_number;\n}\n\n/** \n * Called before parsing the first address in a pair, and also\n * after the first address, to prepare for parsing the next\n * address\n */\nstatic void\n_init_next_address(struct massip_parser *p, int is_second)\n{\n    p->tmp = 0;\n    p->ipv6.ellision_index = 8;\n    p->ipv6.index = 0;\n    p->ipv6.is_bracket = 0;\n    p->digit_count = 0;\n    p->ipv6.is_second = is_second;\n}\n\n\n\nstatic unsigned\n_parser_finish_ipv6(struct massip_parser *p)\n{\n    unsigned index = p->ipv6.index;\n    unsigned ellision = p->ipv6.ellision_index;\n    \n\n    /* We must have seen 8 numbers, or an ellision */\n    if (index < 8 && ellision >= 8)\n        return 1;\n    \n    /* Handle ellision */\n    memmove(\n        &p->ipv6.tmp[8-(index-ellision)],\n        &p->ipv6.tmp[ellision],\n        sizeof(p->ipv6.tmp[0]) * (index-ellision)\n        );\n    memset(\n        &p->ipv6.tmp[ellision],\n        0,\n        sizeof(p->ipv6.tmp[0]) * (8 - index)\n    );\n    \n    /* Copy over to begin/end. We parse the address as a series of 16-bit\n     * integers, but return the result as two 64-bit integers */\n    {\n        ipv6address a;\n        a.hi = (uint64_t)p->ipv6.tmp[0] << 48ULL\n                | (uint64_t)p->ipv6.tmp[1] << 32ULL\n                | (uint64_t)p->ipv6.tmp[2] << 16ULL\n                | (uint64_t)p->ipv6.tmp[3] << 0ULL;\n        a.lo = (uint64_t)p->ipv6.tmp[4] << 48ULL\n                | (uint64_t)p->ipv6.tmp[5] << 32ULL\n                | (uint64_t)p->ipv6.tmp[6] << 16ULL\n                | (uint64_t)p->ipv6.tmp[7] << 0ULL;\n        if (p->ipv6.is_second)\n            p->ipv6._end = a;\n        else {\n            p->ipv6._begin = a;\n\n            /* Set this here in case there is no 'end' address */\n            p->ipv6._end = a;\n        }\n    }\n\n    /* Reset the parser to start parsing the next address */\n    _init_next_address(p, 1);\n\n    return 0;\n}\n\n/***************************************************************************\n * We store the IPv6 addresses that we are building inside the 'state'\n * of the state-machine. This function copies them out of the opaque\n * state into discrete values.\n ***************************************************************************/\nstatic void\n_parser_get_ipv6(struct massip_parser *state, ipv6address *begin, ipv6address *end)\n{\n    *begin = state->ipv6._begin;\n    *end = state->ipv6._end;\n}\n\nenum parser_state_t {\n    LINE_START, ADDR_START,\n    COMMENT,\n    NUMBER0, NUMBER1, NUMBER2, NUMBER3, NUMBER_ERR,\n    SECOND0, SECOND1, SECOND2, SECOND3, SECOND_ERR,\n    IPV4_CIDR_NUM,\n    UNIDASH1, UNIDASH2,\n    IPV6_BEGIN, IPV6_COLON, IPV6_CIDR, IPV6_CIDR_NUM,\n    IPV6_NEXT,\n    IPV6_END,\n    ERROR\n};\n\n/***************************************************************************\n * When we start parsing an address, we don't know whether it's going to \n * be IPv4 or IPv6. We assume IPv4, but when we hit a condition indicating\n * that it's IPv6 instead, we need change the temporary number we \n * are working on from decimal to hex, then move from the middle of \n * parsing an IPv4 address to the middle of parsing an IPv6 address.\n ***************************************************************************/\nstatic int\n_switch_to_ipv6(struct massip_parser *p, int old_state)\n{\n    unsigned num = p->tmp;\n\n    num = ((num/1000)%10) * 16 * 16 * 16\n        + ((num/100)%10) * 16 * 16\n        + ((num/10)%10) * 16\n        + (num % 10);\n    \n    //printf(\"%u -> 0x%x\\n\", p->tmp, num);\n    p->tmp = num;\n    return old_state;\n}\n\n\nenum {\n    IPV4_n, IPV4_nn, IPV4_nnn, IPV4_nnn_, \n    IPV4_nnn_n, IPV4_nnn_nn, IPV4_nnn_nnn, IPV4_nnn_nnn_, \n    IPV4_nnn_nnn_n, IPV4_nnn_nnn_nn, IPV4_nnn_nnn_nnn, IPV4_nnn_nnn_nnn_,\n    IPV4_nnn_nnn_nnn_n, IPV4_nnn_nnn_nnn_nn, IPV4_nnn_nnn_nnn_nnn, IPV4_nnn_nnn_nnn_nnn_,\n    IPV4e_n, IPV4e_nn, IPV4e_nnn, IPV4e_nnn_, \n    IPV4e_nnn_n, IPV4e_nnn_nn, IPV4e_nnn_nnn, IPV4e_nnn_nnn_, \n    IPV4e_nnn_nnn_n, IPV4e_nnn_nnn_nn, IPV4e_nnn_nnn_nnn, IPV4e_nnn_nnn_nnn_,\n    IPV4e_nnn_nnn_nnn_n, IPV4e_nnn_nnn_nnn_nn, IPV4e_nnn_nnn_nnn_nnn, IPV4e_nnn_nnn_nnn_nnn_,\n\n\n};\n\n\n/**\n * Applies a CIDR mask to an IPv4 address to create a begin/end address.\n */\nstatic void\n_ipv4_apply_cidr(unsigned *begin, unsigned *end, unsigned bitcount)\n{\n    unsigned long long mask = 0xFFFFFFFF00000000ULL >> bitcount;\n    \n    /* mask off low-order bits */\n    *begin &= (unsigned)mask;\n\n    /* Set all suffix bits to 1, so that 192.168.1.0/24 has\n     * an ending address of 192.168.1.255. */\n    *end = *begin | (unsigned)~mask;\n}\n\n/**\n * Given an address 'being' and a 'prefix', return the 'begin' and 'end' address of the range.\n * @param begin\n *      An in/out parameter. This may have some extra bits somewhere in the range.\n *      These will be masked off and set to zero when the function returns.\n * @param end\n *      An out parameter. This will be set to the last address of the range, meaning\n *      that all the trailing bits will be set to '1'.\n * @parame prefix\n *      The number of bits of the prefix, from [0..128]. If the value is 0,\n *      then the 'begin' address will be set to all zeroes and the 'end'\n *      address will be set to all ones. If the value is 128,\n *      the 'begin' address is unchanged and the 'end' address\n *      is set to the same as 'begin'.\n */\nstatic void\n_ipv6_apply_cidr(ipv6address *begin, ipv6address *end, unsigned prefix)\n{\n    ipv6address mask;\n    \n    /* For bad prefixes, make sure we return an invalid address */\n    if (prefix > 128) {\n        static const ipv6address invalid = {~0ULL, ~0ULL};\n        *begin = invalid;\n        *end = invalid;\n        return;\n    };\n\n    /* Create the mask from the prefix */\n    if (prefix > 64)\n        mask.hi = ~0ULL;\n    else if (prefix == 0)\n        mask.hi = 0;\n    else\n        mask.hi = ~0ULL << (64 - prefix);\n    \n    if (prefix > 64)\n        mask.lo = ~0ULL << (128 - prefix);\n    else\n        mask.lo = 0;\n\n    /* Mask off any non-zero bits from the start\n     * TODO print warning */\n    begin->hi &= mask.hi;\n    begin->lo &= mask.lo;\n    \n    /* Set all suffix bits to 1, so that 192.168.1.0/24 has\n     * an ending address of 192.168.1.255. */\n    end->hi = begin->hi | ~mask.hi;\n    end->lo = begin->lo | ~mask.lo;\n}\n\n/***************************************************************************\n * Parse the next IPv4/IPv6 address from a text stream, using a\n * 'state-machine parser'.\n ***************************************************************************/\nstatic enum {Still_Working, Found_Error, Found_IPv4, Found_IPv6}\n_parser_next(struct massip_parser *p, const char *buf, size_t *r_offset, size_t length,\n                unsigned *r_begin, unsigned *r_end)\n{ \n    size_t i;\n    enum parser_state_t state = p->state;\n    int result = Still_Working;\n\n    /* The 'offset' parameter is optional. If NULL, then set it to zero */\n    if (r_offset)\n        i = *r_offset;\n    else\n        i = 0;\n\n    /* For all bytes in this chunk. This loop will exit early once\n     * we've found a complete IP address. */\n    while (i < length) {\n        unsigned char c = buf[i++];\n\n        p->char_number++;\n        switch (state) {\n            case LINE_START:\n            case ADDR_START:\n                _init_next_address(p, 0);\n                switch (c) {\n                    case ' ': case '\\t': case '\\r':\n                        /* ignore leading whitespace */\n                        continue;\n                    case '\\n':\n                        p->line_number++;\n                        p->char_number = 0;\n                        continue;\n                    case '#': case ';': case '/': case '-':\n                        state = COMMENT;\n                        continue;\n                        \n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        p->tmp = (c - '0');\n                        p->digit_count = 1;\n                        state = NUMBER0;\n                        break;\n                    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n                        p->tmp = (c - 'a' + 10);\n                        p->digit_count = 1;\n                        state = IPV6_BEGIN;\n                        break;\n                    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n                        p->tmp = (c - 'A' + 10);\n                        p->digit_count = 1;\n                        state = IPV6_BEGIN;\n                        break;\n                    case ':':\n                        p->ipv6.tmp[p->ipv6.index++] = 0;\n                        state = IPV6_COLON;\n                        break;\n                    case '[':\n                        p->ipv6.is_bracket = 1;\n                        state = IPV6_BEGIN;\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i; /* break out of loop */\n                        break;\n                }\n                break;\n            case IPV6_CIDR:\n                p->digit_count = 0;\n                p->tmp = 0;\n                switch (c) {\n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        p->tmp = (c - '0');\n                        p->digit_count = 1;\n                        state = IPV6_CIDR_NUM;\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i; /* break out of loop */\n                        break;\n                }\n                break;\n                \n            case IPV6_COLON:\n                p->digit_count = 0;\n                p->tmp = 0;\n                if (c == ':') {\n                    if (p->ipv6.ellision_index < 8) {\n                        state = ERROR;\n                        length = i;\n                    } else {\n                        p->ipv6.ellision_index = p->ipv6.index;\n                        state = IPV6_COLON;\n                    }\n                    break;\n                }\n                state = IPV6_BEGIN;\n\n                /* drop down */\n            case IPV6_BEGIN:\n            case IPV6_NEXT:\n                switch (c) {\n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        if (p->digit_count >= 4) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            p->tmp = p->tmp * 16 + (c - '0');\n                            p->digit_count++;\n                        }\n                        break;\n                    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n                        if (p->digit_count >= 4) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            p->tmp = p->tmp * 16 + (c - 'a' + 10);\n                            p->digit_count++;\n                        }\n                        break;\n                    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n                        if (p->digit_count >= 4) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            p->tmp = p->tmp * 16 + (c - 'A' + 10);\n                            p->digit_count++;\n                        }\n                        break;\n                    case ':':\n                        if (p->ipv6.index >= 8) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            p->ipv6.tmp[p->ipv6.index++] = (unsigned short)p->tmp;\n                            state = IPV6_COLON;\n                        }\n                        break;\n                    case ']':\n                        if (!p->ipv6.is_bracket) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            state = IPV6_END;\n                        }\n                        break;\n                    case '[':\n                        if (p->ipv6.is_bracket) {\n                            state = ERROR;\n                            length = i;\n                        } else {\n                            p->ipv6.is_bracket = 1;\n                        }\n                        break;\n                    case '/':\n                    case ' ':\n                    case '\\t':\n                    case '\\r':\n                    case '\\n':\n                    case ',':\n                    case '-':\n                        i--; /* push back */\n                        state = IPV6_END;\n                        continue;\n                    default:\n                        state = ERROR;\n                        length = i;\n                        break;\n                }\n                break;\n\n            case IPV6_END:\n                /* Finish off the trailing number */\n                p->ipv6.tmp[p->ipv6.index++] = (unsigned short)p->tmp;\n\n                /* Do the final processing of this IPv6 address and\n                 * prepare for the next one */\n                if (_parser_finish_ipv6(p) != 0) {\n                    state = ERROR;\n                    length = i;\n                    continue;\n                }\n\n                /* Now decide the next state, whether this is a single\n                 * address, an address range, or a CIDR address */\n                switch (c) {\n                    case '/':\n                        result = Still_Working;\n                        state = IPV6_CIDR;\n                        break;\n                    case '-':\n                        result = Still_Working;\n                        state = IPV6_NEXT;\n                        break;\n                    case '\\n':\n                        p->line_number++;\n                        p->char_number = 0;\n                        /* drop down */\n                    case ' ':\n                    case '\\t':\n                    case '\\r':\n                    case ',':\n                        result = Found_IPv6;\n                        state = 0;\n                        length = i; /* shorten the end to break out of loop */\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i;\n                        break;\n                }\n                break;\n            case COMMENT:\n                if (c == '\\n') {\n                    state = LINE_START;\n                    p->line_number++;\n                    p->char_number = 0;\n                } else\n                    state = COMMENT;\n                break;\n            case IPV6_CIDR_NUM:\n                switch (c) {\n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        if (p->digit_count == 4) {\n                            state = ERROR;\n                            length = i; /* break out of loop */\n                        } else {\n                            p->digit_count++;\n                            p->tmp = p->tmp * 10 + (c - '0');\n                            if (p->tmp > 128) {\n                                state = ERROR;\n                                length = i;\n                            }\n                            continue;\n                        }\n                        break;\n                    case ':':\n                    case ',':\n                    case ' ':\n                    case '\\t':\n                    case '\\r':\n                    case '\\n':\n                        {\n                            _ipv6_apply_cidr(&p->ipv6._begin, &p->ipv6._end, p->tmp);\n\n                            state = ADDR_START;\n                            length = i; /* break out of loop */\n                            if (c == '\\n') {\n                                p->line_number++;\n                                p->char_number = 0;\n                            }\n                            *r_begin = p->begin;\n                            *r_end = p->end;\n                            result = Found_IPv6;\n                        }\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i; /* break out of loop */\n                        break;\n                }\n                break;\n            case IPV4_CIDR_NUM:\n                switch (c) {\n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        if (p->digit_count == 3) {\n                            state = ERROR;\n                            length = i; /* break out of loop */\n                        } else {\n                            p->digit_count++;\n                            p->tmp = p->tmp * 10 + (c - '0');\n                            if (p->tmp > 32) {\n                                state = ERROR;\n                                length = i;\n                            }\n                            continue;\n                        }\n                        break;\n                    case ':':\n                    case ',':\n                    case ' ':\n                    case '\\t':\n                    case '\\r':\n                    case '\\n':\n                        {\n                            _ipv4_apply_cidr(&p->begin, &p->end, p->tmp);\n                            state = ADDR_START;\n                            length = i; /* break out of loop */\n                            if (c == '\\n') {\n                                p->line_number++;\n                                p->char_number = 0;\n                            }\n                            *r_begin = p->begin;\n                            *r_end = p->end;\n                            result = Found_IPv4;\n                        }\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i; /* break out of loop */\n                        break;\n                }\n                break;\n\n            case UNIDASH1:\n                if (c == 0x80)\n                    state = UNIDASH2;\n                else {\n                    state = ERROR;\n                    length = i; /* break out of loop */\n                }\n                break;\n            case UNIDASH2:\n                /* This covers:\n                 * U+2010 HYPHEN\n                 * U+2011 NON-BREAKING HYPHEN\n                 * U+2012 FIGURE DASH\n                 * U+2013 EN DASH\n                 * U+2014 EM DASH\n                 * U+2015 HORIZONTAL BAR\n                 */\n                if (c < 0x90 || 0x95 < c) {\n                    state = ERROR;\n                    length = i; /* break out of loop */\n                } else {\n                    c = '-';\n                    state = NUMBER3;\n                    /* drop down */\n                }\n\n\n            case NUMBER0:\n            case NUMBER1:\n            case NUMBER2:\n            case NUMBER3:\n            case SECOND0:\n            case SECOND1:\n            case SECOND2:\n            case SECOND3:\n                switch (c) {\n                    case '.':\n                        p->addr = (p->addr << 8) | p->tmp;\n                        p->tmp = 0;\n                        p->digit_count = 0;\n                        if (state == NUMBER3 || state == SECOND3) {\n                            length = i;\n                            state = ERROR;\n                        } else\n                            state++;\n                        break;\n                    case '0': case '1': case '2': case '3': case '4':\n                    case '5': case '6': case '7': case '8': case '9':\n                        p->digit_count++;\n                        p->tmp = p->tmp * 10 + (c - '0');\n                        if (p->tmp > 255 || p->digit_count > 3) {\n                            if (state == NUMBER0) {\n                                /* Assume that we've actually got an\n                                 * IPv6 number */\n                                _switch_to_ipv6(p, state);\n                                state = IPV6_BEGIN;\n                            } else {\n                                state = ERROR;\n                                length = i;\n                            }\n                        }\n                        continue;\n                        break;\n                    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n                    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n                        if (state == NUMBER0 || state == SECOND0) {\n                            /* Assume that we've actually got an\n                             * IPv6 number */\n                            _switch_to_ipv6(p, state);\n                            state = IPV6_BEGIN;\n                            i--; /* go back one character */\n                        } else {\n                            state = ERROR;\n                            length = i; /* break out of loop */\n                        }\n                        break;\n                    case 0xe2:\n                        if (state == NUMBER3) {\n                            state = UNIDASH1;\n                        } else {\n                            state = ERROR;\n                            length = i; /* break out of loop */\n                        }\n                        break;\n                    case '-':\n                    case 0x96: /* long dash, comes from copy/pasting into exclude files */\n                        if (state == NUMBER3) {\n                            p->begin = (p->addr << 8) | p->tmp;\n                            p->tmp = 0;\n                            p->digit_count = 0;\n                            p->addr = 0;\n                            state = SECOND0;\n                        } else {\n                            state = NUMBER_ERR;\n                            length = i;\n                        }\n                        break;\n                    case '/':\n                        if (state == NUMBER3) {\n                            p->begin = (p->addr << 8) | p->tmp;\n                            p->tmp = 0;\n                            p->digit_count = 0;\n                            p->addr = 0;\n                            state = IPV4_CIDR_NUM;\n                        } else {\n                            state = NUMBER_ERR;\n                            length = i; /* break out of loop */\n                        }\n                        break;\n                    case ':':\n                        if (state == NUMBER0) {\n                            /* Assume this is an IPv6 address instead of an IPv4 address */\n                            _switch_to_ipv6(p, state);\n                            state = IPV6_BEGIN;\n                            i--;\n                            break;\n                        }\n                    case ',':\n                    case ' ':\n                    case '\\t':\n                    case '\\r':\n                    case '\\n':\n                        if (state == NUMBER3) {\n                            p->begin = (p->addr << 8) | p->tmp;\n                            p->end = p->begin;\n                            p->tmp = 0;\n                            p->digit_count = 0;\n                            p->addr = 0;\n                            state = ADDR_START;\n                            length = i; /* break out of loop */\n                            if (c == '\\n') {\n                                p->line_number++;\n                                p->char_number = 0;\n                            }\n                            *r_begin = p->begin;\n                            *r_end = p->end;\n                            result = Found_IPv4;\n                        } else if (state == SECOND3) {\n                            p->end = (p->addr << 8) | p->tmp;\n                            p->tmp = 0;\n                            p->digit_count = 0;\n                            p->addr = 0;\n                            state = ADDR_START;\n                            length = i; /* break out of loop */\n                            if (c == '\\n') {\n                                p->line_number++;\n                                p->char_number = 0;\n                            }\n                            *r_begin = p->begin;\n                            *r_end = p->end;\n                            result = Found_IPv4;\n                        } else {\n                            state = NUMBER_ERR;\n                            length = i;\n                        }\n                        break;\n                    default:\n                        state = ERROR;\n                        length = i; /* break out of loop */\n                        break;\n                }\n                break;\n                \n            default:\n            case ERROR:\n            case NUMBER_ERR:\n            case SECOND_ERR:\n                state = ERROR;\n                length = i; /* break */\n                break;\n        }\n    }\n\n    /* The 'offset' parameter is optional. If NULL, then \n     * we don't return a value */\n    if (r_offset)\n        *r_offset = i;\n\n    p->state = state;\n    if (state == ERROR || state == NUMBER_ERR || state == SECOND_ERR)\n        result = Found_Error;\n    return result;\n}\n\n\n/***************************************************************************\n * Test errors. We should get exactly which line-number and which character\n * in the line caused the error\n ***************************************************************************/\nstatic int\nrangefile_test_error(const char *buf, unsigned long long in_line_number, unsigned long long in_char_number, unsigned which_test)\n{\n    size_t length = strlen(buf);\n    size_t offset = 0;\n    struct massip_parser p[1];\n    unsigned out_begin = 0xa3a3a3a3;\n    unsigned out_end  = 0xa3a3a3a3;\n    unsigned long long out_line_number;\n    unsigned long long out_char_number;\n    int x;\n\n    /* test the entire buffer */\n    _parser_init(p);\n    x = _parser_next(p, buf, &offset, length, &out_begin, &out_end);\n    if (x != Found_Error)\n        goto fail;\n    _parser_err(p, &out_line_number, &out_char_number);\n    if (in_line_number != out_line_number || in_char_number != out_char_number)\n        goto fail;\n\n    /* test one byte at a time */\n    _parser_destroy(p);\n    _parser_init(p);\n    offset = 0;\n    out_begin = 0xa3a3a3a3;\n    out_end  = 0xa3a3a3a3;\n    \n    x = 0;\n    while (offset < length) {\n        x = _parser_next(p, buf, &offset, offset+1, &out_begin, &out_end);\n        if (x == Found_Error)\n            break;\n    }\n    if (x != Found_Error)\n        goto fail;\n    _parser_err(p, &out_line_number, &out_char_number);\n\n    if (in_line_number != out_line_number || in_char_number != out_char_number)\n        goto fail;\n\n    _parser_destroy(p);\n    return 0;\nfail:\n    _parser_destroy(p);\n    fprintf(stderr, \"[-] rangefile test fail, line=%u\\n\", which_test);\n    return 1;\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nmassip_parse_file(struct MassIP *massip, const char *filename)\n{\n    struct RangeList *targets_ipv4 = &massip->ipv4;\n    struct Range6List *targets_ipv6 = &massip->ipv6;\n    struct massip_parser p[1];\n    char buf[65536];\n    FILE *fp = NULL;\n    bool is_error = false;\n    unsigned addr_count = 0;\n    unsigned long long line_number, char_number;\n\n    /* Kludge: should never happen, should fix this when reading in\n     * config, not this deep in the code. */\n    if (filename == 0 || filename[0] == '\\0') {\n        fprintf(stderr, \"[-] missing filename for ranges\\n\");\n        exit(1);\n    }\n\n    /*\n     * Open the file containing IP addresses, which can potentially be\n     * many megabytes in size\n     */\n    if (strcmp(filename, \"-\") == 0) {\n        fp = stdin;\n    } else {\n        fp = fopen(filename, \"rb\");\n        if (fp == NULL) {\n            fprintf(stderr, \"[-] FAIL: parsing IP addresses\\n\");\n            fprintf(stderr, \"[-] %s: %s\\n\", filename, strerror(errno));\n            exit(1);\n        }\n    }\n\n    /*\n     * Create a parser for reading in the IP addresses using a state\n     * machine parser\n     */\n    _parser_init(p);\n\n    /*\n     * Read in the data a block at a time, parsing according to the state\n     * machine.\n     */\n    while (!is_error) {\n        size_t count;\n        size_t offset;\n\n        count = fread(buf, 1, sizeof(buf), fp);\n        if (count <= 0)\n            break;\n\n        offset = 0;\n        while (offset < count) {\n            unsigned begin, end;\n            int err;\n\n            err = _parser_next(p, buf, &offset, count, &begin, &end);\n            switch (err) {\n            case Still_Working:\n                if (offset < count) {\n                    /* We reached this somehow in the middle of the buffer, but\n                     * this return is only possible at the end of the buffer */\n                    fprintf(stderr, \"[-] rangeparse_next(): unknown coding failure\\n\");\n                }\n                break;\n            case Found_Error:\n            default:\n                _parser_err(p, &line_number, &char_number);\n                fprintf(stderr, \"[-] %s:%llu:%llu: invalid IP address on line #%llu\\n\", filename, line_number, char_number, line_number);\n                is_error = true;\n                count = offset;\n                break;\n            case Found_IPv4:\n                rangelist_add_range(targets_ipv4, begin, end);\n                addr_count++;\n                break;\n            case Found_IPv6:\n                {\n                    ipv6address found_begin, found_end;\n                    _parser_get_ipv6(p, &found_begin, &found_end);\n                    range6list_add_range(targets_ipv6, found_begin, found_end);\n                    addr_count++;\n                }\n                break;\n            }\n        }\n    }\n    \n    /* Close the file, unless we are reading from <stdin> */\n    if (fp != stdin && fp != NULL)\n        fclose(fp);\n\n    /* In case the file doesn't end with a newline '\\n', then artificially\n     * add one to the end. This is just a repeat of the code above */\n    if (!is_error) {\n        size_t offset = 0;\n        unsigned begin, end;\n        int err;\n        err = _parser_next(p, \"\\n\", &offset, 1, &begin, &end);\n        switch (err) {\n        case Still_Working:\n                break;\n        case Found_Error:\n        default:\n            _parser_err(p, &line_number, &char_number);\n            fprintf(stderr, \"[-] %s:%llu:%llu: invalid IP address on line #%llu\\n\", filename, line_number, char_number, line_number);\n            is_error = true;\n            break;\n        case Found_IPv4:\n            rangelist_add_range(targets_ipv4, begin, end);\n            addr_count++;\n            break;\n        case Found_IPv6:\n            {\n                ipv6address found_begin, found_end;\n                _parser_get_ipv6(p, &found_begin, &found_end);\n                range6list_add_range(targets_ipv6, found_begin, found_end);\n                addr_count++;\n            }\n            break;\n        }\n    }\n\n    LOG(1, \"[+] %s: %u addresses read\\n\", filename, addr_count);\n\n    /* Target list must be sorted every time it's been changed, \n     * before it can be used */\n    rangelist_sort(targets_ipv4);\n\n    if (is_error)\n        return -1;  /* fail */\n    else\n        return 0; /* success*/\n}\n\n\nipv6address\nmassip_parse_ipv6(const char *line)\n{\n    struct massip_parser p[1];\n    size_t count = strlen(line);\n    size_t offset = 0;\n    int err;\n    unsigned begin, end;\n    ipv6address result;\n    ipv6address range;\n\n    _parser_init(p);\n    err = _parser_next(p, line, &offset, count, &begin, &end);\nagain:\n    switch (err) {\n        case Still_Working:\n            if (offset < count) {\n                /* We reached this somehow in the middle of the buffer, but\n                 * this return is only possible at the end of the buffer */\n                fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                goto fail;\n            } else {\n                err = _parser_next(p, \"\\n\", 0, 1, &begin, &end);\n                if (err == Still_Working) {\n                    fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                    goto fail;\n                } else {\n                    goto again;\n                }\n            }\n            break;\n        case Found_Error:\n        default:\n            goto fail;\n        case Found_IPv4:\n            goto fail;\n        case Found_IPv6:\n            _parser_get_ipv6(p, &result, &range);\n            if (!ipv6address_is_equal(result, range))\n                goto fail;\n            return result;\n    }\nfail:\n    result.hi = ~0ULL;\n    result.lo = ~0ULL;\n    return result;\n}\n\nunsigned\nmassip_parse_ipv4(const char *line)\n{\n    struct massip_parser p[1];\n    size_t count = strlen(line);\n    size_t offset = 0;\n    int err;\n    unsigned begin, end;\n\n\n    _parser_init(p);\n    err = _parser_next(p, line, &offset, count, &begin, &end);\nagain:\n    switch (err) {\n        case Still_Working:\n            if (offset < count) {\n                /* We reached this somehow in the middle of the buffer, but\n                 * this return is only possible at the end of the buffer */\n                fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                goto fail;\n            } else {\n                err = _parser_next(p, \"\\n\", 0, 1, &begin, &end);\n                if (err == Still_Working) {\n                    fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                    goto fail;\n                } else {\n                    goto again;\n                }\n            }\n            break;\n        case Found_Error:\n        default:\n            goto fail;\n        case Found_IPv6:\n            goto fail;\n        case Found_IPv4:\n            if (begin != end)\n                goto fail;\n            return begin;\n    }\nfail:\n    return 0xFFFFFFFF;\n}\n\nenum RangeParseResult\nmassip_parse_range(const char *line, size_t *offset, size_t count, struct Range *ipv4, struct Range6 *ipv6)\n{\n    struct massip_parser p[1];\n    int err;\n    unsigned begin, end;\n    size_t tmp_offset = 0;\n    \n    /* The 'count' (length of the string) is an optional parameter. If\n     * zero, and also the offset is NULL, then set it to the string length */\n    if (count == 0 && offset == NULL)\n        count = strlen(line);\n\n    /* The offset is an optional parameter. If NULL, then we set\n     * it to point to a value on the stack instead */\n    if (offset == NULL)\n        offset = &tmp_offset;\n    \n    /* Create e parser object */\n    _parser_init(p);\n\n    /* Parse the next range from the input */\n    err = _parser_next(p, line, offset, count, &begin, &end);\nagain:\n    switch (err) {\n        case Still_Working:\n            if (*offset < count) {\n                /* We reached this somehow in the middle of the buffer, but\n                 * this return is only possible at the end of the buffer */\n                fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                return Bad_Address;\n            } else {\n                err = _parser_next(p, \"\\n\", 0, 1, &begin, &end);\n                if (err == Still_Working) {\n                    fprintf(stderr, \"[-] _parser_next(): unknown coding failure\\n\");\n                    return Bad_Address;\n                } else {\n                    goto again;\n                }\n            }\n            break;\n        case Found_Error:\n        default:\n            return Bad_Address;\n        case Found_IPv4:\n            ipv4->begin = begin;\n            ipv4->end = end;\n            return Ipv4_Address;\n        case Found_IPv6:\n            _parser_get_ipv6(p, &ipv6->begin, &ipv6->end);\n            return Ipv6_Address;\n    }\n}\n\n/**\n * This tests  parsing when addresses/ranges are specified on the command-line\n * or configuration files, rather than the other test-cases which test parsing\n * when the IP addresses are specified in a file. The thing we are looking for\n * here is specifically when users separate addresses with things like\n * commas and spaces.\n */\nstatic int\nselftest_massip_parse_range(void)\n{\n    struct testcases {\n        const char *line;\n        union {\n            struct Range ipv4;\n            struct Range6 ipv6;\n        } list[4];\n    } cases[] = {\n        {\"0.0.1.0/24,0.0.3.0-0.0.4.0\", {{{0x100,0x1ff}}, {{0x300,0x400}}}},\n        {\"0.0.1.0-0.0.1.255,0.0.3.0-0.0.4.0\", {{{0x100,0x1ff}}, {{0x300,0x400}}}},\n        {\"0.0.1.0/24 0.0.3.0-0.0.4.0\", {{{0x100,0x1ff}}, {{0x300,0x400}}}},\n        {0}\n    };\n    size_t i;\n    \n    for (i=0; cases[i].line; i++) {\n        size_t length = strlen(cases[i].line);\n        size_t offset = 0;\n        size_t j = 0;\n        struct Range6 range6;\n        struct Range range4;\n        \n        while (offset < length) {\n            int x;\n            x = massip_parse_range(cases[i].line, &offset, length, &range4, &range6);\n            switch (x) {\n                default:\n                case Bad_Address:\n                    fprintf(stdout, \"[-] selftest_massip_parse_range[%u] fail\\n\", (unsigned)i);\n                    return 1;\n                case Ipv4_Address:\n                    if (cases[i].list[j].ipv4.begin != range4.begin\n                        || cases[i].list[j].ipv4.end != range4.end) {\n                        fprintf(stdout, \"[-] %u.%u.%u.%u - %u.%u.%u.%u\\n\",\n                                (unsigned char)(range4.begin>>24),\n                                (unsigned char)(range4.begin>>16),\n                                (unsigned char)(range4.begin>> 8),\n                                (unsigned char)(range4.begin>> 0),\n                                (unsigned char)(range4.end>>24),\n                                (unsigned char)(range4.end>>16),\n                                (unsigned char)(range4.end>> 8),\n                                (unsigned char)(range4.end>> 0)\n                                );\n                        fprintf(stdout, \"[-] selftest_massip_parse_range[%u] fail\\n\", (unsigned)i);\n                        return 1;\n                    }\n                    break;\n            }\n            j++;\n        }\n        \n        /* Make sure we have found all the expected cases */\n        if (cases[i].list[j].ipv4.begin != 0) {\n            fprintf(stdout, \"[-] selftest_massip_parse_range[%u] fail\\n\", (unsigned)i);\n            return 1;\n        }\n    }\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nrangefile6_test_buffer(struct massip_parser *parser,\n                       const char *buf,\n                       ipv6address expected_begin,\n                       ipv6address expected_end)\n{\n    size_t length = strlen(buf);\n    size_t offset = 0;\n    ipv6address found_begin = {1,2};\n    ipv6address found_end = {1,2};\n    unsigned tmp1, tmp2;\n    int err;\n    \n    /* test the entire buffer */\n    err = _parser_next(parser, buf, &offset, length, &tmp1, &tmp2);\n    if (err == Still_Working)\n        err = _parser_next(parser, \"\\n\", 0, 1, &tmp1, &tmp2);\n    switch (err) {\n    case Found_IPv6:\n        /* Extract the resulting IPv6 address from the state structure */\n        _parser_get_ipv6(parser, &found_begin, &found_end);\n    \n        /* Test to see if the parsed address equals the expected address */\n        if (!ipv6address_is_equal(found_begin, expected_begin)) {\n            ipaddress_formatted_t fmt1 = ipv6address_fmt(found_begin);\n            ipaddress_formatted_t fmt2 = ipv6address_fmt(expected_begin);\n            fprintf(stderr, \"[-] begin mismatch: found=[%s], expected=[%s]\\n\", fmt1.string, fmt2.string);\n            goto fail;\n        }\n        if (!ipv6address_is_equal(found_end, expected_end)) {\n            ipaddress_formatted_t fmt1 = ipv6address_fmt(found_end);\n            ipaddress_formatted_t fmt2 = ipv6address_fmt(expected_end);\n            fprintf(stderr, \"[-] end mismatch: found=[%s], expected=[%s]\\n\", fmt1.string, fmt2.string);\n            goto fail;\n        }\n        break;\n    case Found_IPv4:\n        if (expected_begin.hi != 0 || expected_end.hi != 0)\n            goto fail;\n        if (tmp1 != expected_begin.lo || tmp2 != expected_end.lo)\n            goto fail;\n        break;\n    case Still_Working:\n        /* Found a partial address, which is a normal result in the \n         * real world at buffer boundaries, but which is an error\n         * here */\n        goto fail;\n    case Found_Error:\n    default:\n        goto fail;\n    }\n\n    return 0; /* success */\nfail:\n    return 1; /* failure */\n}\n\n/***************************************************************************\n * List of test cases. Each test case contains three parts:\n * - the string representation of an address, as read from a file, meaning\n *   that it can contain additional things like comment strings\n * - the first address of a range, which in the case of IPv6 addresses\n *   will be two 64-bit numbers, but an IPv4 address have a high-order\n *   number set to zero and the low-order number set to the IPv4 address\n * - the second address of a range, which in the case of individual\n *   addresses, will be equal to the first number\n ***************************************************************************/\nstruct {\n    const char *string;\n    ipv6address begin;\n    ipv6address end;\n} test_cases[] = {\n    {\"[1::1]/126\", {0x0001000000000000ULL, 0ULL}, {0x0001000000000000ULL, 3ULL}},\n    {\"1::1/126\", {0x0001000000000000ULL, 0ULL}, {0x0001000000000000ULL, 3ULL}},\n    {\"[1::1]-[2::3]\", {0x0001000000000000ULL, 1ULL}, {0x0002000000000000ULL, 3ULL}},\n    {\"1::1-2::3\", {0x0001000000000000ULL, 1ULL}, {0x0002000000000000ULL, 3ULL}},\n    {\"[1234:5678:9abc:def0:0fed:cba9:8765:4321]\", {0x123456789abcdef0ULL, 0x0fedcba987654321ULL}, {0x123456789abcdef0ULL, 0x0fedcba987654321ULL}},\n    {\"22ab::1\", {0x22ab000000000000ULL, 1ULL}, {0x22ab000000000000ULL, 1ULL}},\n    {\"240e:33c:2:c080:d08:d0e:b53:e74e\", {0x240e033c0002c080ULL, 0x0d080d0e0b53e74eULL}, {0x240e033c0002c080ULL, 0x0d080d0e0b53e74eULL}},\n    {\"2a03:90c0:105::9\", {0x2a0390c001050000ULL, 9ULL}, {0x2a0390c001050000ULL, 9ULL}},\n    {\"2a03:9060:0:400::2\", {0x2a03906000000400ULL, 2ULL}, {0x2a03906000000400ULL, 2ULL}},\n    {\"2c0f:ff00:0:a:face:b00c:0:a7\", {0x2c0fff000000000aULL, 0xfaceb00c000000a7ULL}, {0x2c0fff000000000aULL, 0xfaceb00c000000a7ULL}},\n    {\"2a01:5b40:0:4a01:0:e21d:789f:59b1\", {0x2a015b4000004a01ULL, 0x0000e21d789f59b1ULL}, {0x2a015b4000004a01ULL, 0x0000e21d789f59b1ULL}},\n    {\"2001:1200:10::1\", {0x2001120000100000ULL, 1ULL}, {0x2001120000100000ULL, 1ULL}},\n    {\"fec0:0:0:ffff::1\", {0xfec000000000ffffULL, 1ULL}, {0xfec000000000ffffULL, 1ULL}},\n    {\"1234:5678:9abc:def0:0fed:cba9:8765:4321\", {0x123456789abcdef0ULL, 0x0fedcba987654321ULL}, {0x123456789abcdef0ULL, 0x0fedcba987654321ULL}},\n    {\"[1111:2222:3333:4444:5555:6666:7777:8888]\", {0x1111222233334444ULL, 0x5555666677778888ULL}, {0x1111222233334444ULL, 0x5555666677778888ULL}},\n    {\"1::1\", {0x0001000000000000ULL, 1ULL}, {0x0001000000000000ULL, 1ULL}},\n    {\"1.2.3.4\", {0, 0x01020304}, {0, 0x01020304}},\n    {\"#test\\n  97.86.162.161\" \"\\x96\" \"97.86.162.175\\n\", {0, 0x6156a2a1}, {0, 0x6156a2af}},\n    {\"1.2.3.4/24\\n\", {0, 0x01020300}, {0, 0x010203ff}},\n    {\" 1.2.3.4-1.2.3.5\\n\", {0, 0x01020304}, {0, 0x01020305}},\n    {0,{0,0},{0,0}}\n};\n\n/***************************************************************************\n * Called during \"make test\" to run a regression test over this module.\n ***************************************************************************/\nint\nmassip_parse_selftest(void)\n{\n    int x = 0;\n    size_t i;\n    struct massip_parser parser[1];\n\n    \n    /* Run through the test cases, stopping at the first failure */\n    _parser_init(parser);\n    for (i=0; test_cases[i].string; i++) {\n        x += rangefile6_test_buffer(parser,\n                                    test_cases[i].string, \n                                    test_cases[i].begin,\n                                    test_cases[i].end);\n        if (x) {\n            fprintf(stderr, \"[-] failed: %u: %s\\n\", (unsigned)i, test_cases[i].string);\n            break;\n        }\n    }\n    _parser_destroy(parser);\n\n    \n    /* First, do the single line test */\n    x += selftest_massip_parse_range();\n    if (x)\n        return x;\n    \n\n    x += rangefile_test_error(\"#bad ipv4\\n 257.1.1.1\\n\", 2, 5, __LINE__);\n    x += rangefile_test_error(\"#bad ipv4\\n 1.257.1.1.1\\n\", 2, 6, __LINE__);\n    x += rangefile_test_error(\"#bad ipv4\\n 1.10.257.1.1.1\\n\", 2, 9, __LINE__);\n    x += rangefile_test_error(\"#bad ipv4\\n 1.10.255.256.1.1.1\\n\", 2, 13, __LINE__);\n    x += rangefile_test_error(\"#bad ipv4\\n 1.1.1.1.1\\n\", 2, 9, __LINE__);\n\n    if (x)\n       LOG(0, \"[-] rangefile_selftest: fail\\n\");\n    return x;\n}\n\n"
  },
  {
    "path": "src/massip-parse.h",
    "content": "/*\n    massip-parse\n\n    This module parses IPv4 and IPv6 addresses.\n\n    It's not a typical parser. It's optimized around parsing large\n    files containing millions of addresses and ranges using a \n    \"state-machine parser\".\n*/\n#ifndef MASSIP_PARSE_H\n#define MASSIP_PARSE_H\n#include \"massip-addr.h\"\n\nstruct MassIP;\nstruct Range;\nstruct Range6;\n\n/**\n * Parse a file, extracting all the IPv4 and IPv6 addresses and ranges.\n * This is optimized for speed, handling millions of entries in under\n * a second. This is especially tuned for IPv6 addresses, as while IPv4\n * scanning is mostly done with target rnages, IPv6 scanning is mostly\n * done with huge lists of target addresses.\n * @param filename\n *      The name of the file that we'll open, parse, and close.\n * @param targets_ipv4\n *      The list of IPv4 targets that we append any IPv4 addresses to.\n * @param targets_ipv6\n *      The list of IPv6 targets that we append any IPv6 addresses/ranges to.\n * @return \n        0 on success, any other number on failure.\n */\nint\nmassip_parse_file(struct MassIP *massip, const char *filename);\n\n\nenum RangeParseResult {\n    Bad_Address,\n    Ipv4_Address=4,\n    Ipv6_Address=6,\n};\n\n/**\n * Parse the next IPv4/IPv6 range from a string. This is called\n * when parsing strings from the command-line.\n */\nenum RangeParseResult\nmassip_parse_range(const char *line, size_t *inout_offset, size_t max, struct Range *ipv4, struct Range6 *ipv6);\n\n\n\n/**\n * Parse a single IPv6 address. This is called when working with\n * the operating system stack, when querying addresses from\n * the local network adapters.\n */\nipv6address_t\nmassip_parse_ipv6(const char *buf);\n\nipv4address_t\nmassip_parse_ipv4(const char *buf);\n\n\n/**\n * Do a simplistic unit test of the parser.\n * @return 0 on success, 1 on failure\n */\nint\nmassip_parse_selftest(void);\n\n#endif\n\n"
  },
  {
    "path": "src/massip-port.h",
    "content": "#ifndef MASSIP_PORT_H\n#define MASSIP_PORT_H\n\n/*\n * Ports are 16-bit numbers ([0..65535], but different\n * transports (TCP, UDP, SCTP) are distinct port ranges. Thus, we\n * instead of three 64k ranges we could instead treat this internally\n * as a 192k port range. We can expand this range to include other\n * things we scan for, such as ICMP pings or ARP requests.\n */\nenum {\n    Templ_TCP = 0,\n    Templ_TCP_last = 65535,\n    Templ_UDP = 65536,\n    Templ_UDP_last = 65536 + 65535,\n    Templ_SCTP = 65536*2,\n    Templ_SCTP_last = 65536*2 + 65535,\n    Templ_ICMP_echo = 65536*3+0,\n    Templ_ICMP_timestamp = 65536*3+1,\n    Templ_ARP = 65536*3+2,\n    Templ_Oproto_first = 65536*3 + 256,\n    Templ_Oproto_last = 65536*3 + 256 + 255,\n    Templ_VulnCheck = 65536*4,\n    \n};\n\n#endif\n"
  },
  {
    "path": "src/massip-rangesv4.c",
    "content": "/*\n    IPv4 and port ranges\n \n This is one of the more integral concepts to how masscan works internally.\n We combine all the input addresses and address ranges into a sorted list\n of 'target' IP addresses. This allows us to enumerate all the addresses\n in order by incrementing a simple index. It is that index that we randomize\n in order to produce random output, but internally, everything is sorted.\n \n Sorting the list allows us to remove duplicates. It also allows us to\n apply the 'excludes' directly to the input list. In other words, other\n scanners typically work by selecting an IP address at random, then checking\n to see if it's been excluded, then skipping it. In this scanner, however,\n we remove all the excluded address from the targets list before we start\n scanning.\n \n This module has been tuned to support mass lists of millions of target\n IPv4 addresses and excludes. This has required:\n    - a fast way to parse the address from a file (see range-file.c)\n    - fast sort (just using qsort() from the standard C library)\n    - fast application of exludes, using an optimal O(n + m) linear\n      algorithm, where 'n' is the number of targets, and 'm' is the\n      number of excluded ranges.\n Large lists can still take a bit to process. On a fast server with\n 7-million input ranges/addresses and 5000 exclude ranges/addresses,\n it takes almost 3 seconds to process everything before starting.\n \n*/\n#include \"massip-rangesv4.h\"\n#include \"massip-port.h\"\n#include \"util-logger.h\"\n#include \"util-bool.h\"\n#include \"util-malloc.h\"\n\n#include <assert.h>\n#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable:4204)\n#endif\n\n#define BUCKET_COUNT 16\n\n#define REGRESS(x) if (!(x)) return (fprintf(stderr, \"regression failed %s:%d\\n\", __FILE__, __LINE__)|1)\n\n/* An invalid range, where begin comes after the end */\nstatic struct Range INVALID_RANGE = {2,1};\n\n/***************************************************************************\n * Does a linear search to see if the list contains the address/port.\n * FIXME: This should be upgraded to a binary search. However, we don't\n * really use it in any performance critical code, so it's okay\n * as a linear search.\n ***************************************************************************/\nint\nrangelist_is_contains(const struct RangeList *targets, unsigned addr)\n{\n    unsigned i;\n    for (i=0; i<targets->count; i++) {\n        struct Range *range = &targets->list[i];\n\n        if (range->begin <= addr && addr <= range->end)\n            return 1;\n    }\n    return 0;\n}\n\n/***************************************************************************\n * Returns the first CIDR range (which can be specified with prefix bits)\n * that fits within the input range. For example, consider the range\n * [10.0.0.4->10.0.0.255]. This does't match the bigger CIDR range.\n * The first range that would fit would be [10.0.0.04/30], or\n * [10.0.0.4->10.0.0.7].\n *\n * Using this function allows us to decompose\n ***************************************************************************/\nstruct Range\nrange_first_cidr(const struct Range range, unsigned *prefix_bits) {\n    struct Range result = {range.begin, range.end};\n    unsigned zbits = 0;\n\n    /* Kludge: Special Case:\n     * All inputs work but the boundary case of [0.0.0.0/0] or\n     * [0.0.0.0-255.255.255.255]. I can't be bothered to figure out\n     * why the algorithm doesn't work with this range, so I'm just\n     * going to special case it here*/\n    if (range.begin == 0 && range.end == 0xFFFFffff) {\n        if (prefix_bits != NULL)\n            *prefix_bits = 0;\n        return range;\n    }\n\n    /* Count the number of trailing/suffix zeros, which may be range\n     * from none (0) to 32 (all bits are 0) */\n    for (zbits = 0; zbits <= 32; zbits++) {\n        if ((range.begin & (1<<zbits)) != 0)\n            break;\n    }\n\n    /* Now search for the largest CIDR range that starts with this\n     * begining address that fits within the ending address*/\n    while (zbits > 0) {\n        unsigned mask = ~(0xFFFFFFFF << zbits);\n\n        if (range.begin + mask > range.end)\n            zbits--;\n        else\n            break;\n    }\n\n    result.begin = range.begin;\n    result.end = range.begin + ~(0xFFFFffff << zbits);\n    if (prefix_bits != NULL)\n        *prefix_bits = 32-zbits;\n\n    return result;\n}\n\nbool\nrange_is_cidr(const struct Range range, unsigned *prefix_bits) {\n    struct Range out = range_first_cidr(range, prefix_bits);\n    if (out.begin == range.begin && out.end == range.end)\n        return true;\n    else {\n        if (prefix_bits != NULL)\n            *prefix_bits = 0xFFFFFFFF;\n        return false;\n    }\n}\n\n/***************************************************************************\n * Selftest for the above function.\n ***************************************************************************/\nstatic int\nselftest_range_first_cidr(void) {\n    static struct {\n        struct Range in;\n        struct Range out;\n        unsigned prefix_bits;\n    } tests[] = {\n        {{0x00000000, 0xffffffff}, {0x00000000, 0xffffffff}, 0},\n        {{0x00000001, 0xffffffff}, {0x00000001, 0x00000001}, 32},\n        {{0xffffffff, 0xffffffff}, {0xffffffff, 0xffffffff}, 32},\n        {{0xfffffffe, 0xfffffffe}, {0xfffffffe, 0xfffffffe}, 32},\n        {{0x0A000000, 0x0A0000Ff}, {0x0A000000, 0x0A0000ff}, 24},\n        {{0x0A0000ff, 0x0A0000Ff}, {0x0A0000ff, 0x0A0000ff}, 32},\n        {{0x0A000000, 0x0A0000Ff}, {0x0A000000, 0x0A0000Ff}, 24},\n        {{0x0A000001, 0x0A0000Fe}, {0x0A000001, 0x0A000001}, 32},\n        {{0x0A000008, 0x0A0000Fe}, {0x0A000008, 0x0A00000f}, 29},\n        {{0x0A000080, 0x0A0000Fe}, {0x0A000080, 0x0A0000bf}, 26},\n        {{0x0A0000c0, 0x0A0000Fe}, {0x0A0000c0, 0x0A0000df}, 27},\n        {{0x0A0000c1, 0x0A0000Fe}, {0x0A0000c1, 0x0A0000c1}, 32},\n        {{0x0A0000fe, 0x0A0000Fe}, {0x0A0000fe, 0x0A0000fe}, 32},\n        {{0,0}, {0,0}}\n    };\n    size_t i;\n\n    for (i=0; tests[i].in.end != 0; i++) {\n        unsigned prefix_bits = 0xFFFFFFFF;\n        struct Range out = range_first_cidr(tests[i].in, &prefix_bits);\n        if (out.begin != tests[i].out.begin\n            || out.end != tests[i].out.end\n            || prefix_bits != tests[i].prefix_bits) {\n            fprintf(stderr, \"[%u] 0x%08x->0x%08x  /%u   0x%08x->0x%08x /%u\\n\",\n                    (unsigned)i,\n                    out.begin,\n                    out.end,\n                    prefix_bits,\n                    tests[i].out.begin,\n                    tests[i].out.end,\n                    tests[i].prefix_bits);\n            return 1;\n        }\n    }\n\n    return 0;\n}\n\n/***************************************************************************\n * Test if two ranges overlap.\n * FIXME: I need to change this so that it (a) doesn't trigger on invalid\n * ranges (those where begin>end) and (b) use a simpler algorithm\n ***************************************************************************/\nstatic int\nrange_is_overlap(struct Range lhs, struct Range rhs)\n{\n    if (lhs.begin < rhs.begin) {\n        if (lhs.end == 0xFFFFFFFF || lhs.end + 1 >= rhs.begin)\n            return 1;\n    }\n    if (lhs.begin >= rhs.begin) {\n        if (lhs.end <= rhs.end)\n            return 1;\n    }\n\n    if (rhs.begin < lhs.begin) {\n        if (rhs.end == 0xFFFFFFFF || rhs.end + 1 >= lhs.begin)\n            return 1;\n    }\n    if (rhs.begin >= lhs.begin) {\n        if (rhs.end <= lhs.end)\n            return 1;\n    }\n\n    return 0;\n}\n\n\n/***************************************************************************\n * Combine two ranges, such as when they overlap.\n ***************************************************************************/\nstatic void\nrange_combine(struct Range *lhs, struct Range rhs)\n{\n    if (lhs->begin > rhs.begin)\n        lhs->begin = rhs.begin;\n    if (lhs->end < rhs.end)\n        lhs->end = rhs.end;\n}\n\n/***************************************************************************\n * Callback for qsort() for comparing two ranges\n ***************************************************************************/\nstatic int\nrange_compare(const void *lhs, const void *rhs)\n{\n    struct Range *left = (struct Range *)lhs;\n    struct Range *right = (struct Range *)rhs;\n\n    if (left->begin < right->begin)\n        return -1;\n    else if (left->begin > right->begin)\n        return 1;\n    else\n        return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nrangelist_remove_at(struct RangeList *targets, size_t index)\n{\n    memmove(&targets->list[index],\n            &targets->list[index+1],\n            (targets->count - index) * sizeof(targets->list[index])\n            );\n    targets->count--;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrangelist_sort(struct RangeList *targets)\n{\n    size_t i;\n    struct RangeList newlist = {0};\n    unsigned original_count = targets->count;\n\n    /* Empty lists are, of course, sorted. We need to set this\n     * to avoid an error later on in the code which asserts that\n     * the lists are sorted */\n    if (targets->count == 0) {\n        targets->is_sorted = 1;\n        return;\n    }\n    \n    /* If it's already sorted, then skip this */\n    if (targets->is_sorted) {\n        return;\n    }\n    \n    \n    /* First, sort the list */\n    LOG(3, \"[+] range:sort: sorting...\\n\");\n    qsort(  targets->list,              /* the array to sort */\n            targets->count,             /* number of elements to sort */\n            sizeof(targets->list[0]),   /* size of element */\n            range_compare);\n    \n    \n    /* Second, combine all overlapping ranges. We do this by simply creating\n     * a new list from a sorted list, so we don't have to remove things in the\n     * middle when collapsing overlapping entries together, which is painfully\n     * slow. */\n    LOG(3, \"[+] range:sort: combining...\\n\");\n    for (i=0; i<targets->count; i++) {\n        rangelist_add_range(&newlist, targets->list[i].begin, targets->list[i].end);\n    }\n    \n    LOG(3, \"[+] range:sort: combined from %u elements to %u elements\\n\", original_count, newlist.count);\n    free(targets->list);\n    targets->list = newlist.list;\n    targets->count = newlist.count;\n    newlist.list = 0;\n\n    LOG(2, \"[+] range:sort: done...\\n\");\n\n    targets->is_sorted = 1;\n}\n\n/***************************************************************************\n * Add the IPv4 range to our list of ranges.\n ***************************************************************************/\nvoid\nrangelist_add_range(struct RangeList *targets, unsigned begin, unsigned end)\n{\n    struct Range range;\n\n    range.begin = begin;\n    range.end = end;\n\n    /* auto-expand the list if necessary */\n    if (targets->count + 1 >= targets->max) {\n        targets->max = targets->max * 2 + 1;\n        targets->list = REALLOCARRAY(targets->list, targets->max, sizeof(targets->list[0]));\n    }\n\n    /* If empty list, then add this one */\n    if (targets->count == 0) {\n        targets->list[0] = range;\n        targets->count++;\n        targets->is_sorted = 1;\n        return;\n    }\n\n    /* If new range overlaps the last range in the list, then combine it\n     * rather than appending it. This is an optimization for the fact that\n     * we often read in sequential addresses */\n    if (range_is_overlap(targets->list[targets->count - 1], range)) {\n        range_combine(&targets->list[targets->count - 1], range);\n        targets->is_sorted = 0;\n        return;\n    }\n\n    /* append to the end of our list */\n    targets->list[targets->count] = range;\n    targets->count++;\n    targets->is_sorted = 0;\n}\n\n/** Use this when adding TCP ports, to avoid the comoplication of how\n * ports are stored */\nvoid\nrangelist_add_range_tcp(struct RangeList *targets, unsigned begin, unsigned end) {\n    rangelist_add_range(targets,\n                            Templ_TCP + begin,\n                            Templ_TCP + end);\n}\n\n/** Use this when adding UDP ports, to avoid the comoplication of how\n * ports are stored */\nvoid\nrangelist_add_range_udp(struct RangeList *targets, unsigned begin, unsigned end) {\n    rangelist_add_range(targets,\n                            Templ_UDP + begin,\n                            Templ_UDP + end);\n}\n\n\n/***************************************************************************\n * This is the \"free\" function for the list, freeing up any memory we've\n * allocated.\n ***************************************************************************/\nvoid\nrangelist_remove_all(struct RangeList *targets)\n{\n    free(targets->list);\n    free(targets->picker);\n    memset(targets, 0, sizeof(*targets));\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrangelist_merge(struct RangeList *list1, const struct RangeList *list2)\n{\n    unsigned i;\n    \n    for (i=0; i<list2->count; i++) {\n        rangelist_add_range(list1, list2->list[i].begin, list2->list[i].end);\n    }\n    rangelist_sort(list1);\n}\n\n/***************************************************************************\n * This searches a range list and removes that range of IP addresses, if\n * they exist. Since the input range can overlap multiple entries, then\n * more than one entry can be removed, or truncated. Since the range\n * can be in the middle of an entry in the list, it can actually increase\n * the list size by one, as that entry is split into two entries.\n * DEPRECATED: this function is deprecated, and will be removed at some\n * point. It's only remaining in order to serve as a regression test for\n * its replacement.\n ***************************************************************************/\nstatic void\nrangelist_remove_range(struct RangeList *targets, unsigned begin, unsigned end)\n{\n    unsigned i;\n    struct Range x;\n\n    x.begin = begin;\n    x.end = end;\n\n    /* See if the range overlaps any exist range already in the\n     * list */\n    for (i = 0; i < targets->count; i++) {\n        if (!range_is_overlap(targets->list[i], x))\n            continue;\n\n        /* If the removal-range wholly covers the range, delete\n         * it completely */\n        if (begin <= targets->list[i].begin && end >= targets->list[i].end) {\n            rangelist_remove_at(targets, i);\n            i--;\n            continue;\n        }\n\n        /* If the removal-range bisects the target-rage, truncate\n         * the lower end and add a new high-end */\n        if (begin > targets->list[i].begin && end < targets->list[i].end) {\n            struct Range newrange;\n\n            newrange.begin = end+1;\n            newrange.end = targets->list[i].end;\n\n\n            targets->list[i].end = begin-1;\n\n            rangelist_add_range(targets, newrange.begin, newrange.end);\n            i--;\n            continue;\n        }\n\n        /* If overlap on the lower side */\n        if (end >= targets->list[i].begin && end < targets->list[i].end) {\n            targets->list[i].begin = end+1;\n        }\n\n        /* If overlap on the upper side */\n        if (begin > targets->list[i].begin && begin <= targets->list[i].end) {\n             targets->list[i].end = begin-1;\n        }\n\n        //assert(!\"impossible\");\n    }\n}\n\nstatic void\nrangelist_add_range2(struct RangeList *targets, struct Range range)\n{\n    rangelist_add_range(targets, range.begin, range.end);\n}\nstatic void\nrangelist_remove_range2(struct RangeList *targets, struct Range range)\n{\n    rangelist_remove_range(targets, range.begin, range.end);\n}\n\n\n/***************************************************************************\n * Parse an IPv4 address from a line of text, moving the offset forward\n * to the first non-IPv4 character\n ***************************************************************************/\nstatic int\nparse_ipv4(const char *line, unsigned *inout_offset, unsigned max, unsigned *ipv4)\n{\n    unsigned offset = *inout_offset;\n    unsigned result = 0;\n    unsigned i;\n\n    for (i=0; i<4; i++) {\n        unsigned x = 0;\n        unsigned digits = 0;\n\n        if (offset >= max)\n            return -4;\n        if (!isdigit(line[offset]&0xFF))\n            return -1;\n\n        /* clear leading zeros */\n        while (offset < max && line[offset] == '0')\n            offset++;\n\n        /* parse maximum of 3 digits */\n        while (offset < max && isdigit(line[offset]&0xFF)) {\n            x = x * 10 + (line[offset] - '0');\n            offset++;\n            if (++digits > 3)\n                return -2;\n        }\n        if (x > 255)\n            return -5;\n        result = result * 256 + (x & 0xFF);\n        if (i == 3)\n            break;\n\n        if (line[offset] != '.')\n            return -3;\n        offset++; /* skip dot */\n    }\n\n    *inout_offset = offset;\n    *ipv4 = result;\n\n    return 0; /* parse OK */\n}\n\n\n/****************************************************************************\n * Parse from text an IPv4 address range. This can be in one of several\n * formats:\n * - '192.168.1.1\" - a single address\n * - '192.168.1.0/24\" - a CIDR spec\n * - '192.168.1.0-192.168.1.255' - a range\n * @param line\n *      Part of a line of text, probably read from a commandline or conf\n *      file.\n * @param inout_offset\n *      On input, the offset from the start of the line where the address\n *      starts. On output, the offset of the first character after the\n *      range, or equal to 'max' if the line prematurely ended.\n * @param max\n *      The maximum length of the line.\n * @return\n *      The first and last address of the range, inclusive.\n ****************************************************************************/\nstruct Range\nrange_parse_ipv4(const char *line, unsigned *inout_offset, unsigned max)\n{\n    unsigned offset;\n    struct Range result;\n    static const struct Range badrange = {0xFFFFFFFF, 0};\n    int err;\n\n    if (line == NULL)\n        return badrange;\n\n    if (inout_offset == NULL) {\n         inout_offset = &offset;\n         offset = 0;\n         max = (unsigned)strlen(line);\n    } else\n        offset = *inout_offset;\n\n\n    /* trim whitespace */\n    while (offset < max && isspace(line[offset]&0xFF))\n        offset++;\n\n    /* get the first IP address */\n    err = parse_ipv4(line, &offset, max, &result.begin);\n    if (err) {\n        return badrange;\n    }\n    result.end = result.begin;\n\n    /* trim whitespace */\n    while (offset < max && isspace(line[offset]&0xFF))\n        offset++;\n\n    /* If only one IP address, return that */\n    if (offset >= max)\n        goto end;\n\n    /*\n     * Handle CIDR address of the form \"10.0.0.0/8\"\n     */\n    if (line[offset] == '/') {\n        uint64_t prefix = 0;\n        uint64_t mask = 0;\n        unsigned digits = 0;\n\n        /* skip slash */\n        offset++;\n\n        if (!isdigit(line[offset]&0xFF)) {\n            return badrange;\n        }\n\n        /* strip leading zeroes */\n        while (offset<max && line[offset] == '0')\n            offset++;\n\n        /* parse decimal integer */\n        while (offset<max && isdigit(line[offset]&0xFF)) {\n            prefix = prefix * 10 + (line[offset++] - '0');\n            if (++digits > 2)\n                return badrange;\n        }\n        if (prefix > 32)\n            return badrange;\n\n        /* Create the mask from the prefix */\n        mask = 0xFFFFFFFF00000000ULL >> prefix;\n\n        /* Mask off any non-zero bits from the start\n         * TODO print warning */\n        result.begin &= mask;\n\n        /* Set all suffix bits to 1, so that 192.168.1.0/24 has\n         * an ending address of 192.168.1.255. */\n        result.end = result.begin | (unsigned)~mask;\n        goto end;\n    }\n\n    /*\n     * Handle a dashed range like \"10.0.0.100-10.0.0.200\"\n     */\n    if (offset<max && line[offset] == '-') {\n        unsigned ip;\n\n        offset++;\n        err = parse_ipv4(line, &offset, max, &ip);\n        if (err)\n            return badrange;\n        if (ip < result.begin) {\n            result.begin = 0xFFFFFFFF;\n            result.end = 0x00000000;\n            LOG(0, \"err: ending addr %u.%u.%u.%u cannot come before starting addr %u.%u.%u.%u\\n\",\n                ((ip>>24)&0xFF), ((ip>>16)&0xFF), ((ip>>8)&0xFF), ((ip>>0)&0xFF),\n                ((result.begin>>24)&0xFF), ((result.begin>>16)&0xFF), ((result.begin>>8)&0xFF), ((result.begin>>0)&0xFF)\n                );\n        } else\n            result.end = ip;\n        goto end;\n    }\n\nend:\n    *inout_offset = offset;\n    return result;\n}\n\n\n/***************************************************************************\n * This is the old algorithm for applying exclude ranges, very slow\n * for large lists. We keep it around for verifying correctness of the\n * new replacement algorithm.\n ***************************************************************************/\nstatic void\nrangelist_exclude2(  struct RangeList *targets,\n                  const struct RangeList *excludes)\n{\n    unsigned i;\n    \n    for (i=0; i<excludes->count; i++) {\n        struct Range range = excludes->list[i];\n        rangelist_remove_range(targets, range.begin, range.end);\n    }\n    \n    /* Since chopping up large ranges can split ranges, this can\n     * grow the list so we need to re-sort it */\n    rangelist_sort(targets);\n\n}\n\n/**\n * Applies the (presumably overlapping) exclude range to the target. This can have\n * four outcomes:\n *  - there is no overlap, in which case 'target' is unchanged, and 'split'\n *    is set to INVALID.\n *  - the entire target is excluded, in which case it's set to INVALID.\n *  - the overlap is at the beginning, in which case the 'begin' is increased.\n *  - the overlap is at the end, in which case 'end' is reduced.\n *  - the overlap is in the middle, in which case the target is split\n *    in two, with 'target' becoming the low addresses, and 'split' becoming\n *    the high addresses.\n */\nstatic void\nrange_apply_exclude(const struct Range exclude, struct Range *target, struct Range *split)\n{\n    /* Set 'split' to invalid to start with */\n    split->begin = 2;\n    split->end = 1;\n\n    /* Case 1: no overlap */\n    if (target->begin > exclude.end || target->end < exclude.begin) {\n        return;\n    }\n    \n    /* Case 2: complete overlap, mark target as invalid and return */\n    if (target->begin >= exclude.begin && target->end <= exclude.end) {\n        target->begin = 2;\n        target->end = 1;\n        return;\n    }\n    \n    /* Case 3: overlap at start */\n    if (target->begin >= exclude.begin && target->end > exclude.end) {\n        target->begin = exclude.end + 1;\n        return;\n    }\n    \n    /* Case 4: overlap at end */\n    if (target->begin < exclude.begin && target->end <= exclude.end) {\n        target->end = exclude.begin - 1;\n        return;\n    }\n    \n    /* Case 5: this range needs to be split */\n    if (target->begin < exclude.begin && target->end > exclude.end) {\n        split->end = target->end;\n        split->begin = exclude.end + 1;\n        target->end = exclude.begin - 1;\n        return;\n    }\n    \n    /* No other condition should be possible */\n    assert(!\"possible\");\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nrange_is_valid(struct Range range)\n{\n    return range.begin <= range.end;\n}\n\n/***************************************************************************\n * Apply the exclude ranges, which means removing everything from \"targets\"\n * that's also in \"exclude\". This can make the target list even bigger\n * as individually excluded address chop up large ranges.\n ***************************************************************************/\nvoid\nrangelist_exclude(  struct RangeList *targets,\n                  struct RangeList *excludes)\n{\n    unsigned i;\n    unsigned x;\n    struct RangeList newlist = {0};\n    \n    /* Both lists must be sorted */\n    rangelist_sort(targets);\n    rangelist_sort(excludes);\n    \n    /* Go through all target ranges, apply excludes to them\n     * (which may split into two ranges), and add them to\n     * the new target list */\n    x = 0;\n    for (i=0; i<targets->count; i++) {\n        struct Range range = targets->list[i];\n        \n        /* Move the exclude forward until we find a potentially\n         * overlapping candidate */\n        while (x < excludes->count && excludes->list[x].end < range.begin)\n            x++;\n        \n        /* Keep applying excludes to this range as long as there are overlaps */\n        while (x < excludes->count && excludes->list[x].begin <= range.end) {\n            struct Range split = INVALID_RANGE;\n            \n            range_apply_exclude(excludes->list[x], &range, &split);\n            \n            /* If there is a split, then add the original range to our list\n             * and then set that range to the split-ed portion */\n            if (range_is_valid(split)) {\n                rangelist_add_range(&newlist, range.begin, range.end);\n                memcpy(&range, &split, sizeof(range));\n            }\n            \n            if (excludes->list[x].begin > range.end)\n                break;\n            \n            x++;\n        }\n        \n        /* If the range hasn't been completely excluded, then add the remnants */\n        if (range_is_valid(range)) {\n            rangelist_add_range(&newlist, range.begin, range.end);\n        }\n    }\n\n    /* Now free the old list and move over the new list */\n    free(targets->list);\n    targets->list = newlist.list;\n    targets->count = newlist.count;\n    newlist.list = NULL;\n    newlist.count = 0;\n    \n    /* Since chopping up large ranges can split ranges, this can\n     * grow the list so we need to re-sort it */\n    rangelist_sort(targets);\n}\n\n\n/***************************************************************************\n * Counts the total number of addresses in all the ranges combined.\n * For 0.0.0.0/0, this will be 0x100000000, which means we have to use a\n * larger number than 32-bit to return the result. This assumes that\n * all overlaps have been resolved in the list (i.e. it's been sorted).\n ***************************************************************************/\nuint64_t\nrangelist_count(const struct RangeList *targets)\n{\n    unsigned i;\n    uint64_t result = 0;\n\n    for (i=0; i<targets->count; i++) {\n        result += (uint64_t)targets->list[i].end - (uint64_t)targets->list[i].begin + 1UL;\n    }\n\n    return result;\n}\n\n\n/***************************************************************************\n * Get's the indexed port/address.\n *\n * Note that this requires a search of all the ranges. Currently, this is\n * done by a learn search of the ranges. This needs to change, because\n * once we start adding in a lot of \"exclude ranges\", the address space\n * will get fragmented, and the linear search will take too long.\n ***************************************************************************/\nstatic unsigned\nrangelist_pick_linearsearch(const struct RangeList *targets, uint64_t index)\n{\n    unsigned i;\n\n    for (i=0; i<targets->count; i++) {\n        uint64_t range = (uint64_t)targets->list[i].end - (uint64_t)targets->list[i].begin + 1UL;\n        if (index < range)\n            return (unsigned)(targets->list[i].begin + index);\n        else\n            index -= range;\n    }\n\n    assert(!\"end of list\");\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nrangelist_pick(const struct RangeList *targets, uint64_t index)\n{\n    unsigned maxmax = targets->count;\n    unsigned min = 0;\n    unsigned max = targets->count;\n    unsigned mid;\n    const unsigned *picker = targets->picker;\n\n    if (!targets->is_sorted)\n        rangelist_sort((struct RangeList *)targets);\n    assert(targets->is_sorted);\n\n    if (picker == NULL) {\n        /* optimization wasn't done */\n        return rangelist_pick_linearsearch(targets, index);\n    }\n\n\n    for (;;) {\n        mid = min + (max-min)/2;\n        if (index < picker[mid]) {\n            max = mid;\n            continue;\n        } if (index >= picker[mid]) {\n            if (mid + 1 == maxmax)\n                break;\n            else if (index < picker[mid+1])\n                break;\n            else\n                min = mid+1;\n        }\n    }\n\n    return (unsigned)(targets->list[mid].begin + (index - picker[mid]));\n}\n\n\n/***************************************************************************\n * The normal \"pick\" function is a linear search, which is slow when there\n * are a lot of ranges. Therefore, the \"pick2\" creates sort of binary\n * search that'll be a lot faster. We choose \"binary search\" because\n * it's the most cache-efficient, having the least overhead to fit within\n * the cache.\n ***************************************************************************/\nvoid\nrangelist_optimize(struct RangeList *targets)\n{\n    unsigned *picker;\n    unsigned i;\n    unsigned total = 0;\n\n    if (targets->count == 0)\n        return;\n\n    /* This technique only works when the targets are in\n     * ascending order */\n    if (!targets->is_sorted)\n        rangelist_sort(targets);\n\n    if (targets->picker)\n        free(targets->picker);\n\n    picker = REALLOCARRAY(NULL, targets->count, sizeof(*picker));\n\n    for (i=0; i<targets->count; i++) {\n        picker[i] = total;\n        total += targets->list[i].end - targets->list[i].begin + 1;\n    }\n\n    targets->picker = picker;\n}\n\n\n\n/***************************************************************************\n * Provide my own rand() simply to avoid static-analysis warning me that\n * 'rand()' is unrandom, when in fact we want the non-random properties of\n * rand() for regression testing.\n ***************************************************************************/\nstatic unsigned\nr_rand(unsigned *seed)\n{\n    static const unsigned a = 214013;\n    static const unsigned c = 2531011;\n\n    *seed = (*seed) * a + c;\n    return (*seed)>>16 & 0x7fff;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nregress_pick2()\n{\n    unsigned i;\n    unsigned seed = 0;\n\n    /*\n     * Run 100 randomized regression tests\n     */\n    for (i=0; i<100; i++) {\n        unsigned j;\n        unsigned num_targets;\n        unsigned begin = 0;\n        unsigned end;\n        struct RangeList targets[1] = {{0}};\n        struct RangeList duplicate[1] = {{0}};\n        unsigned range;\n\n\n        /* Create a new target list */\n        memset(targets, 0, sizeof(targets[0]));\n\n        /* fill the target list with random ranges */\n        num_targets = r_rand(&seed)%5 + 1;\n        for (j=0; j<num_targets; j++) {\n            begin += r_rand(&seed)%10;\n            end = begin + r_rand(&seed)%10;\n\n            rangelist_add_range(targets, begin, end);\n        }\n        rangelist_sort(targets);\n        range = (unsigned)rangelist_count(targets);\n\n        /* Optimize for faster 'picking' addresses from an index */\n        rangelist_optimize(targets);\n\n        /* Duplicate the targetlist using the picker */\n        memset(duplicate, 0, sizeof(duplicate[0]));\n        for (j=0; j<range; j++) {\n            unsigned x;\n\n            x = rangelist_pick(targets, j);\n            rangelist_add_range(duplicate, x, x);\n        }\n        rangelist_sort(duplicate);\n\n        /* at this point, the two range lists should be identical */\n        REGRESS(targets->count == duplicate->count);\n        REGRESS(memcmp(targets->list, duplicate->list, targets->count*sizeof(targets->list[0])) == 0);\n\n        rangelist_remove_all(targets);\n        rangelist_remove_all(duplicate);\n    }\n\n    return 0;\n}\n\n\n/***************************************************************************\n * This returns a character pointer where parsing ends so that it can\n * handle multiple stuff on the same line\n ***************************************************************************/\nconst char *\nrangelist_parse_ports(struct RangeList *ports, const char *string, unsigned *is_error, unsigned proto_offset)\n{\n    char *p = (char*)string;\n    unsigned tmp = 0;\n\n    if (is_error == NULL)\n        is_error = &tmp;\n    \n    *is_error = 0;\n    while (*p) {\n        unsigned port;\n        unsigned end;\n\n        /* skip whitespace */\n        while (*p && isspace(*p & 0xFF))\n            p++;\n\n        /* end at comment */\n        if (*p == 0 || *p == '#')\n            break;\n\n        /* special processing. Nmap allows ports to be prefixed with a\n         * characters to clarify TCP, UDP, or SCTP */\n        if (isalpha(*p&0xFF) && p[1] == ':') {\n            switch (*p) {\n                case 'T': case 't':\n                    proto_offset = 0;\n                    break;\n                case 'U': case 'u':\n                    proto_offset = Templ_UDP;\n                    break;\n                case 'S': case 's':\n                    proto_offset = Templ_SCTP;\n                    break;\n                case 'O': case 'o':\n                    proto_offset = Templ_Oproto_first;\n                    break;\n                case 'I': case 'i':\n                    proto_offset = Templ_ICMP_echo;\n                    break;\n                default:\n                    LOG(0, \"bad port character = %c\\n\", p[0]);\n                    *is_error = 1;\n                    return p;\n            }\n            p += 2;\n        }\n\n        /*\n         * Get the start of the range.\n         */\n        if (p[0] == '-') {\n            /* nmap style port range spec meaning starting with 0 */\n            port = 1;\n        } else if (isdigit(p[0] & 0xFF)) {\n            port = (unsigned)strtoul(p, &p, 0);\n        } else {\n            break;\n        }\n\n        /* \n         * Get the end of the range \n         */\n        if (*p == '-') {\n            p++;\n            if (!isdigit(*p)) {\n                /* nmap style range spec meaning end with 65535 */\n                end = (proto_offset == Templ_Oproto_first) ? 0xFF : 0xFFFF;\n            } else {\n                end = (unsigned)strtoul(p, &p, 0);\n            }\n        } else\n            end = port;\n\n        /* Check for out-of-range */\n        if (port > 0xFF && proto_offset == Templ_Oproto_first) {\n            *is_error = 2;\n            return p;\n        } else if (port > 0xFFFF || end > 0xFFFF || end < port) {\n            *is_error = 2;\n            return p;\n        }\n\n        /* Add to our list */\n        rangelist_add_range(ports, port+proto_offset, end+proto_offset);\n\n        /* skip trailing whitespace */\n        while (*p && isspace(*p & 0xFF))\n            p++;\n\n        /* Now get the next port/range if there is one */\n        if (*p != ',')\n            break;\n        p++;\n    }\n\n    return p;\n}\n\n\n\n/***************************************************************************\n * Deterministic random number generator for repeatable tests.\n ***************************************************************************/\nstatic unsigned\nlcgrand(unsigned *state)\n{\n    *state = 1103515245 * (*state) + 12345;\n    return *state;\n}\n\n/***************************************************************************\n * Create an exact duplicate range.\n ***************************************************************************/\nstatic void\nrangelist_copy(struct RangeList *dst, const struct RangeList *src)\n{\n    free(dst->list);\n    free(dst->picker);\n    memset(dst, 0, sizeof(*dst));\n    dst->list = CALLOC(src->count, sizeof(src->list[0]));\n    memcpy(dst->list, src->list, src->count * sizeof(src->list[0]));\n    dst->count = src->count;\n    dst->max = dst->count;\n    dst->is_sorted = src->is_sorted;\n}\n\n/***************************************************************************\n * Test if two ranges are exact duplicates\n * @return true if equal, false if not equal\n ***************************************************************************/\nstatic bool\nrangelist_is_equal(const struct RangeList *lhs, const struct RangeList *rhs)\n{\n    unsigned i;\n    \n    if (lhs->count != rhs->count)\n        return false;\n    for (i=0; i<lhs->count; i++) {\n        if (lhs->list[i].begin != rhs->list[i].begin) {\n            return false;\n        }\n        if (lhs->list[i].end != rhs->list[i].end) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\n/***************************************************************************\n * The old way of excluding addresses assume unsorted lists, so had to\n * search the entire exclude list for each included address, which is\n * O(n * m), and fails when we have millions of excludes and includes,\n * because it takes forever to apply.\n * This was revamped with a new version that sorts both lists first,\n * the applies the excludes sequentially in an O(n + m) operation.\n * This selftest simply creates random lists and runs the new code\n * against the old code, and make sure the results match.\n ***************************************************************************/\nstatic int\nexclude_selftest(void)\n{\n    unsigned seed = 0;\n    struct RangeList includes1 = {0};\n    struct RangeList includes2 = {0};\n    struct RangeList excludes = {0};\n    unsigned addr = 0;\n    size_t i;\n    \n    /* In my initial tests, simply using 10 as the count seems to\n     * catch all the combinations. On the other hand, 100,000 takes\n     * a long time to complete, because it's O(n2) quadratic time.\n     * Therefore, I pick a thousand as a compromise, likely to catch\n     * any possibility, yet fast enough to complete quickly even on\n     * a Raspberry Pi */\n    static const unsigned MAXCOUNT = 1000;\n    \n    /* Fill the include list. This is designed to make short ranges\n     * that are a short distance apart. We'll do the same for the\n     * same for the excludes, using a different random seed. This\n     * should create two lists that have lots and lots of overlapping\n     * and non-overlapping ranges.\n     */\n    seed = 0;\n    addr = 0;\n    for (i=0; i<MAXCOUNT; i++) {\n        unsigned begin;\n        unsigned end;\n        \n        addr += lcgrand(&seed) & 0xF;\n        begin = addr;\n        addr += lcgrand(&seed) & 0xF;\n        end = addr;\n        \n        rangelist_add_range(&includes1, begin, end);\n    }\n    rangelist_sort(&includes1);\n    \n    /* Fill the exclude list, using the same algorithm as above for\n     * includes, but now with a different seed. This creates lots of\n     * conflicts. */\n    seed = 1;\n    addr = 0;\n    for (i=0; i<MAXCOUNT; i++) {\n        unsigned begin;\n        unsigned end;\n        \n        addr += lcgrand(&seed) & 0xF;\n        begin = addr;\n        addr += lcgrand(&seed) & 0xF;\n        end = addr;\n        \n        rangelist_add_range(&excludes, begin, end);\n    }\n    rangelist_sort(&excludes);\n    \n    /* Now create a copy of the include list, because we want to\n     * apply excludes using two different algorithms to see if the\n     * results match */\n    rangelist_copy(&includes2, &includes1);\n    if (!rangelist_is_equal(&includes1, &includes2))\n        return 1;\n\n    \n    /* Now apply the exclude algorithms, both new and old, to\n     * the include lists. */\n    rangelist_exclude(&includes1, &excludes);\n    rangelist_exclude2(&includes2, &excludes);\n    if (!rangelist_is_equal(&includes1, &includes2))\n        return 1; /* fail */\n    \n    /* If we reach this point, the selftest has succeeded */\n    return 0;\n\n}\n\n/***************************************************************************\n * Called during \"make test\" to run a regression test over this module.\n ***************************************************************************/\nint\nranges_selftest(void)\n{\n    struct Range r;\n    struct RangeList targets[1] = {{0}};\n\n    REGRESS(regress_pick2() == 0);\n\n    /* Do a separate test of the 'exclude' feature */\n    if (exclude_selftest())\n        return 1;\n    \n    memset(targets, 0, sizeof(targets[0]));\n#define ERROR() LOG(0, \"selftest: failed %s:%u\\n\", __FILE__, __LINE__);\n\n    /* test for the /0 CIDR block, since we'll be using that a lot to scan the entire\n     * Internet */\n    r = range_parse_ipv4(\"0.0.0.0/0\", 0, 0);\n    REGRESS(r.begin == 0 && r.end == 0xFFFFFFFF);\n\n    r = range_parse_ipv4(\"0.0.0./0\", 0, 0);\n    REGRESS(r.begin > r.end);\n\n    r = range_parse_ipv4(\"75.748.86.91\", 0, 0);\n    REGRESS(r.begin > r.end);\n\n    r = range_parse_ipv4(\"23.75.345.200\", 0, 0);\n    REGRESS(r.begin > r.end);\n\n    r = range_parse_ipv4(\"192.1083.0.1\", 0, 0);\n    REGRESS(r.begin > r.end);\n\n    r = range_parse_ipv4(\"192.168.1.3\", 0, 0);\n    if (r.begin != 0xc0a80103 || r.end != 0xc0a80103) {\n        LOG(0, \"r.begin = 0x%08x r.end = 0x%08x\\n\", r.begin, r.end);\n        ERROR();\n        return 1;\n    }\n\n    r = range_parse_ipv4(\"10.0.0.20-10.0.0.30\", 0, 0);\n    if (r.begin != 0x0A000000+20 || r.end != 0x0A000000+30) {\n        LOG(0,  \"r.begin = 0x%08x r.end = 0x%08x\\n\", r.begin, r.end);\n        ERROR();\n        return 1;\n    }\n\n    r = range_parse_ipv4(\"10.0.1.2/16\", 0, 0);\n    if (r.begin != 0x0A000000 || r.end != 0x0A00FFFF) {\n        LOG(0, \"r.begin = 0x%08x r.end = 0x%08x\\n\", r.begin, r.end);\n        ERROR();\n        return 1;\n    }\n\n\n    rangelist_add_range2(targets, range_parse_ipv4(\"10.0.0.0/24\", 0, 0));\n    rangelist_add_range2(targets, range_parse_ipv4(\"10.0.1.10-10.0.1.19\", 0, 0));\n    rangelist_add_range2(targets, range_parse_ipv4(\"10.0.1.20-10.0.1.30\", 0, 0));\n    rangelist_add_range2(targets, range_parse_ipv4(\"10.0.0.0-10.0.1.12\", 0, 0));\n    rangelist_sort(targets);\n\n    if (targets->count != 1) {\n        LOG(0, \"count = %u\\n\", targets->count);\n        ERROR();\n        return 1;\n    }\n    if (targets->list[0].begin != 0x0a000000 || targets->list[0].end != 0x0a000100+30) {\n        LOG(0, \"r.begin = 0x%08x r.end = 0x%08x\\n\", targets->list[0].begin, targets->list[0].end);\n        ERROR();\n        return 1;\n    }\n\n    rangelist_remove_all(targets);\n\n    /*\n     * Test removal\n     */\n    memset(targets, 0, sizeof(targets[0]));\n\n    rangelist_add_range2(targets, range_parse_ipv4(\"10.0.0.0/8\", 0, 0));\n    rangelist_sort(targets);\n\n    /* These removals shouldn't change anything */\n    rangelist_remove_range2(targets, range_parse_ipv4(\"9.255.255.255\", 0, 0));\n    rangelist_remove_range2(targets, range_parse_ipv4(\"11.0.0.0/16\", 0, 0));\n    rangelist_remove_range2(targets, range_parse_ipv4(\"192.168.0.0/16\", 0, 0));\n    rangelist_sort(targets);\n\n    if (targets->count != 1\n        || targets->list->begin != 0x0a000000\n        || targets->list->end != 0x0aFFFFFF) {\n        ERROR();\n        return 1;\n    }\n\n    /* These removals should remove a bit from the edges */\n    rangelist_remove_range2(targets, range_parse_ipv4(\"1.0.0.0-10.0.0.0\", 0, 0));\n    rangelist_remove_range2(targets, range_parse_ipv4(\"10.255.255.255-11.0.0.0\", 0, 0));\n    rangelist_sort(targets);\n    if (targets->count != 1\n        || targets->list->begin != 0x0a000001\n        || targets->list->end != 0x0aFFFFFE) {\n        ERROR();\n        return 1;\n    }\n\n\n    /* remove things from the middle */\n    rangelist_remove_range2(targets, range_parse_ipv4(\"10.10.0.0/16\", 0, 0));\n    rangelist_remove_range2(targets, range_parse_ipv4(\"10.20.0.0/16\", 0, 0));\n    rangelist_sort(targets);\n    if (targets->count != 3) {\n        ERROR();\n        return 1;\n    }\n\n    rangelist_remove_range2(targets, range_parse_ipv4(\"10.12.0.0/16\", 0, 0));\n    rangelist_sort(targets);\n    if (targets->count != 4) {\n        ERROR();\n        return 1;\n    }\n\n    rangelist_remove_range2(targets, range_parse_ipv4(\"10.10.10.10-10.12.12.12\", 0, 0));\n    rangelist_sort(targets);\n    if (targets->count != 3) {\n        ERROR();\n        return 1;\n    }\n    rangelist_remove_all(targets);\n\n    /* test ports */\n    {\n        unsigned is_error = 0;\n        memset(targets, 0, sizeof(targets[0]));\n\n        rangelist_parse_ports(targets, \"80,1000-2000,1234,4444\", &is_error, 0);\n        rangelist_sort(targets);\n        if (targets->count != 3 || is_error) {\n            ERROR();\n            return 1;\n        }\n\n        if (targets->list[0].begin != 80 || targets->list[0].end != 80 ||\n            targets->list[1].begin != 1000 || targets->list[1].end != 2000 ||\n            targets->list[2].begin != 4444 || targets->list[2].end != 4444) {\n            ERROR();\n            return 1;\n        }\n    }\n\n    if (selftest_range_first_cidr() != 0) {\n        ERROR();\n        return 1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/massip-rangesv4.h",
    "content": "#ifndef RANGES_H\n#define RANGES_H\n#include <stdint.h>\n#include <stdio.h>\n#include \"util-bool.h\" /*<stdbool.h>*/\n\n/**\n * A range of either IP addresses or ports\n */\nstruct Range\n{\n    unsigned begin;\n    unsigned end; /* inclusive, so [n..m] includes both 'n' and 'm' */\n};\n\n\n/**\n * Find the first CIDR range (one that can be specified with a /prefix)\n * inside the current range. If the current range can already be\n * specified with a CIDR /prefix, then the entire range is returned.\n * Examples:\n *  [10.0.0.0->10.0.0.255] returns [10.0.0.0->10.0.0.255] (no change)\n *  [10.0.0.1->10.0.0.255] returns [10.0.0.1->10.0.0.1]\n *  [10.0.0.2->10.0.0.255] returns [10.0.0.2->10.0.0.3]\n *  [10.0.0.4->10.0.0.255] returns [10.0.0.4->10.0.0.7]\n *  [10.0.0.248->10.0.0.254] returns [10.0.0.248->10.0.0.251]\n *  [10.0.0.252->10.0.0.254] returns [10.0.0.252->10.0.0.253]\n *  [10.0.0.254->10.0.0.254] returns [10.0.0.254->10.0.0.254]\n *  @param range\n *      A range specified by a starting IPv4 address and an ending\n *      IPv4 address, like [10.0.0.4->10.0.0.255].\n *  @param prefix_length\n *      An out-only parameter that receives the CIDR prefix length\n *      (number of bits) of the resulting range. This parameter is\n *      optional (may be NULL).\n *  @return the smaller range, and the number of prefix bits in the range.\n */\nstruct Range\nrange_first_cidr(const struct Range range, unsigned *prefix_length /*out*/);\n\n/**\n * Test if the range can instead be expressed using a CIDR /prefix.\n * In other words, [10.0.0.0-10.0.0.255] can be expressed as [10.0.0.0/24].\n * @param range to be tested\n * @param prefix_length receivesoutput of the number of prefix bits if\n *  successful, otherwise set to 0xFFFFFFFF. This is optional, may\n *  be NULL and receive no output.\n * @return True if the range can be expressed in CIDR notation, in\n *  which case `prefix_length` is set to the number of bits in the prefix\n *  for printing in that notation. False otherwise, in which case\n *  `prefix_length` is set to 0xFFFFFFFF (an invalid value).\n */\nbool range_is_cidr(const struct Range range, unsigned *prefix_length /*out*/);\n\n\n\n\n/**\n * An array of ranges in sorted order\n */\nstruct RangeList\n{\n    struct Range *list;\n    unsigned count;\n    unsigned max;\n    unsigned *picker;\n    unsigned is_sorted:1;\n};\n\n/**\n * Adds the given range to the task list. The given range can be a duplicate\n * or overlap with an existing range, which will get combined with existing\n * ranges. \n * @param task\n *      A list of ranges of either IPv4 addresses or port numbers.\n * @param begin\n *      The first address of the range that'll be added.\n * @param end\n *      The last address (inclusive) of the range that'll be added.\n */\nvoid\nrangelist_add_range(struct RangeList *task, unsigned begin, unsigned end);\n\nvoid\nrangelist_add_range_tcp(struct RangeList *targets, unsigned begin, unsigned end);\nvoid\nrangelist_add_range_udp(struct RangeList *targets, unsigned begin, unsigned end);\n\n\n/**\n * Returns 'true' is the indicated port or IP address is in one of the task\n * ranges.\n * @param task\n *      A list of ranges of either IPv4 addresses or port numbers.\n * @param number\n *      Either an IPv4 address or a TCP/UDP port number.\n * @return \n *      'true' if the ranges contain the item, or 'false' otherwise\n */\nint\nrangelist_is_contains(const struct RangeList *task, unsigned number);\n\n\n/**\n * Returns 'true' if the indicate range is valid, which is simple the\n * fact that 'begin' comes before 'end'. We mark invalid ranges\n * by putting 'begin' after the 'end'\n */\nint\nrange_is_valid(struct Range range);\n\n/**\n * Parses IPv4 addresses out of a string. A number of formats are allowed,\n * either an individual IPv4 address, a CIDR spec, or a start/stop address.\n * @param line\n *      A line of text, probably read from a configuration file, or a string\n *      probably input from the command line. It doesn't need to be nul\n *      terminated.\n * @param inout_offset\n *      The offset into the line were we are parsing. This integer will be\n *      be incremented by the number of bytes we've parsed from the string.\n * @param max\n *      The length of the line, in other words, the max value of inout_offset.\n */\nstruct Range \nrange_parse_ipv4(const char *line, unsigned *inout_offset, unsigned max);\n\n\n/**\n * Remove things from the target list. The primary use of this is the\n * \"exclude-file\" containing a list of IP addresses that we should\n * not scan\n * @param targets\n *      Our array of target IP address (or port) ranges that we'll be\n *      scanning.\n * @param excludes\n *      A list, probably read in from --excludefile, of things that we\n *      should not be scanning, that will override anything we otherwise\n *      try to scan.\n */\nvoid\nrangelist_exclude(  struct RangeList *targets,\n                    struct RangeList *excludes);\n\n\n/**\n * Counts the total number of IP addresses or ports in the target list. This\n * iterates over all the ranges in the table, summing up the count within\n * each range.\n * @param targets\n *      A list of IP address or port ranges.\n * @return\n *      The total number of address or ports.\n */\nuint64_t\nrangelist_count(const struct RangeList *targets);\n\n/**\n * Given an index in a continuous range of [0...count], pick a corresponding\n * number (IP address or port) from a list of non-continuous ranges (not\n * necessarily starting from 0). In other words, given the two ranges\n *    10-19 50-69\n * we'll have a total of 30 possible numbers. Thus, the index goes from\n * [0..29], with the values 0..9 picking the corresponding values from the\n * first range, and the values 10..29 picking the corresponding values\n * from the second range.\n *\n * NOTE: This is a fundamental part of this program's design, that the user\n * can specify non-contiguous IP and port ranges, but yet we iterate over\n * them using a monotonically increasing index variable.\n *\n * @param targets\n *      A list of IP address ranges, or a list of port ranges (one or the\n *      other, but not both).\n * @param index\n *      An integer starting at 0 up to (but not including) the value returned\n *      by 'rangelist_count()' for this target list.\n * @return\n *      an IP address or port corresponding to this index.\n */\nunsigned\nrangelist_pick(const struct RangeList *targets, uint64_t i);\n\n\n/**\n * Given a string like \"80,8080,20-25,U:161\", parse it into a structure\n * containing a list of port ranges.\n *\n * @param ports\n *      The array of port ranges that's produced by this parsing function.\n *      This structure will be used by the transmit thread when sending\n *      probes to a target IP address.\n * @param string\n *      A string from either the command-line or configuration file\n *      in the nmap \"ports\" format.\n * @param is_error\n *      Set to zero is no error occurred while parsing the string, or\n *      set to a non-zero value if an error was found.\n * @return\n *      the pointer in the string where the parsing ended, so that additional\n *      things can be contained in the string, such as comments\n */\nconst char *\nrangelist_parse_ports(  struct RangeList *ports,\n                        const char *string,\n                        unsigned *is_error,\n                        unsigned proto_offset\n                      );\n\n\n/**\n * Remove all the ranges in the range list.\n */\nvoid\nrangelist_remove_all(struct RangeList *list);\n\n/**\n * Merge two range lists\n */\nvoid\nrangelist_merge(struct RangeList *list1, const struct RangeList *list2);\n\n\n/**\n * Optimizes the target list, so that when we call \"rangelist_pick()\"\n * from an index, it runs faster. It currently configures this for \n * a binary-search, though in the future some more efficient\n * algorithm may be chosen.\n */\nvoid\nrangelist_optimize(struct RangeList *targets);\n\n\n/**\n * Sorts the list of target. We maintain the list of targets in sorted\n * order internally even though we scan the targets in random order\n * externally.\n */\nvoid\nrangelist_sort(struct RangeList *targets);\n\n\n/**\n * Does a regression test of this module\n * @return\n *      0 if the regression test succeeds, or a positive value on failure\n */\nint\nranges_selftest(void);\n\n\n#endif\n"
  },
  {
    "path": "src/massip-rangesv6.c",
    "content": "/*\n    for tracking IP/port ranges\n*/\n#include \"massip-rangesv6.h\"\n#include \"massip-rangesv4.h\"\n#include \"util-malloc.h\"\n#include \"util-logger.h\"\n#include \"massip.h\"\n#include \"massip-parse.h\"\n\n#include <assert.h>\n#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n\n#define BUCKET_COUNT 16\n\n#define REGRESS(i,x) if (!(x)) return (fprintf(stderr, \"[-] %u: regression failed %s:%d\\n\", (unsigned)i, __FILE__, __LINE__)|1)\n#ifndef false\n#define false 0\n#endif\n#ifndef true\n#define true 1\n#endif\n\n#define EQUAL(x,y) ipv6address_is_equal(x,y)\n\nstatic inline ipv6address\n_int128_add(ipv6address x, ipv6address y)\n{\n  ipv6address result;\n  result.lo = x.lo + y.lo;\n  result.hi = x.hi + y.hi + (result.lo < x.lo);\n  return result;\n}\n\nstatic inline ipv6address\n_int128_subtract(ipv6address x, ipv6address y)\n{\n  ipv6address result;\n  result.lo = x.lo - y.lo;\n  result.hi = x.hi - y.hi - (result.lo > x.lo);\n  return result;\n}\n\nstatic ipv6address \n_int128_add64(const ipv6address lhs, uint64_t rhs)\n{\n    ipv6address result = lhs;\n    result.lo += rhs;\n    if (result.lo < lhs.lo)\n        result.hi++;\n    return result;\n}\n\nstatic inline massint128_t\n_int128_mult64(massint128_t lhs, uint64_t rhs)\n{\n    massint128_t result = {0,0};\n    uint64_t x;\n    uint64_t b;\n    uint64_t a;\n    \n    /* low-order 32 */\n    a = (rhs>>0) & 0xFFFFFFFFULL;\n    b = (lhs.lo>>0) & 0xFFFFFFFFULL;\n    x = (a * b);\n    result.lo += x;\n    \n    b = (lhs.lo>>32ULL) & 0xFFFFFFFFULL;\n    x =  (a * b);\n    result.lo += x<<32ULL;\n    result.hi += x>>32ULL;\n\n    b = lhs.hi;\n    x = (a * b);\n    result.hi += x;\n\n    /* next 32 */\n    a = (rhs>>32ULL) & 0xFFFFFFFFULL;\n    b = (lhs.lo>>0ULL) & 0xFFFFFFFFULL;\n    x = (a * b);\n    result.lo += x<<32ULL;\n    result.hi += (x>>32ULL) + (result.lo < (x<<32ULL));\n\n    b = (lhs.lo>>32ULL) & 0xFFFFFFFFULL;\n    x =  (a * b);\n    result.hi += x;\n\n    b = lhs.hi;\n    x =  (a * b);\n    result.hi += x<<32ULL;\n\n    return result;\n}\n\nstatic int\nLESS(const ipv6address lhs, const ipv6address rhs)\n{\n    if (lhs.hi < rhs.hi)\n        return 1;\n    else if (lhs.hi == rhs.hi && lhs.lo < rhs.lo)\n        return 1;\n    else\n        return 0;\n}\n#define GREATEREQ(x,y) (!LESS(x,y))\n\nstatic int\nLESSEQ(const ipv6address lhs, const ipv6address rhs)\n{\n    if (lhs.hi < rhs.hi)\n        return 1;\n    if (lhs.hi > rhs.hi)\n        return 0;\n    \n    if (lhs.lo <= rhs.lo)\n        return 1;\n    else\n        return 0;\n}\n\nint range6_is_bad_address(const struct Range6 *range)\n{\n    return LESS(range->end, range->begin);\n}\n\nstatic int\n_int128_is_equals(const ipv6address lhs, const ipv6address rhs)\n{\n    return lhs.hi == rhs.hi && lhs.lo == rhs.lo;\n}\n\nstatic ipv6address\nMINUS_ONE(const ipv6address ip)\n{\n    ipv6address result;\n    \n    if (ip.lo == 0) {\n        result.hi = ip.hi - 1;\n        result.lo = ~0ULL;\n    } else {\n        result.hi = ip.hi;\n        result.lo = ip.lo - 1;\n    }\n\n    return result;\n}\n\nstatic ipv6address PLUS_ONE(const ipv6address ip)\n{\n    ipv6address result;\n    \n    if (ip.lo == ~0) {\n        result.hi = ip.hi + 1;\n        result.lo = 0;\n    } else {\n        result.hi = ip.hi;\n        result.lo = ip.lo + 1;\n    }\n\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nmassint128_t \nmassip_range(struct MassIP *massip)\n{\n    massint128_t result;\n\n\n    result = range6list_count(&massip->ipv6);\n    result = _int128_add64(result, rangelist_count(&massip->ipv4));\n    result = _int128_mult64(result, rangelist_count(&massip->ports));\n\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nrange6list_is_contains(const struct Range6List *targets, const ipv6address ip)\n{\n    unsigned i;\n\n    for (i=0; i<targets->count; i++) {\n        struct Range6 *range = &targets->list[i];\n\n        if (LESSEQ(range->begin, ip) && LESSEQ(ip, range->end))\n            return 1;\n    }\n    return 0;\n}\n\n/***************************************************************************\n * ???\n ***************************************************************************/\nstatic void\ntodo_remove_at(struct Range6List *targets, unsigned index)\n{\n    memmove(&targets->list[index],\n            &targets->list[index+1],\n            (targets->count - index) * sizeof(targets->list[index])\n            );\n    targets->count--;\n}\n\n\n/***************************************************************************\n * Test if two ranges overlap.\n * This is easiest done by testing that they don't overlap, and inverting\n * the result.\n * Note that adjacent addresses overlap.\n ***************************************************************************/\nstatic int\nrange6_is_overlap(const struct Range6 lhs, const struct Range6 rhs)\n{\n    static const ipv6address FFFF = {~0ULL, ~0ULL};\n\n    if (LESS(lhs.begin, rhs.begin)) {\n        if (EQUAL(lhs.end, FFFF) || GREATEREQ(PLUS_ONE(lhs.end), rhs.begin))\n            return 1;\n    }\n    if (GREATEREQ(lhs.begin, rhs.begin)) {\n        if (LESSEQ(lhs.end, rhs.end))\n            return 1;\n    }\n\n    if (LESS(rhs.begin, lhs.begin)) {\n        if (EQUAL(rhs.end, FFFF) || GREATEREQ(PLUS_ONE(rhs.end), lhs.begin))\n            return 1;\n    }\n    if (GREATEREQ(rhs.begin, lhs.begin)) {\n        if (LESSEQ(rhs.end, lhs.end))\n            return 1;\n    }\n\n    return 0;\n#if 0\n    static const ipv6address zero = {0, 0};\n    ipv6address lhs_endm = MINUS_ONE(lhs.end);\n    ipv6address rhs_endm = MINUS_ONE(rhs.end);\n    \n    /* llll rrrr */\n    if (LESS(zero, lhs.end) && LESS(lhs_endm, rhs.begin))\n        return 0;\n\n    /* rrrr llll */\n    if (LESS(zero, rhs.end) && LESS(rhs_endm, lhs.begin))\n        return 0;\n\n    return 1;\n#endif\n}\n\n\n/***************************************************************************\n * Combine two ranges, such as when they overlap.\n ***************************************************************************/\nstatic void\nrange6_combine(struct Range6 *lhs, const struct Range6 rhs)\n{\n    if (LESSEQ(rhs.begin, lhs->begin))\n        lhs->begin = rhs.begin;\n    if (LESSEQ(lhs->end, rhs.end))\n        lhs->end = rhs.end;\n}\n\n\n/***************************************************************************\n * Callback for qsort() for comparing two ranges\n ***************************************************************************/\nstatic int\nrange6_compare(const void *lhs, const void *rhs)\n{\n    struct Range6 *left = (struct Range6 *)lhs;\n    struct Range6 *right = (struct Range6 *)rhs;\n\n    if (ipv6address_is_equal(left->begin, right->begin))\n        return 0;\n    else if (LESS(left->begin, right->begin))\n        return -1;\n    else \n        return 1;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrange6list_sort(struct Range6List *targets)\n{\n    size_t i;\n    struct Range6List newlist = {0};\n    size_t original_count = targets->count;\n\n    /* Empty lists are, of course, sorted. We need to set this\n     * to avoid an error later on in the code which asserts that\n     * the lists are sorted */\n    if (targets->count == 0) {\n        targets->is_sorted = 1;\n        return;\n    }\n    \n    /* If it's already sorted, then skip this */\n    if (targets->is_sorted) {\n        return;\n    }\n    \n    \n    /* First, sort the list */\n    LOG(3, \"[+] range6:sort: sorting...\\n\");\n    qsort(  targets->list,              /* the array to sort */\n            targets->count,             /* number of elements to sort */\n            sizeof(targets->list[0]),   /* size of element */\n            range6_compare);\n    \n    \n    /* Second, combine all overlapping ranges. We do this by simply creating\n     * a new list from a sorted list, so we don't have to remove things in the\n     * middle when collapsing overlapping entries together, which is painfully\n     * slow. */\n    LOG(3, \"[+] range:sort: combining...\\n\");\n    for (i=0; i<targets->count; i++) {\n        range6list_add_range(&newlist, targets->list[i].begin, targets->list[i].end);\n    }\n    \n    LOG(3, \"[+] range:sort: combined from %u elements to %u elements\\n\", original_count, newlist.count);\n    free(targets->list);\n    targets->list = newlist.list;\n    targets->count = newlist.count;\n    newlist.list = 0;\n\n    LOG(2, \"[+] range:sort: done...\\n\");\n\n    targets->is_sorted = 1;\n}\n\n\n\nvoid\nrange6list_add_range(struct Range6List *targets, ipv6address begin, ipv6address end)\n{\n    struct Range6 range;\n\n    range.begin = begin;\n    range.end = end;\n\n    /* auto-expand the list if necessary */\n    if (targets->count + 1 >= targets->max) {\n        targets->max = targets->max * 2 + 1;\n        targets->list = REALLOCARRAY(targets->list, targets->max, sizeof(targets->list[0]));\n    }\n\n    /* If empty list, then add this one */\n    if (targets->count == 0) {\n        targets->list[0] = range;\n        targets->count++;\n        targets->is_sorted = 1;\n        return;\n    }\n\n    /* If new range overlaps the last range in the list, then combine it\n     * rather than appending it. This is an optimization for the fact that\n     * we often read in sequential addresses */\n    if (range6_is_overlap(targets->list[targets->count - 1], range)) {\n        range6_combine(&targets->list[targets->count - 1], range);\n        targets->is_sorted = 0;\n        return;\n    }\n\n    /* append to the end of our list */\n    targets->list[targets->count] = range;\n    targets->count++;\n    targets->is_sorted = 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrange6list_remove_all(struct Range6List *targets)\n{\n    if (targets->list)\n        free(targets->list);\n    if (targets->picker)\n        free(targets->picker);\n    memset(targets, 0, sizeof(*targets));\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrange6list_merge(struct Range6List *list1, const struct Range6List *list2)\n{\n    unsigned i;\n    \n    for (i=0; i<list2->count; i++) {\n        range6list_add_range(list1, list2->list[i].begin, list2->list[i].end);\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrange6list_remove_range(struct Range6List *targets, const ipv6address begin, const ipv6address end)\n{\n    unsigned i;\n    struct Range6 x;\n\n    x.begin = begin;\n    x.end = end;\n\n    /* See if the range overlaps any exist range already in the\n     * list */\n    for (i = 0; i < targets->count; i++) {\n        if (!range6_is_overlap(targets->list[i], x))\n            continue;\n\n        /* If the removal-range wholly covers the range, delete\n         * it completely */\n        if (LESSEQ(begin, targets->list[i].begin) && LESSEQ(targets->list[i].end, end)) {\n            todo_remove_at(targets, i);\n            i--;\n            continue;\n        }\n\n        /* If the removal-range bisects the target-rage, truncate\n         * the lower end and add a new high-end */\n        if (LESSEQ(targets->list[i].begin, begin) && LESSEQ(end, targets->list[i].end)) {\n            struct Range6 newrange;\n\n            newrange.begin = PLUS_ONE(end);\n            newrange.end = targets->list[i].end;\n\n\n            targets->list[i].end = MINUS_ONE(begin);\n\n            range6list_add_range(targets, newrange.begin, newrange.end);\n            i--;\n            continue;\n        }\n\n        /* If overlap on the lower side */\n        if (LESSEQ(targets->list[i].begin, end) && LESSEQ(end, targets->list[i].end)) {\n            targets->list[i].begin = PLUS_ONE(end);\n        }\n\n        /* If overlap on the upper side */\n        if (LESSEQ(targets->list[i].begin, begin) && LESSEQ(begin, targets->list[i].end)) {\n             targets->list[i].end = MINUS_ONE(begin);\n        }\n    }\n}\n\nvoid\nrange6list_remove_range2(struct Range6List *targets, struct Range6 range)\n{\n    range6list_remove_range(targets, range.begin, range.end);\n}\n\n/***************************************************************************\n ***************************************************************************/\nipv6address\nrange6list_exclude(  struct Range6List *targets,\n                  const struct Range6List *excludes)\n{\n    ipv6address count = {0,0};\n    unsigned i;\n    \n    for (i=0; i<excludes->count; i++) {\n        struct Range6 range = excludes->list[i];\n        ipv6address x;\n        \n        x = _int128_subtract(range.end, range.begin);\n        x = _int128_add64(x, 1);\n\n        count = _int128_add(count, x);\n        range6list_remove_range(targets, range.begin, range.end);\n    }\n    \n    return count;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nmassint128_t\nrange6list_count(const struct Range6List *targets)\n{\n    unsigned i;\n    ipv6address result = {0,0};\n\n    for (i=0; i<targets->count; i++) {\n        ipv6address x;\n\n        x = _int128_subtract(targets->list[i].end, targets->list[i].begin);\n        if (x.hi == ~0ULL && x.lo == ~0ULL)\n            return x; /* overflow */\n        x = _int128_add64(x, 1);\n        result = _int128_add(result, x);\n    }\n\n    return result;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nipv6address\nrange6list_pick(const struct Range6List *targets, uint64_t index)\n{\n    size_t maxmax = targets->count;\n    size_t min = 0;\n    size_t max = targets->count;\n    size_t mid;\n    const size_t *picker = targets->picker;\n\n    if (picker == NULL) {\n        fprintf(stderr, \"[-] ipv6 picker is null\\n\");\n        exit(1);\n    }\n\n\n    for (;;) {\n        mid = min + (max-min)/2;\n        if (index < picker[mid]) {\n            max = mid;\n            continue;\n        } if (index >= picker[mid]) {\n            if (mid + 1 == maxmax)\n                break;\n            else if (index < picker[mid+1])\n                break;\n            else\n                min = mid+1;\n        }\n    }\n\n    return _int128_add64(targets->list[mid].begin, (index - picker[mid]));\n}\n\n\n/***************************************************************************\n * The normal \"pick\" function is a linear search, which is slow when there\n * are a lot of ranges. Therefore, the \"pick2\" creates sort of binary\n * search that'll be a lot faster. We choose \"binary search\" because\n * it's the most cache-efficient, having the least overhead to fit within\n * the cache.\n ***************************************************************************/\nvoid\nrange6list_optimize(struct Range6List *targets)\n{\n    size_t *picker;\n    size_t i;\n    ipv6address total = {0,0};\n\n    if (targets->count == 0)\n        return;\n\n    /* This technique only works when the targets are in\n     * ascending order */\n    if (!targets->is_sorted)\n        range6list_sort(targets);\n\n    if (targets->picker)\n        free(targets->picker);\n\n    picker = REALLOCARRAY(NULL, targets->count, sizeof(*picker));\n\n    for (i=0; i<targets->count; i++) {\n        ipv6address x;\n        picker[i] = (size_t)total.lo;\n        x = _int128_subtract(targets->list[i].end, targets->list[i].begin);\n        x = _int128_add64(x, 1);\n        total = _int128_add(total, x);\n    }\n    \n    targets->picker = picker;\n}\n\n\n\n/***************************************************************************\n * Provide my own rand() simply to avoid static-analysis warning me that\n * 'rand()' is unrandom, when in fact we want the non-random properties of\n * rand() for regression testing.\n ***************************************************************************/\nstatic unsigned\nr_rand(unsigned *seed)\n{\n    static const unsigned a = 214013;\n    static const unsigned c = 2531011;\n\n    *seed = (*seed) * a + c;\n    return (*seed)>>16 & 0x7fff;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nregress_pick2()\n{\n    unsigned i;\n    unsigned seed = 0;\n\n    /*\n    */\n    for (i=0; i<65536; i++)\n    {\n        ipv6address a;\n        ipv6address b;\n        ipv6address c;\n        ipv6address d;\n\n        a.hi = r_rand(&seed);\n        a.lo = (unsigned long long)r_rand(&seed)<<49ULL;\n        b.hi = r_rand(&seed);\n        b.lo = 0x8765432100000000ULL;\n\n        c = _int128_add(a, b);\n        d = _int128_subtract(c, b);\n\n        if (!_int128_is_equals(a, d)) {\n            fprintf(stderr, \"[-] %s:%d: test failed (%u)\\n\", __FILE__, __LINE__, (unsigned)i);\n            return 1;\n        }\n    }\n\n    /*\n     * Run 100 randomized regression tests\n     */\n    for (i=3; i<100; i++) {\n        unsigned j;\n        unsigned num_targets;\n        ipv6address begin = {0};\n        ipv6address end = {0};\n        struct Range6List targets[1];\n        struct Range6List duplicate[1];\n        uint64_t range;\n        ipv6address x;\n\n        seed = i;\n\n        /* Create a new target list */\n        memset(targets, 0, sizeof(targets[0]));\n\n        /* fill the target list with random ranges */\n        num_targets = r_rand(&seed)%5 + 1;\n        for (j=0; j<num_targets; j++) {\n            begin.lo += r_rand(&seed)%10;\n            end.lo = begin.lo + r_rand(&seed)%10;\n\n            range6list_add_range(targets, begin, end);\n        }\n\n        /* Optimize for faster 'picking' addresses from an index */\n        range6list_optimize(targets);\n\n\n        /* Duplicate the targetlist using the picker */\n        memset(duplicate, 0, sizeof(duplicate[0]));\n        x = range6list_count(targets);\n        if (x.hi) {\n            fprintf(stderr, \"[-] range6: range too big\\n\");\n            return 1;\n        }\n        range = x.lo;\n        for (j=0; j<range; j++) {\n            ipv6address addr;\n\n            addr = range6list_pick(targets, j);\n            range6list_add_range(duplicate, addr, addr);\n        }\n\n        /* at this point, the two range lists should be identical */\n        REGRESS(i, targets->count == duplicate->count);\n        REGRESS(i, memcmp(targets->list, duplicate->list, targets->count*sizeof(targets->list[0])) == 0);\n\n        range6list_remove_all(targets);\n        range6list_remove_all(duplicate);\n    }\n\n    return 0;\n}\n\n\n\n\n\n/***************************************************************************\n * Called during \"make regress\" to run a regression test over this module.\n ***************************************************************************/\nint\nranges6_selftest(void)\n{\n    struct Range6 r;\n    struct Range6List targets[1];\n    int err;\n\n    REGRESS(0, regress_pick2() == 0);\n\n    memset(targets, 0, sizeof(targets[0]));\n#define ERROR() fprintf(stderr, \"selftest: failed %s:%u\\n\", __FILE__, __LINE__);\n\n    err = massip_parse_range(\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\", 0, 0, 0, &r);\n    if (err != Ipv6_Address)\n        ERROR();\n    \n    /* test for the /0 CIDR block, since we'll be using that a lot to scan the entire\n     * Internet */\n    if (r.begin.hi != 0x20010db885a30000ULL)\n        return 1;\n    if (r.begin.lo != 0x00008a2e03707334ULL)\n        return 1;\n\n    return 0;\n}\n\n"
  },
  {
    "path": "src/massip-rangesv6.h",
    "content": "/*\n    List of IPv6 ranges.\n\n    Sames as the \"ranges.h\" module, but for IPv6 instead of IPv4.\n*/\n#ifndef RANGES6_H\n#define RANGES6_H\n#include \"massip-addr.h\"\n#include <stdio.h>\n#include <stdint.h>\nstruct Range;\n\n/**\n * A range of IPv6 ranges.\n * Inclusive, so [n..m] includes both 'n' and 'm'.\n */\nstruct Range6\n{\n    ipv6address begin;\n    ipv6address end; \n};\n\n/**\n * An array of ranges in sorted order\n */\nstruct Range6List\n{\n    struct Range6 *list;\n    size_t count;\n    size_t max;\n    size_t *picker;\n    unsigned is_sorted:1;\n};\n\n/**\n * Adds the given range to the targets list. The given range can be a duplicate\n * or overlap with an existing range, which will get combined with existing\n * ranges. \n * @param targets\n *      A list of IPv6 ranges.\n * @param begin\n *      The first address of the range that'll be added.\n * @param end\n *      The last address (inclusive) of the range that'll be added.\n */\nvoid\nrange6list_add_range(struct Range6List *targets, ipv6address begin, ipv6address end);\n\n\n/**\n * Removes the given range from the target list. The input range doesn't\n * have to exist, or can partial overlap with existing ranges.\n * @param targets\n *      A list of IPv6 ranges.\n * @param begin\n *      The first address of the range that'll be removed.\n * @param end\n *      The last address of the range that'll be removed (inclusive).\n */\nvoid\nrange6list_remove_range(struct Range6List *targets, const ipv6address begin, const ipv6address end);\n\n/**\n * Same as 'rangelist_remove_range()', except the input is a range\n * structure instead of a start/stop numbers.\n */\nvoid\nrange6list_remove_range2(struct Range6List *targets, struct Range6 range);\n\n/**\n * Returns 'true' if the indicated IPv6 address is in one of the target\n * ranges.\n * @param targets\n *      A list of IPv6 ranges\n * @param ip\n *      An IPv6 address that might in be in the list of ranges\n * @return \n *      'true' if the ranges contain the item, or 'false' otherwise\n */\nint\nrange6list_is_contains(const struct Range6List *targets, const ipv6address ip);\n\n\n/**\n * Tests if the range is bad/invalid.\n * @return 1 is invalid, 0 if good.\n */\nint range6_is_bad_address(const struct Range6 *range);\n\n/**\n * Remove things from the target list. The primary use of this is the\n * \"exclude-file\" containing a list of IP addresses that we should\n * not scan\n * @param targets\n *      Our array of target IP address (or port) ranges that we'll be\n *      scanning.\n * @param excludes\n *      A list, probably read in from --excludefile, of things that we\n *      should not be scanning, that will override anything we otherwise\n *      try to scan.\n * @return\n *      the total number of IP addresses or ports removed.\n */\nipv6address\nrange6list_exclude( struct Range6List *targets,\n                    const struct Range6List *excludes);\n\n\n/**\n * Counts the total number of IPv6 addresses in the target list. This\n * iterates over all the ranges in the table, summing up the count within\n * each range.\n * @param targets\n *      A list of IP address or port ranges.\n * @return\n *      The total number of address or ports.\n */\nmassint128_t\nrange6list_count(const struct Range6List *targets);\n\n/**\n * Given an index in a continuous range of [0...count], pick a corresponding\n * number (IP address or port) from a list of non-continuous ranges (not\n * necessarily starting from 0). In other words, given the two ranges\n *    10-19 50-69\n * we'll have a total of 30 possible numbers. Thus, the index goes from\n * [0..29], with the values 0..9 picking the corresponding values from the\n * first range, and the values 10..29 picking the corresponding values\n * from the second range.\n *\n * NOTE: This is a fundamental part of this program's design, that the user\n * can specify non-contiguous IP and port ranges, but yet we iterate over\n * them using a monotonically increasing index variable.\n *\n * @param targets\n *      A list of IP address ranges, or a list of port ranges (one or the\n *      other, but not both).\n * @param index\n *      An integer starting at 0 up to (but not including) the value returned\n *      by 'rangelist_count()' for this target list.\n * @return\n *      an IP address or port corresponding to this index.\n */\nipv6address\nrange6list_pick(const struct Range6List *targets, uint64_t index);\n\n\n\n/**\n * Remove all the ranges in the range list.\n */\nvoid\nrange6list_remove_all(struct Range6List *list);\n\n/**\n * Merge two range lists\n */\nvoid\nrange6list_merge(struct Range6List *list1, const struct Range6List *list2);\n\n\n/**\n * Optimizes the target list, so that when we call \"rangelist_pick()\"\n * from an index, it runs faster. It currently configures this for \n * a binary-search, though in the future some more efficient\n * algorithm may be chosen.\n */\nvoid\nrange6list_optimize(struct Range6List *targets);\n\n/**\n * Sorts the list of target. We maintain the list of targets in sorted\n * order internally even though we scan the targets in random order\n * externally.\n */\nvoid\nrange6list_sort(struct Range6List *targets);\n\n/**\n * Does a regression test of this module\n * @return\n *      0 if the regression test succeeds, or a positive value on failure\n */\nint\nranges6_selftest(void);\n\n\n#endif\n"
  },
  {
    "path": "src/massip.c",
    "content": "#include \"massip.h\"\n#include \"massip-parse.h\"\n#include \"massip-rangesv4.h\"\n#include \"massip-rangesv6.h\"\n#include <string.h>\n#include <ctype.h>\n\nvoid massip_apply_excludes(struct MassIP *targets, struct MassIP *exclude)\n{\n    rangelist_exclude(&targets->ipv4, &exclude->ipv4);\n    range6list_exclude(&targets->ipv6, &exclude->ipv6);\n    rangelist_exclude(&targets->ports, &exclude->ports);\n}\n\nvoid massip_optimize(struct MassIP *targets)\n{\n    rangelist_optimize(&targets->ipv4);\n    range6list_optimize(&targets->ipv6);\n    rangelist_optimize(&targets->ports);\n\n    targets->count_ports = rangelist_count(&targets->ports);\n    targets->count_ipv4s = rangelist_count(&targets->ipv4);\n    targets->count_ipv6s = range6list_count(&targets->ipv6).lo;\n    targets->ipv4_index_threshold = targets->count_ipv4s * rangelist_count(&targets->ports);\n}\n\nint massip_pick(const struct MassIP *massip, uint64_t index, ipaddress *addr, unsigned *port)\n{\n    /*\n     * We can return either IPv4 or IPv6 addresses\n     */\n    if (index < massip->ipv4_index_threshold) {\n        addr->version = 4;\n        addr->ipv4 = rangelist_pick(&massip->ipv4, index % massip->count_ipv4s);\n        *port = rangelist_pick(&massip->ports, index / massip->count_ipv4s);\n    } else {\n        addr->version = 6;\n        index -= massip->ipv4_index_threshold;\n        addr->ipv6 = range6list_pick(&massip->ipv6, index % massip->count_ipv6s);\n        *port = rangelist_pick(&massip->ports, index / massip->count_ipv6s);\n    }\n    return 0;\n}\n\nint massip_has_ip(const struct MassIP *massip, ipaddress ip)\n{\n    if (ip.version == 6)\n        return range6list_is_contains(&massip->ipv6, ip.ipv6);\n    else\n        return rangelist_is_contains(&massip->ipv4, ip.ipv4);\n}\n\nint massip_has_port(const struct MassIP *massip, unsigned port)\n{\n    return rangelist_is_contains(&massip->ports, port);\n}\n\nint massip_has_ipv4_targets(const struct MassIP *massip)\n{\n    return massip->ipv4.count != 0;\n}\nint massip_has_target_ports(const struct MassIP *massip)\n{\n    return massip->ports.count != 0;\n}\nint massip_has_ipv6_targets(const struct MassIP *massip)\n{\n    return massip->ipv6.count != 0;\n}\n\n\nint massip_add_target_string(struct MassIP *massip, const char *string)\n{\n    const char *ranges = string;\n    size_t offset = 0;\n    size_t max_offset = strlen(ranges);\n\n    while (offset < max_offset) {\n        struct Range range;\n        struct Range6 range6;\n        int err;\n\n        /* Grab the next IPv4 or IPv6 range */\n        err = massip_parse_range(ranges, &offset, max_offset, &range, &range6);\n        switch (err) {\n        case Ipv4_Address:\n            rangelist_add_range(&massip->ipv4, range.begin, range.end);\n            break;\n        case Ipv6_Address:\n            range6list_add_range(&massip->ipv6, range6.begin, range6.end);\n            break;\n        default:\n            offset = max_offset; /* An error means skipping the rest of the string */\n            return 1;\n        }\n        while (offset < max_offset && (isspace(ranges[offset]&0xFF) || ranges[offset] == ','))\n            offset++;\n    }\n    return 0;\n}\n\nint massip_add_port_string(struct MassIP *targets, const char *string, unsigned defaultrange)\n{\n    unsigned is_error = 0;\n    rangelist_parse_ports(&targets->ports, string, &is_error, defaultrange);\n    if (is_error)\n        return 1;\n    else\n        return 0;\n}\n\nint massip_selftest(void)\n{\n    struct MassIP targets;\n    struct MassIP excludes;\n    int err;\n    int line;\n    massint128_t count;\n\n    memset(&targets, 0, sizeof(targets));\n    memset(&excludes, 0, sizeof(targets));\n\n    rangelist_parse_ports(&targets.ports, \"80\", 0, 0);\n\n    /* First, create a list of targets */\n    line = __LINE__;\n    err = massip_add_target_string(&targets, \"2607:f8b0:4002:801::2004/124,1111::1\");\n    if (err)\n        goto fail;\n\n    /* Second, create an exclude list */\n    line = __LINE__;\n    err = massip_add_target_string(&excludes, \"2607:f8b0:4002:801::2004/126,1111::/16\");\n    if (err)\n        goto fail;\n\n    /* Third, apply the excludes, causing ranges to be removed\n     * from the target list */\n    massip_apply_excludes(&targets, &excludes);\n\n    /* Now make sure the count equals the expected count */\n    line = __LINE__;\n    count = massip_range(&targets);\n    if (count.hi != 0 || count.lo != 12)\n        goto fail;\n\n    return 0;\nfail:\n    fprintf(stderr, \"[-] massip: test fail, line=%d\\n\", line);\n    return 1;\n}\n\n"
  },
  {
    "path": "src/massip.h",
    "content": "#ifndef MASSIP_H\n#define MASSIP_H\n#include <stddef.h>\n#include \"massip-rangesv4.h\"\n#include \"massip-rangesv6.h\"\n\nstruct MassIP {\n    struct RangeList ipv4;\n    struct Range6List ipv6;\n\n    /**\n     * The ports we are scanning for. The user can specify repeated ports\n     * and overlapping ranges, but we'll deduplicate them, scanning ports\n     * only once.\n     * NOTE: TCP ports are stored 0-64k, but UDP ports are stored in the\n     * range 64k-128k, thus, allowing us to scan both at the same time.\n     */\n    struct RangeList ports;\n\n    /**\n     * Used internally to differentiate between indexes selecting an\n     * IPv4 address and higher ones selecting an IPv6 address.\n     */\n    uint64_t ipv4_index_threshold;\n\n    uint64_t count_ports;\n    uint64_t count_ipv4s;\n    uint64_t count_ipv6s;\n};\n\n/**\n * Count the total number of targets in a scan. This is calculated\n * the (IPv6 addresses * IPv4 addresses * ports). This can produce\n * a 128-bit number (larger, actually).\n */\nmassint128_t massip_range(struct MassIP *massip);\n\n/**\n * Remove everything in \"targets\" that's listed in the \"exclude\"\n * list. The reason for this is that we'll have a single policy\n * file of those address ranges which we are forbidden to scan.\n * Then, each time we run a scan with different targets, we\n * apply this policy file.\n */\nvoid massip_apply_excludes(struct MassIP *targets, struct MassIP *exclude);\n\n/**\n * The last step after processing the configuration, setting up the \n * state to be used for scanning. This sorts the address, removes\n * duplicates, and creates an optimized 'picker' system to easily\n * find an address given an index, or find an index given an address.\n */\nvoid massip_optimize(struct MassIP *targets);\n\n/**\n * This selects an IP+port combination given an index whose value\n * is [0..range], where 'range' is the value returned by the function\n * `massip_range()`. Since the optimization step (`massip_optimized()`)\n * sorted all addresses/ports, a monotonically increasing index will\n * list everything in sorted order. The intent, however, is to use the\n * \"blackrock\" algorithm to randomize the index before calling this function.\n *\n * It is this function, plus the 'blackrock' randomization algorithm, that\n * is at the heart of Masscan. \n */\nint massip_pick(const struct MassIP *massip, uint64_t index, ipaddress *addr, unsigned *port);\n\n\nint massip_has_ip(const struct MassIP *massip, ipaddress ip);\n\nint massip_has_port(const struct MassIP *massip, unsigned port);\n\nint massip_add_target_string(struct MassIP *massip, const char *string);\n\n/**\n * Parse the string contain port specifier.\n */\nint massip_add_port_string(struct MassIP *massip, const char *string, unsigned proto);\n\n\n/**\n * Indicates whether there are IPv4 targets. If so, we'll have to \n * initialize the IPv4 portion of the stack.\n * @return true if there are IPv4 targets to be scanned, false\n * otherwise\n */\nint massip_has_ipv4_targets(const struct MassIP *massip);\nint massip_has_target_ports(const struct MassIP *massip);\n\n/**\n * Indicates whether there are IPv6 targets. If so, we'll have to \n * initialize the IPv6 portion of the stack.\n * @return true if there are IPv6 targets to be scanned, false\n * otherwise\n */\nint massip_has_ipv6_targets(const struct MassIP *massip);\n\n\nint massip_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/misc-rstfilter.c",
    "content": "#include \"misc-rstfilter.h\"\n#include \"util-malloc.h\"\n#include \"crypto-siphash24.h\"\n#include <time.h>\n\nstruct ResetFilter\n{\n    unsigned long long seed;\n    size_t bucket_count;\n    size_t bucket_mask;\n    unsigned counter;\n    unsigned char *buckets;\n};\n\nstatic size_t\nnext_pow2(size_t n)\n{\n    size_t bit_count = 0;\n    \n    /* Always have at least one bit */\n    if (n == 0)\n        return 1;\n    \n    /* If already a power-of-two, then return that */\n    if ((n & (n - 1)) == 0)\n        return n;\n    \n    /* Count the number of bits */\n    while (n != 0) {\n        n >>= 1;\n        bit_count += 1;\n    }\n    \n    return (size_t)1 << (size_t)bit_count;\n}\n\nstruct ResetFilter *\nrstfilter_create(unsigned long long seed, size_t bucket_count)\n{\n    struct ResetFilter *rf;\n    \n    rf = CALLOC(1, sizeof(*rf));\n    rf->seed = seed;\n    rf->bucket_count = next_pow2(bucket_count);\n    rf->bucket_mask = rf->bucket_count - 1;\n    rf->buckets = CALLOC(rf->bucket_count/2, sizeof(*rf->buckets));\n    \n    return rf;\n}\n\n\nvoid\nrstfilter_destroy(struct ResetFilter *rf)\n{\n    if (rf == NULL)\n        return;\n    free(rf->buckets);\n    free(rf);\n}\n\nint\nrstfilter_is_filter(struct ResetFilter *rf,\n                    ipaddress src_ip, unsigned src_port,\n                    ipaddress dst_ip, unsigned dst_port)\n{\n    uint64_t hash;\n    uint64_t input[5];\n    uint64_t key[2];\n    size_t index;\n    unsigned char *p;\n    int result = 0;\n    \n    /*\n     * Setup the input\n     */\n    switch (src_ip.version) {\n    case 4:\n        input[0] = src_ip.ipv4;\n        input[1] = src_port;\n        input[2] = dst_ip.ipv4;\n        input[3] = dst_port;\n        break;\n    case 6:\n        input[0] = src_ip.ipv6.hi;\n        input[1] = src_ip.ipv6.lo;\n        input[2] = dst_ip.ipv6.hi;\n        input[3] = dst_ip.ipv6.lo;\n        input[4] = src_port<<16 | dst_port;\n        break;\n    }\n    key[0] = rf->seed;\n    key[1] = rf->seed;\n    \n    /*\n     * Grab the bucket\n     */\n    hash = siphash24(input, sizeof(input), key);\n    index = hash & rf->bucket_mask;\n    \n    /*\n     * Find the result (1=filterout, 0=sendrst)\n     */\n    p = &rf->buckets[index/2];\n    if (index & 1) {\n        if ((*p & 0x0F) == 0x0F)\n            result = 1; /* filter out */\n        else\n            *p = (*p) + 0x01;\n    } else {\n        if ((*p & 0xF0) == 0xF0)\n            result = 1; /* filter out */\n        else\n            *p = (*p) + 0x10;\n    }\n    \n    /*\n     * Empty a random bucket\n     */\n    input[0] = (unsigned)hash;\n    input[1] = rf->counter++;\n    hash = siphash24(input, sizeof(input), key);\n    index = hash & rf->bucket_mask;\n    p = &rf->buckets[index/2];\n    if (index & 1) {\n        if ((*p & 0x0F))\n            *p = (*p) - 0x01;\n    } else {\n        if ((*p & 0xF0))\n            *p = (*p) - 0x10;\n    }\n\n    return result;\n}\n\n\n\nint\nrstfilter_selftest(void)\n{\n    struct ResetFilter *rf;\n    size_t i;\n    unsigned count_filtered = 0;\n    unsigned count_passed = 0;\n\n    ipaddress src;\n    ipaddress dst;\n\n    src.version = 4;\n    src.ipv4 = 1;\n    dst.version = 4;\n    dst.ipv4 = 3;\n\n    rf = rstfilter_create(time(0), 64);\n    \n    /* Verify the first 15 packets pass the filter */\n    for (i=0; i<15; i++) {\n        int x;\n\n        x = rstfilter_is_filter(rf, src, 2, dst, 4);\n        if (x) {\n            fprintf(stderr, \"[-] rstfilter failed, line=%u\\n\", __LINE__);\n            return 1;\n        }\n    }\n    \n    /* Now run 10000 more times */\n    for (i=0; i<1000; i++) {\n        int x;\n        x = rstfilter_is_filter(rf, src, 2, dst, 4);\n        count_filtered += x;\n        count_passed += !x;\n    }\n    \n    /* SOME must have passed, due to us emptying random buckets */\n    if (count_passed == 0) {\n        fprintf(stderr, \"[-] rstfilter failed, line=%u\\n\", __LINE__);\n        return 1;\n    }\n    \n    /* However, while some pass, the vast majority should be filtered */\n    if (count_passed > count_filtered/10) {\n        fprintf(stderr, \"[-] rstfilter failed, line=%u\\n\", __LINE__);\n        return 1;\n    }\n    //printf(\"filtered=%u passed=%u\\n\", count_filtered, count_passed);\n    return 0;\n}\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/misc-rstfilter.h",
    "content": "/*\n RST filter\n \n In theory, we should transmit a RST packet every time we receive an invalid\n TCP packet. In practice, this can lead to endless transmits when the other\n size continues to transmit bad packets. This may happen accidentally, or this\n may happen on purpose from the other side trying to attack the scanner\n intentionally. In May 2019 I see this from somebody who I suspect is trying\n to do that, replying back as fast as the scanner transmits (when running\n at 10,000 packets per-second). This halts the scan, as it's throttle limit\n is filled sending RSTs and not doing something useful.\n \n The design is a simple non-deterministic algorithm. It hashes the\n IP/prot combo, then updates a counter at that bucket. When it reaches\n its limit, it stops transmitting resets. However, it'll also slowly\n empty buckets, so can occasionally transmit a RST now and then.\n */\n#ifndef MISC_RSTFILTER_H\n#define MISC_RSTFILTER_H\n#include <stdio.h>\n#include \"massip-addr.h\"\n\nstruct ResetFilter;\n\n/**\n * Create a structure for this.\n * @param seed\n *      A random seed chosen via entropy at startup, so that adversaries\n *      can't predict where the buckets will be.\n * @param bucket_count\n *      The number of buckets. This'll be rounded up to the nearest\n *      power-of-two. 16384 is probably a good number.\n * @return an instance of this object that should be eventually\n *      cleaned up with 'rstfilter_destroy()'.\n */\nstruct ResetFilter *\nrstfilter_create(unsigned long long seed, size_t bucket_count);\n\n/**\n * Cleans up the object that was created with 'rstfilter_create()'.\n */\nvoid\nrstfilter_destroy(struct ResetFilter *rf);\n\n/**\n * Tests to see if we should ignore the given RST packet. This will\n * also slowly empty a random bucket\n * @return 1 if we should filter out the offending packet and ignore it,\n *          or else 0 if we shouldn't ignore it.\n */\nint\nrstfilter_is_filter(struct ResetFilter *rf, ipaddress src_ip, unsigned src_port, ipaddress dst_ip, unsigned dst_port);\n\nint\nrstfilter_selftest(void);\n\n\n\n#endif\n\n"
  },
  {
    "path": "src/out-binary.c",
    "content": "#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"out-record.h\"\n#include \"util-safefunc.h\"\n#include <assert.h>\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_open(struct Output *out, FILE *fp)\n{\n    char firstrecord[2+'a'];\n    size_t bytes_written;\n\n    UNUSEDPARM(out);\n\n\n    memset(firstrecord, 0, 2+'a');\n    snprintf(firstrecord, 2+'a', \"masscan/1.1\\ns:%u\\n\", \n        (unsigned)out->when_scan_started);\n    bytes_written = fwrite(firstrecord, 1, 2+'a', fp);\n    if (bytes_written != 2+'a') {\n        perror(\"output\");\n        exit(1);\n    }\n\n    out->rotate.bytes_written += bytes_written;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_close(struct Output *out, FILE *fp)\n{\n    char firstrecord[2+'a'];\n    size_t bytes_written;\n\n    UNUSEDPARM(out);\n\n    memset(firstrecord, 0, 2+'a');\n    snprintf(firstrecord, 2+'a', \"masscan/1.1\");\n    bytes_written = fwrite(firstrecord, 1, 2+'a', fp);\n    if (bytes_written != 2+'a') {\n        perror(\"output\");\n        exit(1);\n    }\n    out->rotate.bytes_written += bytes_written;\n}\n\nstatic void\n_put_byte(unsigned char *buf, size_t length, size_t *r_offset, unsigned long long num)\n{\n    size_t offset = *r_offset;\n    (*r_offset) += 1;\n    if (*r_offset <= length) {\n        buf[offset++] = (unsigned char)(num>>0);\n    }\n}\nstatic void\n_put_short(unsigned char *buf, size_t length, size_t *r_offset, unsigned long long num)\n{\n    size_t offset = *r_offset;\n    (*r_offset) += 2;\n    if (*r_offset <= length) {\n        buf[offset++] = (unsigned char)(num>>8);\n        buf[offset++] = (unsigned char)(num>>0);\n    }\n}\nstatic void\n_put_integer(unsigned char *buf, size_t length, size_t *r_offset, unsigned long long num)\n{\n    size_t offset = *r_offset;\n    (*r_offset) += 4;\n    if (*r_offset <= length) {\n        buf[offset++] = (unsigned char)(num>>24);\n        buf[offset++] = (unsigned char)(num>>16);\n        buf[offset++] = (unsigned char)(num>>8);\n        buf[offset++] = (unsigned char)(num>>0);\n    }\n}\nstatic void\n_put_long(unsigned char *buf, size_t length, size_t *r_offset, unsigned long long num)\n{\n    size_t offset = *r_offset;\n    (*r_offset) += 8;\n    if (*r_offset <= length) {\n        buf[offset++] = (unsigned char)(num>>56);\n        buf[offset++] = (unsigned char)(num>>48);\n        buf[offset++] = (unsigned char)(num>>40);\n        buf[offset++] = (unsigned char)(num>>32);\n        buf[offset++] = (unsigned char)(num>>24);\n        buf[offset++] = (unsigned char)(num>>16);\n        buf[offset++] = (unsigned char)(num>>8);\n        buf[offset++] = (unsigned char)(num>>0);\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_status_ipv6(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    unsigned char buf[256+1];\n    size_t max = sizeof(buf)-1;\n    size_t offset = 0;\n    size_t bytes_written;\n\n \n    /* [TYPE] field */\n    switch (status) {\n    case PortStatus_Open:\n        _put_byte(buf, max, &offset, Out_Open6);\n        break;\n    case PortStatus_Closed:\n        _put_byte(buf, max, &offset, Out_Closed6);\n        break;\n    case PortStatus_Arp:\n        _put_byte(buf, max, &offset, Out_Arp6);\n        break;\n    default:\n        return;\n    }\n\n    /* [LENGTH] field\n     * see assert() below */\n    _put_byte(buf, max, &offset, 26);\n\n    _put_integer(buf, max, &offset, timestamp);\n    _put_byte(buf, max, &offset, ip_proto);\n    _put_short(buf, max, &offset, port);\n    _put_byte(buf, max, &offset, reason);\n    _put_byte(buf, max, &offset, ttl);\n    _put_byte(buf, max, &offset, ip.version);\n    _put_long(buf, max, &offset, ip.ipv6.hi);\n    _put_long(buf, max, &offset, ip.ipv6.lo);\n    \n    assert(offset == 2 + 26);\n    \n    bytes_written = fwrite(buf, 1, offset, fp);\n    if (bytes_written != offset) {\n        perror(\"output\");\n        exit(1);\n    }\n    out->rotate.bytes_written += bytes_written;\n\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    unsigned char foo[256];\n    size_t bytes_written;\n\n    /* This function is for IPv6, call a different function for IPv6 */\n    if (ip.version == 6) {\n        binary_out_status_ipv6(out, fp, timestamp, status, ip, ip_proto, port, reason, ttl);\n        return;\n    }\n \n    /* [TYPE] field */\n    switch (status) {\n    case PortStatus_Open:\n        foo[0] = Out_Open2;\n        break;\n    case PortStatus_Closed:\n        foo[0] = Out_Closed2;\n        break;\n    case PortStatus_Arp:\n        foo[0] = Out_Arp2;\n        break;\n    default:\n        return;\n    }\n\n    /* [LENGTH] field */\n    foo[1] = 13;\n\n    /* [TIMESTAMP] field */\n    foo[2] = (unsigned char)(timestamp>>24);\n    foo[3] = (unsigned char)(timestamp>>16);\n    foo[4] = (unsigned char)(timestamp>> 8);\n    foo[5] = (unsigned char)(timestamp>> 0);\n\n    foo[6] = (unsigned char)(ip.ipv4 >>24);\n    foo[7] = (unsigned char)(ip.ipv4 >>16);\n    foo[8] = (unsigned char)(ip.ipv4 >> 8);\n    foo[9] = (unsigned char)(ip.ipv4 >> 0);\n\n    foo[10] = (unsigned char)(ip_proto);\n\n    foo[11] = (unsigned char)(port>>8);\n    foo[12] = (unsigned char)(port>>0);\n\n    foo[13] = (unsigned char)reason;\n    foo[14] = (unsigned char)ttl;\n\n\n\n    bytes_written = fwrite(&foo, 1, 15, fp);\n    if (bytes_written != 15) {\n        perror(\"output\");\n        exit(1);\n    }\n    out->rotate.bytes_written += bytes_written;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_banner_ipv6(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    unsigned char foo[32768];\n    unsigned i;\n    size_t bytes_written;\n    static const unsigned HeaderLength = 14 + 13;\n\n    \n    /* [TYPE] field */\n    foo[0] = Out_Banner6; /*banner*/\n\n    /* [LENGTH] field*/\n    if (length >= 128 * 128 - HeaderLength)\n        return;\n    if (length < 128 - HeaderLength) {\n        foo[1] = (unsigned char)(length + HeaderLength);\n        i = 2;\n    } else {\n        foo[1] = (unsigned char)((length + HeaderLength)>>7) | 0x80;\n        foo[2] = (unsigned char)((length + HeaderLength) & 0x7F);\n        i = 3;\n    }\n\n    /* [TIMESTAMP] field */\n    foo[i+0] = (unsigned char)(timestamp>>24);\n    foo[i+1] = (unsigned char)(timestamp>>16);\n    foo[i+2] = (unsigned char)(timestamp>> 8);\n    foo[i+3] = (unsigned char)(timestamp>> 0);\n\n    foo[i+ 4] = (unsigned char)(ip_proto);\n\n    foo[i+ 5] = (unsigned char)(port>>8);\n    foo[i+ 6] = (unsigned char)(port>>0);\n\n    foo[i+ 7] = (unsigned char)(proto>>8);\n    foo[i+ 8] = (unsigned char)(proto>>0);\n\n    foo[i+ 9] = (unsigned char)(ttl);\n\n    foo[i+10] = (unsigned char)(ip.version);\n\n    foo[i+11] = (unsigned char)(ip.ipv6.hi >> 56ULL);\n    foo[i+12] = (unsigned char)(ip.ipv6.hi >> 48ULL);\n    foo[i+13] = (unsigned char)(ip.ipv6.hi >> 40ULL);\n    foo[i+14] = (unsigned char)(ip.ipv6.hi >> 32ULL);\n    foo[i+15] = (unsigned char)(ip.ipv6.hi >> 24ULL);\n    foo[i+16] = (unsigned char)(ip.ipv6.hi >> 16ULL);\n    foo[i+17] = (unsigned char)(ip.ipv6.hi >>  8ULL);\n    foo[i+18] = (unsigned char)(ip.ipv6.hi >>  0ULL);\n\n    foo[i+19] = (unsigned char)(ip.ipv6.lo >> 56ULL);\n    foo[i+20] = (unsigned char)(ip.ipv6.lo >> 48ULL);\n    foo[i+21] = (unsigned char)(ip.ipv6.lo >> 40ULL);\n    foo[i+22] = (unsigned char)(ip.ipv6.lo >> 32ULL);\n    foo[i+23] = (unsigned char)(ip.ipv6.lo >> 24ULL);\n    foo[i+24] = (unsigned char)(ip.ipv6.lo >> 16ULL);\n    foo[i+25] = (unsigned char)(ip.ipv6.lo >>  8ULL);\n    foo[i+26] = (unsigned char)(ip.ipv6.lo >>  0ULL);\n\n    /* Banner */\n    memcpy(foo+i+14+13, px, length);\n\n\n    bytes_written = fwrite(&foo, 1, length+i+HeaderLength, fp);\n    if (bytes_written != length+i+HeaderLength) {\n        perror(\"output\");\n        exit(1);\n    }\n    out->rotate.bytes_written += bytes_written;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nbinary_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    unsigned char foo[32768];\n    unsigned i;\n    size_t bytes_written;\n    static const unsigned HeaderLength = 14;\n\n    if (ip.version == 6) {\n        binary_out_banner_ipv6(out, fp, timestamp, ip, ip_proto, port, proto, ttl, px, length);\n        return;\n    }\n    \n    /* [TYPE] field */\n    foo[0] = Out_Banner9; /*banner*/\n\n    /* [LENGTH] field*/\n    if (length >= 128 * 128 - HeaderLength)\n        return;\n    if (length < 128 - HeaderLength) {\n        foo[1] = (unsigned char)(length + HeaderLength);\n        i = 2;\n    } else {\n        foo[1] = (unsigned char)((length + HeaderLength)>>7) | 0x80;\n        foo[2] = (unsigned char)((length + HeaderLength) & 0x7F);\n        i = 3;\n    }\n\n    /* [TIMESTAMP] field */\n    foo[i+0] = (unsigned char)(timestamp>>24);\n    foo[i+1] = (unsigned char)(timestamp>>16);\n    foo[i+2] = (unsigned char)(timestamp>> 8);\n    foo[i+3] = (unsigned char)(timestamp>> 0);\n\n    foo[i+4] = (unsigned char)(ip.ipv4 >> 24);\n    foo[i+5] = (unsigned char)(ip.ipv4 >> 16);\n    foo[i+6] = (unsigned char)(ip.ipv4 >>  8);\n    foo[i+7] = (unsigned char)(ip.ipv4 >>  0);\n\n    foo[i+8] = (unsigned char)(ip_proto);\n\n    foo[i+ 9] = (unsigned char)(port>>8);\n    foo[i+10] = (unsigned char)(port>>0);\n\n    foo[i+11] = (unsigned char)(proto>>8);\n    foo[i+12] = (unsigned char)(proto>>0);\n\n    foo[i+13] = (unsigned char)(ttl);\n\n    /* Banner */\n    memcpy(foo+i+14, px, length);\n\n\n    bytes_written = fwrite(&foo, 1, length+i+HeaderLength, fp);\n    if (bytes_written != length+i+HeaderLength) {\n        perror(\"output\");\n        exit(1);\n    }\n    out->rotate.bytes_written += bytes_written;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType binary_output = {\n    \"scan\",\n    0,\n    binary_out_open,\n    binary_out_close,\n    binary_out_status,\n    binary_out_banner,\n};\n\n\n"
  },
  {
    "path": "src/out-certs.c",
    "content": "#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"util-safefunc.h\"\n#include <ctype.h>\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ncert_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ncert_out_close(struct Output *out, FILE *fp)\n{    \n    UNUSEDPARM(out);\n    fprintf(fp, \"{finished: 1}\\n\");\n}\n\n/******************************************************************************\n ******************************************************************************/\nstatic void\ncert_out_status(struct Output *out, FILE *fp, time_t timestamp, int status,\n                ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    /* certificates only come with banner info, so there is no port info\n     * to report */\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(status);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(port);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(ttl);\n}\n\n\n/******************************************************************************\n ******************************************************************************/\nstatic void\ncert_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n                ipaddress ip, unsigned ip_proto, unsigned port,\n                enum ApplicationProtocol proto, \n                unsigned ttl,\n                const unsigned char *px, unsigned length)\n{\n    unsigned i;\n\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(proto);\n    UNUSEDPARM(port);\n\n    if (length > 5 && memcmp(px, \"cert:\", 5) == 0) {\n        px += 5;\n        length -= 5;\n    }\n    \n    printf(\"-----BEGIN CERTIFICATE-----\\n\");\n    for (i=0; i<length; i += 72) {\n        unsigned len = length - i;\n        if (len > 72)\n            len = 72;\n        printf(\"%.*s\\n\", len, px+i);\n    }\n    printf(\"-----END CERTIFICATE-----\\n\");\n}\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType certs_output = {\n    \"cert\",\n    0,\n    cert_out_open,\n    cert_out_close,\n    cert_out_status,\n    cert_out_banner\n};\n\n"
  },
  {
    "path": "src/out-grepable.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n#include \"masscan-version.h\"\n#include \"masscan-status.h\"\n#include \"out-tcp-services.h\"\n#include \"massip-port.h\"\n#include \"util-safefunc.h\"\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic unsigned\ncount_type(const struct RangeList *ports, int start_type, int end_type)\n{\n    unsigned min_port = start_type;\n    unsigned max_port = end_type;\n    unsigned i;\n    unsigned result = 0;\n\n    for (i=0; i<ports->count; i++) {\n        struct Range r = ports->list[i];\n        if (r.begin > max_port)\n            continue;\n        if (r.end < min_port)\n            continue;\n\n        if (r.begin < min_port)\n            r.begin = min_port;\n        if (r.end > max_port)\n            r.end = max_port;\n\n\n        result += r.end - r.begin + 1;\n    }\n\n    return result;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nprint_port_list(const struct RangeList *ports, int type, FILE *fp)\n{\n    unsigned min_port = type;\n    unsigned max_port = type + 65535;\n    unsigned i;\n\n    for (i=0; i<ports->count; i++) {\n        struct Range r = ports->list[i];\n        if (r.begin > max_port)\n            continue;\n        if (r.end < min_port)\n            continue;\n\n        if (r.begin < min_port)\n            r.begin = min_port;\n        if (r.end > max_port)\n            r.end = max_port;\n\n        fprintf(fp, \"%u-%u%s\", r.begin, r.end, (i+1<ports->count)?\",\":\"\");\n    }\n}\n\nextern const char *debug_recv_status;\n\n/****************************************************************************\n * This function doesn't really \"open\" the file. Instead, the purpose of\n * this function is to initialize the file by printing header information.\n ****************************************************************************/\nstatic void\ngrepable_out_open(struct Output *out, FILE *fp)\n{\n    char timestamp[64];\n    struct tm tm;\n    unsigned count;\n\n    \n    safe_gmtime(&tm, &out->when_scan_started);\n\n    //Tue Jan 21 20:23:22 2014\n    //%a %b %d %H:%M:%S %Y\n    strftime(timestamp, sizeof(timestamp), \"%c\", &tm);\n\n    fprintf(fp, \"# Masscan \" MASSCAN_VERSION \" scan initiated %s\\n\", \n                timestamp);\n\n    count = count_type(&out->masscan->targets.ports, Templ_TCP, Templ_TCP_last);\n    fprintf(fp, \"# Ports scanned: TCP(%u;\", count);\n    if (count)\n        print_port_list(&out->masscan->targets.ports, Templ_TCP, fp);\n\n    count = count_type(&out->masscan->targets.ports, Templ_UDP, Templ_UDP_last);\n    fprintf(fp, \") UDP(%u;\", count);\n    if (count)\n        print_port_list(&out->masscan->targets.ports, Templ_UDP, fp);\n    \n    \n    count = count_type(&out->masscan->targets.ports, Templ_SCTP, Templ_SCTP_last);\n    fprintf(fp, \") SCTP(%u;\", count);\n    if (count)\n        print_port_list(&out->masscan->targets.ports, Templ_SCTP, fp);\n\n    count = count_type(&out->masscan->targets.ports, Templ_Oproto_first, Templ_Oproto_last);\n    fprintf(fp, \") PROTOCOLS(%u;\", count);\n    if (count)\n        print_port_list(&out->masscan->targets.ports, Templ_Oproto_first, fp);\n    \n    fprintf(fp, \")\\n\");\n}\n\n/****************************************************************************\n * This function doesn't really \"close\" the file. Instead, it's purpose\n * is to print trailing information to the file. This is pretty much only\n * a concern for XML files that need stuff appended to the end.\n ****************************************************************************/\nstatic void\ngrepable_out_close(struct Output *out, FILE *fp)\n{\n    time_t now = time(0);\n    char timestamp[64];\n    struct tm tm;\n\n    UNUSEDPARM(out);\n\n    safe_gmtime(&tm, &now);\n\n    //Tue Jan 21 20:23:22 2014\n    //%a %b %d %H:%M:%S %Y\n    strftime(timestamp, sizeof(timestamp), \"%c\", &tm);\n\n    fprintf(fp, \"# Masscan done at %s\\n\", \n                timestamp);\n}\n\n/****************************************************************************\n * Prints out the status of a port, which is almost always just \"open\"\n * or \"closed\".\n ****************************************************************************/\nstatic void\ngrepable_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    const char *service;\n    ipaddress_formatted_t fmt;\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(ttl);\n\n    if (ip_proto == 6)\n        service = tcp_service_name(port);\n    else if (ip_proto == 17)\n        service = udp_service_name(port);\n    else\n        service = oproto_service_name(ip_proto);\n    \n    fprintf(fp, \"Timestamp: %llu\", (unsigned long long)timestamp);\n\n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"\\tHost: %s ()\", fmt.string);\n    fprintf(fp, \"\\tPorts: %u/%s/%s/%s/%s/%s/%s\\n\",\n                port,\n                status_string(status),      //\"open\", \"closed\"\n                name_from_ip_proto(ip_proto),  //\"tcp\", \"udp\", \"sctp\"\n                \"\", //owner\n                service, //service\n                \"\", //SunRPC info\n                \"\" //Version info\n                );\n}\n\n/****************************************************************************\n * Prints out \"banner\" information for a port. This is done when there is\n * a protocol defined for a port, and we do some interaction to find out\n * more information about which protocol is running on a port, it's version,\n * and other useful information.\n ****************************************************************************/\nstatic void\ngrepable_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    char banner_buffer[MAX_BANNER_LENGTH];\n    ipaddress_formatted_t fmt;\n\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(ip_proto);\n    \n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"Host: %s ()\", fmt.string);\n    fprintf(fp, \"\\tPort: %u\", port);\n\n    fprintf(fp, \"\\tService: %s\", masscan_app_to_string(proto));\n\n    normalize_string(px, length, banner_buffer, sizeof(banner_buffer));\n\n    fprintf(fp, \"\\tBanner: %s\\n\", banner_buffer);\n\n}\n\n\n\n/****************************************************************************\n * This is the only structure exposed to the rest of the system. Everything\n * else in the file is defined 'static' or 'private'.\n ****************************************************************************/\nconst struct OutputType grepable_output = {\n    \"grepable\",\n    0,\n    grepable_out_open,\n    grepable_out_close,\n    grepable_out_status,\n    grepable_out_banner\n};\n"
  },
  {
    "path": "src/out-hostonly.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"unusedparm.h\"\n#include \"out-tcp-services.h\"\n\n\n\n\n\nstatic void\nhostonly_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(fp);\n    UNUSEDPARM(out);\n}\n\n\nstatic void\nhostonly_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(fp);\n    UNUSEDPARM(out);\n}\n\nstatic void\nhostonly_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(out);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(port);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(status);\n    fprintf(fp, \"%s\\n\", fmt.string);\n}\n\n\n/*************************************** *************************************\n ****************************************************************************/\nstatic void\nhostonly_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{ /* SYN only - no banner */\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n    UNUSEDPARM(out);\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(port);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(proto);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n    fprintf(fp, \"%s\\n\", fmt.string);\n\n    return;\n} \n \n\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType hostonly_output = {\n    \"hostonly\",\n    0,\n    hostonly_out_open,\n    hostonly_out_close,\n    hostonly_out_status,\n    hostonly_out_banner\n};\n\n\n\n"
  },
  {
    "path": "src/out-json.c",
    "content": "#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"util-safefunc.h\"\n#include <ctype.h>\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\njson_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"[\\n\"); // enclose the atomic {}'s into an []\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\njson_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"]\\n\"); // enclose the atomic {}'s into an []\n}\n\n//{ ip: \"124.53.139.201\", ports: [ {port: 443, proto: \"tcp\", status: \"open\", reason: \"syn-ack\", ttl: 48} ] }\n/****************************************************************************\n ****************************************************************************/\nstatic void\njson_out_status(struct Output *out, FILE *fp, time_t timestamp, int status,\n               ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    char reason_buffer[128];\n    ipaddress_formatted_t fmt;\n    UNUSEDPARM(out);\n    //UNUSEDPARM(timestamp);\n\n    /* Trailing comma breaks some JSON parsers. We don't know precisely when\n     * we'll end, but we do know when we begin, so instead of appending\n     * a command to the record, we prepend it -- but not before first record */\n    if (out->is_first_record_seen)\n        fprintf(fp, \",\\n\");\n    else\n        out->is_first_record_seen = 1;\n    \n    fprintf(fp, \"{ \");\n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"  \\\"ip\\\": \\\"%s\\\", \", fmt.string);\n    fprintf(fp, \"  \\\"timestamp\\\": \\\"%d\\\", \\\"ports\\\": [ {\\\"port\\\": %u, \\\"proto\\\": \\\"%s\\\", \\\"status\\\": \\\"%s\\\",\"\n                \" \\\"reason\\\": \\\"%s\\\", \\\"ttl\\\": %u} ] \",\n                (int) timestamp,\n                port,\n                name_from_ip_proto(ip_proto),\n                status_string(status),\n                reason_string(reason, reason_buffer, sizeof(reason_buffer)),\n                ttl\n            );\n    fprintf(fp, \"}\\n\");\n\n\n}\n\n/*****************************************************************************\n * Remove bad characters from the banner, especially new lines and HTML\n * control codes.\n *****************************************************************************/\nstatic const char *\nnormalize_json_string(const unsigned char *px, size_t length,\n                 char *buf, size_t buf_len)\n{\n    size_t i=0;\n    size_t offset = 0;\n\n\n    for (i=0; i<length; i++) {\n        unsigned char c = px[i];\n\n        if (isprint(c) && c != '<' && c != '>' && c != '&' && c != '\\\\' && c != '\\\"' && c != '\\'') {\n            if (offset + 2 < buf_len)\n                buf[offset++] = px[i];\n        } else {\n            if (offset + 7 < buf_len) {\n                buf[offset++] = '\\\\';\n                buf[offset++] = 'u';\n                buf[offset++] = '0';\n                buf[offset++] = '0';\n                buf[offset++] = \"0123456789abcdef\"[px[i]>>4];\n                buf[offset++] = \"0123456789abcdef\"[px[i]&0xF];\n            }\n        }\n    }\n\n    buf[offset] = '\\0';\n\n    return buf;\n}\n\n/******************************************************************************\n ******************************************************************************/\nstatic void\njson_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n               ipaddress ip, unsigned ip_proto, unsigned port,\n               enum ApplicationProtocol proto,\n               unsigned ttl,\n               const unsigned char *px, unsigned length)\n{\n    char banner_buffer[65536];\n    ipaddress_formatted_t fmt;\n\n    UNUSEDPARM(ttl);\n\n    /* Trailing comma breaks some JSON parsers. We don't know precisely when\n     * we'll end, but we do know when we begin, so instead of appending\n     * a command to the record, we prepend it -- but not before first record */\n    if (out->is_first_record_seen)\n        fprintf(fp, \",\\n\");\n    else\n        out->is_first_record_seen = 1;\n    \n    fprintf(fp, \"{ \");\n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"  \\\"ip\\\": \\\"%s\\\", \", fmt.string);\n    fprintf(fp, \"  \\\"timestamp\\\": \\\"%d\\\", \\\"ports\\\": [ {\\\"port\\\": %u, \\\"proto\\\": \\\"%s\\\", \\\"service\\\": {\\\"name\\\": \\\"%s\\\", \\\"banner\\\": \\\"%s\\\"} } ] \",\n            (int) timestamp,\n            port,\n            name_from_ip_proto(ip_proto),\n            masscan_app_to_string(proto),\n            normalize_json_string(px, length, banner_buffer, sizeof(banner_buffer))\n            );\n    fprintf(fp, \"}\\n\");\n\n    UNUSEDPARM(out);\n}\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType json_output = {\n    \"json\",\n    0,\n    json_out_open,\n    json_out_close,\n    json_out_status,\n    json_out_banner\n};\n"
  },
  {
    "path": "src/out-ndjson.c",
    "content": "#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"util-safefunc.h\"\n#include <ctype.h>\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nndjson_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nndjson_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp); \n}\n\n//{ ip: \"124.53.139.201\", ports: [ {port: 443, proto: \"tcp\", status: \"open\", reason: \"syn-ack\", ttl: 48} ] }\n/****************************************************************************\n ****************************************************************************/\nstatic void\nndjson_out_status(struct Output *out, FILE *fp, time_t timestamp, int status,\n                 ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    char reason_buffer[128];\n    ipaddress_formatted_t fmt;\n    UNUSEDPARM(out);\n\n    fprintf(fp, \"{\");\n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"\\\"ip\\\":\\\"%s\\\",\", fmt.string);\n    fprintf(fp, \"\\\"timestamp\\\":\\\"%d\\\",\\\"port\\\":%u,\\\"proto\\\":\\\"%s\\\",\\\"rec_type\\\":\\\"status\\\",\\\"data\\\":{\\\"status\\\":\\\"%s\\\",\"\n                \"\\\"reason\\\":\\\"%s\\\",\\\"ttl\\\":%u}\",\n                (int) timestamp,\n                port,\n                name_from_ip_proto(ip_proto),\n                status_string(status),\n                reason_string(reason, reason_buffer, sizeof(reason_buffer)),\n                ttl\n            );\n    fprintf(fp, \"}\\n\");\n\n\n}\n\n/*****************************************************************************\n * Remove bad characters from the banner, especially new lines and HTML\n * control codes.\n *\n * Keeping this here since we may need to change the behavior from what \n * is done in the sister `normalize_json_string` function. It's unlikely\n * but it's a small function and will save time later if needed. Could also\n * set it up to base64 encode the banner payload.\n *****************************************************************************/\nstatic const char *\nnormalize_ndjson_string(const unsigned char *px, size_t length,\n                       char *buf, size_t buf_len)\n{\n    size_t i=0;\n    size_t offset = 0;\n\n\n    for (i=0; i<length; i++) {\n        unsigned char c = px[i];\n\n        if (isprint(c) && c != '<' && c != '>' && c != '&' && c != '\\\\' && c != '\\\"' && c != '\\'') {\n            if (offset + 2 < buf_len)\n                buf[offset++] = px[i];\n        } else {\n            if (offset + 7 < buf_len) {\n                buf[offset++] = '\\\\';\n                buf[offset++] = 'u';\n                buf[offset++] = '0';\n                buf[offset++] = '0';\n                buf[offset++] = \"0123456789abcdef\"[px[i]>>4];\n                buf[offset++] = \"0123456789abcdef\"[px[i]&0xF];\n            }\n        }\n    }\n\n    buf[offset] = '\\0';\n\n    return buf;\n}\n\n/******************************************************************************\n ******************************************************************************/\nstatic void\nndjson_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n                 ipaddress ip, unsigned ip_proto, unsigned port,\n                 enum ApplicationProtocol proto,\n                 unsigned ttl,\n                 const unsigned char *px, unsigned length)\n{\n    char banner_buffer[65536];\n    ipaddress_formatted_t fmt;\n\n    UNUSEDPARM(ttl);\n    //UNUSEDPARM(timestamp);\n\n    fprintf(fp, \"{\");\n    fmt = ipaddress_fmt(ip);\n    fprintf(fp, \"\\\"ip\\\":\\\"%s\\\",\", fmt.string);\n    fprintf(fp, \"\\\"timestamp\\\":\\\"%d\\\",\\\"port\\\":%u,\\\"proto\\\":\\\"%s\\\",\\\"rec_type\\\":\\\"banner\\\",\\\"data\\\":{\\\"service_name\\\":\\\"%s\\\",\\\"banner\\\":\\\"%s\\\"}\",\n            (int) timestamp,\n            port,\n            name_from_ip_proto(ip_proto),\n            masscan_app_to_string(proto),\n            normalize_ndjson_string(px, length, banner_buffer, sizeof(banner_buffer))\n            );\n    // fprintf(fp, \"\\\"timestamp\\\":\\\"%d\\\",\\\"ports\\\":[{\\\"port\\\":%u,\\\"proto\\\":\\\"%s\\\",\\\"service\\\":{\\\"name\\\":\\\"%s\\\",\\\"banner\\\":\\\"%s\\\"}}]\",\n    //         (int) timestamp,\n    //         port,\n    //         name_from_ip_proto(ip_proto),\n    //         masscan_app_to_string(proto),\n    //         normalize_ndjson_string(px, length, banner_buffer, sizeof(banner_buffer))\n    //         );\n    fprintf(fp, \"}\\n\");\n\n    UNUSEDPARM(out);\n\n/*    fprintf(fp, \"<host endtime=\\\"%u\\\">\"\n            \"<address addr=\\\"%u.%u.%u.%u\\\" addrtype=\\\"ipv4\\\"/>\"\n            \"<ports>\"\n            \"<port protocol=\\\"%s\\\" portid=\\\"%u\\\">\"\n            \"<state state=\\\"open\\\" reason=\\\"%s\\\" reason_ttl=\\\"%u\\\" />\"\n            \"<service name=\\\"%s\\\" banner=\\\"%s\\\"></service>\"\n            \"</port>\"\n            \"</ports>\"\n            \"</host>\"\n            \"\\r\\n\",\n            (unsigned)timestamp,\n            (ip>>24)&0xFF,\n            (ip>>16)&0xFF,\n            (ip>> 8)&0xFF,\n            (ip>> 0)&0xFF,\n            name_from_ip_proto(ip_proto),\n            port,\n            reason, ttl,\n            masscan_app_to_string(proto),\n            normalize_string(px, length, banner_buffer, sizeof(banner_buffer))\n            );*/\n}\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType ndjson_output = {\n    \"ndjson\",\n    0,\n    ndjson_out_open,\n    ndjson_out_close,\n    ndjson_out_status,\n    ndjson_out_banner\n};\n"
  },
  {
    "path": "src/out-null.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n\n\n/****************************************************************************\n * This function doesn't really \"open\" the file. Instead, the purpose of\n * this function is to initialize the file by printing header information.\n ****************************************************************************/\nstatic void\nnull_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n}\n\n/****************************************************************************\n * This function doesn't really \"close\" the file. Instead, it's purpose\n * is to print trailing information to the file. This is pretty much only\n * a concern for XML files that need stuff appended to the end.\n ****************************************************************************/\nstatic void\nnull_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n}\n\n/****************************************************************************\n * Prints out the status of a port, which is almost always just \"open\"\n * or \"closed\".\n ****************************************************************************/\nstatic void\nnull_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(status);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(port);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(ttl);\n\n}\n\n/****************************************************************************\n * Prints out \"banner\" information for a port. This is done when there is\n * a protocol defined for a port, and we do some interaction to find out\n * more information about which protocol is running on a port, it's version,\n * and other useful information.\n ****************************************************************************/\nstatic void\nnull_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(port);\n    UNUSEDPARM(proto);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n\n}\n\n\n/****************************************************************************\n * This is the only structure exposed to the rest of the system. Everything\n * else in the file is defined 'static' or 'private'.\n ****************************************************************************/\nconst struct OutputType null_output = {\n    \"null\",\n    0,\n    null_out_open,\n    null_out_close,\n    null_out_status,\n    null_out_banner\n};\n"
  },
  {
    "path": "src/out-record.h",
    "content": "#ifndef OUT_RECORD_H\n#define OUT_RECORD_H\n\nenum OutputRecordType {\n    Out_Open = 1,\n    Out_Closed = 2,\n    Out_Banner1 = 5,\n    Out_Open2 = 6,\n    Out_Closed2 = 7,\n    Out_Arp2 = 8,\n    Out_Banner9 = 9,\n    Out_Open6 = 10,\n    Out_Closed6 = 11,\n    Out_Arp6 = 12,\n    Out_Banner6 = 13,\n\n};\n#endif\n"
  },
  {
    "path": "src/out-redis.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n#include \"pixie-sockets.h\"\n#include \"util-logger.h\"\n#include <ctype.h>\n\n/****************************************************************************\n * Receive a full line from the socket\n ****************************************************************************/\nstatic size_t\nrecv_line(SOCKET fd, void *buf, size_t buf_size)\n{\n    size_t count = 0;\n\n    while (count < buf_size) {\n        size_t bytes_received;\n\n        bytes_received = recv(fd, (char*)buf+count, 1, 0);\n        if (bytes_received == 0) {\n            LOG(0, \"redis: recv_line() failed\\n\");\n            exit(1);\n        }\n        count++;\n        if (((unsigned char*)buf)[count-1] == '\\n')\n            break;\n    }\n\n    return count;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic int\nparse_state_machine(struct Output *out, const unsigned char *px, size_t length)\n{\n    unsigned state = out->redis.state;\n    unsigned i;\n    enum {\n        START,\n        NUMBER,\n        P,\n        PO,\n        PON,\n        PONG,\n        PONG_CR,\n        PONG_CR_LF\n    };\n\n    for (i=0; i<length; i++)\n    switch (state) {\n    case START:\n        switch (px[i]) {\n        case '+':\n            state = P;\n            break;\n        case ':':\n            state = NUMBER;\n            break;\n        default:\n            LOG(0, \"redis: unexpected data: %.*s\\n\", (int)(length-i), px+i);\n            exit(1);\n            break;\n        }\n        break;\n    case NUMBER:\n        if (isdigit(px[i]) || px[i] == '\\r')\n            ;\n        else if (px[i] == '\\n') {\n            state = 0;\n            if (out->redis.outstanding == 0) {\n                LOG(0, \"redis: out of sync\\n\");\n                exit(1);\n            }\n            out->redis.outstanding--;\n        } else {\n            LOG(0, \"redis: unexpected data: %.*s\\n\", (int)(length-i), px+i);\n            exit(1);\n        }\n        break;\n    case P:\n    case PO:\n    case PON:\n    case PONG_CR:\n    case PONG_CR_LF:\n        if (\"PONG+\\r\\n\"[i-P] == px[i]) {\n            state++;\n            if (px[i] == '\\n') {\n                out->redis.state = 0;\n                return 1;\n            }\n        } else {\n            LOG(0, \"redis: unexpected data: %.*s\\n\", (int)(length-i), px+i);\n            exit(1);\n        }\n    default:\n        LOG(0, \"redis: unexpected state: %u\\n\", state);\n        exit(1);\n    }\n    out->redis.state = state;\n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic int\nclean_response_queue(struct Output *out, SOCKET fd)\n{\n    fd_set readfds;\n    struct timeval tv = {0,0};\n    int x;\n    int nfds;\n    unsigned char buf[1024];\n    size_t bytes_read;\n\n    FD_ZERO(&readfds);\n#ifdef _MSC_VER\n#pragma warning(disable:4127)\n#endif\n    FD_SET(fd, &readfds);\n    nfds = (int)fd;\n\n    x = select(nfds, &readfds, 0, 0, &tv);\n    if (x == 0)\n        return 1;\n    if (x < 0) {\n        LOG(0, \"redis:select() failed\\n\");\n        exit(1);\n    }\n    if (x != 1) {\n        LOG(0, \"redis:select() failed\\n\");\n        exit(1);\n    }\n\n    /*\n     * Data exists, so parse it\n     */\n    bytes_read = recv(fd, (char*)buf, sizeof(buf), 0);\n    if (bytes_read == 0) {\n        LOG(0, \"redis:recv() failed\\n\");\n        exit(1);\n    }\n\n    return parse_state_machine(out, buf, bytes_read);\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nredis_out_open(struct Output *out, FILE *fp)\n{\n    /*FIXME: why did I write this code using ptrdiff_t? */\n    ptrdiff_t fd = (ptrdiff_t)fp;\n    size_t count;\n    char line[1024];\n\n    UNUSEDPARM(out);\n    if (out->redis.password != NULL)\n    {\n        snprintf(line, sizeof(line),\n                  \"*2\\r\\n\"\n                  \"$4\\r\\nAUTH\\r\\n\"\n                  \"$%u\\r\\n%s\\r\\n\",\n                  (unsigned)strlen(out->redis.password), out->redis.password);\n\n        count = send((SOCKET)fd, line, (int)strlen(line), 0);\n        if (count != strlen(line))\n        {\n            LOG(0, \"redis: error auth\\n\");\n            exit(1);\n        }\n\n        count = recv_line((SOCKET)fd, line, sizeof(line));\n        if (count != 5 && memcmp(line, \"+OK\\r\\n\", 5) != 0)\n        {\n            LOG(0, \"redis: unexpected response from redis server: %s\\n\", line);\n            exit(1);\n        }\n    }\n\n    count = send((SOCKET)fd, \"PING\\r\\n\", 6, 0);\n    if (count != 6) {\n        LOG(0, \"redis: send(ping) failed\\n\");\n        exit(1);\n    }\n\n    count = recv_line((SOCKET)fd, line, sizeof(line));\n    if (count != 7 && memcmp(line, \"+PONG\\r\\n\", 7) != 0) {\n        LOG(0, \"redis: unexpected response from redis server: %s\\n\", line);\n        exit(1);\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nredis_out_close(struct Output *out, FILE *fp)\n{\n    ptrdiff_t fd = (ptrdiff_t)fp;\n    size_t count;\n    unsigned char line[1024];\n\n    UNUSEDPARM(out);\n\n    count = send((SOCKET)fd, \"QUIT\\r\\n\", 6, 0);\n    if (count != 6) {\n        LOG(0, \"redis: send(quit) failed\\n\");\n        exit(1);\n    }\n\n    count = recv_line((SOCKET)fd, line, sizeof(line));\n    if ((count != 5 && memcmp(line, \"+OK\\r\\n\", 5) != 0) && (count != 4 && memcmp(line, \":0\\r\\n\", 4) != 0)){\n        LOG(0, \"redis: unexpected response from redis server: %s\\n\", line);\n        exit(1);\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nredis_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    ptrdiff_t fd = (ptrdiff_t)fp;\n    char line[1024];\n    int line_length;\n    char ip_string[64];\n    char port_string[10];\n    int ip_string_length;\n    int port_string_length;\n    size_t count;\n    char values[64];\n    int values_length;\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n\n    ip_string_length = snprintf(ip_string, sizeof(ip_string), \"%s\", fmt.string);\n    port_string_length = snprintf(port_string, sizeof(port_string), \"%u/%s\", port, name_from_ip_proto(ip_proto));\n\n/**3\n$3\nSET\n$5\nmykey\n$7\nmyvalue\n*/\n\n    /*\n     * KEY: \"host\"\n     * VALUE: ip\n     */\n    snprintf(line, sizeof(line),\n            \"*3\\r\\n\"\n            \"$4\\r\\nSADD\\r\\n\"\n            \"$%d\\r\\n%s\\r\\n\"\n            \"$%d\\r\\n%s\\r\\n\"\n            ,\n            4, \"host\",\n            ip_string_length, ip_string\n            );\n\n    count = send((SOCKET)fd, line, (int)strlen(line), 0);\n    if (count != strlen(line)) {\n        LOG(0, \"redis: error sending data\\n\");\n        exit(1);\n    }\n    out->redis.outstanding++;\n\n    /*\n     * KEY: ip\n     * VALUE: port\n     */\n    snprintf(line, sizeof(line),\n            \"*3\\r\\n\"\n            \"$4\\r\\nSADD\\r\\n\"\n            \"$%d\\r\\n%s\\r\\n\"\n            \"$%d\\r\\n%s\\r\\n\"\n            ,\n            ip_string_length, ip_string,\n            port_string_length, port_string);\n\n    count = send((SOCKET)fd, line, (int)strlen(line), 0);\n    if (count != strlen(line)) {\n        LOG(0, \"redis: error sending data\\n\");\n        exit(1);\n    }\n    out->redis.outstanding++;\n\n\n    /*\n     * KEY: ip:port\n     * VALUE: timestamp:status:reason:ttl\n     */\n    values_length = snprintf(values, sizeof(values), \"%u:%u:%u:%u\",\n        (unsigned)timestamp, status, reason, ttl);\n    line_length = snprintf(line, sizeof(line),\n            \"*3\\r\\n\"\n            \"$4\\r\\nSADD\\r\\n\"\n            \"$%d\\r\\n%s:%s\\r\\n\"\n            \"$%d\\r\\n%s\\r\\n\"\n            ,\n            ip_string_length + 1 + port_string_length,\n            ip_string, port_string,\n            values_length, values\n            );\n\n    count = send((SOCKET)fd, line, (int)line_length, 0);\n    if (count != (size_t)line_length) {\n        LOG(0, \"redis: error sending data\\n\");\n        exit(1);\n    }\n    out->redis.outstanding++;\n\n    clean_response_queue(out, (SOCKET)fd);\n\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nredis_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(port);\n    UNUSEDPARM(proto);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType redis_output = {\n    \"redis\",\n    0,\n    redis_out_open,\n    redis_out_close,\n    redis_out_status,\n    redis_out_banner\n};\n\n\n\n"
  },
  {
    "path": "src/out-tcp-services.c",
    "content": "#include \"out-tcp-services.h\"\n#include <string.h>\n#include <stdlib.h>\n\n#ifndef WIN32\n#include <netdb.h>\n#else\n#include <WinSock2.h>\n#endif\n#include <ctype.h>\n\n/**\n * This is a stupid hack to avoid dependencies. I want to minimize the dependence\n * on network libraries. For example, I get a warning message on FreeBSD about\n * a missing `htons()`. I could just add a system header, but then this increases\n * dependencies on other things. Alternatively, I could just implement the\n * function myself. So I chose that route.\n */\nstatic unsigned short my_htons(unsigned port)\n{\n    static const char test[3] = \"\\x11\\x22\";\n    if (*(unsigned short*)test == 0x1122)\n        return (unsigned short)(0xFFFF & port);\n    else\n        return (unsigned short)((port>>8)&0xFF) | ((port&0xFF)<<8);\n}\n\n#if _MSC_VER\n#define strdup _strdup\n#endif\n\nstatic char *tcp_services[65536];\nstatic char *udp_services[65536];\nstatic char *oproto_services[256];\n\n\nconst char *\ntcp_service_name(int port)\n{\n    if (tcp_services[port])\n        return tcp_services[port];\n\n#if defined(__linux__) && !defined(__TERMUX__)\n    int r;\n    struct servent result_buf;\n    struct servent *result;\n    char buf[2048];\n    \n    r = getservbyport_r(my_htons(port), \"tcp\", &result_buf,buf, sizeof(buf), &result);\n    \n    /* ignore ERANGE - if the result can't fit in 2k, just return unknown */\n    if (r != 0 || result == NULL)\n        return \"unknown\";\n    \n    return tcp_services[port] = strdup(result_buf.s_name);\n#else\n    {\n    struct servent *result;\n    \n    result = getservbyport(my_htons((unsigned short)port), \"tcp\");\n    \n    if (result == 0)\n        return \"unknown\";\n    \n    return tcp_services[port] = strdup(result->s_name);\n    }\n#endif\n}\n\nconst char *\nudp_service_name(int port)\n{\n    if (udp_services[port])\n        return udp_services[port];\n#if defined(__linux__) && !defined(__TERMUX__)\n    int r;\n    struct servent result_buf;\n    struct servent *result;\n    char buf[2048];\n    \n    r = getservbyport_r(my_htons(port), \"udp\", &result_buf,buf, sizeof(buf), &result);\n    \n    /* ignore ERANGE - if the result can't fit in 2k, just return unknown */\n    if (r != 0 || result == NULL)\n        return \"unknown\";\n    \n    return udp_services[port] = strdup(result_buf.s_name);\n#else\n    {\n    struct servent *result;\n    \n    result = getservbyport(my_htons((unsigned short)port), \"udp\");\n    \n    if (result == 0)\n        return \"unknown\";\n    \n    return udp_services[port] = strdup(result->s_name);\n    }\n#endif\n}\n\nconst char *\noproto_service_name(int port)\n{\n    if (oproto_services[port])\n        return oproto_services[port];\n    {\n        struct protoent *result;\n        \n        result = getprotobynumber(port);\n        \n        if (result == 0)\n            return \"unknown\";\n        \n        return oproto_services[port] = strdup(result->p_name);\n    }\n}\n"
  },
  {
    "path": "src/out-tcp-services.h",
    "content": "#ifndef OUT_TCP_SERVICES_H\n#define OUT_TCP_SERVICES_H\n\nconst char *tcp_service_name(int port);\nconst char *udp_service_name(int port);\nconst char *oproto_service_name(int protocol_number);\n\n#endif\n\n"
  },
  {
    "path": "src/out-text.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"unusedparm.h\"\n\n#include <ctype.h>\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ntext_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"#masscan\\n\");\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ntext_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"# end\\n\");\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ntext_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(out);\n\n\n    fprintf(fp, \"%s %s %u %s %u\\n\",\n        status_string(status),\n        name_from_ip_proto(ip_proto),\n        port,\n        fmt.string,\n        (unsigned)timestamp\n        );\n}\n\n\n/*************************************** *************************************\n ****************************************************************************/\nstatic void\ntext_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    char banner_buffer[MAX_BANNER_LENGTH];\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n\n\n    UNUSEDPARM(out);\n    UNUSEDPARM(ttl);\n\n    fprintf(fp, \"%s %s %u %s %u %s %s\\n\",\n        \"banner\",\n        name_from_ip_proto(ip_proto),\n        port,\n        fmt.string,\n        (unsigned)timestamp,\n        masscan_app_to_string(proto),\n        normalize_string(px, length, banner_buffer, sizeof(banner_buffer))\n        );\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType text_output = {\n    \"txt\",\n    0,\n    text_out_open,\n    text_out_close,\n    text_out_status,\n    text_out_banner\n};\n\n\n\n"
  },
  {
    "path": "src/out-unicornscan.c",
    "content": "#include \"output.h\"\n#include \"masscan.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"unusedparm.h\"\n#include \"out-tcp-services.h\"\n\n\n\n\n\nstatic void\nunicornscan_out_open(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"#masscan\\n\");\n}\n\n\nstatic void\nunicornscan_out_close(struct Output *out, FILE *fp)\n{\n    UNUSEDPARM(out);\n    fprintf(fp, \"# end\\n\");\n}\n\nstatic void\nunicornscan_out_status(struct Output *out, FILE *fp, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n    UNUSEDPARM(reason);\n    UNUSEDPARM(out);\n    UNUSEDPARM(timestamp);\n\n    if (ip_proto == 6) {\n        fprintf(fp,\"TCP %s\\t%16s[%5d]\\t\\tfrom %s  ttl %-3d\\n\",\n              status_string(status),\n              tcp_service_name(port),\n              port,\n              fmt.string,\n              ttl);\n    } else {\n        /* unicornscan is TCP only, so just use grepable format for other protocols */\n        fprintf(fp, \"Host: %s ()\", fmt.string);\n        fprintf(fp, \"\\tPorts: %u/%s/%s/%s/%s/%s/%s\\n\",\n                port,\n                status_string(status),      //\"open\", \"closed\"\n                name_from_ip_proto(ip_proto),  //\"tcp\", \"udp\", \"sctp\"\n                \"\", //owner\n                \"\", //service\n                \"\", //SunRPC info\n                \"\" //Version info\n                );\n    }\n}\n\n\n/*************************************** *************************************\n ****************************************************************************/\nstatic void\nunicornscan_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, unsigned ttl,\n        const unsigned char *px, unsigned length)\n{ /* SYN only - no banner */\n    UNUSEDPARM(out);\n    UNUSEDPARM(ttl);\n    UNUSEDPARM(port);\n    UNUSEDPARM(fp);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(ip);\n    UNUSEDPARM(ip_proto);\n    UNUSEDPARM(proto);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n\n    return;\n} \n \n\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType unicornscan_output = {\n    \"uni\",\n    0,\n    unicornscan_out_open,\n    unicornscan_out_close,\n    unicornscan_out_status,\n    unicornscan_out_banner\n};\n\n\n\n"
  },
  {
    "path": "src/out-xml.c",
    "content": "#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"masscan-status.h\"\n#include \"util-safefunc.h\"\n\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nxml_out_open(struct Output *out, FILE *fp)\n{\n    //const struct Masscan *masscan = out->masscan;\n\n    fprintf(fp, \"<?xml version=\\\"1.0\\\"?>\\r\\n\");\n    fprintf(fp, \"<!-- masscan v1.0 scan -->\\r\\n\");\n    if (out->xml.stylesheet && out->xml.stylesheet[0]) {\n        fprintf(fp, \"<?xml-stylesheet href=\\\"%s\\\" type=\\\"text/xsl\\\"?>\\r\\n\",\n            out->xml.stylesheet);\n    }\n    fprintf(fp, \"<nmaprun scanner=\\\"%s\\\" start=\\\"%u\\\" version=\\\"%s\\\"  xmloutputversion=\\\"%s\\\">\\r\\n\",\n        \"masscan\",\n        (unsigned)time(0),\n        \"1.0-BETA\",\n        \"1.03\" /* xml output version I copied from their site */\n        );\n    fprintf(fp, \"<scaninfo type=\\\"%s\\\" protocol=\\\"%s\\\" />\\r\\n\",\n        \"syn\", \"tcp\" );\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nxml_out_close(struct Output *out, FILE *fp)\n{\n    char buffer[256];\n    time_t now = time(0);\n    struct tm tm;\n\n    if (out->is_gmt)\n        safe_gmtime(&tm, &now);\n    else\n        safe_localtime(&tm, &now);\n    strftime(buffer, sizeof(buffer), \"%Y-%m-%d %H:%M:%S\", &tm);\n\n    fprintf(fp,\n             \"<runstats>\\r\\n\"\n              \"<finished time=\\\"%u\\\" timestr=\\\"%s\\\" elapsed=\\\"%u\\\" />\\r\\n\"\n              \"<hosts up=\\\"%\" PRIu64 \"\\\" down=\\\"%\" PRIu64 \"\\\" total=\\\"%\" PRIu64 \"\\\" />\\r\\n\"\n             \"</runstats>\\r\\n\"\n            \"</nmaprun>\\r\\n\",\n            (unsigned)now,                    /* time */\n            buffer,                 /* timestr */\n            (unsigned)(now - out->rotate.last), /* elapsed */\n            out->counts.tcp.open,\n            out->counts.tcp.closed,\n            out->counts.tcp.open + out->counts.tcp.closed\n            );\n\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nxml_out_status(struct Output *out, FILE *fp, time_t timestamp, int status,\n               ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)\n{\n    char reason_buffer[128];\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n    \n    UNUSEDPARM(out);\n    fprintf(fp, \"<host endtime=\\\"%u\\\">\"\n                    \"<address addr=\\\"%s\\\" addrtype=\\\"ipv4\\\"/>\"\n                    \"<ports>\"\n                    \"<port protocol=\\\"%s\\\" portid=\\\"%u\\\">\"\n                    \"<state state=\\\"%s\\\" reason=\\\"%s\\\" reason_ttl=\\\"%u\\\"/>\"\n                    \"</port>\"\n                    \"</ports>\"\n                \"</host>\"\n                \"\\r\\n\",\n        (unsigned)timestamp,\n        fmt.string,\n        name_from_ip_proto(ip_proto),\n        port,\n        status_string(status),\n        reason_string(reason, reason_buffer, sizeof(reason_buffer)),\n        ttl\n        );\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nxml_out_banner(struct Output *out, FILE *fp, time_t timestamp,\n        ipaddress ip, unsigned ip_proto, unsigned port,\n        enum ApplicationProtocol proto, \n        unsigned ttl,\n        const unsigned char *px, unsigned length)\n{\n    char banner_buffer[MAX_BANNER_LENGTH];\n    const char *reason;\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n\n    switch (proto) {\n    case 6: reason = \"syn-ack\"; break;\n    default: reason = \"response\"; break;\n    }\n\n    UNUSEDPARM(out);\n\n    fprintf(fp, \"<host endtime=\\\"%u\\\">\"\n                    \"<address addr=\\\"%s\\\" addrtype=\\\"ipv4\\\"/>\"\n                    \"<ports>\"\n                    \"<port protocol=\\\"%s\\\" portid=\\\"%u\\\">\"\n                      \"<state state=\\\"open\\\" reason=\\\"%s\\\" reason_ttl=\\\"%u\\\" />\"\n                      \"<service name=\\\"%s\\\" banner=\\\"%s\\\"></service>\"\n                    \"</port>\"\n                    \"</ports>\"\n                \"</host>\"\n                \"\\r\\n\",\n        (unsigned)timestamp,\n        fmt.string,\n        name_from_ip_proto(ip_proto),\n        port,\n        reason, ttl,\n        masscan_app_to_string(proto),\n        normalize_string(px, length, banner_buffer, sizeof(banner_buffer))\n        );\n}\n\n/****************************************************************************\n ****************************************************************************/\nconst struct OutputType xml_output = {\n    \"xml\",\n    0,\n    xml_out_open,\n    xml_out_close,\n    xml_out_status,\n    xml_out_banner\n};\n\n"
  },
  {
    "path": "src/output.c",
    "content": "/*\n    output logging/reporting\n\n    This is the file that formats the output files -- that is to say,\n    where we report everything we find.\n\n    PLUGINS\n\n    The various types of output (XML, binary, Redis, etc.) are written vaguely\n    as \"plugins\", which means as a structure with function pointers. In the\n    future, it should be possible to write plugins as DDLs/shared-objects\n    and load them at runtime, but right now, they are just hard coded.\n\n    ROTATE\n\n    Files can be \"rotated\". This is done by prefixing the file with the\n    date/time when the file was created.\n\n    A key feature of this design is to prevent files being lost during\n    rotation. Therefore, the files are renamed while they are still open.\n    If the rename function fails, then the file is left in-place and still\n    open for writing, with continued appending to the file.\n\n    Thus, you could start the program logging to \"--rotate-dir ../foobar\"\n    and then notice the error messages saying that rotating isn't working,\n    then go create the \"foobar\" directory, at which point rotating will now\n    work -- it's just that the first rotated file will contain several\n    periods of data.\n*/\n\n/* Needed for Linux to make offsets 64 bits */\n#define _FILE_OFFSET_BITS 64\n\n#include \"output.h\"\n#include \"masscan.h\"\n#include \"masscan-status.h\"\n#include \"proto-banner1.h\"\n#include \"masscan-app.h\"\n#include \"main-globals.h\"\n#include \"pixie-file.h\"\n#include \"pixie-sockets.h\"\n#include \"util-malloc.h\"\n#include \"util-errormsg.h\"\n#include \"util-logger.h\"\n\n#include <limits.h>\n#include <ctype.h>\n#include <string.h>\n\n/* Put this at the bottom of the include lists because of warnings */\n#include \"util-safefunc.h\"\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int64_t ftell_x(FILE *fp)\n{\n#if defined(WIN32) && defined(__GNUC__)\n    return ftello64(fp);\n#elif defined(WIN32) && defined(_MSC_VER)\n    return _ftelli64(fp);\n#else\n    return ftello(fp);\n#endif\n}\n\n/*****************************************************************************\n * The 'status' variable contains both the open/closed info as well as the\n * protocol info. This splits it back out into two values.\n *****************************************************************************/\nconst char *\nname_from_ip_proto(unsigned ip_proto)\n{\n    switch (ip_proto) {\n        case 0: return \"arp\";\n        case 1: return \"icmp\";\n        case 6: return \"tcp\";\n        case 17: return \"udp\";\n        case 132: return \"sctp\";\n        default: return \"err\";\n    }\n}\n\n\n/*****************************************************************************\n * The actual 'status' variable is narrowly defined depending on the\n * underlying protocol. This function creates a gross \"open\" v. \"closed\"\n * string based on the narrow variable.\n *****************************************************************************/\nconst char *\nstatus_string(enum PortStatus status)\n{\n    switch (status) {\n        case PortStatus_Open: return \"open\";\n        case PortStatus_Closed: return \"closed\";\n        case PortStatus_Arp: return \"up\";\n        default: return \"unknown\";\n    }\n}\n\n\n/*****************************************************************************\n * Convert TCP flags into an nmap-style \"reason\" string\n *****************************************************************************/\nconst char *\nreason_string(int x, char *buffer, size_t sizeof_buffer)\n{\n    snprintf(buffer, sizeof_buffer, \"%s%s%s%s%s%s%s%s\",\n        (x&0x01)?\"fin-\":\"\",\n        (x&0x02)?\"syn-\":\"\",\n        (x&0x04)?\"rst-\":\"\",\n        (x&0x08)?\"psh-\":\"\",\n        (x&0x10)?\"ack-\":\"\",\n        (x&0x20)?\"urg-\":\"\",\n        (x&0x40)?\"ece-\":\"\",\n        (x&0x80)?\"cwr-\":\"\"\n        );\n    if (buffer[0] == '\\0')\n        return \"none\";\n    else\n        buffer[strlen(buffer)-1] = '\\0';\n    return buffer;\n}\n\n\n/*****************************************************************************\n * Remove bad characters from the banner, especially new lines and HTML\n * control codes.\n *****************************************************************************/\nconst char *\nnormalize_string(const unsigned char *px, size_t length,\n                 char *buf, size_t buf_len)\n{\n    size_t i=0;\n    size_t offset = 0;\n\n\n    for (i=0; i<length; i++) {\n        unsigned char c = px[i];\n\n        if (isprint(c) && c != '<' && c != '>' && c != '&' && c != '\\\\' && c != '\\\"' && c != '\\'') {\n            if (offset + 2 < buf_len)\n                buf[offset++] = px[i];\n        } else {\n            if (offset + 5 < buf_len) {\n                buf[offset++] = '\\\\';\n                buf[offset++] = 'x';\n                buf[offset++] = \"0123456789abcdef\"[px[i]>>4];\n                buf[offset++] = \"0123456789abcdef\"[px[i]&0xF];\n            }\n        }\n    }\n\n    buf[offset] = '\\0';\n\n    return buf;\n}\n\n\n/*****************************************************************************\n * PORTABILITY: WINDOWS\n *\n * Windows POSIX functions open the file without the \"share-delete\" flag,\n * meaning they can't be renamed while open. Therefore, we need to\n * construct our own open flag.\n *****************************************************************************/\nstatic FILE *\nopen_rotate(struct Output *out, const char *filename)\n{\n    FILE *fp = 0;\n    unsigned is_append = out->is_append;\n    int x;\n\n    /*\n     * KLUDGE: do something special for redis\n     */\n    if (out->format == Output_Redis) {\n        ptrdiff_t fd = out->redis.fd;\n        if (fd < 1) {\n            struct sockaddr_in sin = {0};\n            fd = (ptrdiff_t)socket(AF_INET, SOCK_STREAM, 0);\n            if (fd == -1) {\n                LOG(0, \"redis: socket() failed to create socket\\n\");\n                exit(1);\n            }\n            sin.sin_addr.s_addr = htonl(out->redis.ip.ipv4); /* TODO: IPv6 */\n            sin.sin_port = htons((unsigned short)out->redis.port);\n            sin.sin_family = AF_INET;\n            x = connect((SOCKET)fd, (struct sockaddr*)&sin, sizeof(sin));\n            if (x != 0) {\n                LOG(0, \"redis: connect() failed\\n\");\n                perror(\"connect\");\n            }\n            out->redis.fd = fd;\n        }\n        out->funcs->open(out, (FILE*)fd);\n\n        return (FILE*)fd;\n    }\n\n    /* Do something special for the \"-\" filename */\n    if (filename[0] == '-' && filename[1] == '\\0')\n        fp = stdout;\n\n    /* open a \"shareable\" file. On Windows, by default files can't be renamed\n     * while they are open, so we need a special function that takes care\n     * of this. */\n    if (fp == 0) {\n        x = pixie_fopen_shareable(&fp, filename, is_append);\n        if (x != 0 || fp == NULL) {\n            fprintf(stderr, \"out: could not open file for %s\\n\",\n                    is_append?\"appending\":\"writing\");\n            perror(filename);\n            is_tx_done = 1;\n            return NULL;\n        }\n    }\n\n    /*\n     * Mark the file as newly opened. That way, before writing any data\n     * to it, we'll first have to write headers\n     */\n    out->is_virgin_file = 1;\n\n    return fp;\n}\n\n\n/*****************************************************************************\n * Write the remaining data the file and close it. This function is\n * called \"rotate\", but it doesn't actually rotate, this name just reflects\n * how it's used in the rotate process.\n *****************************************************************************/\nstatic void\nclose_rotate(struct Output *out, FILE *fp)\n{\n    if (out == NULL)\n        return;\n    if (fp == NULL)\n        return;\n\n    /*\n     * Write the format-specific trailers, like </xml>\n     */\n    if (!out->is_virgin_file)\n        out->funcs->close(out, fp);\n\n    memset(&out->counts, 0, sizeof(out->counts));\n\n    /* Redis Kludge*/\n    if (out->format == Output_Redis)\n        return;\n\n    fflush(fp);\n    fclose(fp);\n}\n\n\n/*****************************************************************************\n * Returns the time when the next rotate should occur. Rotations are\n * aligned to the period, which means that if you rotate hourly, it's done\n * on the hour every hour, like at 9:00:00 o'clock exactly. In other words,\n * a period of \"hourly\" doesn't really mean \"every 60 minutes\", but\n * on the hour\". Since the program will be launched midway in a period,\n * that means the first rotation will happen in less than a full period.\n *****************************************************************************/\nstatic time_t\nnext_rotate_time(time_t last_rotate, unsigned period, unsigned offset)\n{\n    time_t next;\n\n    next = last_rotate - (last_rotate % period) + period + offset;\n\n    return next;\n}\n\n\n#if 0\n/*****************************************************************************\n *****************************************************************************/\nstatic int\nends_with(const char *filename, const char *extension)\n{\n    if (filename == NULL || extension == NULL)\n        return 0;\n    if (strlen(filename) + 1 < strlen(extension))\n        return 0;\n    if (memcmp(filename + strlen(filename) - strlen(extension),\n                extension, strlen(extension)) != 0)\n        return 0;\n    if (filename[strlen(filename) - strlen(extension) - 1] != '.')\n        return 0;\n\n    return 1;\n}\n#endif\n\n/*****************************************************************************\n * strdup(): compilers don't like strdup(), so I just write my own here. I\n * should probably find a better solution.\n *****************************************************************************/\nstatic char *\nduplicate_string(const char *str)\n{\n    size_t length;\n    char *result;\n\n    /* Find the length of the string. We allow NULL strings, in which case\n     * the length is zero */\n    if (str == NULL)\n        length = 0;\n    else\n        length = strlen(str);\n\n    /* Allocate memory for the string */\n    result = MALLOC(length + 1);\n    \n\n    /* Copy the string */\n    if (str)\n        memcpy(result, str, length+1);\n    result[length] = '\\0';\n\n    return result;\n}\n\n/*****************************************************************************\n * Adds the index variable to just before the file extension. For example,\n * if the original filename is \"foo.bar\", and the index is 1, then the\n * new filename becomes \"foo.01.bar\". By putting the index before the\n * extension, it preserves the file type. By prepending a zero on the index,\n * it allows up to 100 files while still being able to easily sort the files.\n *****************************************************************************/\nstatic char *\nindexed_filename(const char *filename, unsigned index)\n{\n    size_t len = strlen(filename);\n    size_t ext;\n    char *new_filename;\n    size_t new_length = strlen(filename) + 32;\n\n    /* find the extension */\n    ext = len;\n    while (ext) {\n        ext--;\n        if (filename[ext] == '.')\n            break;\n        if (filename[ext] == '/' || filename[ext] == '\\\\') {\n            /* no dot found, so ext is end of file */\n            ext = len;\n            break;\n        }\n    }\n    if (ext == 0 && len > 0 && filename[0] != '.')\n        ext = len;\n\n    /* allocate memory */\n    new_filename = MALLOC(new_length);\n    \n\n    /* format the new name */\n    snprintf(new_filename, new_length, \"%.*s.%02u%s\",\n              (unsigned)ext, filename,\n              index,\n              filename+ext);\n\n    return new_filename;\n\n}\n\n/*****************************************************************************\n * Create an \"output\" structure. If we are writing a file, we create the\n * file now, so that any errors creating the file are caught immediately,\n * rather than later in the scan when it might fail.\n *****************************************************************************/\nstruct Output *\noutput_create(const struct Masscan *masscan, unsigned thread_index)\n{\n    struct Output *out;\n    unsigned i;\n\n    /* allocate/initialize memory */\n    out = CALLOC(1, sizeof(*out));\n    out->masscan = masscan;\n    out->when_scan_started = time(0);\n    out->is_virgin_file = 1;\n\n    /*\n     * Copy the configuration information from the 'masscan' structure.\n     */\n    out->rotate.period = masscan->output.rotate.timeout;\n    out->rotate.offset = masscan->output.rotate.offset;\n    out->rotate.filesize = masscan->output.rotate.filesize;\n    out->redis.port = masscan->redis.port;\n    out->redis.ip = masscan->redis.ip;\n    out->redis.password = masscan ->redis.password;\n    out->is_banner = masscan->is_banners;               /* --banners */\n    out->is_banner_rawudp = masscan->is_banners_rawudp; /* --rawudp */\n    out->is_gmt = masscan->is_gmt;\n    out->is_interactive = masscan->output.is_interactive;\n    out->is_show_open = masscan->output.is_show_open;\n    out->is_show_closed = masscan->output.is_show_closed;\n    out->is_show_host = masscan->output.is_show_host;\n    out->is_append = masscan->output.is_append;\n    out->xml.stylesheet = duplicate_string(masscan->output.stylesheet);\n    out->rotate.directory = duplicate_string(masscan->output.rotate.directory);\n    if (masscan->nic_count <= 1)\n        out->filename = duplicate_string(masscan->output.filename);\n    else\n        out->filename = indexed_filename(masscan->output.filename, thread_index);\n\n    for (i=0; i<8; i++) {\n        out->src[i] = masscan->nic[i].src;\n    }\n\n    /*\n     * Link the appropriate output module.\n     * TODO: support multiple output modules\n     */\n    out->format = masscan->output.format;\n    switch (out->format) {\n    case Output_List:\n        out->funcs = &text_output;\n        break;\n    case Output_Unicornscan:\n        out->funcs = &unicornscan_output;\n        break;\n    case Output_XML:\n        out->funcs = &xml_output;\n        break;\n    case Output_JSON:\n        out->funcs = &json_output;\n        break;\n    case Output_NDJSON:\n        out->funcs = &ndjson_output;\n        break;\n    case Output_Certs:\n        out->funcs = &certs_output;\n        break;\n    case Output_Binary:\n        out->funcs = &binary_output;\n        break;\n    case Output_Grepable:\n        out->funcs = &grepable_output;\n        break;\n    case Output_Redis:\n        out->funcs = &redis_output;\n        break;\n    case Output_Hostonly:\n        out->funcs = &hostonly_output;\n        break;\n    case Output_None:\n        out->funcs = &null_output;\n        break;\n    default:\n        out->funcs = &null_output;\n        break;\n    }\n\n    /*\n     * Open the desired output file. We do this now at the start of the scan\n     * so that we can immediately notify the user of an error, rather than\n     * waiting midway through a long scan and have it fail.\n     */\n    if (masscan->output.filename[0] && out->funcs != &null_output) {\n        FILE *fp;\n\n        fp = open_rotate(out, masscan->output.filename);\n        if (fp == NULL) {\n            perror(masscan->output.filename);\n            exit(1);\n        }\n\n        out->fp = fp;\n        out->rotate.last = time(0);\n    }\n\n    /*\n     * Set the time of the next rotation. If we aren't rotating files, then\n     * this time will be set at \"infinity\" in the future.\n     * TODO: this code isn't Y2036 compliant.\n     */\n    if (masscan->output.rotate.timeout == 0) {\n        /* TODO: how does one find the max time_t value??*/\n        out->rotate.next = (time_t)LONG_MAX;\n    } else {\n        if (out->rotate.offset > 1) {\n            out->rotate.next = next_rotate_time(\n                                    out->rotate.last-out->rotate.period,\n                                    out->rotate.period, out->rotate.offset);\n        } else {\n            out->rotate.next = next_rotate_time(\n                                    out->rotate.last,\n                                    out->rotate.period, out->rotate.offset);\n        }\n    }\n\n\n\n    return out;\n}\n\n\n/*****************************************************************************\n * Rotate the file, moving it from the local directory to a remote directory\n * and changing the name to include the timestamp. This is done while the file\n * is still open: we move the file and rename it first, then close it.\n *****************************************************************************/\nstatic FILE *\noutput_do_rotate(struct Output *out, int is_closing)\n{\n    const char *dir;\n    const char *filename;\n    char *new_filename;\n    size_t new_filename_size;\n    struct tm tm;\n    int err;\n\n    /* Don't do anything if there is no file */\n    if (out == NULL || out->fp == NULL)\n        return NULL;\n\n    dir = out->rotate.directory;\n    filename = out->filename;\n\n    /* Make sure that all output has been flushed to the file */\n    fflush(out->fp);\n\n    /* Remove directory prefix from filename, we just want the root filename\n     * to start with */\n    while (strchr(filename, '/')) {\n        filename = strchr(filename, '/');\n        if (*filename == '/')\n            filename++;\n    }\n\n    while (strchr(filename, '\\\\')) {\n        filename = strchr(filename, '\\\\');\n        if (*filename == '\\\\')\n            filename++;\n    }\n\n    /* Allocate memory for the new filename */\n    new_filename_size =     strlen(dir)\n                            + strlen(\"/\")\n                            + strlen(filename)\n                            + strlen(\"1308201101-\")\n                            + strlen(filename)\n                            + 1  /* - */\n                            + 1; /* null */\n    new_filename = MALLOC(new_filename_size);\n\n    /* Get the proper timestamp for the file */\n    if (out->is_gmt) {\n        err = safe_gmtime(&tm, &out->rotate.last);\n    } else {\n        err = safe_localtime(&tm, &out->rotate.last);\n    }\n    if (err != 0) {\n        free(new_filename);\n        perror(\"gmtime(): file rotation ended\");\n        return out->fp;\n    }\n\n\n    /* Look for a name that doesn't collide with an exist name. If the desired\n     * file already exists, then increment the filename. This should never\n     * happen. */\n    err = 0;\nagain:\n    if (out->rotate.filesize) {\n        size_t x_off=0, x_len=0;\n        if (strrchr(filename, '.')) {\n            x_off = strrchr(filename, '.') - filename;\n            x_len = strlen(filename + x_off);\n        } else {\n            x_off = strlen(filename);\n            x_len = 0;\n        }\n        snprintf(new_filename, new_filename_size,\n                      \"%s/%.*s-%05u%.*s\",\n                dir,\n                (unsigned)x_off, filename,\n                out->rotate.filecount++,\n                (unsigned)x_len, filename + x_off\n                );\n    } else {\n        snprintf(new_filename, new_filename_size,\n                  \"%s/%02u%02u%02u-%02u%02u%02u\" \"-%s\",\n            dir,\n            tm.tm_year % 100,\n            tm.tm_mon+1,\n            tm.tm_mday,\n            tm.tm_hour,\n            tm.tm_min,\n            tm.tm_sec,\n            filename);\n        if (access(new_filename, 0) == 0) {\n            tm.tm_sec++;\n            if (err++ == 0)\n                goto again;\n        }\n    }\n    filename = out->filename;\n\n    /*\n     * Move the file\n     */\n    err = rename(filename, new_filename);\n    if (err) {\n        LOG(0, \"rename(\\\"%s\\\", \\\"%s\\\"): failed\\n\", filename, new_filename);\n        perror(\"rename()\");\n        free(new_filename);\n        return out->fp;\n    }\n\n    /*\n     * Set the next rotate time, which is the current time plus the period\n     * length\n     */\n    out->rotate.bytes_written = 0;\n\n    if (out->rotate.period) {\n        out->rotate.next = next_rotate_time(time(0),\n                                        out->rotate.period, out->rotate.offset);\n    }\n\n    LOG(1, \"rotated: %s\\n\", new_filename);\n    free(new_filename);\n\n    /*\n     * Now create a new file\n     */\n    if (is_closing)\n        out->fp = NULL; /* program shutting down, so don't create new file */\n    else {\n        FILE *fp;\n\n        fp = open_rotate(out, filename);\n        if (fp == NULL) {\n            LOG(0, \"rotate: %s: failed: %s\\n\", filename, strerror(errno));\n        } else {\n            close_rotate(out, out->fp);\n            out->fp = fp;\n            out->rotate.last = time(0);\n            LOG(1, \"rotate: started new file: %s\\n\", filename);\n        }\n    }\n    return out->fp;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nis_rotate_time(const struct Output *out, time_t now, FILE *fp)\n{\n    if (out->is_virgin_file)\n        return 0;\n    if (now >= out->rotate.next)\n        return 1;\n    if (out->rotate.filesize != 0 &&\n        ftell_x(fp) >= (int64_t)out->rotate.filesize)\n        return 1;\n    return 0;\n}\n\n/***************************************************************************\n * Return the vendor/OUI string matching the first three bytes of a\n * MAC address.\n * TODO: this should be read in from a file\n ***************************************************************************/\nstatic const char *\noui_from_mac(const unsigned char mac[6])\n{\n    unsigned oui = mac[0]<<16 | mac[1]<<8 | mac[2];\n    switch (oui) {\n    case 0x0001c0: return \"Compulab\";\n    case 0x000732: return \"Aaeon\";\n    case 0x00089B: return \"ICPelec\";\n    case 0x000c29: return \"VMware\";\n    case 0x001075: return \"Seagate\";\n    case 0x001132: return \"Synology\";\n    case 0x022618: return \"Asus\";\n    case 0x0022b0: return \"D-Link\";\n    case 0x00236c: return \"Apple\";\n    case 0x0016CB: return \"Apple\";\n    case 0x001e06: return \"Odroid\";\n    case 0x001ff3: return \"Apple\";\n    case 0x002590: return \"Supermicro\";\n    case 0x04421A: return \"Asus\";\n    case 0x08cc68: return \"Cisco\";\n    case 0x0C9D92: return \"Asus\";\n    case 0x244BFE: return \"Asus\";\n    case 0x244CE3: return \"Amazon\";\n    case 0x28CDC1: return \"RPi 22-02\";\n    case 0x2c27d7: return \"HP\";\n    case 0x3497f6: return \"Asus\";\n    case 0x38f73d: return \"Amazon\";\n    case 0x3A3541: return \"RPi 19-12\";\n    case 0x3C22FB: return \"Apple\";\n    case 0x404a03: return \"Zyxel\";\n    case 0x4C9EFF: return \"Zyxel\";\n    case 0x5855CA: return \"Apple\";\n    case 0x60a44c: return \"Asus\";\n    case 0x640BD7: return \"Apple\";\n    case 0x6c72e7: return \"Apple\";\n    case 0x8C3BAD: return \"Netgear\";\n    case 0x9003b7: return \"Parrot\";\n    case 0x9009d0: return \"Synology\";\n    case 0x94A408: return \"Trolink\";\n    case 0x94dbc9: return \"Azurewave\";\n    case 0xA0CEC8: return \"CeLink\";\n    case 0xacbc32: return \"Apple\";\n    case 0xb827eb: return \"RPi 12-03\";\n    case 0xc05627: return \"Belkin\";\n    case 0xc0c1c0: return \"Cisco-Linksys\";\n    case 0xD83ADD: return \"RPi 22-11\";\n    case 0xDCA4CA: return \"Apple\";\n    case 0xdca632: return \"RPi 19-03\";\n    case 0xE45F01: return \"RPi 20-07\";\n    case 0xe4956e: return \"[random]\";\n    case 0xFCECDA: return \"Ubiquiti\";\n    default: return \"\";\n    }\n}\n\n/***************************************************************************\n * Report simply \"open\" or \"closed\", with little additional information.\n * This is called directly from the receive thread when responses come\n * back.\n ***************************************************************************/\nvoid\noutput_report_status(struct Output *out, time_t timestamp, int status,\n        ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl,\n        const unsigned char mac[6])\n{\n    FILE *fp = out->fp;\n    time_t now = time(0);\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n\n    global_now = now;\n\n    /* if \"--open\"/\"--open-only\" parameter specified on command-line, then\n     * don't report the status of closed-ports */\n    if (!out->is_show_closed && status == PortStatus_Closed)\n        return;\n    if (!out->is_show_open && status == PortStatus_Open)\n        return;\n\n    /* If in \"--interactive\" mode, then print the banner to the command\n     * line screen */\n    if (out->is_interactive || out->format == 0 || out->format == Output_Interactive) {\n        unsigned count;\n\n        switch (ip_proto) {\n        case 0: /* ARP */\n            count = fprintf(stdout, \"Discovered %s port %u/%s on %s (%02x:%02x:%02x:%02x:%02x:%02x) %s\",\n                        status_string(status),\n                        port,\n                        name_from_ip_proto(ip_proto),\n                        fmt.string,\n                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],\n                        oui_from_mac(mac)\n                        );\n            break;\n        default:\n            count = fprintf(stdout, \"Discovered %s port %u/%s on %s\",\n                        status_string(status),\n                        port,\n                        name_from_ip_proto(ip_proto),\n                        fmt.string\n                        );\n        }\n\n        /* Because this line may overwrite the \"%done\" status line, print\n         * some spaces afterward to completely cover up the line */\n        if (count < 80)\n            fprintf(stdout, \"%.*s\", (int)(79-count),\n                    \"                                          \"\n                    \"                                          \");\n\n        fprintf(stdout, \"\\n\");\n        fflush(stdout);\n\n    } else if (fp == NULL) {\n        ERRMSG(\"no output file, use `--output-filename <filename>` to set one\\n\");\n        ERRMSG(\"for `stdout`, use `--output-filename -`\\n\");\n        return;\n    }\n\n    /* Rotate, if we've pass the time limit. Rotating the log files happens\n     * inline while writing output, whenever there's output to write to the\n     * file, rather than in a separate thread right at the time interval.\n     * Thus, if results are coming in slowly, the rotation won't happen\n     * on precise boundaries */\n    if (is_rotate_time(out, now, fp)) {\n        fp = output_do_rotate(out, 0);\n        if (fp == NULL)\n            return;\n    }\n\n\n    /* Keep some statistics so that the user can monitor how much stuff is\n     * being found. */\n    switch (status) {\n        case PortStatus_Open:\n            switch (ip_proto) {\n            case 1:\n                out->counts.icmp.echo++;\n                break;\n            case 6:\n                out->counts.tcp.open++;\n                break;\n            case 17:\n                out->counts.udp.open++;\n                break;\n            case 132:\n                out->counts.sctp.open++;\n                break;\n            default:\n                out->counts.oproto.open++;\n                break;\n            }\n            if (!out->is_show_open)\n                return;\n            break;\n        case PortStatus_Closed:\n            switch (ip_proto) {\n            case 6:\n                out->counts.tcp.closed++;\n                break;\n            case 17:\n                out->counts.udp.closed++;\n                break;\n            case 132:\n                out->counts.sctp.closed++;\n                break;\n            }\n            if (!out->is_show_closed)\n                return;\n            break;\n        case PortStatus_Arp:\n            out->counts.arp.open++;\n            break;\n        default:\n            LOG(0, \"unknown status type: %u\\n\", status);\n            return;\n    }\n\n    /*\n     * If this is a newly opened file, then write file headers\n     */\n    if (out->is_virgin_file) {\n        out->funcs->open(out, fp);\n        out->is_virgin_file = 0;\n    }\n\n    /*\n     * Now do the actual output, whether it be XML, binary, JSON, ndjson, Redis,\n     * and so on.\n     */\n    out->funcs->status(out, fp, timestamp, status, ip, ip_proto, port, reason, ttl);\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\noutput_report_banner(struct Output *out, time_t now,\n                ipaddress ip, unsigned ip_proto, unsigned port,\n                unsigned proto, \n                unsigned ttl, \n                const unsigned char *px, unsigned length)\n{\n    FILE *fp = out->fp;\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip);\n\n    /* If we aren't doing banners, then don't do anything. That's because\n     * when doing UDP scans, we'll still get banner information from\n     * decoding the response packets, even if the user isn't interested */\n    if (!out->is_banner)\n        return;\n\n    /* If in \"--interactive\" mode, then print the banner to the command\n     * line screen */\n    if (out->is_interactive || out->format == 0 || out->format == Output_Interactive) {\n        unsigned count;\n        char banner_buffer[MAX_BANNER_LENGTH];\n\n        count = fprintf(stdout, \"Banner on port %u/%s on %s: [%s] %s\",\n            port,\n            name_from_ip_proto(ip_proto),\n            fmt.string,\n            masscan_app_to_string(proto),\n            normalize_string(px, length, banner_buffer, sizeof(banner_buffer))\n            );\n\n        /* Because this line may overwrite the \"%done\" status line, print\n         * some spaces afterward to completely cover up the line */\n        if (count < 80)\n            fprintf(stdout, \"%.*s\", (int)(79-count),\n                    \"                                          \"\n                    \"                                          \");\n\n        fprintf(stdout, \"\\n\");\n    }\n\n    /* If not outputting to a file, then don't do anything */\n    if (fp == NULL)\n        return;\n\n    /* Rotate, if we've pass the time limit. Rotating the log files happens\n     * inline while writing output, whenever there's output to write to the\n     * file, rather than in a separate thread right at the time interval.\n     * Thus, if results are coming in slowly, the rotation won't happen\n     * on precise boundaries */\n    if (is_rotate_time(out, now, fp)) {\n        fp = output_do_rotate(out, 0);\n        if (fp == NULL)\n            return;\n    }\n\n    /*\n     * If this is a newly opened file, then write file headers\n     */\n    if (out->is_virgin_file) {\n        out->funcs->open(out, fp);\n        out->is_virgin_file = 0;\n    }\n\n    /*\n     * Now do the actual output, whether it be XML, binary, JSON, ndjson, Redis,\n     * and so on.\n     */\n    out->funcs->banner(out, fp, now, ip, ip_proto, port, proto, ttl, px, length);\n\n}\n\n\n/***************************************************************************\n * Called on exit of the program to close/free everything\n ***************************************************************************/\nvoid\noutput_destroy(struct Output *out)\n{\n    if (out == NULL)\n        return;\n\n    /* If rotating files, then do one last rotate of this file to the\n     * destination directory */\n    if (out->rotate.period || out->rotate.filesize) {\n        LOG(1, \"doing finale rotate\\n\");\n        output_do_rotate(out, 1);\n    }\n\n    /* If not rotating files, then simply close this file. Remember\n     * that some files will write closing information before closing\n     * the file */\n    if (out->fp)\n        close_rotate(out, out->fp);\n\n\n\n    free(out->xml.stylesheet);\n    free(out->rotate.directory);\n    free(out->filename);\n\n    free(out);\n}\n\n\n/*****************************************************************************\n * Regression tests for this unit.\n *****************************************************************************/\nint\noutput_selftest(void)\n{\n    char *f;\n\n    f = indexed_filename(\"foo.bar\", 1);\n    if (strcmp(f, \"foo.01.bar\") != 0) {\n        fprintf(stderr, \"output: failed selftest\\n\");\n        return 1;\n    }\n    free(f);\n\n    f = indexed_filename(\"foo.b/ar\", 2);\n    if (strcmp(f, \"foo.b/ar.02\") != 0) {\n        fprintf(stderr, \"output: failed selftest\\n\");\n        return 1;\n    }\n    free(f);\n\n    f = indexed_filename(\".foobar\", 3);\n    if (strcmp(f, \".03.foobar\") != 0) {\n        fprintf(stderr, \"output: failed selftest\\n\");\n        return 1;\n    }\n    free(f);\n\n    return 0;\n}\n\n"
  },
  {
    "path": "src/output.h",
    "content": "#ifndef OUTPUT_H\n#define OUTPUT_H\n#include <stddef.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <time.h>\n#include \"massip-addr.h\"\n#include \"stack-src.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n\n#define MAX_BANNER_LENGTH 8192\n\nstruct Masscan;\nstruct Output;\nenum ApplicationProtocol;\nenum PortStatus;\n\n/**\n * Output plugins\n *\n * The various means for writing output are essentially plugins. As new methods\n * are created, we just fill in a structure of function pointers.\n * TODO: this needs to be a loadable DLL, but in the meantime, it's just\n * internal structures.\n */\nstruct OutputType {\n    const char *file_extension;\n    void *(*create)(struct Output *out);\n    void (*open)(struct Output *out, FILE *fp);\n    void (*close)(struct Output *out, FILE *fp);\n    void (*status)(struct Output *out, FILE *fp,\n                   time_t timestamp, int status,\n                   ipaddress ip, unsigned ip_proto, unsigned port, \n                   unsigned reason, unsigned ttl);\n    void (*banner)(struct Output *out, FILE *fp,\n                   time_t timestamp, ipaddress ip, unsigned ip_proto,\n                   unsigned port, enum ApplicationProtocol proto,\n                   unsigned ttl,\n                   const unsigned char *px, unsigned length);\n};\n\n/**\n * Masscan creates one \"output\" structure per thread.\n */\nstruct Output\n{\n    const struct Masscan *masscan;\n    char *filename;\n    struct stack_src_t src[8];\n    FILE *fp;\n    const struct OutputType *funcs;\n    unsigned format;\n\n    /**\n     * The timestamp when this scan started. This is preserved in output files\n     * because that's what nmap does, and a lot of tools parse this.\n     */\n    time_t when_scan_started;\n\n    /**\n     * Whether we've started writing to a file yet. We are lazy writing\n     * the file header until we've actually go something to write\n     */\n    unsigned is_virgin_file:1;\n    \n    /**\n     * used by json output to test if the first record has been seen, in order\n     * to determine if it needs a , comma before the record\n     */\n    unsigned is_first_record_seen:1;\n\n    struct {\n        time_t next;\n        time_t last;\n        unsigned period;\n        unsigned offset;\n        uint64_t filesize;\n        uint64_t bytes_written;\n        unsigned filecount; /* filesize rotates */\n        char *directory;\n    } rotate;\n\n    unsigned is_banner:1;           /* --banners */\n    unsigned is_banner_rawudp:1;    /* --rawudp */\n    unsigned is_gmt:1; /* --gmt */\n    unsigned is_interactive:1; /* echo to command line */\n    unsigned is_show_open:1; /* show open ports (default) */\n    unsigned is_show_closed:1; /* show closed ports */\n    unsigned is_show_host:1; /* show host status info, like up/down */\n    unsigned is_append:1; /* append to file */\n    struct {\n        struct {\n            uint64_t open;\n            uint64_t closed;\n            uint64_t banner;\n        } tcp;\n        struct {\n            uint64_t open;\n            uint64_t closed;\n        } udp;\n        struct {\n            uint64_t open;\n            uint64_t closed;\n        } sctp;\n        struct {\n            uint64_t echo;\n            uint64_t timestamp;\n        } icmp;\n        struct {\n            uint64_t open;\n        } arp;\n        struct {\n            uint64_t open;\n            uint64_t closed;\n        } oproto;\n    } counts;\n\n    struct {\n        ipaddress ip;\n        unsigned port;\n        char *password;\n        ptrdiff_t fd;\n        uint64_t outstanding;\n        unsigned state;\n    } redis;\n    struct {\n        char *stylesheet;\n    } xml;\n};\n\nconst char *name_from_ip_proto(unsigned ip_proto);\nconst char *status_string(enum PortStatus x);\nconst char *reason_string(int x, char *buffer, size_t sizeof_buffer);\nconst char *normalize_string(const unsigned char *px, size_t length,\n                             char *buf, size_t buf_len);\n\n\nextern const struct OutputType text_output;\nextern const struct OutputType unicornscan_output;\nextern const struct OutputType xml_output;\nextern const struct OutputType json_output;\nextern const struct OutputType ndjson_output;\nextern const struct OutputType certs_output;\nextern const struct OutputType binary_output;\nextern const struct OutputType null_output;\nextern const struct OutputType redis_output;\nextern const struct OutputType hostonly_output;\nextern const struct OutputType grepable_output;\n\n/**\n * Creates an \"output\" object. This is called by the receive thread in order\n * to send \"status\" information (open/closed ports) and \"banners\" to either\n * the command-line or to files in specific formats, such as XML or Redis\n * @param masscan\n *      The master configuration.\n * @param thread_index\n *      When there are more than one receive threads, they are differentiated\n *      by this index number.\n * @return\n *      an output object that must eventually be destroyed by output_destroy().\n */\nstruct Output *\noutput_create(const struct Masscan *masscan, unsigned thread_index);\n\nvoid output_destroy(struct Output *output);\n\nvoid output_report_status(struct Output *output, time_t timestamp,\n    int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl,\n    const unsigned char mac[6]);\n\n\ntypedef void (*OUTPUT_REPORT_BANNER)(\n                struct Output *output, time_t timestamp,\n                ipaddress ip, unsigned ip_proto, unsigned port,\n                unsigned proto, unsigned ttl,\n                const unsigned char *px, unsigned length);\n\nvoid output_report_banner(\n                struct Output *output,\n                time_t timestamp,\n                ipaddress ip, unsigned ip_proto, unsigned port,\n                unsigned proto,\n                unsigned ttl,\n                const unsigned char *px, unsigned length);\n\n/**\n * Regression tests this unit.\n * @return\n *      0 on success, or positive integer on failure\n */\nint\noutput_selftest(void);\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/pixie-backtrace.c",
    "content": "/*\n    When program crashes, print backtrace with line numbers\n*/\n#include \"pixie-backtrace.h\"\n#include \"unusedparm.h\"\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <signal.h>\n\nchar global_self[512] = \"\";\n\n\n#if defined(__GLIBC__) && !defined(WIN32)\n#include <unistd.h>\n#include <execinfo.h>\n#include <dlfcn.h>\n\n\n\n\n#define BACKTRACE_SIZE 256\nstatic void\nhandle_segfault(int sig)\n{\n\tvoid *func[BACKTRACE_SIZE];\n\tchar **symb = NULL;\n\tint size;\n\n    printf(\"======================================================================\\n\");\n    printf(\" Segmentation fault: please post this backtrace to:\\n\");\n    printf(\" https://github.com/robertdavidgraham/masscan/issues\\n\");\n    printf(\"======================================================================\\n\");\n\tsize = backtrace(func, BACKTRACE_SIZE);\n\tsymb = backtrace_symbols(func, size);\n\twhile (size > 0) {\n        const char *symbol = symb[size - 1];\n        char foo[1024];\n\t\tprintf(\"%d: [%s]\\n\", size, symbol);\n        if (strstr(symbol, \"[0x\")) {\n            char *p = strstr(symbol, \"[0x\") + 1;\n            char *pp = strchr(p, ']');\n\n            snprintf(foo, sizeof(foo), \"addr2line -p -i -f -e %s %.*s\",\n                global_self,\n                (unsigned)(pp-p),\n                p);\n            if (system(foo) == -1)\n                printf(\"(addr2line missing)\\n\");\n        }\n\t\tsize --;\n\t}\n    exit(1);\n    return;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\npixie_backtrace_finish(void)\n{\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\npixie_backtrace_init(const char *self)\n{\n    ssize_t x;\n\n    /* Need to get a handle to the currently executing program. On Linux,\n     * we'll get this with /proc/self/exe, but on other platforms, we may\n     * need to do other things */\n    /* TODO: should we use readlink() to get the actual filename? */\n#if defined(__linux__)\n    x = readlink(\"/proc/self/exe\", global_self, sizeof(global_self));\n#elif defined(__FreeBSD__)\n    x = readlink(\"/proc/curproc/file\", global_self, sizeof(global_self));\n#elif defined(__Solaris__)\n    x = readlink(\"/proc/self/path/a.out\", global_self, sizeof(global_self));\n#else\n    x = -1;\n#endif\n\n    if (x == -1)\n        snprintf(global_self, sizeof(global_self), \"%s\", self);\n\n    signal(SIGSEGV, handle_segfault);\n}\n#elif defined(__MINGW32__)\n\nvoid\npixie_backtrace_init(const char *self)\n{\n}\n\n#elif defined(WIN32)\n#include <Windows.h>\n\ntypedef struct _SYMBOL_INFO {\n    ULONG       SizeOfStruct;\n    ULONG       TypeIndex;        // Type Index of symbol\n    ULONG64     Reserved[2];\n    ULONG       Index;\n    ULONG       Size;\n    ULONG64     ModBase;          // Base Address of module containing this symbol\n    ULONG       Flags;\n    ULONG64     Value;            // Value of symbol, ValuePresent should be 1\n    ULONG64     Address;          // Address of symbol including base address of module\n    ULONG       Register;         // register holding value or pointer to value\n    ULONG       Scope;            // scope of the symbol\n    ULONG       Tag;              // pdb classification\n    ULONG       NameLen;          // Actual length of name\n    ULONG       MaxNameLen;\n    CHAR        Name[1];          // Name of symbol\n} SYMBOL_INFO, *PSYMBOL_INFO;\n\n\ntypedef BOOL (__stdcall *FUNC_SymInitialize)(\n                            HANDLE hProcess,\n                            PCSTR UserSearchPath,\n                            BOOL fInvadeProcess\n                            );\ntypedef BOOL (__stdcall * FUNC_SymFromAddr)(\n                            HANDLE hProcess,\n                            DWORD64 Address,\n                            PDWORD64 Displacement,\n                            PSYMBOL_INFO Symbol\n                            );\n\n\nstruct _Dbg {\n    FUNC_SymInitialize SymInitialize;\n    FUNC_SymFromAddr SymFromAddr;\n} Dbg;\n\nvoid printStack( void );\nvoid printStack( void )\n{\n     unsigned int   i;\n     void         * stack[ 100 ];\n     unsigned short frames;\n     SYMBOL_INFO  * symbol;\n     HANDLE         process;\n\n     process = GetCurrentProcess();\n\n     if (Dbg.SymInitialize == NULL)\n         return;\n     if (Dbg.SymFromAddr == NULL)\n         return;\n     if (RtlCaptureStackBackTrace == NULL)\n         return;\n\n     Dbg.SymInitialize( process, NULL, TRUE );\n\n     frames               = CaptureStackBackTrace( 0, 100, stack, NULL );\n     symbol               = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );\n     symbol->MaxNameLen   = 255;\n     symbol->SizeOfStruct = sizeof( SYMBOL_INFO );\n\n     for( i = 0; i < frames; i++ ) {\n         Dbg.SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );\n\n         printf( \"%u: %s - 0x%0X\\n\", frames - i - 1, symbol->Name, symbol->Address );\n     }\n\n     free( symbol );\n}\n\nstatic void\nhandle_segfault(int sig)\n{\n\n    UNUSEDPARM(sig);\n    printf(\"======================================================================\");\n    printf(\" Segmentation fault: please post this backtrace to:\\n\");\n    printf(\" https://github.com/robertdavidgraham/masscan/issues\\n\");\n    printf(\"======================================================================\");\n    exit(1);\n}\n\n\nvoid\npixie_backtrace_init(const char *self)\n{\n    self;\n\n    GetModuleFileNameA(NULL, global_self, sizeof(global_self));\n\n    {\n        HMODULE h;\n\n        h = LoadLibraryA(\"DbgHelp.dll\");\n        if (h != NULL) {\n            //printf(\"found DbgHelp.dll\\n\");\n            Dbg.SymFromAddr = (FUNC_SymFromAddr)GetProcAddress(h, \"SymFromAddr\");\n            //if (Dbg.SymFromAddr) printf(\"found Dbg.SymFromAddr\\n\");\n            Dbg.SymInitialize = (FUNC_SymInitialize)GetProcAddress(h, \"SymInitialize\");\n            //if (Dbg.SymInitialize) printf(\"found Dbg.SymInitialize\\n\");\n\n            h = LoadLibraryA(\"Kernel32.dll\");\n            if (GetProcAddress(NULL, \"RtlCaptureStackBackTrace\") != NULL)\n                ; //printf(\"found Dbg.SymInitialize\\n\");\n        }\n    }\n\n\t//signal(SIGSEGV, handle_segfault);\n}\n#else\nvoid\npixie_backtrace_init(const char *self)\n{\n}\n#endif\n"
  },
  {
    "path": "src/pixie-backtrace.h",
    "content": "#ifndef PIXIE_BACKTRACE_H\n#define PIXIE_BACKTRACE_H\n\n/**\n * Call this function at program startup in order to insert a signal handler\n * that will be caught when the program crashes. This signal handler will\n * print debug information to the console, such as the line numbers where\n * the program crashes.\n */\nvoid\npixie_backtrace_init(const char *self);\n\n#endif\n\n"
  },
  {
    "path": "src/pixie-file.c",
    "content": "#include \"pixie-file.h\"\n\n#if defined(WIN32)\n#include <Windows.h>\n#include <io.h>\n#include <fcntl.h>\n#define access _access\n#else\n#include <unistd.h>\n#include <errno.h>\n#endif\n\nint\npixie_fopen_shareable(FILE **in_fp, const char *filename, unsigned is_append)\n{\n    FILE *fp;\n\n    *in_fp = NULL;\n\n#if defined(WIN32)\n    /* PORTABILITY: WINDOWS\n     *  This bit of code deals with the fact that on Windows, fopen() opens\n     *  a file so that it can't be moved. This code opens it a different\n     *  way so that we can move it.\n     *\n     * NOTE: this is probably overkill, it appears that there is a better\n     * API _fsopen() that does what I want without all this nonsense.\n     */\n    {\n    HANDLE hFile;\n    int fd;\n\n    /* The normal POSIX C functions lock the file */\n    /* int fd = open(filename, O_RDWR | O_CREAT, _S_IREAD | _S_IWRITE); */ /* Fails */\n    /* int fd = _sopen(filename, O_RDWR | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); */ /* Also fails */\n\n    /* We need to use WINAPI + _open_osfhandle to be able to use\n       file descriptors (instead of WINAPI handles) */\n    hFile = CreateFileA(    filename,\n                            GENERIC_WRITE | (is_append?FILE_APPEND_DATA:0),\n                            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,\n                            NULL,\n                            CREATE_ALWAYS,\n                            FILE_ATTRIBUTE_TEMPORARY,\n                            NULL);\n    if (hFile == INVALID_HANDLE_VALUE) {\n        return -1;\n    }\n\n    fd = _open_osfhandle((intptr_t)hFile, _O_CREAT | _O_RDONLY | _O_TEMPORARY);\n    if (fd == -1) {\n        perror(\"_open_osfhandle\");\n        return -1;\n    }\n\n    fp = _fdopen(fd, \"w\");\n    }\n\n#else\n    fp = fopen(filename, is_append?\"a\":\"w\");\n    if (fp == NULL)\n        return errno;\n#endif\n\n    *in_fp = fp;\n    return 0;\n}\n"
  },
  {
    "path": "src/pixie-file.h",
    "content": "#ifndef PIXIE_FILE_H\n#define PIXIE_FILE_H\n#include <stdio.h>\n\n#if defined(WIN32)\n#include <io.h>\n#define access _access\n#else\n#include <unistd.h>\n#endif\n\n/**\n * On Windows, files aren't shareable, so we need to have a portable function\n * to open files that can be shared and renamed while they are still open.\n */\nint\npixie_fopen_shareable(FILE **in_fp, const char *filename, unsigned is_append);\n\n#endif\n"
  },
  {
    "path": "src/pixie-sockets.h",
    "content": "#ifndef PIXIE_SOCKETS_H\n#define PIXIE_SOCKETS_H\n#include <stddef.h>\n#if defined(WIN32)\n#include <WinSock2.h>\n#else\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <netinet/in.h>\ntypedef int SOCKET;\n#endif\n\n\n#endif\n"
  },
  {
    "path": "src/pixie-threads.c",
    "content": "#define _GNU_SOURCE\n#include \"pixie-threads.h\"\n\n#if defined(WIN32)\n#include <Windows.h>\n#include <process.h>\n#endif\n\n#if defined(__GNUC__) && !defined(WIN32)\n#include <unistd.h>\n#include <pthread.h>\n#include <sched.h>\n#include <errno.h>\n#endif\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)\n#include <sys/types.h>\n#include <sys/sysctl.h>\n#endif\n\n#ifndef UNUSEDPARM\n#ifdef _MSC_VER\n#define UNUSEDPARM(x) x\n#else\n#define UNUSEDPARM(x)\n#endif\n#endif\n\n/****************************************************************************\n ****************************************************************************/\nvoid\npixie_cpu_raise_priority(void)\n{\n#if defined WIN32\nDWORD_PTR result;\n    result = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);\n    if (result == 0) {\n        fprintf(stderr, \"set_priority: returned error win32:%u\\n\", (unsigned)GetLastError());\n    }\n#elif defined(__linux__) && defined(__GNUC__)\n    pthread_t thread = pthread_self();\n    pthread_attr_t thAttr;\n    int policy = 0;\n    int max_prio_for_policy = 0;\n\n    pthread_attr_init(&thAttr);\n    pthread_attr_getschedpolicy(&thAttr, &policy);\n    max_prio_for_policy = sched_get_priority_max(policy);\n\n\n    pthread_setschedprio(thread, max_prio_for_policy);\n    pthread_attr_destroy(&thAttr);\n    return;\n\n#endif\n}\n\n/****************************************************************************\n * Set the current thread (implicit) to run exclusively on the explicit\n * process.\n * http://en.wikipedia.org/wiki/Processor_affinity\n ****************************************************************************/\nvoid\npixie_cpu_set_affinity(unsigned processor)\n{\n#if defined WIN32\n    DWORD_PTR mask;\n    DWORD_PTR result;\n    if (processor > 0)\n        processor--;\n    mask = ((size_t)1)<<processor;\n\n    //printf(\"mask(%u) = 0x%08x\\n\", processor, mask);\n    result = SetThreadAffinityMask(GetCurrentThread(), mask);\n    if (result == 0) {\n        fprintf(stderr, \"set_affinity: returned error win32:%u\\n\", (unsigned)GetLastError());\n    }\n#elif defined(__linux__) && defined(__GNUC__) && !defined(__TERMUX__)\n    int x;\n    pthread_t thread = pthread_self();\n    cpu_set_t cpuset;\n\n    CPU_ZERO(&cpuset);\n\n    CPU_SET(processor+1, &cpuset);\n\n    x = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);\n    if (x != 0) {\n        fprintf(stderr, \"set_affinity: returned error linux:%d\\n\", errno);\n    }\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)\n    /* FIXME: add code here */\n    UNUSEDPARM(x);\n#endif\n}\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\npixie_cpu_get_count(void)\n{\n#if defined WIN32\n    /* WINDOWS - use GetProcessAffinityMask() function */\n    size_t x;\n#if defined _M_X64\n    DWORD_PTR process_mask = 0;\n    DWORD_PTR system_mask = 0;\n#else\n    unsigned long process_mask = 0;\n    unsigned long system_mask = 0;\n#endif\n    unsigned count = 0;\n    unsigned i;\n\n    x = GetProcessAffinityMask(GetCurrentProcess(), &process_mask, &system_mask);\n    if (x == 0) {\n        printf(\"GetProcessAffinityMask() returned error %u\\n\", (unsigned)GetLastError());\n        return 1;\n    }\n    for (i=0; i<32; i++) {\n        if (system_mask & 1)\n            count++;\n        system_mask >>= 1;\n    }\n    if (count == 0)\n        return 1;\n    else\n        return count;\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)\n    /* BSD - use sysctl() function */\n        int x;\n        int mib[2];\n        size_t ncpu_length;\n        int ncpu = 1;\n\n        mib[0] = CTL_HW;\n        mib[1] = HW_NCPU;\n        ncpu_length = sizeof(ncpu);\n        x = sysctl(mib, 2, &ncpu, &ncpu_length, NULL, 0);\n        if (x == -1) {\n          perror(\"sysctl(HW_NCPU) failed\");\n          return 1;\n        } else\n          return (unsigned)ncpu;\n#elif defined linux\n    /* http://linux.die.net/man/2/sched_getaffinity */\n    {\n        pid_t pid;\n        cpu_set_t mask;\n        int err;\n\n        /* Gegret our process ID */\n        pid = getpid();\n\n        /* Get list of available CPUs for our system */\n        err = sched_getaffinity(pid, sizeof(mask), &mask);\n        if (err) {\n            perror(\"sched_getaffinity\");\n            return 1;\n        } else {\n#ifndef CPU_COUNT\n            return 1;\n#else\n            return CPU_COUNT(&mask);\n#endif\n        }\n    }\n#elif defined(_SC_NPROCESSORS_ONLN)\n    /* Linux, Solaris, Mac OS>=10.4 */\n    return sysconf(_SC_NPROCESSORS_ONLN);\n#elif defined(_SC_NPROC_ONLN)\n    /* Irix */\n    return sysconf(_SC_NPROC_ONLN);\n#elif defined(MPC_GETNUMSPUS)\n    return mpctl(MPC_GETNUMSPUS, 0, 0);\n#else\n#error need to find CPU count\n    /* UNKNOWN - Well, we don't know the type of system which means we won't\n     * be able to start multiple threads anyway, so just return '1' */\n    return 1;\n#endif\n}\n\n/****************************************************************************\n ****************************************************************************/\nsize_t\npixie_begin_thread(\n    void (*worker_thread)(void*),\n    unsigned flags,\n    void *worker_data)\n{\n#if defined(WIN32)\n    UNUSEDPARM(flags);\n    return _beginthread(worker_thread, 0, worker_data);\n#else\n    typedef void *(*PTHREADFUNC)(void*);\n    pthread_t thread_id = 0;\n    pthread_create(\n                          &thread_id,\n                          NULL,\n                          (PTHREADFUNC)worker_thread,\n                          worker_data);\n    return (size_t)thread_id;\n#endif\n}\n\n/****************************************************************************\n ****************************************************************************/\nvoid pixie_thread_join(size_t thread_handle)\n{\n#if defined(WIN32)\n    WaitForSingleObject((HANDLE)thread_handle, INFINITE);\n#else\n    void *p;\n\n    pthread_join((pthread_t)thread_handle, &p);\n#endif\n}\n"
  },
  {
    "path": "src/pixie-threads.h",
    "content": "#ifndef PORT_THREADS_H\n#define PORT_THREADS_H\n#include <stdio.h>\n#include <stdint.h>\n#if defined(_MSC_VER)\n#include <intrin.h>\n#endif\n\n/**\n * Returns the number of CPUs in the system, including virtual CPUs.\n * On a single processor system, the number returned will be '1'.\n * On a dual socket, dual-core per socket, hyperthreaded system, the\n * count will be '8'.\n */\nunsigned pixie_cpu_get_count(void);\n\n/**\n * Launch a thread\n */\nsize_t pixie_begin_thread(void (*worker_thread)(void*),\n                          unsigned flags,\n                          void *worker_data);\n\nvoid pixie_thread_join(size_t thread_handle);\n\nvoid pixie_cpu_set_affinity(unsigned processor);\nvoid pixie_cpu_raise_priority(void);\n\nvoid pixie_locked_subtract_u32(unsigned *lhs, unsigned rhs);\n\n\n\n#if defined(_MSC_VER)\n#define pixie_locked_add_u32(dst, src) _InterlockedExchangeAdd((volatile long*)(dst), (src))\n#define pixie_locked_CAS32(dst, src, expected) (_InterlockedCompareExchange((volatile long*)dst, src, expected) == (expected))\n#define pixie_locked_CAS64(dst, src, expected) (_InterlockedCompareExchange64((volatile long long*)dst, src, expected) == (expected))\n#define rte_atomic32_cmpset(dst, exp, src) (_InterlockedCompareExchange((volatile long *)dst, (long)src, (long)exp)==(long)(exp))\n\n#elif defined(__GNUC__)\n#define pixie_locked_add_u32(dst, src) __sync_add_and_fetch((volatile int*)(dst), (int)(src));\n#define rte_atomic32_cmpset(dst, expected, src) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src)\n#define pixie_locked_CAS32(dst, src, expected) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src);\n#define pixie_locked_CAS64(dst, src, expected) __sync_bool_compare_and_swap((volatile long long int*)(dst),(long long int)expected,(long long int)src);\n\n#if !defined(__x86_64__) && !defined(__i386__)\n#define rte_wmb() __sync_synchronize()\n#define rte_rmb() __sync_synchronize()\n#define rte_pause()\n#else\n#define rte_wmb() asm volatile(\"sfence;\" : : : \"memory\")\n#define rte_rmb() asm volatile(\"lfence;\" : : : \"memory\")\n#define rte_pause()   asm volatile (\"pause\")\n#endif\n#else\nunsigned pixie_locked_add_u32(volatile unsigned *lhs, unsigned rhs);\nint pixie_locked_CAS32(volatile unsigned *dst, unsigned src, unsigned expected);\nint pixie_locked_CAS64(volatile uint64_t *dst, uint64_t src, uint64_t expected);\n#endif\n\n#endif\n"
  },
  {
    "path": "src/pixie-timer.c",
    "content": "/*\n    portability: time\n\n    Since this program runs on both Linux and Windows, I need a portable\n    way to get a high-resolution timer.\n\n    NOTE: The time I'm looking for is \"elapsed time\" not \"wall clock\"\n    time. In other words, if you put the system to sleep and wake it\n    up a day later, this function should see no change, since time\n    wasn't elapsing while the system was asleep.\n\n    Reference:\n    http://www.python.org/dev/peps/pep-0418/#monotonic-clocks\n    http://www.brain-dump.org/blog/entry/107\n\n*/\n#include \"pixie-timer.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <errno.h>\n#include <string.h>\n\n#ifndef UNUSEDPARM\n#ifdef __GNUC__\n#define UNUSEDPARM(x)\n#else\n#define UNUSEDPARM(x) x=(x)\n#endif\n#endif\n\n\n#if defined(WIN32)\n#include <Windows.h>\n\nLARGE_INTEGER\ngetFILETIMEoffset(void)\n{\n    SYSTEMTIME s;\n    FILETIME f;\n    LARGE_INTEGER t;\n\n    s.wYear = 1970;\n    s.wMonth = 1;\n    s.wDay = 1;\n    s.wHour = 0;\n    s.wMinute = 0;\n    s.wSecond = 0;\n    s.wMilliseconds = 0;\n    SystemTimeToFileTime(&s, &f);\n    t.QuadPart = f.dwHighDateTime;\n    t.QuadPart <<= 32;\n    t.QuadPart |= f.dwLowDateTime;\n    return (t);\n}\n\nint\nwin_clock_gettime(int X, struct timeval *tv)\n{\n    LARGE_INTEGER           t;\n    FILETIME            f;\n    double                  microseconds;\n    static LARGE_INTEGER    offset;\n    static double           frequencyToMicroseconds;\n    static int              initialized = 0;\n    static BOOL             usePerformanceCounter = 0;\n\n    UNUSEDPARM(X);\n\n    if (!initialized) {\n        LARGE_INTEGER performanceFrequency;\n        initialized = 1;\n        usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);\n        if (usePerformanceCounter) {\n            QueryPerformanceCounter(&offset);\n            frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;\n        } else {\n            offset = getFILETIMEoffset();\n            frequencyToMicroseconds = 10.;\n        }\n    }\n    if (usePerformanceCounter) QueryPerformanceCounter(&t);\n    else {\n        GetSystemTimeAsFileTime(&f);\n        t.QuadPart = f.dwHighDateTime;\n        t.QuadPart <<= 32;\n        t.QuadPart |= f.dwLowDateTime;\n    }\n\n    t.QuadPart -= offset.QuadPart;\n    microseconds = (double)t.QuadPart / frequencyToMicroseconds;\n    t.QuadPart = (LONGLONG)microseconds;\n    tv->tv_sec = (long)(t.QuadPart / 1000000);\n    tv->tv_usec = t.QuadPart % 1000000;\n    return (0);\n}\n\n\nuint64_t\npixie_gettime(void)\n{\n    //struct timeval tv;\n    //clock_gettime(0, &tv);\n\n    uint64_t time1 = 0, freq = 0;\n    double seconds;\n\n    QueryPerformanceCounter((LARGE_INTEGER *) &time1);\n    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);\n\n    seconds = (double)time1/(double)freq;\n\n    return (uint64_t)(seconds * 1000000.0);\n\n    //return (uint64_t)tv.tv_sec * 1000000UL + tv.tv_usec;\n}\nuint64_t\npixie_nanotime(void)\n{\n    uint64_t time1 = 0, freq = 0;\n    double seconds;\n    QueryPerformanceCounter((LARGE_INTEGER *) &time1);\n    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);\n    seconds = (double)time1/(double)freq;\n    return (uint64_t)(seconds * 1000000000.0);\n}\n\nvoid\npixie_mssleep(unsigned waitTime)\n{\n    Sleep(waitTime);\n}\n\nvoid\npixie_usleep(uint64_t waitTime)\n{\n    /*\n    uint64_t time1 = 0, time2 = 0, freq = 0;\n\n    QueryPerformanceCounter((LARGE_INTEGER *) &time1);\n    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);\n\n    do {\n        QueryPerformanceCounter((LARGE_INTEGER *) &time2);\n    } while((time2-time1) < waitTime);\n    */\n\n    uint64_t start;\n\n    start = pixie_gettime();\n\n    if (waitTime > 1000)\n        Sleep((DWORD)(waitTime/1000));\n\n    while (pixie_gettime() - start < waitTime)\n        ;\n}\n#elif defined(CLOCK_MONOTONIC)\n#include <unistd.h>\n\nvoid\npixie_mssleep(unsigned milliseconds)\n{\n    pixie_usleep(milliseconds * 1000ULL);\n}\n\nvoid\npixie_usleep(uint64_t microseconds)\n{\n    struct timespec ts;\n    struct timespec remaining;\n    int err;\n\n    ts.tv_sec  =  microseconds/1000000;\n    ts.tv_nsec = (microseconds%1000000) * 1000;\n\nagain:\n    err = nanosleep(&ts, &remaining);\n    if (err == -1 && errno == EINTR) {\n        memcpy(&ts, &remaining, sizeof(ts));\n        goto again;\n    }\n\n    //usleep(microseconds);\n}\nuint64_t\npixie_gettime(void)\n{\n    int x;\n    struct timespec tv;\n\n#if defined(CLOCK_UPTIME_RAW)\n    /* macOS: ignores time when suspended/sleep */\n    x = clock_gettime(CLOCK_UPTIME_RAW, &tv);\n//#elif defined(CLOCK_MONOTONIC_RAW)\n//    x = clock_gettime(CLOCK_MONOTONIC_RAW, &tv);\n#else\n    x = clock_gettime(CLOCK_MONOTONIC, &tv);\n#endif\n    if (x != 0) {\n        printf(\"clock_gettime() err %d\\n\", errno);\n    }\n\n    return tv.tv_sec * 1000000 + tv.tv_nsec/1000;\n}\nuint64_t\npixie_nanotime(void)\n{\n    int x;\n    struct timespec tv;\n\n#ifdef CLOCK_MONOTONIC_RAW\n    x = clock_gettime(CLOCK_MONOTONIC_RAW, &tv);\n#else\n    x = clock_gettime(CLOCK_MONOTONIC, &tv);\n#endif\n    if (x != 0) {\n        printf(\"clock_gettime() err %d\\n\", errno);\n    }\n\n    return tv.tv_sec * 1000000000 + tv.tv_nsec;\n}\n#elif defined(__MACH__) || defined(__FreeBSD__) /* works for Apple */\n#include <unistd.h>\n#include <mach/mach_time.h>\n\nvoid pixie_usleep(uint64_t microseconds)\n{\n    struct timespec t;\n    t.tv_nsec = microseconds * 1000;\n    if (microseconds > 1000000)\n        t.tv_sec = microseconds/1000000;\n    else {\n        t.tv_sec = 0;\n    }\n\n    nanosleep(&t, 0);\n    //usleep(microseconds);\n}\nvoid\npixie_mssleep(unsigned milliseconds)\n{\n    pixie_usleep(milliseconds * 1000ULL);\n}\nuint64_t\npixie_gettime(void)\n{\n    return mach_absolute_time()/1000;\n}\nuint64_t\npixie_nanotime(void)\n{\n    return mach_absolute_time();\n}\n#endif\n\n/*\n * Timing is incredibly importatn to masscan because we need to throttle\n * how fast we spew packets. Every platofrm has slightly different timing\n * even given standard APIs. We need to make sure we have an accurate\n * timing function.\n *\n * This function tests betwe [0.9, 1.9] the expected results. I want something\n * tight, like [0.99,1.01] (plus/minus 1%), but unfortunately automated\n * testing platforms, like GitHub Actions, are overloaded, so when I wait\n * for half a second, they might actually wait for 0.7 seconds, causing\n * this test to fail. Thus, I have to greatly expand the range that passes\n * this test.\n */\nint pixie_time_selftest(void)\n{\n    static const uint64_t duration = 456789;\n    uint64_t start, stop, elapsed;\n\n\n    start = pixie_gettime();\n    pixie_usleep(duration);\n    stop = pixie_gettime();\n    elapsed = stop - start;\n\n    if (elapsed < 0.9 * duration) {\n        fprintf(stderr, \"timing error, long delay\\n\");\n        return 1;\n    }\n    if (1.9 * duration < elapsed) {\n        fprintf(stderr, \"timing error, long delay %5.0f%%\\n\", elapsed*100.0/duration);\n        return 1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/pixie-timer.h",
    "content": "#ifndef PIXIE_TIMER_H\n#define PIXIE_TIMER_H\n#include <stdint.h>\n\n/**\n * The current time, in microseconds\n */\nuint64_t pixie_gettime(void);\n\n/**\n * The current time, in nanoseconds\n */\nuint64_t pixie_nanotime(void);\n\n/**\n * Wait the specified number of microseconds\n */\nvoid pixie_usleep(uint64_t usec);\n\n/**\n * Wait the specified number of milliseconds\n */\nvoid pixie_mssleep(unsigned milliseconds);\n\n/**\n * Do a self-test. Note that in some cases, this may\n * actually fail when there is no problem. So far it hasn't, but I should\n * probably add some code to fix this.\n */\nint pixie_time_selftest(void);\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/proto-arp.c",
    "content": "#include \"proto-arp.h\"\n#include \"proto-preprocess.h\"\n#include \"util-logger.h\"\n#include \"output.h\"\n#include \"masscan-status.h\"\n#include \"unusedparm.h\"\n\n\n\n/***************************************************************************\n * Process an ARP packet received in response to an ARP-scan.\n ***************************************************************************/\nvoid\narp_recv_response(struct Output *out, time_t timestamp, const unsigned char *px,\n           unsigned length, struct PreprocessedInfo *parsed)\n{\n    ipaddress ip_them = parsed->src_ip;\n    ipaddress_formatted_t fmt = ipaddress_fmt(ip_them);\n    \n    UNUSEDPARM(length);\n    UNUSEDPARM(px);\n\n\n    LOG(3, \"ARP %s = [%02X:%02X:%02X:%02X:%02X:%02X]\\n\",\n        fmt.string,\n        parsed->mac_src[0], parsed->mac_src[1], parsed->mac_src[2], \n        parsed->mac_src[3], parsed->mac_src[4], parsed->mac_src[5]);\n\n\n    output_report_status(\n                    out,\n                    timestamp,\n                    PortStatus_Arp,\n                    ip_them,\n                    0, /* ip proto */\n                    0,\n                    0,\n                    0,\n                    parsed->mac_src);\n\n}\n"
  },
  {
    "path": "src/proto-arp.h",
    "content": "#ifndef PROTO_ARP_H\n#define PROTO_ARP_H\n#include <time.h>\nstruct Output;\nstruct PreprocessedInfo;\n\n\nvoid\narp_recv_response(struct Output *out, time_t timestamp, const unsigned char *px, unsigned length, struct PreprocessedInfo *parsed);\n\n#endif\n"
  },
  {
    "path": "src/proto-banner1.c",
    "content": "/*\n     state machine for receiving banners\n*/\n#include \"smack.h\"\n#include \"rawsock-pcapfile.h\"\n#include \"proto-preprocess.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-banner1.h\"\n#include \"proto-http.h\"\n#include \"proto-ssl.h\"\n#include \"proto-smb.h\"\n#include \"proto-ssh.h\"\n#include \"proto-ftp.h\"\n#include \"proto-smtp.h\"\n#include \"proto-tcp-telnet.h\"\n#include \"proto-tcp-rdp.h\"\n#include \"proto-imap4.h\"\n#include \"proto-pop3.h\"\n#include \"proto-vnc.h\"\n#include \"proto-memcached.h\"\n#include \"proto-mc.h\"\n#include \"proto-versioning.h\"\n#include \"masscan-app.h\"\n#include \"scripting.h\"\n#include \"util-malloc.h\"\n#include \"util-logger.h\"\n#include <ctype.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stddef.h>\n\n\n\nstruct Patterns patterns[] = {\n    {\"\\x00\\x00\" \"**\" \"\\xff\" \"SMB\", 8, PROTO_SMB, SMACK_ANCHOR_BEGIN | SMACK_WILDCARDS, 0},\n    {\"\\x00\\x00\" \"**\" \"\\xfe\" \"SMB\", 8, PROTO_SMB, SMACK_ANCHOR_BEGIN | SMACK_WILDCARDS, 0},\n    \n    {\"\\x82\\x00\\x00\\x00\", 4, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Positive Session Response */\n    \n    {\"\\x83\\x00\\x00\\x01\\x80\", 5, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Not listening on called name */\n    {\"\\x83\\x00\\x00\\x01\\x81\", 5, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Not listening for calling name */\n    {\"\\x83\\x00\\x00\\x01\\x82\", 5, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Called name not present */\n    {\"\\x83\\x00\\x00\\x01\\x83\", 5, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Called name present, but insufficient resources */\n    {\"\\x83\\x00\\x00\\x01\\x8f\", 5, PROTO_SMB, SMACK_ANCHOR_BEGIN, 0}, /* Unspecified error */\n\n    /* ...the remainder can be in any order */\n    {\"{\\x22\", 2, PROTO_MC, 0, 0},\n    {\"SSH-1.\",      6, PROTO_SSH1, SMACK_ANCHOR_BEGIN, 0},\n    {\"SSH-2.\",      6, PROTO_SSH2, SMACK_ANCHOR_BEGIN, 0},\n    {\"HTTP/1.\",     7, PROTO_HTTP, SMACK_ANCHOR_BEGIN, 0},\n    {\"220-\",        4, PROTO_FTP, SMACK_ANCHOR_BEGIN, 0},\n    {\"220 \",        4, PROTO_FTP, SMACK_ANCHOR_BEGIN, 1},\n    {\"+OK \",        4, PROTO_POP3, SMACK_ANCHOR_BEGIN, 0},\n    {\"* OK \",       5, PROTO_IMAP4, SMACK_ANCHOR_BEGIN, 0},\n    {\"521 \",        4, PROTO_SMTP, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x16\\x03\\x00\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x16\\x03\\x01\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x16\\x03\\x02\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x16\\x03\\x03\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x15\\x03\\x00\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x15\\x03\\x01\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x15\\x03\\x02\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x15\\x03\\x03\",3, PROTO_SSL3, SMACK_ANCHOR_BEGIN, 0},\n    {\"RFB 000.000\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 1}, /* UltraVNC repeater mode */\n    {\"RFB 003.003\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 3}, /* default version for everything */\n    {\"RFB 003.005\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 3}, /* broken, same as 003.003 */\n    {\"RFB 003.006\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 3}, /* broken, same as 003.003 */\n    {\"RFB 003.007\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 7}, \n    {\"RFB 003.008\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8}, \n    {\"RFB 003.889\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8}, /* Apple's remote desktop, 003.007 */\n    {\"RFB 003.009\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8}, \n    {\"RFB 004.000\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8}, /* Intel AMT KVM */\n    {\"RFB 004.001\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8}, /* RealVNC 4.6 */\n    {\"RFB 004.002\\n\", 12, PROTO_VNC_RFB, SMACK_ANCHOR_BEGIN, 8},\n    {\"STAT pid \",      9, PROTO_MEMCACHED,SMACK_ANCHOR_BEGIN, 0}, /* memcached stat response */\n    \n    \n    {\"\\xff\\xfb\\x01\\xff\\xf0\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\xff\\xfb\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\xff\\xfc\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\xff\\xfe\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\x0a\\x0d\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\x0d\\x0a\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\x0d\\x0d\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\x0a\\x0a\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb%\\x25xff\\xfb\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x26\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfd\\x18\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfd\\x20\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfd\\x23\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfd\\x27\\xff\\xfd\", 5, PROTO_TELNET, 0, 0},\n    {\"\\xff\\xfb\\x01\\x1b[\",    5, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\xff\\xfb\\x01Input\",    8, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\xff\\xfb\\x01   \",      6, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\xff\\xfb\\x01login\",    8, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    {\"login:\",               6, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    {\"password:\",            9, PROTO_TELNET, SMACK_ANCHOR_BEGIN, 0},\n    \n    {\"\\x03\\x00\\x00\\x13\\x0e\\xd0\\xbe\\xef\\x12\\x34\\x00\\x02\\x0f\\x08\\x00\\x00\\x00\\x00\\x00\",\n        12, PROTO_RDP, SMACK_ANCHOR_BEGIN, 0},\n    {\"\\x03\\x00\\x00\\x13\\x0e\\xd0\\x00\\x00\\x12\\x34\\x00\\x02\\x0f\\x08\\x00\\x00\\x00\\x00\\x00\",\n        12, PROTO_RDP, SMACK_ANCHOR_BEGIN, 0},\n\n    {0,0,0,0,0}\n};\n\n\n\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nbanner1_parse(\n        const struct Banner1 *banner1,\n        struct StreamState *tcb_state,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    size_t x;\n    unsigned offset = 0;\n    unsigned proto;\n\n\n    switch (tcb_state->app_proto) {\n    case PROTO_NONE:\n    case PROTO_HEUR:\n        x = smack_search_next(\n                        banner1->smack,\n                        &tcb_state->state,\n                        px, &offset, (unsigned)length);\n        if (x == SMACK_NOT_FOUND)\n            proto = 0xFFFFFFFF;\n        else\n            proto = patterns[x].id;\n        if (proto != 0xFFFFFFFF\n            && !(proto == PROTO_SSL3 && !tcb_state->is_sent_sslhello)) {\n            unsigned i;\n\n            /* re-read the stuff that we missed */\n            for (i=0; patterns[i].id && patterns[i].id != tcb_state->app_proto; i++)\n                ;\n\n            /* Kludge: patterns look confusing, so add port info to the\n             * pattern */\n            switch (proto) {\n            case PROTO_FTP:\n                if (patterns[x].extra == 1) {\n                    if (tcb_state->port == 25 || tcb_state->port == 587)\n                        proto = PROTO_SMTP;\n                }\n                break;\n            case PROTO_VNC_RFB:\n                tcb_state->sub.vnc.version = (unsigned char)patterns[x].extra;\n                break;\n            }\n\n            tcb_state->app_proto = (unsigned short)proto;\n\n            /* reset the state back again */\n            tcb_state->state = 0;\n\n            /* If there is any data from a previous packet, re-parse that */\n            {\n                const unsigned char *s = banout_string(banout, PROTO_HEUR);\n                unsigned s_len = banout_string_length(banout, PROTO_HEUR);\n\n                if (s && s_len)\n                banner1_parse(\n                                banner1,\n                                tcb_state,\n                                s, s_len,\n                                banout,\n                                socket);\n            }\n            banner1_parse(\n                            banner1,\n                            tcb_state,\n                            px, length,\n                            banout,\n                            socket);\n        } else {\n            banout_append(banout, PROTO_HEUR, px, length);\n        }\n        break;\n    case PROTO_FTP:\n            banner_ftp.parse(   banner1,\n                             banner1->http_fields,\n                             tcb_state,\n                             px, length,\n                             banout,\n                             socket);\n            break;\n        case PROTO_SMTP:\n            banner_smtp.parse(   banner1,\n                              banner1->http_fields,\n                              tcb_state,\n                              px, length,\n                              banout,\n                              socket);\n            break;\n            \n        case PROTO_TELNET:\n            banner_telnet.parse(   banner1,\n                              banner1->http_fields,\n                              tcb_state,\n                              px, length,\n                              banout,\n                              socket);\n            break;\n        case PROTO_RDP:\n            banner_rdp.parse(   banner1,\n                                banner1->http_fields,\n                                tcb_state,\n                                px, length,\n                                banout,\n                                socket);\n            break;\n        case PROTO_POP3:\n            banner_pop3.parse(   banner1,\n                              banner1->http_fields,\n                              tcb_state,\n                              px, length,\n                              banout,\n                              socket);\n            break;\n    case PROTO_IMAP4:\n            banner_imap4.parse(banner1,\n                              banner1->http_fields,\n                              tcb_state,\n                              px, length,\n                              banout,\n                              socket);\n            break;\n            \n    case PROTO_SSH1:\n    case PROTO_SSH2:\n        /* generic text-based parser\n         * TODO: in future, need to split these into separate protocols,\n         * especially when binary parsing is added to SSH */\n        banner_ssh.parse(   banner1,\n                            banner1->http_fields,\n                            tcb_state,\n                            px, length,\n                            banout,\n                            socket);\n        break;\n    case PROTO_HTTP:\n        banner_http.parse(\n                        banner1,\n                        banner1->http_fields,\n                        tcb_state,\n                        px, length,\n                        banout,\n                        socket);\n        break;\n    case PROTO_SSL3:\n        banner_ssl.parse(\n                        banner1,\n                        banner1->http_fields,\n                        tcb_state,\n                        px, length,\n                        banout,\n                        socket);\n        break;\n    case PROTO_SMB:\n        banner_smb1.parse(\n                        banner1,\n                        banner1->http_fields,\n                        tcb_state,\n                        px, length,\n                        banout,\n                        socket);\n        break;\n    case PROTO_VNC_RFB:\n        banner_vnc.parse(    banner1,\n                             banner1->http_fields,\n                             tcb_state,\n                             px, length,\n                             banout,\n                             socket);\n        break;\n    case PROTO_MEMCACHED:\n        banner_memcached.parse(    banner1,\n                             banner1->http_fields,\n                             tcb_state,\n                             px, length,\n                             banout,\n                             socket);\n        break;\n    case PROTO_SCRIPTING:\n        banner_scripting.parse(    banner1,\n                                   banner1->http_fields,\n                                   tcb_state,\n                                   px, length,\n                                   banout,\n                                   socket);\n        break;\n    case PROTO_VERSIONING:\n        banner_versioning.parse(      banner1,\n                                   banner1->http_fields,\n                                   tcb_state,\n                                   px, length,\n                                   banout,\n                                   socket);\n        break;\n    case PROTO_MC:\n        banner_mc.parse(\n                        banner1,\n                        banner1->http_fields,\n                        tcb_state,\n                        px, length,\n                        banout,\n                        socket);\n        break;\n\n    default:\n        fprintf(stderr, \"banner1: internal error\\n\");\n        break;\n\n    }\n\n    return tcb_state->app_proto;\n}\n\n/*\n * Simple banners with hello probes from nmap-service-probes\n */\n\nstatic const char\ngenericlines_hello[] = \"\\r\\n\\r\\n\";\n\nstruct ProtocolParserStream banner_genericlines = {\n    \"banner-GenericLines\", 1098, genericlines_hello, sizeof(genericlines_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nx11_hello[] = \"\\x6C\\0\\x0B\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n\nstruct ProtocolParserStream banner_x11 = {\n    \"banner-X11Probe\", 6000, x11_hello, sizeof(x11_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\njavarmi_hello[] = \"\\x4a\\x52\\x4d\\x49\\0\\x02\\x4b\";\n\nstruct ProtocolParserStream banner_javarmi = {\n    \"banner-JavaRMI\", 1098, javarmi_hello, sizeof(javarmi_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nmongodb_hello[] = \"\\x41\\0\\0\\0\\x3a\\x30\\0\\0\\xff\\xff\\xff\\xff\\xd4\\x07\\0\\0\\0\\0\\0\\0test.$cmd\\0\\0\\0\\0\\0\\xff\\xff\\xff\\xff\\x1b\\0\\0\\0\\x01serverStatus\\0\\0\\0\\0\\0\\0\\0\\xf0\\x3f\\0\";\n\nstruct ProtocolParserStream banner_mongodb = {\n    \"banner-mongodb\", 27017, mongodb_hello, sizeof(mongodb_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nkerberos_hello[] = \"\\0\\0\\0\\x71\\x6a\\x81\\x6e\\x30\\x81\\x6b\\xa1\\x03\\x02\\x01\\x05\\xa2\\x03\\x02\\x01\\x0a\\xa4\\x81\\x5e\\x30\\x5c\\xa0\\x07\\x03\\x05\\0\\x50\\x80\\0\\x10\\xa2\\x04\\x1b\\x02NM\\xa3\\x17\\x30\\x15\\xa0\\x03\\x02\\x01\\0\\xa1\\x0e\\x30\\x0c\\x1b\\x06krbtgt\\x1b\\x02NM\\xa5\\x11\\x18\\x0f\"\"19700101000000Z\\xa7\\x06\\x02\\x04\\x1f\\x1e\\xb9\\xd9\\xa8\\x17\\x30\\x15\\x02\\x01\\x12\\x02\\x01\\x11\\x02\\x01\\x10\\x02\\x01\\x17\\x02\\x01\\x01\\x02\\x01\\x03\\x02\\x01\\x02\";\n\nstruct ProtocolParserStream banner_kerberos = {\n    \"banner-Kerberos\", 88, kerberos_hello, sizeof(kerberos_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\ndicom_hello[] = \"\\x01\\x00\\x00\\x00\\x00\\xcd\\x00\\x01\\x00\\x00\"\"ANY-SCP         ECHOSCU         0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x15\"\"1.2.840.10008.3.1.1.1 \\x00\\x00.\\x01\\x00\\x00\\x00\"\"0\\x00\\x00\\x11\"\"1.2.840.10008.1.1@\\x00\\x00\\x11\"\"1.2.840.10008.1.2P\\x00\\x00:Q\\x00\\x00\\x04\\x00\\x00@\\x00R\\x00\\x00\\x1b\"\"1.2.276.0.7230010.3.0.3.6.2U\\x00\\x00\\x0fOFFIS_DCMTK_362\";\n\nstruct ProtocolParserStream banner_dicom = {\n    \"banner-dicom\", 104, dicom_hello, sizeof(dicom_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nldap_hello[] = \"\\x30\\x84\\x00\\x00\\x00\\x2d\\x02\\x01\\x07\\x63\\x84\\x00\\x00\\x00\\x24\\x04\\x00\\x0a\\x01\\x00\\x0a\\x01\\x00\\x02\\x01\\x00\\x02\\x01\\x64\\x01\\x01\\x00\\x87\\x0b\\x6f\\x62\\x6a\\x65\\x63\\x74\\x43\\x6c\\x61\\x73\\x73\\x30\\x84\\x00\\x00\\x00\\x00\";\n\nstruct ProtocolParserStream banner_ldap = {\n    \"banner-LDAPSearchReq\", 389, ldap_hello, sizeof(ldap_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nsip_hello[] = \"OPTIONS sip:nm SIP/2.0\\r\\nVia: SIP/2.0/TCP nm;branch=foo\\r\\nFrom: <sip:nm@nm>;tag=root\\r\\nTo: <sip:nm2@nm2>\\r\\nCall-ID: 50000\\r\\nCSeq: 42 OPTIONS\\r\\nMax-Forwards: 70\\r\\nContent-Length: 0\\r\\nContact: <sip:nm@nm>\\r\\nAccept: application/sdp\\r\\n\\r\\n\";\n\nstruct ProtocolParserStream banner_sip = {\n    \"banner-SIPOptions\", 5060, sip_hello, sizeof(sip_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nrtsp_hello[] = \"OPTIONS / RTSP/1.0\\r\\n\\r\\n\";\n\nstruct ProtocolParserStream banner_rtsp = {\n    \"banner-RTSPRequest\", 554, rtsp_hello, sizeof(rtsp_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nrpc_hello[] = \"\\x80\\0\\0\\x28\\x72\\xFE\\x1D\\x13\\0\\0\\0\\0\\0\\0\\0\\x02\\0\\x01\\x86\\xA0\\0\\x01\\x97\\x7C\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n\nstruct ProtocolParserStream banner_rpc = {\n    \"banner-RPCCheck\", 111, rpc_hello, sizeof(rpc_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\ndns_hello[] = \"\\0\\x1E\\0\\x06\\x01\\0\\0\\x01\\0\\0\\0\\0\\0\\0\\x07version\\x04\"\"bind\\0\\0\\x10\\0\\x03\";\n\nstruct ProtocolParserStream banner_dns = {\n    \"banner-DNSVersionBindReqTCP\", 53, dns_hello, sizeof(dns_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\ndocker_hello[] = \"GET /version HTTP/1.1\\r\\n\\r\\n\";\n\nstruct ProtocolParserStream banner_docker = {\n    \"banner-docker\", 2375, docker_hello, sizeof(docker_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nredis_hello[] = \"*1\\r\\n$4\\r\\ninfo\\r\\n\";\n\nstruct ProtocolParserStream banner_redis = {\n    \"banner-redis-server\", 6379, redis_hello, sizeof(redis_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nnotes_rpc_hello[] = \"\\x3A\\x00\\x00\\x00\\x2F\\x00\\x00\\x00\\x02\\x00\\x00\\x40\\x02\\x0F\\x00\\x01\\x00\\x3D\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x2F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x40\\x1F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\n\nstruct ProtocolParserStream banner_notes_rpc = {\n    \"banner-NotesRPC\", 6379, notes_rpc_hello, sizeof(notes_rpc_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nms_sql_s_hello[] = \"\\x12\\x01\\x00\\x34\\x00\\x00\\x00\\x00\\x00\\x00\\x15\\x00\\x06\\x01\\x00\\x1b\\x00\\x01\\x02\\x00\\x1c\\x00\\x0c\\x03\\x00\\x28\\x00\\x04\\xff\\x08\\x00\\x01\\x55\\x00\\x00\\x00\\x4d\\x53\\x53\\x51\\x4c\\x53\\x65\\x72\\x76\\x65\\x72\\x00\\x48\\x0f\\x00\\x00\";\n\nstruct ProtocolParserStream banner_ms_sql_s = {\n    \"banner-ms-sql-s\", 6379, ms_sql_s_hello, sizeof(ms_sql_s_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\nstatic const char\nafp_hello[] = \"\\x00\\x03\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x0f\\x00\";\n\nstruct ProtocolParserStream banner_afp = {\n    \"banner-afp\", 548, afp_hello, sizeof(afp_hello) - 1, 0,\n    NULL,\n    NULL,\n    NULL,\n};\n\n\n/***************************************************************************\n * Create the --banners systems\n ***************************************************************************/\nstruct Banner1 *\nbanner1_create(void)\n{\n    struct Banner1 *b;\n    unsigned i;\n\n    b = CALLOC(1, sizeof(*b));\n    \n\n    /*\n     * This creates a pattern-matching blob for heuristically determining\n     * a protocol that runs on wrong ports, such as how FTP servers\n     * often respond with \"220 \" or VNC servers respond with \"RFB\".\n     */\n    b->smack = smack_create(\"banner1\", SMACK_CASE_INSENSITIVE);\n    for (i=0; patterns[i].pattern; i++)\n        smack_add_pattern(\n                    b->smack,\n                    patterns[i].pattern,\n                    patterns[i].pattern_length,\n                    i,\n                    patterns[i].is_anchored);\n    smack_compile(b->smack);\n\n    /*\n     * [TODO] These need to be moved into the 'init' functions\n     */\n    b->payloads.tcp[80] = &banner_http;\n    b->payloads.tcp[8080] = &banner_http;\n    b->payloads.tcp[139] = (void*)&banner_smb0;\n    b->payloads.tcp[445] = (void*)&banner_smb1;\n    b->payloads.tcp[8530] = (void*)&banner_http; /* WSUS */\n    b->payloads.tcp[8531] = (void*)&banner_ssl;  /* WSUS/s */\n    /* https://www.nomotion.net/blog/sharknatto/ */\n    b->payloads.tcp[49955] = (void*)&banner_ssl; /* AT&T box */\n    b->payloads.tcp[443] = (void*)&banner_ssl;   /* HTTP/s */\n    b->payloads.tcp[465] = (void*)&banner_ssl;   /* SMTP/s */\n    b->payloads.tcp[990] = (void*)&banner_ssl;   /* FTP/s */\n    b->payloads.tcp[991] = (void*)&banner_ssl;\n    b->payloads.tcp[992] = (void*)&banner_ssl;   /* Telnet/s */\n    b->payloads.tcp[993] = (void*)&banner_ssl;   /* IMAP4/s */\n    b->payloads.tcp[994] = (void*)&banner_ssl;\n    b->payloads.tcp[995] = (void*)&banner_ssl;   /* POP3/s */\n    b->payloads.tcp[2083] = (void*)&banner_ssl;  /* cPanel - SSL */\n    b->payloads.tcp[2087] = (void*)&banner_ssl;  /* WHM - SSL */\n    b->payloads.tcp[2096] = (void*)&banner_ssl;  /* cPanel webmail - SSL */\n    b->payloads.tcp[8443] = (void*)&banner_ssl;  /* Plesk Control Panel - SSL */\n    b->payloads.tcp[9050] = (void*)&banner_ssl;  /* Tor */\n    b->payloads.tcp[8140] = (void*)&banner_ssl;  /* puppet */\n    b->payloads.tcp[11211] = (void*)&banner_memcached;\n    b->payloads.tcp[23] = (void*)&banner_telnet;\n    b->payloads.tcp[3389] = (void*)&banner_rdp;\n\n    b->payloads.tcp[1098] = (void*)&banner_javarmi;\n    b->payloads.tcp[1099] = (void*)&banner_javarmi;\n    for (i=0; i < 20; i++) {\n      b->payloads.tcp[6000 + i] = (void*)&banner_x11;\n    }\n    b->payloads.tcp[88] = (void*)&banner_kerberos;\n    b->payloads.tcp[9001] = (void*)&banner_mongodb;\n    b->payloads.tcp[27017] = (void*)&banner_mongodb;\n    b->payloads.tcp[49153] = (void*)&banner_mongodb;\n    b->payloads.tcp[104] = (void*)&banner_dicom;\n    b->payloads.tcp[2345] = (void*)&banner_dicom;\n    b->payloads.tcp[2761] = (void*)&banner_dicom;\n    b->payloads.tcp[2762] = (void*)&banner_dicom;\n    b->payloads.tcp[4242] = (void*)&banner_dicom;\n    b->payloads.tcp[11112] = (void*)&banner_dicom;\n    b->payloads.tcp[256] = (void*)&banner_ldap;\n    b->payloads.tcp[257] = (void*)&banner_ldap;\n    b->payloads.tcp[389] = (void*)&banner_ldap;\n    b->payloads.tcp[390] = (void*)&banner_ldap;\n    b->payloads.tcp[1702] = (void*)&banner_ldap;\n    b->payloads.tcp[3268] = (void*)&banner_ldap;\n    b->payloads.tcp[3892] = (void*)&banner_ldap;\n    b->payloads.tcp[11711] = (void*)&banner_ldap;\n    /* LDAP/s */\n    b->payloads.tcp[636] = (void*)&banner_ssl;\n    b->payloads.tcp[637] = (void*)&banner_ssl;\n    b->payloads.tcp[3269] = (void*)&banner_ssl;\n    b->payloads.tcp[11712] = (void*)&banner_ssl;\n    b->payloads.tcp[406] = (void*)&banner_sip;\n    b->payloads.tcp[5060] = (void*)&banner_sip;\n    b->payloads.tcp[8081] = (void*)&banner_sip;\n    b->payloads.tcp[31337] = (void*)&banner_sip;\n    /* SIP/s */\n    b->payloads.tcp[5061] = (void*)&banner_ssl;\n    b->payloads.tcp[554] = (void*)&banner_rtsp;\n    b->payloads.tcp[8554] = (void*)&banner_rtsp;\n    /* RTSP/s */\n    b->payloads.tcp[322] = (void*)&banner_ssl;\n    b->payloads.tcp[111] = (void*)&banner_rpc;\n    b->payloads.tcp[2049] = (void*)&banner_rpc;\n    b->payloads.tcp[53] = (void*)&banner_dns;\n    b->payloads.tcp[135] = (void*)&banner_dns;\n    b->payloads.tcp[50000] = (void*)&banner_dns;\n    b->payloads.tcp[50001] = (void*)&banner_dns;\n    b->payloads.tcp[50002] = (void*)&banner_dns;\n    b->payloads.tcp[2375] = (void*)&banner_docker;\n    /* Docker/s */\n    b->payloads.tcp[2376] = (void*)&banner_ssl;\n    b->payloads.tcp[2379] = (void*)&banner_docker;\n    b->payloads.tcp[2380] = (void*)&banner_docker;\n    b->payloads.tcp[6379] = (void*)&banner_redis;\n    b->payloads.tcp[130] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[427] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[1352] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[1972] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[7171] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[8728] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[22001] = (void*)&banner_notes_rpc;\n    b->payloads.tcp[1433] = (void*)&banner_ms_sql_s;\n    /* AFP */\n    b->payloads.tcp[548] = (void*)&banner_afp;\n\n    /* \n     * This goes down the list of all the TCP protocol handlers and initializes\n     * them.\n     */\n    banner_ftp.init(b);\n    banner_http.init(b);\n    banner_imap4.init(b);\n    banner_memcached.init(b);\n    banner_pop3.init(b);\n    banner_smtp.init(b);\n    banner_ssh.init(b);\n    banner_ssl.init(b);\n    banner_ssl_12.init(b);\n    banner_smb0.init(b);\n    banner_smb1.init(b);\n    banner_telnet.init(b);\n    banner_rdp.init(b);\n    banner_vnc.init(b);\n    banner_mc.init(b);\n\n    /* scripting/versioning come after the rest */\n    //banner_scripting.init(b);\n    //banner_versioning.init(b);\n\n\n    return b;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanner1_destroy(struct Banner1 *b)\n{\n    if (b == NULL)\n        return;\n    if (b->smack)\n        smack_destroy(b->smack);\n    if (b->http_fields)\n        smack_destroy(b->http_fields);\n    free(b);\n}\n\n\n\n\n\n/***************************************************************************\n * Test the banner1 detection system by throwing random frames at it\n ***************************************************************************/\nvoid\nbanner1_test(const char *filename)\n{\n    struct PcapFile *cap;\n    unsigned link_type;\n\n    cap = pcapfile_openread(filename);\n    if (cap == NULL) {\n        fprintf(stderr, \"%s: can't open capture file\\n\", filename);\n        return;\n    }\n\n    link_type = pcapfile_datalink(cap);\n\n    for (;;) {\n        int packets_read;\n        unsigned secs;\n        unsigned usecs;\n        unsigned origlength;\n        unsigned length;\n        unsigned char px[65536];\n        struct PreprocessedInfo parsed;\n        unsigned x;\n\n\n        packets_read = pcapfile_readframe(\n                    cap,    /* capture dump file */\n                    &secs, &usecs,\n                    &origlength, &length,\n                    px, sizeof(px));\n        if (packets_read == 0)\n            break;\n\n\n        x = preprocess_frame(px, length, link_type, &parsed);\n        if (x == 0)\n            continue;\n\n    }\n\n    pcapfile_close(cap);\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\nbanner1_selftest()\n{\n    unsigned i;\n    struct Banner1 *b;\n    struct StreamState tcb_state[1];\n    const unsigned char *px;\n    unsigned length;\n    struct BannerOutput banout[1];\n    static const char *http_header =\n        \"HTTP/1.0 302 Redirect\\r\\n\"\n        \"Date: Tue, 03 Sep 2013 06:50:01 GMT\\r\\n\"\n        \"Connection: close\\r\\n\"\n        \"Via: HTTP/1.1 ir14.fp.bf1.yahoo.com (YahooTrafficServer/1.2.0.13 [c s f ])\\r\\n\"\n        \"Server: YTS/1.20.13\\r\\n\"\n        \"Cache-Control: no-store\\r\\n\"\n        \"Content-Type: text/html\\r\\n\"\n        \"Content-Language: en\\r\\n\"\n        \"Location: http://failsafe.fp.yahoo.com/404.html\\r\\n\"\n        \"Content-Length: 227\\r\\n\"\n        \"\\r\\n<title>hello</title>\\n\";\n    px = (const unsigned char *)http_header;\n    length = (unsigned)strlen(http_header);\n\n\n    LOG(1, \"[ ] banners: selftesting\\n\");\n\n    /*\n     * First, test the \"banout\" subsystem\n     */\n    if (banout_selftest() != 0) {\n        fprintf(stderr, \"banout: failed\\n\");\n        return 1;\n    }\n\n\n    /*\n     * Test one character at a time\n     */\n    b = banner1_create();\n    banout_init(banout);\n\n    memset(tcb_state, 0, sizeof(tcb_state[0]));\n\n    for (i=0; i<length; i++) {\n        struct stack_handle_t more = {0,0};\n\n        banner1_parse(\n                    b,\n                    tcb_state,\n                    px+i, 1,\n                    banout,\n                    &more);\n    }\n\n\n    {\n        const unsigned char *s = banout_string(banout, PROTO_HTTP);\n        if (memcmp(s, \"HTTP/1.0 302\", 11) != 0) {\n            printf(\"banner1: test failed\\n\");\n            return 1;\n        }\n    }\n    banout_release(banout);\n    banner1_destroy(b);\n\n    /*\n     * Test whole buffer\n     */\n    b = banner1_create();\n\n    memset(tcb_state, 0, sizeof(tcb_state[0]));\n\n    banner1_parse(\n                    b,\n                    tcb_state,\n                    px, length,\n                    banout,\n                    0);\n    banner1_destroy(b);\n    /*if (memcmp(banner, \"Via:HTTP/1.1\", 11) != 0) {\n        printf(\"banner1: test failed\\n\");\n        return 1;\n    }*/\n\n\n    {\n        int x = 0;\n\n        x = banner_ssl.selftest();\n        if (x) {\n            fprintf(stderr, \"SSL banner: selftest failed\\n\");\n            return 1;\n        }\n\n        x = banner_ssl_12.selftest();\n        if (x) {\n            fprintf(stderr, \"SSL banner: selftest failed\\n\");\n            return 1;\n        }\n        \n        x = banner_smb1.selftest();\n        if (x) {\n            fprintf(stderr, \"SMB banner: selftest failed\\n\");\n            return 1;\n        }\n        \n        x = banner_http.selftest();\n        if (x) {\n            fprintf(stderr, \"HTTP banner: selftest failed\\n\");\n            return 1;\n        }\n        \n        x = banner_telnet.selftest();\n        if (x) {\n            fprintf(stderr, \"Telnet banner: selftest failed\\n\");\n            return 1;\n        }\n        \n        x = banner_rdp.selftest();\n        if (x) {\n            fprintf(stderr, \"RDP banner: selftest failed\\n\");\n            return 1;\n        }\n\n        if (x)\n            goto failure;\n        else\n            goto success;\n    }\n\nsuccess:\n    LOG(1, \"[+] banners: success\\n\");\n    return 0;\nfailure:\n    LOG(1, \"[-] banners: failure\\n\");\n    return 1;\n}\n\n"
  },
  {
    "path": "src/proto-banner1.h",
    "content": "#ifndef PROTO_BANNER1_H\n#define PROTO_BANNER1_H\n#include <stdint.h>\n\n#include <stdio.h>\n#include \"masscan-app.h\"\n#include \"proto-banout.h\"\n#include \"proto-x509.h\"\n#include \"proto-spnego.h\"\n\nstruct stack_handle_t;\nstruct Banner1;\nstruct StreamState;\n\ntypedef void (*BannerParser)(\n              const struct Banner1 *banner1,\n              void *banner1_private,\n              struct StreamState *stream_state,\n              const unsigned char *px, size_t length,\n              struct BannerOutput *banout,\n              struct stack_handle_t *socket);\nstruct Banner1\n{\n    struct lua_State *L;\n    struct SMACK *smack;\n    struct SMACK *http_fields;\n    struct SMACK *html_fields;\n    struct SMACK *memcached_responses;\n    struct SMACK *memcached_stats;\n\n    unsigned is_capture_html:1;\n    unsigned is_capture_cert:1;\n    unsigned is_capture_servername:1;\n    unsigned is_capture_heartbleed:1;\n    unsigned is_capture_ticketbleed:1;\n    unsigned is_heartbleed:1;\n    unsigned is_ticketbleed:1;\n    unsigned is_poodle_sslv3:1;\n\n    struct {\n        const struct ProtocolParserStream *tcp[65536];\n    } payloads;\n    \n    BannerParser parser[PROTO_end_of_list];\n};\n\nstruct BannerBase64\n{\n    unsigned state:2;\n    unsigned temp:24;\n};\n\nstruct SSL_SERVER_HELLO {\n    unsigned state;\n    unsigned remaining;\n    unsigned timestamp;\n    unsigned short cipher_suite;\n    unsigned short ext_tag;\n    unsigned short ext_remaining;\n    unsigned char compression_method;\n    unsigned char version_major;\n    unsigned char version_minor;\n};\nstruct SSL_SERVER_CERT {\n    unsigned state;\n    unsigned remaining;\n    struct {\n        unsigned remaining;\n    } sub;\n    struct CertDecode x509;\n};\nstruct SSL_SERVER_ALERT {\n    unsigned char level;\n    unsigned char description;\n};\n\nstruct SSLRECORD {\n    unsigned char type;\n    unsigned char version_major;\n    unsigned char version_minor;\n\n    struct {\n        unsigned state;\n        unsigned char type;\n        unsigned remaining;\n    } handshake;\n\n    union {\n        struct {\n            /* all these structs should start with state */\n            unsigned state;\n        } all;\n        struct SSL_SERVER_HELLO server_hello;\n        struct SSL_SERVER_CERT server_cert;\n        struct SSL_SERVER_ALERT server_alert;\n    } x;\n\n};\n\nstruct PIXEL_FORMAT {\n    unsigned short red_max;\n    unsigned short green_max;\n    unsigned short blue_max;\n    unsigned char red_shift;\n    unsigned char green_shift;\n    unsigned char blue_shift;\n    unsigned char bits_per_pixel;\n    unsigned char depth;\n    unsigned big_endian_flag:1;\n    unsigned true_colour_flag:1;\n};\nstruct VNCSTUFF {\n    unsigned sectype;\n    unsigned char version;\n    unsigned char len;\n    \n    unsigned short width;\n    unsigned short height;\n    \n    struct PIXEL_FORMAT pixel;    \n};\n\nstruct FTPSTUFF {\n    unsigned code;\n    unsigned is_last:1;\n};\n\nstruct MCSTUFF {\n    char * banmem;\n    size_t totalLen;\n    size_t imgstart;\n    size_t imgend;\n    int brackcount;\n};\n\nstruct SMTPSTUFF {\n    unsigned code;\n    unsigned is_last:1;\n};\n\nstruct POP3STUFF {\n    unsigned code;\n    unsigned is_last:1;\n};\n\nstruct MEMCACHEDSTUFF {\n    unsigned match;\n};\n\nstruct Smb72_Negotiate {\n    uint16_t DialectIndex;\n    uint16_t SecurityMode;\n    uint64_t SystemTime;\n    uint32_t SessionKey;\n    uint32_t Capabilities;\n    uint16_t ServerTimeZone;\n    uint8_t  ChallengeLength;\n    uint8_t  ChallengeOffset;\n};\n\nstruct Smb73_Setup {\n    uint16_t BlobLength;\n    uint16_t BlobOffset;\n};\n\nstruct SMBSTUFF {\n    unsigned nbt_state;\n    unsigned char nbt_type;\n    unsigned char nbt_flags;\n    unsigned is_printed_ver:1;\n    unsigned is_printed_guid:1;\n    unsigned is_printed_time:1;\n    unsigned is_printed_boottime:1;\n    unsigned nbt_length;\n    unsigned nbt_err;\n    \n    union {\n        struct {\n            unsigned char   command;\n            unsigned        status;\n            unsigned char   flags1;\n            unsigned short  flags2;\n            unsigned        pid;\n            unsigned char   signature[8];\n            unsigned short  tid;\n            unsigned short  uid;\n            unsigned short  mid;\n            unsigned short  param_length;\n            unsigned short  param_offset;\n            unsigned short  byte_count;\n            unsigned short  byte_offset;\n            unsigned short  byte_state;\n            unsigned short  unicode_char;\n        } smb1;\n        struct {\n            unsigned seqno;\n            unsigned short header_length;\n            unsigned short offset;\n            unsigned short state;\n            unsigned short opcode;\n            unsigned short struct_length;\n            unsigned is_dynamic:1;\n            unsigned char flags;\n            unsigned ntstatus;\n            unsigned number;\n            unsigned short blob_offset;\n            unsigned short blob_length;\n        } smb2;\n    } hdr;\n    union {\n        struct Smb72_Negotiate negotiate;\n        struct Smb73_Setup setup;\n        struct {\n            uint64_t current_time;\n            uint64_t boot_time;\n        } negotiate2;\n    } parms;\n    struct SpnegoDecode spnego;\n};\n\nstruct RDPSTUFF {\n    unsigned short tpkt_length;\n    struct {\n        unsigned state;\n        unsigned short dstref;\n        unsigned short srcref;\n        unsigned char len;\n        unsigned char type;\n        unsigned char flags;\n    } cotp;\n    struct {\n        unsigned state;\n        unsigned result;\n        unsigned char type;\n        unsigned char flags;\n        unsigned char len;\n    } cc;\n};\n\nstruct SSHSTUFF{\n    size_t packet_length;\n};\n\nstruct StreamState {\n    unsigned state;\n    unsigned remaining;\n    unsigned short port;\n    unsigned short app_proto;\n    unsigned is_sent_sslhello:1;\n    struct BannerBase64 base64;\n\n    union {\n        struct SSLRECORD ssl;\n        struct VNCSTUFF vnc;\n        struct FTPSTUFF ftp;\n        struct SMTPSTUFF smtp;\n        struct POP3STUFF pop3;\n        struct MEMCACHEDSTUFF memcached;\n        struct SMBSTUFF smb;\n        struct RDPSTUFF rdp;\n        struct MCSTUFF mc;\n        struct SSHSTUFF ssh;\n    } sub;\n};\n\nenum StreamFlags {\n    SF__none = 0,\n    SF__close = 0x01, /* send FIN after the static Hello is sent*/\n    SF__nowait_hello = 0x02,    /* send our hello immediately, don't wait for their hello */\n};\n\n\n/**\n * A registration structure for various TCP stream protocols\n * like HTTP, SSL, and SSH\n */\nstruct ProtocolParserStream {\n    const char *name;\n    unsigned port;\n    const void *hello;\n    size_t hello_length;\n    enum StreamFlags flags;\n    int (*selftest)(void);\n    void *(*init)(struct Banner1 *b);\n    void (*parse)(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *stream_state,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket);\n    void (*cleanup)(struct StreamState *stream_state);\n    void (*transmit_hello)(const struct Banner1 *banner1, struct stack_handle_t *socket);\n    \n    /* When multiple items are registered for a port. When one\n     * connection is closed, the next will be opened.*/\n    struct ProtocolParserStream *next;\n    \n    /*NOTE: the 'next' parameter should be the last one in this structure,\n     * because we statically initialize the rest of the members at compile\n     * time, and then use this last parameter to link up structures\n     * at runtime */\n};\n\n\n/**\n * Patterns that match the data from the start of a TCP connection.\n * This will hint at what protocol that connection might be.\n */\nstruct Patterns {\n    \n    /** A string like \"SSH-\" or \"220 \" that matches a banner */\n    const char *pattern;\n    \n    /** The length of that string, since it may be binary containing\n     * nul characters */\n    unsigned pattern_length;\n    \n    /** An integer arbitrarily assigned to this pattern, which should\n     * probably match the protocol ID that we are looking for */\n    unsigned id;\n    \n    /**\n     * Whether this string matches only at the beginning ('anchored')\n     * or anywhere in the input. Virtually all the patterns are anchored.\n     */\n    unsigned is_anchored;\n    \n    /**\n     * Some extra flags for the pattern matcher for a few of the patterns.\n     */\n    unsigned extra;\n};\n\nstruct Banner1 *\nbanner1_create(void);\n\n\nvoid\nbanner1_destroy(struct Banner1 *b);\n\nunsigned\nbanner1_parse(\n        const struct Banner1 *banner1,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket);\n\n\n\n/**\n * Test the banner protocol-parsing system by reading\n * in a capture file\n */\nvoid banner1_test(const char *filename);\n\nint banner1_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/proto-banout.c",
    "content": "/*\n    Banner Output\n\n    This module remembers \"banners\" from a connection. These are often\n    simple strings, like the FTP hello string. The can also be more\n    complex strings, parsed from binary protocols. They also may\n    contain bulk data, such as BASE64 encoded X.509 certificates from\n    SSL.\n\n    One complication is that since we can extract multiple types of \n    information from the same connection, we can have more than one\n    banner for the same connection.\n*/\n#include \"proto-banner1.h\"\n#include \"util-malloc.h\"\n#include <stddef.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_init(struct BannerOutput *banout)\n{\n    banout->length = 0;\n    banout->protocol = 0;\n    banout->next = 0;\n    banout->max_length = sizeof(banout->banner);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_release(struct BannerOutput *banout)\n{\n    while (banout->next) {\n        struct BannerOutput *next = banout->next->next;\n        free(banout->next);\n        banout->next = next;\n    }\n    banout_init(banout);\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic struct BannerOutput *\nbanout_find_proto(struct BannerOutput *banout, unsigned proto)\n{\n    while (banout && banout->protocol != proto)\n        banout = banout->next;\n    return banout;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst unsigned char *\nbanout_string(const struct BannerOutput *banout, unsigned proto)\n{\n    while (banout && (banout->protocol&0xFFFF) != proto)\n        banout = banout->next;\n\n    if (banout)\n        return banout->banner;\n    else\n        return NULL;\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nbanout_is_equal(const struct BannerOutput *banout, unsigned proto,\n                const char *string)\n{\n    const unsigned char *string2;\n    size_t string_length;\n    size_t string2_length;\n\n    /*\n     * Grab the string\n     */\n    string2 = banout_string(banout, proto);\n    if (string2 == NULL)\n        return string == NULL;\n\n    if (string == NULL)\n        return 0;\n    \n    string_length = strlen(string);\n    string2_length = banout_string_length(banout, proto);\n\n    if (string_length != string2_length)\n        return 0;\n    \n    return memcmp(string, string2, string2_length) == 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nbanout_is_contains(const struct BannerOutput *banout, unsigned proto,\n                const char *string)\n{\n    const unsigned char *string2;\n    size_t string_length;\n    size_t string2_length;\n    size_t i;\n\n    /*\n     * Grab the string\n     */\n    string2 = banout_string(banout, proto);\n    if (string2 == NULL)\n        return string == NULL;\n\n    if (string == NULL)\n        return 0;\n    \n    string_length = strlen(string);\n    string2_length = banout_string_length(banout, proto);\n\n    if (string_length > string2_length)\n        return 0;\n    \n    for (i=0; i<string2_length-string_length+1; i++) {\n        if (memcmp(string, string2+i, string_length) == 0)\n            return 1;\n    }\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nbanout_string_length(const struct BannerOutput *banout, unsigned proto)\n{\n    while (banout && banout->protocol != proto)\n        banout = banout->next;\n\n    if (banout)\n        return banout->length;\n    else\n        return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_newline(struct BannerOutput *banout, unsigned proto)\n{\n    struct BannerOutput *p;\n\n    p = banout_find_proto(banout, proto);\n    if (p && p->length) {\n        banout_append_char(banout, proto, '\\n');\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_end(struct BannerOutput *banout, unsigned proto)\n{\n    struct BannerOutput *p;\n\n    p = banout_find_proto(banout, proto);\n    if (p && p->length) {\n        p->protocol |= 0x80000000;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_append_char(struct BannerOutput *banout, unsigned proto, int c)\n{\n    char cc = (char)c;\n    banout_append(banout, proto, &cc, 1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_append_hexint(struct BannerOutput *banout, unsigned proto, unsigned long long number, int digits)\n{\n    if (digits == 0) {\n        for (digits=16; digits>0; digits--)\n            if (number>>((digits-1)*4) & 0xF)\n                break;\n    }\n    \n    for (;digits>0; digits--) {\n        char c = \"0123456789abcdef\"[(number>>(unsigned long long)((digits-1)*4)) & 0xF];\n        banout_append_char(banout, proto, c);\n    }\n}\n\n/***************************************************************************\n * Output either a normal character, or the hex form of a UTF-8 string\n ***************************************************************************/\nvoid\nbanout_append_unicode(struct BannerOutput *banout, unsigned proto, unsigned c)\n{\n    if (c & ~0xFFFF) {\n        unsigned c2;\n        c2 = 0xF0 | ((c>>18)&0x03);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>>12)&0x3F);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>> 6)&0x3F);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>> 0)&0x3F);\n        banout_append_char(banout, proto, c2);\n    } else if (c & ~0x7FF) {\n        unsigned c2;\n        c2 = 0xE0 | ((c>>12)&0x0F);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>> 6)&0x3F);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>> 0)&0x3F);\n        banout_append_char(banout, proto, c2);\n    } else if (c & ~0x7f) {\n        unsigned c2;\n        c2 = 0xc0 | ((c>> 6)&0x1F);\n        banout_append_char(banout, proto, c2);\n        c2 = 0x80 | ((c>> 0)&0x3F);\n        banout_append_char(banout, proto, c2);\n    } else\n        banout_append_char(banout, proto, c);\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic struct BannerOutput *\nbanout_new_proto(struct BannerOutput *banout, unsigned proto)\n{\n    struct BannerOutput *p;\n\n    if (banout->protocol == 0 && banout->length == 0) {\n        banout->protocol = proto;\n        return banout;\n    }\n\n    p = CALLOC(1, sizeof(*p));\n    p->protocol = proto;\n    p->max_length = sizeof(p->banner);\n    p->next = banout->next;\n    banout->next = p;\n    return p;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic struct BannerOutput *\nbanout_expand(struct BannerOutput *banout, struct BannerOutput *p)\n{\n    struct BannerOutput *n;\n\n    /* Double the space */\n    n = MALLOC(  offsetof(struct BannerOutput, banner)\n                 + 2 * p->max_length);\n\n    /* Copy the old structure */\n    memcpy(n, p, offsetof(struct BannerOutput, banner) + p->max_length);\n    n->max_length *= 2;\n\n    if (p == banout) {\n        /* 'p' is the head of the linked list, so we can't free it */\n        banout->next = n;\n        p->protocol = 0;\n        p->length = 0;\n    } else {\n        /* 'p' is not the head, so replace it in the list with 'n',\n         * then free it. */\n        while (banout->next != p)\n            banout = banout->next;\n        banout->next = n;\n        free(p);\n    }\n\n    return n;\n}\n\n\n\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nbanout_vprintf(struct BannerOutput *banout, unsigned proto,\n               const char *fmt, va_list marker) {\n    char str[10];\n    int len;\n    va_list marker_cpy;  // a va_list is consumed when passed to vsnprintf.\n    \n    va_copy(marker_cpy, marker);\n    len = vsnprintf(str, sizeof(str), fmt, marker_cpy);\n    va_end(marker_cpy);\n    if (len > sizeof(str)-1) {\n        char *tmp = malloc(len+1);\n        vsnprintf(tmp, len+1, fmt, marker);\n        banout_append(banout, proto, tmp, len);\n        free(tmp);\n    } else {\n        banout_append(banout, proto, str, len);\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_printf(struct BannerOutput *banout, unsigned proto, const char *fmt, ...) {\n    va_list marker;\n\n    va_start(marker, fmt);\n    banout_vprintf(banout, proto, fmt, marker);\n    va_end(marker);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nbanout_append(struct BannerOutput *banout, unsigned proto, \n              const void *px, size_t length)\n{\n    struct BannerOutput *p;\n\n    if (length == AUTO_LEN)\n        length = strlen((const char*)px);\n    \n    /*\n     * Get the matching record for the protocol (e.g. HTML, SSL, etc.).\n     * If it doesn't already exist, add the protocol object to the linked\n     * list.\n     */\n    p = banout_find_proto(banout, proto);\n    if (p == NULL) {\n        p = banout_new_proto(banout, proto);\n    }\n\n\n    /*\n     * If the current object isn't big enough, expand it\n     */\n    while (p->length + length >= p->max_length) {\n        p = banout_expand(banout, p);\n    }\n\n    \n    \n    /*\n     * Now that we are assured there is enough space, do the copy\n     */\n    memcpy(p->banner + p->length, px, length);\n    p->length = (unsigned)(p->length + length);\n\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic const char *b64 =\n\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\"abcdefghijklmnopqrstuvwxyz\"\n\"0123456789\"\n\"+/\";\n\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nbanout_init_base64(struct BannerBase64 *base64)\n{\n    base64->state = 0;\n    base64->temp = 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nbanout_append_base64(struct BannerOutput *banout, unsigned proto,\n                     const void *vpx, size_t length,\n                     struct BannerBase64 *base64)\n{\n    const unsigned char *px = (const unsigned char *)vpx;\n    size_t i;\n    unsigned x = base64->temp;\n    unsigned state = base64->state;\n    \n    for (i=0; i<length; i++) {\n        switch (state) {\n            case 0:\n                x = px[i]<<16;\n                state++;\n                break;\n            case 1:\n                x |= px[i]<<8;\n                state++;\n                break;\n            case 2:\n                x |= px[i];\n                state = 0;\n                banout_append_char(banout, proto, b64[(x>>18)&0x3F]);\n                banout_append_char(banout, proto, b64[(x>>12)&0x3F]);\n                banout_append_char(banout, proto, b64[(x>> 6)&0x3F]);\n                banout_append_char(banout, proto, b64[(x>> 0)&0x3F]);\n        }\n    }\n    \n    base64->temp = x;\n    base64->state = state;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nbanout_finalize_base64(struct BannerOutput *banout, unsigned proto,\n                       struct BannerBase64 *base64)\n{\n    unsigned x = base64->temp;\n    switch (base64->state) {\n        case 0:\n            break;\n        case 1:\n            banout_append_char(banout, proto, b64[(x>>18)&0x3F]);\n            banout_append_char(banout, proto, b64[(x>>12)&0x3F]);\n            banout_append_char(banout, proto, '=');\n            banout_append_char(banout, proto, '=');\n            break;\n        case 2:\n            banout_append_char(banout, proto, b64[(x>>18)&0x3F]);\n            banout_append_char(banout, proto, b64[(x>>12)&0x3F]);\n            banout_append_char(banout, proto, b64[(x>>6)&0x3F]);\n            banout_append_char(banout, proto, '=');\n            break;\n    }\n}\n\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int\nbanout_string_equals(struct BannerOutput *banout, unsigned proto,\n                     const char *rhs)\n{\n    const unsigned char *lhs = banout_string(banout, proto);\n    size_t lhs_length = banout_string_length(banout, proto);\n    size_t rhs_length = strlen(rhs);\n    \n    if (lhs_length != rhs_length)\n        return 0;\n    return memcmp(lhs, rhs, rhs_length) == 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nint\nbanout_selftest(void)\n{\n    /*\n     * Basic test\n     */\n    {\n        struct BannerOutput banout[1];\n        unsigned i;\n        \n        banout_init(banout);\n        \n        for (i=0; i<10; i++) {\n            banout_append(banout, 1, \"xxxx\", 4);\n            banout_append(banout, 2, \"yyyyy\", 5);\n        }\n        \n        if (banout->next == 0)\n            return 1;\n        if (banout_string_length(banout, 1) != 40)\n            return 1;\n        if (banout_string_length(banout, 2) != 50)\n            return 1;\n        \n        banout_release(banout);\n        if (banout->next != 0)\n            return 1;\n    }\n    \n    /*\n     * Test BASE64 encoding. We are going to do strings of various lengths\n     * in order to test the boundary condition of finalizing various strings\n     * properly\n     */\n    {\n        struct BannerOutput banout[1];\n        struct BannerBase64 base64[1];\n    \n        banout_init(banout);\n\n        banout_init_base64(base64);\n        banout_append_base64(banout, 1, \"x\", 1, base64);\n        banout_finalize_base64(banout, 1, base64);\n        \n        banout_init_base64(base64);\n        banout_append_base64(banout, 2, \"bc\", 2, base64);\n        banout_finalize_base64(banout, 2, base64);\n        \n        banout_init_base64(base64);\n        banout_append_base64(banout, 3, \"mno\", 3, base64);\n        banout_finalize_base64(banout, 3, base64);\n        \n        banout_init_base64(base64);\n        banout_append_base64(banout, 4, \"stuv\", 4, base64);\n        banout_finalize_base64(banout, 4, base64);\n        \n        banout_init_base64(base64);\n        banout_append_base64(banout, 5, \"fghij\", 5, base64);\n        banout_finalize_base64(banout, 5, base64);\n        \n        \n        if (!banout_string_equals(banout, 1, \"eA==\"))\n            return 1;\n        if (!banout_string_equals(banout, 2, \"YmM=\"))\n            return 1;\n        if (!banout_string_equals(banout, 3, \"bW5v\"))\n            return 1;\n        if (!banout_string_equals(banout, 4, \"c3R1dg==\"))\n            return 1;\n        if (!banout_string_equals(banout, 5, \"ZmdoaWo=\"))\n            return 1;\n\n        banout_release(banout);\n    }\n    \n    \n    return 0;\n}\n\n"
  },
  {
    "path": "src/proto-banout.h",
    "content": "#ifndef PROTO_BANOUT_H\n#define PROTO_BANOUT_H\nstruct BannerBase64;\n\n/**\n * A structure for tracking one or more banners from a target.\n * There can be multiple banner information from a target, such\n * as SSL certificates, or HTTP headers separate from HTML\n * content, and so on. This will be exploited more in the future\n * for extracting multiple bits of information from the same\n * port, but giving them different labels. This will also be\n * used for doing optional stuff, such as grabbing the entire\n * default webpage when connecting to port 80.\n */\nstruct BannerOutput {\n    struct BannerOutput *next;\n    unsigned protocol;\n    unsigned length;\n    unsigned max_length;\n    unsigned char banner[200];\n};\n\n/**\n * Initialize the list of banners. This doesn't allocate any\n * memory, such sets it to zero.\n */\nvoid\nbanout_init(struct BannerOutput *banout);\n\n/**\n * Release any memory. If the list contains only one short\n * banner, then no memory was allocated, so nothing gets\n * freed.\n */\nvoid\nbanout_release(struct BannerOutput *banout);\n\n/**\n * Just appends a newline '\\n' character. In the future, this may do something\n * more interesting, which is why it's a separate function.\n */\nvoid\nbanout_newline(struct BannerOutput *banout, unsigned proto);\n\n/**\n * End the banner of the current. This is called when the protocol parser\n * knows it's at the end. The major reason for this is processing the\n * SSL certificates, so that each certificate comes back as a separate\n * banner.\n */\nvoid\nbanout_end(struct BannerOutput *banout, unsigned proto);\n\n/**\n * Append text onto the banner. If this exceeds the buffer, then the\n * buffer will be expanded.\n */\nvoid\nbanout_append(struct BannerOutput *banout, unsigned proto, const void *px, size_t length);\n#define AUTO_LEN ((size_t)~0)\n\nvoid\nbanout_printf(struct BannerOutput *banout, unsigned proto, const char *fmt, ...);\n\n/**\n * Append a single character to the banner.\n */\nvoid\nbanout_append_char(struct BannerOutput *banout, unsigned proto, int c);\n\n/**\n * Append an integer, with hex digits, with the specified number of\n * digits\n */\nvoid\nbanout_append_hexint(struct BannerOutput *banout, unsigned proto, unsigned long long number, int digits);\n\nvoid\nbanout_append_unicode(struct BannerOutput *banout, unsigned proto, unsigned c);\n\n/**\n * Select a specific string (of the specified protocol).\n * The \"banner output\" can have multiple protocol objects associated\n * with it, such as an SSL protocol object and an X.509 certificate.\n * Thus, instead of just grabbing the string, we need to grab the\n * specific protocol instead.\n */\nconst unsigned char *\nbanout_string(const struct BannerOutput *banout, unsigned proto);\n\n/**\n * Get the length of a specific string of the specified protocol.\n * This is the matching function to banout_string.\n */\nunsigned\nbanout_string_length(const struct BannerOutput *banout, unsigned proto);\n\n\n/**\n * Prepare to start calling banout_append_base64()\n */\nvoid\nbanout_init_base64(struct BannerBase64 *base64);\n\n/**\n * Converts the string to BASE64 and appends it to the banner.\n * Since this can be called iteratively as new input arrives,\n * a call to banout_init_base64() must be called before the first fragment,\n * and a call to banout_finalize_base64() must be called after the last\n * fragment\n */\nvoid\nbanout_append_base64(struct BannerOutput *banout, unsigned proto,\n                     const void *px, size_t length,\n                     struct BannerBase64 *base64);\n\n/**\n * Finish encoding the BASE64 string, appending the '==' things on the\n * end if necessary\n */\nvoid\nbanout_finalize_base64(struct BannerOutput *banout, unsigned proto,\n                       struct BannerBase64 *base64);\n\n/**\n * Compares a banner string to a fixed string. This is primarily used\n * in the \"self-test\" feature in order to compare parsed banners from\n * expected banners.\n */\nunsigned\nbanout_is_equal(const struct BannerOutput *banout, unsigned proto,\n                const char *string);\n\nunsigned\nbanout_is_contains(const struct BannerOutput *banout, unsigned proto,\n                const char *string);\n\n/**\n * Do the typical unit/regression test, for this module.\n */\nint\nbanout_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/proto-coap.c",
    "content": "/*\n    CoAP - Constrained Application Protocol\n    https://en.wikipedia.org/wiki/Constrained_Application_Protocol\n \n This is a very simple protocol for interacting with IoT devices\n that have a minimal amount of resources, such as less than a\n megabyte of RAM.\n \n From a scanner point of view, we want to execute the equivalent\n of:\n    GET /.well-known/core\n This will return the list of additional items that we can access\n on the target device.\n \n 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |Ver| T |  TKL  |      Code     |          Message ID           |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |   Token (if any, TKL bytes) ...\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |   Options (if any) ...\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |1 1 1 1 1 1 1 1|    Payload (if any) ...\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n*/\n\n#include \"proto-coap.h\"\n#include \"proto-banner1.h\"\n#include \"smack.h\"\n#include \"unusedparm.h\"\n#include \"util-logger.h\"\n#include \"masscan-app.h\"\n#include \"output.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-ssl.h\"\n#include \"proto-udp.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n#include \"util-malloc.h\"\n#include \"util-safefunc.h\"\n#include \"util-bool.h\"\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n\nstruct CoapLink\n{\n    unsigned link_offset;\n    unsigned link_length;\n    unsigned parms_offset;\n    unsigned parms_length;\n};\n\n/****************************************************************************\n ****************************************************************************/\nstatic const char *\nresponse_code(unsigned code)\n{\n#define CODE(x,y) (((x)<<5) | (y))\n    switch (code) {\n        case CODE(2,0): return \"Okay\";\n        case CODE(2,1): return \"Created\";\n        case CODE(2,2): return \"Deleted\";\n        case CODE(2,3): return \"Valid\";\n        case CODE(2,4): return \"Changed\";\n        case CODE(2,5): return \"Content\";\n        \n        case CODE(4,0): return \"Bad Request\";\n        case CODE(4,1): return \"Unauthorized\";\n        case CODE(4,2): return \"Bad Option\";\n        case CODE(4,3): return \"Forbidden\";\n        case CODE(4,4): return \"Not Found\";\n        case CODE(4,5): return \"Method Not Allowed\";\n        case CODE(4,6): return \"Not Acceptable\";\n        case CODE(4,12): return \"Precondition Failed\";\n        case CODE(4,13): return \"Request Too Large\";\n        case CODE(4,15): return \"Unsupported Content-Format\";\n            \n        case CODE(5,0): return \"Internal Server Error\";\n        case CODE(5,1): return \"Not Implemented\";\n        case CODE(5,2): return \"Bad Gateway\";\n        case CODE(5,3): return \"Service Unavailable\";\n        case CODE(5,4): return \"Gateway Timeout\";\n        case CODE(5,5): return \"Proxying Not Supported\";\n    }\n    \n    switch (code>>5) {\n        case 2: return \"Okay\";\n        case 4: return \"Error\";\n        default: return \"PARSE_ERR\";\n    }\n}\n\n/****************************************************************************\n * RFC5987\n *  attr-char     = ALPHA / DIGIT\n *                  / \"!\" / \"#\" / \"$\" / \"&\" / \"+\" / \"-\" / \".\"\n *                  / \"^\" / \"_\" / \"`\" / \"|\" / \"~\"\n *                  ; token except ( \"*\" / \"'\" / \"%\" )\n * We need this in parsing the links, which may have parameters afterwards\n * whose names are in this format.\n ****************************************************************************/\nstatic bool\nis_attr_char(unsigned c)\n{\n    switch (c) {\n        case '!': case '#': case '$': case '&': case '+': case '-': case '.':\n        case '^': case '_': case '`': case '|': case '~':\n            return true;\n        default:\n            return isalnum(c) != 0;\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic struct CoapLink *\nparse_links(const unsigned char *px, unsigned offset, unsigned length, size_t *r_count)\n{\n    struct CoapLink *l;\n    struct CoapLink *links;\n    unsigned count = 0;\n    enum {\n        LINK_BEGIN=0,\n        LINK_VALUE,\n        LINK_END,\n        PARM_BEGIN,\n        PARM_NAME_BEGIN,\n        PARM_VALUE_BEGIN,\n        PARM_QUOTED,\n        PARM_QUOTED_ESCAPE,\n        PARM_NAME,\n        PARM_VALUE,\n        INVALID\n    } state = LINK_BEGIN;\n    \n    /* For selftesting purposes, we pass in nul-terminated strings,\n     * indicated by a length of (~0) */\n    if (length == ~0)\n        length = (unsigned)strlen((const char *)px);\n    \n    /* Allocate space for at least one result */\n    links = CALLOC(1, sizeof(*links));\n    l = &links[0];\n    l->parms_offset = offset;\n    l->link_offset = offset;\n    \n    for (; offset < length; offset++)\n    switch (state) {\n        case INVALID:\n            offset = length;\n            break;\n        case LINK_BEGIN:\n            /* Ignore leading whitespace */\n            if (isspace(px[offset]))\n                continue;\n            \n            /* Links must start with \"<\" character */\n            if (px[offset] != '<') {\n                state = INVALID;\n                break;\n            }\n            \n            \n            /* Reserve space for next link */\n            links = REALLOCARRAY(links, ++count+1, sizeof(*links));\n            links[count].link_offset = length; /* indicate end-of-list by pointing to end-of-input */\n            links[count].link_length = 0;\n            links[count].parms_offset = length;\n            links[count].parms_length = 0;\n            \n            /* Grab a pointer to this <link> */\n            l = &links[count-1];\n            l->link_offset = offset+1;\n            l->parms_offset = l->link_offset;\n            \n            state = LINK_VALUE;\n            break;\n        case LINK_VALUE:\n            if (px[offset] == '>') {\n                /* End of the link, it may be followed by parameters */\n                state = LINK_END;\n            } else {\n                l->link_length++;\n            }\n            break;\n        case LINK_END:\n            l->parms_offset = offset+1;\n            l->parms_length = 0;\n            if (isspace(px[offset])) {\n                continue;\n            } else if (px[offset] == ',') {\n                /* next link */\n                state = LINK_BEGIN;\n            } else if (px[offset] == ';') {\n                state = PARM_NAME_BEGIN;\n            } else {\n                state = INVALID;\n            }\n            break;\n        case PARM_BEGIN:\n            if (isspace(px[offset])) {\n                continue;\n            } else if (px[offset] == ',') {\n                /* next link */\n                l->parms_length = offset - l->parms_offset;\n                state = LINK_BEGIN;\n            } else if (px[offset] == ';') {\n                state = PARM_NAME_BEGIN;\n            } else {\n                state = INVALID;\n            }\n            break;\n        case PARM_NAME_BEGIN:\n            if (isspace(px[offset]))\n                continue;\n            if (!is_attr_char(px[offset]))\n                state = INVALID;\n            else\n                state = PARM_NAME;\n            break;\n        case PARM_NAME:\n            if (isspace(px[offset])) {\n                continue;\n            } else if (px[offset] == '=') {\n                state = PARM_VALUE_BEGIN;\n            } else if (!is_attr_char(px[offset])) {\n                state = INVALID;\n            }\n            break;\n        case PARM_VALUE_BEGIN:\n            if (isspace(px[offset]))\n                continue;\n            else if (px[offset] == '\\\"') {\n                state = PARM_QUOTED;\n            } else if (offset == ';') {\n                state = PARM_NAME_BEGIN;\n            } else if (px[offset] == ',') {\n                l->parms_length = offset - l->parms_offset;\n                state = LINK_BEGIN;\n            } else\n                state = PARM_VALUE;\n            break;\n        case PARM_VALUE:\n            if (isspace(px[offset]))\n                continue;\n            else if (px[offset] == ';')\n                state = PARM_NAME_BEGIN;\n            else if (px[offset] == ',') {\n                l->parms_length = offset - l->parms_offset;\n                state = LINK_BEGIN;\n            } else {\n                ; /* do nothing */\n            }\n            break;\n        case PARM_QUOTED:\n            /* RFC2616:\n             quoted-string  = ( <\"> *(qdtext | quoted-pair ) <\"> )\n             qdtext         = <any TEXT except <\">>\n             quoted-pair    = \"\\\" CHAR\n             */\n            if (px[offset] == '\\\\') {\n                state = PARM_QUOTED_ESCAPE;\n            } else if (px[offset] == '\\\"') {\n                state = PARM_VALUE;\n            }\n            break;\n        case PARM_QUOTED_ESCAPE:\n            state = PARM_QUOTED;\n            break;\n        default:\n            fprintf(stderr, \"invalid state\\n\");\n            state = INVALID;\n            break;\n                        \n    }\n\n    /* Return an array of links and a count of the number of links */\n    *r_count = count;\n    return links;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic bool\ncoap_parse(const unsigned char *px, size_t length, struct BannerOutput *banout,\n           unsigned *request_id)\n{\n    unsigned version;\n    unsigned type;\n    unsigned code = 0;\n    unsigned token_length = 0;\n    unsigned long long token = 0;\n    unsigned offset;\n    unsigned optnum;\n    unsigned content_format;\n    size_t i;\n\n    /* All coap responses will be at least 8 bytes */\n    if (length < 4) {\n        LOG(3, \"[-] CoAP: short length\\n\");\n        goto not_this_protocol;\n    }\n    \n    /*\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |Ver| T |  TKL  |      Code     |          Message ID           |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |   Token (if any, TKL bytes) ...\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |   Options (if any) ...\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |1 1 1 1 1 1 1 1|    Payload (if any) ...\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     */\n    version = (px[0]>>6) & 3;\n    type = (px[0]>>4) & 3;\n    \n    token_length = px[0] & 0x0F;\n    code = px[1];\n    *request_id = px[2]<<8 | px[3];\n    \n    /* Only version supported is v1 */\n    if (version != 1) {\n        LOG(3, \"[-] CoAP: version=%u\\n\", version);\n        goto not_this_protocol;\n    }\n    \n    /* Only ACKs suported */\n    if (type != 2) {\n        LOG(3, \"[-] CoAP: type=%u\\n\", type);\n        goto not_this_protocol;\n    }\n    \n    /* Only token lengths up to 8 bytes are supported.\n     * Token length must fit within the packet */\n    if (token_length > 8 || 4 + token_length > length) {\n        LOG(3, \"[-] CoAP: token-length=%u\\n\", token_length);\n        goto not_this_protocol;\n    }\n    \n    token = 0;\n    for (i=0; i<token_length; i++) {\n        token = token << 8ULL;\n        token = token | (unsigned long long)px[i];\n    }\n    \n    \n    /* Response code */\n    {\n        char buf[64];\n        snprintf(buf, sizeof(buf), \"rsp=%u.%u(%s)\", code>>5, code&0x1F, response_code(code));\n        banout_append(banout, PROTO_COAP, buf, AUTO_LEN);\n        //code >>= 5;\n    }\n    \n    \n    /* If there was a token, the print it. */\n    if (token) {\n        char buf[64];\n        snprintf(buf, sizeof(buf), \" token=0x%llu\", token);\n        banout_append(banout, PROTO_COAP, buf, AUTO_LEN);\n    }\n    \n    /*\n     * Now process the options fields\n     \n     0   1   2   3   4   5   6   7\n     +---------------+---------------+\n     |               |               |\n     |  Option Delta | Option Length |   1 byte\n     |               |               |\n     +---------------+---------------+\n     \\                               \\\n     /         Option Delta          /   0-2 bytes\n     \\          (extended)           \\\n     +-------------------------------+\n     \\                               \\\n     /         Option Length         /   0-2 bytes\n     \\          (extended)           \\\n     +-------------------------------+\n     \\                               \\\n     /                               /\n     \\                               \\\n     /         Option Value          /   0 or more bytes\n     \\                               \\\n     /                               /\n     \\                               \\\n     +-------------------------------+\n     */\n    offset = 4 + token_length;\n    optnum = 0;\n    content_format = 0;\n    while (offset < length) {\n        unsigned delta;\n        unsigned opt;\n        unsigned optlen;\n        \n        /* Get the 'opt' byte */\n        opt = px[offset++];\n        if (opt == 0xFF)\n            break;\n        optlen = (opt>>0) & 0x0F;\n        delta = (opt>>4) & 0x0F;\n        \n        /* Decode the delta field */\n        switch (delta) {\n            default:\n                optnum += delta;\n                break;\n            case 13:\n                if (offset >= length) {\n                    banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n                    optnum = 0xFFFFFFFF;\n                } else {\n                    delta = px[offset++] + 13;\n                    optnum += delta;\n                }\n                break;\n            case 14:\n                if (offset + 1 >= length) {\n                    banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n                    optnum = 0xFFFFFFFF;\n                } else {\n                    delta = px[offset+0]<<8 | px[offset+1];\n                    delta += 269;\n                    offset += 2;\n                    optnum += delta;\n                }\n                break;\n            case 15:\n                if (optlen != 15)\n                    banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n                optnum = 0xFFFFFFFF;\n        }\n        \n        /* Decode the optlen field */\n        switch (optlen) {\n            default:\n                break;\n            case 13:\n                if (offset >= length) {\n                    banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n                    optnum = 0xFFFFFFFF;\n                } else {\n                    optlen = px[offset++] + 13;\n                }\n                break;\n            case 14:\n                if (offset + 1 >= length) {\n                    banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n                    optnum = 0xFFFFFFFF;\n                } else {\n                    optlen = px[offset+0]<<8 | px[offset+1];\n                    optlen += 269;\n                    offset += 2;\n                }\n                break;\n        }\n        if (offset + optlen > length) {\n            banout_append(banout, PROTO_COAP, \" PARSE_ERR\", AUTO_LEN);\n            optnum = 0xFFFFFFFF;\n        }\n        \n        /* Process the option contents */\n        switch (optnum) {\n            case 0xFFFFFFFF:\n                break;\n            case  1: banout_append(banout, PROTO_COAP, \" /If-Match/\", AUTO_LEN); break;\n            case  3: banout_append(banout, PROTO_COAP, \" /Uri-Host/\", AUTO_LEN); break;\n            case  4: banout_append(banout, PROTO_COAP, \" /Etag\", AUTO_LEN); break;\n            case  5: banout_append(banout, PROTO_COAP, \" /If-None-Match/\", AUTO_LEN); break;\n            case  7: banout_append(banout, PROTO_COAP, \" /Uri-Port/\", AUTO_LEN); break;\n            case  8: banout_append(banout, PROTO_COAP, \" /Location-Path/\", AUTO_LEN); break;\n            case 11: banout_append(banout, PROTO_COAP, \" /Uri-Path/\", AUTO_LEN); break;\n            case 12:\n                banout_append(banout, PROTO_COAP, \" /Content-Format/\", AUTO_LEN);\n                content_format = 0;\n                \n                for (i=0; i<optlen; i++) {\n                    content_format = content_format<<8 | px[offset+i];\n                }\n                break;\n            case 14: banout_append(banout, PROTO_COAP, \" /Max-Age/\", AUTO_LEN); break;\n            case 15: banout_append(banout, PROTO_COAP, \" /Uri-Query/\", AUTO_LEN); break;\n            case 17: banout_append(banout, PROTO_COAP, \" /Accept/\", AUTO_LEN); break;\n            case 20: banout_append(banout, PROTO_COAP, \" /Location-Query/\", AUTO_LEN); break;\n            case 35: banout_append(banout, PROTO_COAP, \" /Proxy-Uri/\", AUTO_LEN); break;\n            case 39: banout_append(banout, PROTO_COAP, \" /Proxy-Scheme/\", AUTO_LEN); break;\n            case 60: banout_append(banout, PROTO_COAP, \" /Size1/\", AUTO_LEN); break;\n            default: banout_append(banout, PROTO_COAP, \" /(Unknown)/\", AUTO_LEN); break;\n                \n        }\n        \n        if (optnum == 0xFFFFFFFF)\n            break;\n        \n        offset += optlen;\n    }\n    \n    switch (content_format) {\n        case  0: banout_append(banout, PROTO_COAP, \" text-plain\", AUTO_LEN); break;\n        case 40:\n            banout_append(banout, PROTO_COAP, \" application/link-format\", AUTO_LEN);\n        {\n            struct CoapLink *links;\n            size_t count = 0;\n            \n            links = parse_links(px, offset, (unsigned)length, &count);\n            for (i=0; i<count; i++) {\n                banout_append(banout, PROTO_COAP, \" \", AUTO_LEN);\n                banout_append(banout, PROTO_COAP, px+links[i].link_offset, links[i].link_length);\n            }\n            free(links);\n        }\n            break;\n        case 41: banout_append(banout, PROTO_COAP, \" application/xml\", AUTO_LEN); break;\n        case 42: banout_append(banout, PROTO_COAP, \" application/octet-stream\", AUTO_LEN); break;\n        case 47: banout_append(banout, PROTO_COAP, \" application/exi\", AUTO_LEN); break;\n        case 50: banout_append(banout, PROTO_COAP, \" application/json\", AUTO_LEN); break;\n        default: banout_append(banout, PROTO_COAP, \" (unknown-content-type)\", AUTO_LEN); break;\n    }\n\n    LOG(3, \"[+] CoAP: valid\\n\");\n    return true;\nnot_this_protocol:\n    return false;\n}\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\ncoap_handle_response(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            )\n{\n    ipaddress ip_them = parsed->src_ip;\n    ipaddress ip_me = parsed->dst_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    unsigned message_id = 0;\n    unsigned cookie;\n    struct BannerOutput banout[1];\n    bool is_valid;\n    \n    LOG(1, \"[+] COAP\\n\");\n    \n    /* Initialize the \"banner output\" module that we'll use to print\n     * pretty text in place of the raw packet */\n    banout_init(banout);\n    \n    /*\n     * Do the protocol parsing\n     */\n    is_valid = coap_parse(px, length, banout, &message_id);\n    \n    \n    /* Validate the \"syn-cookie\" style information, which should match the \"Message ID field*/\n    cookie = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n    /*if ((seqno&0xffff) != message_id)\n     goto not_this_protocol;*/\n    \n    /* See if cookies match. So far, we are allowing responses with the\n     * wrong cookie */\n    if ((cookie&0xffff) != message_id)\n        banout_append(banout, PROTO_COAP, \" IP-MISMATCH\", AUTO_LEN);\n\n    \n    /* Print the banner information, or save to a file, depending */\n    if (is_valid) {\n        output_report_banner(\n            out, timestamp,\n            ip_them, 17 /*udp*/, parsed->port_src,\n            PROTO_COAP,\n            parsed->ip_ttl,\n            banout_string(banout, PROTO_COAP),\n            banout_string_length(banout, PROTO_COAP));\n        banout_release(banout);\n        return 0;\n    } else {\n        banout_release(banout);\n        return default_udp_parse(out, timestamp, px, length, parsed, entropy);\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\ncoap_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    /*\n     The frame header is 4 bytes long, with bytes 2 and 3 being\n     the Message ID.\n     We can also put up to 8 bytes of a \"token\" here instead of\n     just using the message ID.\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |Ver| T |  TKL  |      Code     |          Message ID           |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |   Token (if any, TKL bytes) ...\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    */\n\n    if (length < 4)\n        return 0;\n\n    px[2] = (unsigned char)(seqno >> 8);\n    px[3] = (unsigned char)(seqno >> 0);\n\n    return 0;\n}\n\n\n/****************************************************************************\n * For the selftest code, tests whether the indicated link is within the\n * given list.\n ****************************************************************************/\nstatic int\ntest_is_link(const char *name, const unsigned char *vinput, struct CoapLink *links, size_t count, int line_number)\n{\n    size_t i;\n    size_t name_length = strlen(name);\n    const char *input = (const char *)vinput;\n    \n    for (i=0; i<count; i++) {\n        const char *name2;\n        if (name_length != links[i].link_length)\n            continue;\n        name2 = input + links[i].link_offset;\n        if (memcmp(name2, name, name_length) != 0)\n            continue;\n        return 1; /* found */\n    }\n    \n    fprintf(stderr, \"[-] proto-coap failed at line number %d\\n\", line_number);\n    return 0; /* not found */\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nproto_coap_selftest(void)\n{\n    \n    \n    struct CoapLink *links;\n    size_t count=0;\n\n    /* test quoted */\n    {\n        static const unsigned char *input = (const unsigned char *)\n        \"</sensors/temp>;if=\\\"se\\\\\\\"\\\\;\\\\,\\\\<\\\\>\\\\\\\\nsor\\\",</success>\";\n        links = parse_links(input, 0, (unsigned)(~0), &count);\n        if (!test_is_link(\"/success\", input, links, count, __LINE__))\n            return 1;\n    }\n\n    /* test a simple link */\n    {\n        static const unsigned char *input = (const unsigned char *)\n            \"</sensors/temp>;if=\\\"sensor\\\"\";\n        links = parse_links(input, 0, (unsigned)(~0), &count);\n        if (!test_is_link(\"/sensors/temp\", input, links, count, __LINE__))\n            return 1;\n    }\n\n\n    /* Test a complex dump */\n    {\n        static const unsigned char *input = (const unsigned char *)\n            \"</sensors/temp>;if=\\\"sensor\\\",\"\n            \"</sensors/light>;if=\\\"sensor\\\",\"\n            \"</sensors>;ct=40,\"\n            \"</sensors/temp>;rt=\\\"temperature-c\\\";if=\\\"sensor\\\",\"\n            \"</sensors/light>;rt=\\\"light-lux\\\";if=\\\"sensor\\\",\"\n            \"</sensors/light>;rt=\\\"light-lux\\\";if=\\\"sensor\\\",\"\n            \"</sensors/light>;rt=\\\"light-lux core.sen-light\\\";if=\\\"sensor\\\",\"\n            \"</sensors>;ct=40;title=\\\"Sensor Index\\\",\"\n            \"</sensors/temp>;rt=\\\"temperature-c\\\";if=\\\"sensor\\\",\"\n            \"</sensors/light>;rt=\\\"light-lux\\\";if=\\\"sensor\\\",\"\n            \"<http://www.example.com/sensors/t123>;anchor=\\\"/sensors/temp\\\";rel=\\\"describedby\\\",\"\n            \"</t>;anchor=\\\"/sensors/temp\\\";rel=\\\"alternate\\\",\"\n            \"</firmware/v2.1>;rt=\\\"firmware\\\";sz=262144\"\n            ;\n        links = parse_links(input, 0, (unsigned)(~0), &count);\n        if (!test_is_link(\"/firmware/v2.1\", input, links, count, __LINE__))\n            return 1;\n    }\n    \n    /* Now test an entire packet */\n    {\n        const char input[] =\n            \"\\x60\\x45\\x01\\xce\\xc1\\x28\\xff\\x3c\\x2f\\x72\\x65\\x67\\x69\\x73\\x74\\x65\"\n            \"\\x72\\x3e\\x2c\\x3c\\x2f\\x6e\\x64\\x6d\\x2f\\x64\\x69\\x73\\x3e\\x2c\\x3c\\x2f\"\n            \"\\x6e\\x64\\x6d\\x2f\\x63\\x69\\x3e\\x2c\\x3c\\x2f\\x6d\\x69\\x72\\x72\\x6f\\x72\"\n            \"\\x3e\\x2c\\x3c\\x2f\\x75\\x68\\x70\\x3e\\x2c\\x3c\\x2f\\x6e\\x64\\x6d\\x2f\\x6c\"\n            \"\\x6f\\x67\\x6f\\x75\\x74\\x3e\\x2c\\x3c\\x2f\\x6e\\x64\\x6d\\x2f\\x6c\\x6f\\x67\"\n            \"\\x69\\x6e\\x3e\\x2c\\x3c\\x2f\\x69\\x6e\\x66\\x6f\\x3e\";\n        unsigned request_id = 0;\n        struct BannerOutput banout[1];\n        bool is_valid;\n        banout_init(banout);\n        \n        /* parse a test packet */\n        is_valid = coap_parse( (const unsigned char*)input,\n                   sizeof(input)-1,\n                   banout,\n                   &request_id\n                   );\n        //fprintf(stderr, \"[+] %.*s\\n\", (int)banout_string_length(banout, PROTO_COAP), banout_string(banout, PROTO_COAP));\n        \n        if (!is_valid)\n            return 1;\n        if (request_id != 462)\n            return 1;\n        \n        {\n            const unsigned char *str = banout_string(banout, PROTO_COAP);\n            size_t str_length = banout_string_length(banout, PROTO_COAP);\n            if (str_length <= 16 && memcmp(str, \"rsp=2.5(Content)\", 16) != 0)\n                return 1;\n        }\n        \n        banout_release(banout);\n\n    }\n    \n    return 0;\n}\n"
  },
  {
    "path": "src/proto-coap.h",
    "content": "#ifndef PROTO_COAP_H\n#define PROTO_COAP_H\n#include \"proto-banner1.h\"\nstruct Output;\nstruct PreprocessedInfo;\n\n/*\n * For sending TCP requests and parsing TCP responses.\n */\nextern const struct ProtocolParserStream banner_coap;\n\n/*\n * For parsing UDP responses\n */\nunsigned\ncoap_handle_response(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            );\n\n/* \n * For creating UDP request\n */\nunsigned\ncoap_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\nint\nproto_coap_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/proto-dns-parse.h",
    "content": "#ifndef PROTO_DNS_PARSE_H\n#define PROTO_DNS_PARSE_H\nstruct DomainPointer\n{\n    const unsigned char *name;\n    unsigned length;\n};\nstruct DNS_Incoming\n{\n    unsigned id;        /* transaction id */\n    unsigned is_valid:1;\n    unsigned is_formerr:1;\n    unsigned is_edns0:1;/* edns0 features found */\n    unsigned qr:1;      /* 'query' or 'response' */\n    unsigned aa:1;      /* 'authoritative answer' */\n    unsigned tc:1;      /* 'truncation' */\n    unsigned rd:1;      /* 'recursion desired' */\n    unsigned ra:1;      /* 'recursion available' */\n    unsigned z:3;       /* reserved */\n    unsigned opcode;\n    unsigned rcode;     /* response error code */\n    unsigned qdcount;   /* query count */\n    unsigned ancount;   /* answer count */\n    unsigned nscount;   /* name-server/authority count */\n    unsigned arcount;   /* additional record count */\n    struct {\n        unsigned payload_size;\n        unsigned version;\n        unsigned z;\n    } edns0;\n    const unsigned char *req;\n    unsigned req_length;\n\n    /* the query name */\n    struct DomainPointer query_name;\n    unsigned query_type;\n    unsigned char query_name_buffer[256];\n\n    unsigned rr_count;\n    unsigned short rr_offset[1024];\n    unsigned edns0_offset;\n};\n\n\nvoid\nproto_dns_parse(struct DNS_Incoming *dns, const unsigned char px[], unsigned offset, unsigned max);\n\nunsigned\ndns_name_skip(const unsigned char px[], unsigned offset, unsigned max);\n\n#endif\n"
  },
  {
    "path": "src/proto-dns.c",
    "content": "/*\n\n    Parses DNS response information\n\n    The scanner sends a CHAOS TXT query for \"version.bind\". This module parses\n    DNS in order to find the response string.\n*/\n#include \"proto-udp.h\"\n#include \"proto-dns.h\"\n#include \"proto-dns-parse.h\"\n#include \"proto-preprocess.h\"\n#include \"syn-cookie.h\"\n#include \"util-logger.h\"\n#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"proto-banner1.h\"\n#include \"massip-port.h\"\n#include \"masscan.h\"\n#include \"unusedparm.h\"\n\n\n\n\n#define VERIFY_REMAINING(n) if (offset+(n) > length) return;\n\n\n/****************************************************************************\n * This skips over a name field while parsing the packet. If the name\n * is just a two-byte compression field like 0xc0 0x1a, then it'll skip\n * those two bytes. However, when it does the skip, it does validate\n * the name. Thus, if it's a compressed name, it'll follow the compression\n * links to validate things like long names and infinite recursion.\n ****************************************************************************/\nstatic unsigned\ndns_name_skip_validate(const unsigned char *px, unsigned offset, unsigned length, unsigned name_length)\n{\n    unsigned ERROR = length + 1;\n    unsigned result = offset + 2;\n    unsigned recursion = 0;\n\n    /* 'for all labels' */\n    for (;;) {\n        unsigned len;\n\n        /* validate: the eventual uncompressed name will be less than 255 */\n        if (name_length >= 255)\n            return ERROR;\n\n        /* validate: haven't gone off end of packet */\n        if (offset >= length)\n            return ERROR;\n\n        /* grab length of next label */\n        len = px[offset];\n\n        /* Do two types of processing, either a compression code or a\n         * original label. Note that we can alternate back and forth\n         * between these two states. */\n        if (len & 0xC0) {\n            /* validate: top 2 bits are 11*/\n            if ((len & 0xC0) != 0xC0)\n                return ERROR;\n\n            /* validate: enough bytes left for 2 byte compression field */\n            if (offset + 1 >= length)\n                return ERROR;\n\n            /* follow the compression pointer to the next location */\n            offset = (px[offset]&0x3F)<<8 | px[offset+1];\n\n            /* validate: follow a max of 4 links */\n            if (++recursion > 4)\n                return ERROR;\n        } else {\n            /* we have a normal label */\n            recursion = 0;\n\n            /* If the label-length is zero, then that means we've reached\n             * the end of the name */\n            if (len == 0) {\n                return result; /* end of domain name */\n            }\n\n            /* There are more labels to come, therefore skip this and go\n             * to the next one */\n            name_length += len + 1;\n            offset += len + 1;\n        }\n    }\n}\n\n/****************************************************************************\n * Just skip the name, without validating whether it's valid or not. This\n * is for re-parsing the packet usually, after we've validated that all\n * the names are OK.\n ****************************************************************************/\nunsigned\ndns_name_skip(const unsigned char px[], unsigned offset, unsigned max)\n{\n    unsigned name_length = 0;\n\n    /* Loop through all labels\n     * NOTE: the only way this loops around is in the case of a normal\n     * label. All other conditions cause a 'return' from this function */\n    for (;;) {\n        if (name_length >= 255)\n            return max + 1;\n\n        if (offset >= max)\n            return max + 1;\n\n        switch (px[offset]>>6) {\n        case 0:\n            /* uncompressed label */\n            if (px[offset] == 0) {\n                return offset+1; /* end of domain name */\n            } else {\n                name_length += px[offset] + 1;\n                offset += px[offset] + 1;\n                continue;\n            }\n            break;\n        case 3:\n            /* 0xc0 = compressed name */\n            return dns_name_skip_validate(px, offset, max, name_length);\n        case 2:\n            /* 0x40 - ENDS0 extended label type\n             * rfc2671 section 3.1\n             * I have no idea how to parse this */\n            return max + 1; /* totally clueless how to parse it */\n        case 1:\n            return max + 1;\n        }\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ndns_extract_name(const unsigned char px[], unsigned offset, unsigned max,\n                 struct DomainPointer *name)\n{\n    name->length = 0;\n\n    for (;;) {\n        unsigned len;\n\n        if (offset >= max)\n            return;\n\n        len = px[offset];\n        if (len & 0xC0) {\n            if ((len & 0xC0) != 0xC0)\n                return;\n            else if (offset + 1 >= max)\n                return;\n            else {\n                offset = (px[offset]&0x3F)<<8 | px[offset+1];\n            }\n        } else {\n            if (len == 0) {\n                return; /* end of domain name */\n            } else {\n                memcpy((unsigned char*)name->name+name->length, px+offset, len+1);\n                name->length = (unsigned char)(name->length + len + 1);\n                offset += len + 1;\n            }\n        }\n    }\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nvoid\nproto_dns_parse(struct DNS_Incoming *dns, const unsigned char px[], unsigned offset, unsigned max)\n{\n    static const unsigned MAX_RRs = sizeof(dns->rr_offset)/sizeof(dns->rr_offset[0]);\n    unsigned i;\n\n    dns->is_valid = 0; /* not valid yet until we've successfully parsed*/\n\n    dns->req = px;\n    dns->req_length = max-offset;\n    dns->edns0.payload_size = 512; /* RFC 1035 4.2.1 */\n\n\n    /*\n                                    1  1  1  1  1  1\n      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                      ID                       |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                    QDCOUNT                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                    ANCOUNT                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                    NSCOUNT                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                    ARCOUNT                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    */\n    if (max - offset < 12)\n        return;\n    dns->id = px[offset+0]<<8 | px[offset+1];\n    dns->qr = (px[offset+2]>>7)&1;\n    dns->aa = (px[offset+2]>>2)&1;\n    dns->tc = (px[offset+2]>>1)&1;\n    dns->rd = (px[offset+2]>>0)&1;\n    dns->ra = (px[offset+3]>>7)&1;\n    dns->z = (px[offset+3]>>4)&7;\n    dns->opcode = (px[offset+2]>>3)&0xf;\n    dns->rcode = (px[offset+3]>>0)&0xf;\n    dns->qdcount = px[offset+4]<<8 | px[offset+5];\n    dns->ancount = px[offset+6]<<8 | px[offset+7];\n    dns->nscount = px[offset+8]<<8 | px[offset+9];\n    dns->arcount = px[offset+10]<<8 | px[offset+11];\n    dns->rr_count = 0; /* so far */\n    offset += 12;\n    dns->is_valid = 1;\n    dns->is_formerr = 1; /* is \"formate-error\" until we've finished parsing */\n\n    /*\n                                    1  1  1  1  1  1\n      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                                               |\n    /                     QNAME                     /\n    /                                               /\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                     QTYPE                     |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                     QCLASS                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    */\n    for (i=0; i<dns->qdcount; i++) {\n        unsigned xclass;\n        unsigned xtype;\n        if (dns->rr_count >= MAX_RRs)\n            return;\n        dns->rr_offset[dns->rr_count++] = (unsigned short)offset;\n        offset = dns_name_skip(px, offset, max);\n        offset += 4; /* length of type and class */\n        if (offset > max)\n            return;\n        xclass = px[offset-2]<<8 | px[offset-1];\n        if (xclass != 1 && xclass != 255 && xclass != 3)\n            return;\n        xtype = px[offset-4]<<8 | px[offset-3];\n        dns->query_type = xtype;\n    }\n\n    /*\n                                    1  1  1  1  1  1\n      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                                               |\n    /                                               /\n    /                      NAME                     /\n    |                                               |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                      TYPE                     |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                     CLASS                     |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                      TTL                      |\n    |                                               |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    |                   RDLENGTH                    |\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|\n    /                     RDATA                     /\n    /                                               /\n    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n    */\n    for (i=0; i<dns->ancount + dns->nscount; i++) {\n        unsigned rdlength;\n        if (dns->rr_count >= sizeof(dns->rr_offset)/sizeof(dns->rr_offset[0]))\n            return;\n        dns->rr_offset[dns->rr_count++] = (unsigned short)offset;\n        offset = dns_name_skip(px, offset, max);\n        offset += 10;\n        if (offset > max)\n            return;\n        rdlength = px[offset-2]<<8 | px[offset-1];\n        offset += rdlength;\n        if (offset > max)\n            return;\n    }\n    for (i=0; i<dns->arcount; i++) {\n        unsigned rdlength;\n        if (dns->rr_count >= sizeof(dns->rr_offset)/sizeof(dns->rr_offset[0]))\n            return;\n        dns->rr_offset[dns->rr_count++] = (unsigned short)offset;\n\n        /* ENDS0 OPT parsing */\n        if (offset + 11 <= max && px[offset] == 0 && px[offset+1] == 0 && px[offset+2] == 0x29) {\n            dns->edns0.payload_size = px[offset+3]<<8 | px[offset+4];\n            if (dns->edns0.payload_size < 512)\n                return;\n            dns->rcode |= px[offset+5]<<4;\n            dns->edns0.version = px[offset+6];\n            dns->is_edns0 = 1;\n        }\n\n        offset = dns_name_skip(px, offset, max);\n        offset += 10;\n        if (offset > max)\n            return;\n        rdlength = px[offset-2]<<8 | px[offset-1];\n        offset += rdlength;\n        if (offset > max)\n            return;\n    }\n\n    dns->query_name.name = dns->query_name_buffer;\n    dns_extract_name(px, dns->rr_offset[0], max, &dns->query_name);\n\n    dns->is_formerr = 0;\n    return;\n}\n\n\n/***************************************************************************\n * Set the \"syn-cookie\" style information so that we can validate replies\n * match a valid request. We don't hold \"state\" on the requests, so this\n * becomes a hash of the port/IP information.\n * DNS has a two-byte \"transaction id\" field, so we can't use the full\n * cookie, just the lower two bytes of it.\n * Below in \"handle_dns\", we validate that the cookie is correct.\n ***************************************************************************/\nunsigned\ndns_set_cookie(unsigned char *px, size_t length, uint64_t cookie)\n{\n    if (length > 2) {\n        px[0] = (unsigned char)(cookie >> 8);\n        px[1] = (unsigned char)(cookie >> 0);\n        return cookie & 0xFFFF;\n    } else\n        return 0;\n}\n\n/***************************************************************************\n * Process a DNS packet received in response to UDP probes to port 53.\n * This function has three main tasks:\n *  - parse the DNS protocol, and make sure it's valid DNS.\n *  - make sure that the DNS response matches a valid request using\n *    the \"syn-cookie\" approach.\n *  - parse the \"version.bind\" response and report it as the version\n *    string for the banner.\n ***************************************************************************/\nunsigned\nhandle_dns(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length, \n            struct PreprocessedInfo *parsed,\n            uint64_t entropy)\n{\n    ipaddress ip_them = parsed->src_ip;\n    ipaddress ip_me = parsed->dst_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    struct DNS_Incoming dns[1];\n    unsigned offset;\n    uint64_t seqno;\n    const char *reason = 0;\n\n\n    seqno = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n\n    proto_dns_parse(dns, px, parsed->app_offset, parsed->app_offset + parsed->app_length);\n\n    if ((seqno & 0xFFFF) != dns->id)\n        return 1;\n\n    /*\n     * In practice, DNS queries always have the query count set to 1,\n     * though in theory servers could support multiple queries in a \n     * single request, almost none of them do\n     */\n    if (dns->qr != 1)\n        return 0;\n    \n    /*\n     * If we get back NOERROR, we drop through and extract the strings in\n     * the packet. Otherwise, we report the error here.\n     */\n    switch (dns->rcode) {\n        case 0: reason = 0; break; /* NOERROR */\n        case 1: reason = \"1:FORMERR\"; break;\n        case 2: reason = \"2:SERVFAIL\"; break;\n        case 3: reason = \"3:NXDOMAIN\"; break;\n        case 4: reason = \"4:NOTIMP\"; break;\n        case 5: reason = \"5:REFUSED\"; break;\n        case 6: reason = \"6:YXDOMAIN\"; break;\n        case 7: reason = \"7:XRRSET\"; break;\n        case 8: reason = \"8:NOTAUTH\"; break;\n        case 9: reason = \"9:NOTZONE\"; break;\n    }\n    if (reason != 0) {\n        output_report_banner(\n                         out, timestamp,\n                         ip_them, 17, port_them,\n                         PROTO_DNS_VERSIONBIND,\n                         parsed->ip_ttl,\n                         (const unsigned char*)reason,\n                         (unsigned)strlen(reason));\n        return 0;\n    }\n    \n    /*if (dns->qdcount != 1)\n        return 0;\n    if (dns->ancount < 1)\n        return 0;\n    if (dns->rr_count < 2)\n        return 0;*/\n\n\n    offset = dns->rr_offset[1];\n    offset = dns_name_skip(px, offset, length);\n    if (offset + 10 >= length)\n        return 0;\n\n    {\n        unsigned type = px[offset+0]<<8 | px[offset+1];\n        unsigned xclass = px[offset+2]<<8 | px[offset+3];\n        unsigned rrlen = px[offset+8]<<8 | px[offset+9];\n        unsigned txtlen = px[offset+10];\n\n        offset += 11;\n\n        /* Make sure can't exceed bounds of RR */\n        if (txtlen > length - offset)\n            txtlen = length - offset;\n        \n        if (rrlen == 0 || txtlen > rrlen-1)\n            return 0;\n        if (type != 0x10 || xclass != 3)\n            return 0;\n\n        output_report_banner(\n                out, timestamp,\n                ip_them, 17, port_them,\n                PROTO_DNS_VERSIONBIND,\n                parsed->ip_ttl,\n                px + offset, txtlen);\n        return 1;\n    }\n}\n"
  },
  {
    "path": "src/proto-dns.h",
    "content": "#ifndef PROTO_DNS_H\n#define PROTO_DNS_H\n#include <time.h>\n#include <stdint.h>\nstruct PreprocessedInfo;\nstruct Output;\n\nunsigned handle_dns(struct Output *out, time_t timestamp,\n    const unsigned char *px, unsigned length, struct PreprocessedInfo *parsed, uint64_t entropy);\n\nunsigned dns_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\n#endif\n"
  },
  {
    "path": "src/proto-ftp.c",
    "content": "#include \"proto-ftp.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-ssl.h\"\n#include <ctype.h>\n#include <string.h>\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nftp_parse(  const struct Banner1 *banner1,\n          void *banner1_private,\n          struct StreamState *pstate,\n          const unsigned char *px, size_t length,\n          struct BannerOutput *banout,\n          struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    struct FTPSTUFF *ftp = &pstate->sub.ftp;\n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n\n    \n    for (i=0; i<length; i++) {\n        \n        switch (state) {\n            case 0:\n            case 100:\n                ftp->code = 0;\n                state++;\n                /* fall through */\n            case 1:\n            case 2:\n            case 3:\n            case 101:\n            case 102:\n            case 103:\n                if (!isdigit(px[i]&0xFF)) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                } else {\n                    ftp->code *= 10;\n                    ftp->code += (px[i] - '0');\n                    state++;\n                    banout_append_char(banout, PROTO_FTP, px[i]);\n                }\n                break;\n            case 4:\n            case 104:\n                if (px[i] == ' ') {\n                    ftp->is_last = 1;\n                    state++;\n                    banout_append_char(banout, PROTO_FTP, px[i]);\n                } else if (px[i] == '-') {\n                    ftp->is_last = 0;\n                    state++;\n                    banout_append_char(banout, PROTO_FTP, px[i]);\n                } else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 5:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    if (ftp->is_last) {\n                        tcpapi_send(socket, \"AUTH TLS\\r\\n\", 10, 0);\n                        state = 100;\n                        banout_append_char(banout, PROTO_FTP, px[i]);\n                    } else {\n                        banout_append_char(banout, PROTO_FTP, px[i]);\n                        state = 0;\n                    }\n                } else if (px[i] == '\\0' || !isprint(px[i])) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                    continue;\n                } else {\n                    banout_append_char(banout, PROTO_FTP, px[i]);\n                }\n                break;\n            case 105:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    \n                    if (ftp->code == 234) {\n                        \n                        /* change the state here to SSL */\n                        unsigned port = pstate->port;\n                        memset(pstate, 0, sizeof(*pstate));\n                        pstate->app_proto = PROTO_SSL3;\n                        pstate->is_sent_sslhello = 1;\n                        pstate->port = (unsigned short)port;\n                        state = 0;\n                        \n                        tcpapi_send(socket, banner_ssl.hello, banner_ssl.hello_length, 0);\n                        \n                    } else {\n                        state = 0xffffffff;\n                        tcpapi_close(socket);\n                    }\n                } else if (px[i] == '\\0' || !isprint(px[i])) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                    continue;\n                } else {\n                    banout_append_char(banout, PROTO_FTP, px[i]);\n                }\n                break;\n            default:\n                i = (unsigned)length;\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nftp_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    //banner1->payloads.tcp[21] = &banner_ftp;\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nftp_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_ftp = {\n    \"ftp\", 21, 0, 0, 0,\n    ftp_selftest,\n    ftp_init,\n    ftp_parse,\n};\n"
  },
  {
    "path": "src/proto-ftp.h",
    "content": "#ifndef PROTO_FTP_H\n#define PROTO_FTP_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_ftp;\n\n#endif\n"
  },
  {
    "path": "src/proto-http.c",
    "content": "#include \"proto-http.h\"\n#include \"proto-banner1.h\"\n#include \"stack-tcp-api.h\"\n#include \"smack.h\"\n#include \"unusedparm.h\"\n#include \"util-safefunc.h\"\n#include \"masscan-app.h\"\n#include \"util-malloc.h\"\n#include \"util-bool.h\"\n#include \"stack-tcp-core.h\"\n#include <ctype.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\nenum {\n    HTTPFIELD_INCOMPLETE,\n    HTTPFIELD_SERVER,\n    HTTPFIELD_CONTENT_LENGTH,\n    HTTPFIELD_CONTENT_TYPE,\n    HTTPFIELD_VIA,\n    HTTPFIELD_LOCATION,\n    HTTPFIELD_UNKNOWN,\n    HTTPFIELD_NEWLINE,\n};\nstatic struct Patterns http_fields[] = {\n    {\"Server:\",          7, HTTPFIELD_SERVER,           SMACK_ANCHOR_BEGIN},\n    //{\"Content-Length:\", 15, HTTPFIELD_CONTENT_LENGTH,   SMACK_ANCHOR_BEGIN},\n    //{\"Content-Type:\",   13, HTTPFIELD_CONTENT_TYPE,     SMACK_ANCHOR_BEGIN},\n    {\"Via:\",             4, HTTPFIELD_VIA,              SMACK_ANCHOR_BEGIN},\n    {\"Location:\",        9, HTTPFIELD_LOCATION,         SMACK_ANCHOR_BEGIN},\n    {\":\",                1, HTTPFIELD_UNKNOWN, 0},\n    {\"\\n\",               1, HTTPFIELD_NEWLINE, 0},\n    {0,0,0,0}\n};\nenum {\n    HTML_INCOMPLETE,\n    HTML_TITLE,\n    HTML_UNKNOWN,\n};\nstatic struct Patterns html_fields[] = {\n    {\"<TiTle\",          6, HTML_TITLE, 0},\n    {0,0,0,0}\n};\n\nextern struct ProtocolParserStream banner_http;\n\n/**\n * We might have an incomplete HTTP request header. Thus, as we insert\n * fields into it, we'll add missing components onto the end.\n */\nstatic size_t\n_http_append(unsigned char **inout_header, size_t length1, size_t length2, const char *str)\n{\n    size_t str_length = strlen(str);\n\n    *inout_header = REALLOC(*inout_header, length1 + length2 + str_length + 1);\n    memcpy(*inout_header + length1, str, str_length + 1);\n\n    return str_length;\n}\n\nenum What {spaces, notspaces, end_of_line, end_of_field};\nstatic size_t\n_skip(enum What what, const unsigned char *hdr, size_t offset, size_t header_length)\n{\n    switch (what) {\n    case notspaces:\n        while (offset < header_length && !isspace(hdr[offset]&0xFF))\n            offset++;\n        break;\n    case spaces:\n        while (offset < header_length && hdr[offset] != '\\n' && isspace(hdr[offset]&0xFF))\n            offset++;\n        if (offset < header_length && hdr[offset] == '\\n') {\n            while (offset > 0 && hdr[offset-1] == '\\r')\n                offset--;\n        }\n        break;\n    case end_of_field:\n        while (offset < header_length && hdr[offset] != '\\n')\n            offset++;\n        if (offset < header_length && hdr[offset] == '\\n') {\n            while (offset > 0 && hdr[offset-1] == '\\r')\n                offset--;\n        }\n        break;\n    case end_of_line:\n        while (offset < header_length && hdr[offset] != '\\n')\n            offset++;\n        if (offset < header_length && hdr[offset] == '\\n')\n            offset++;\n        break;\n    }\n    return offset;\n}\n\n/**\n * Used when editing our HTTP prototype request, it replaces the existing\n * field (start..end) with the new field. The header is resized and data moved\n * to accommodate this insertion.\n */\nstatic size_t\n_http_insert(unsigned char **r_hdr, size_t start, size_t end, size_t header_length, size_t field_length, const void *field)\n{\n    size_t old_field_length = (end-start);\n    size_t new_header_length = header_length + field_length - old_field_length;\n    unsigned char *hdr;\n\n    *r_hdr = REALLOC(*r_hdr, new_header_length + 1);\n    hdr = *r_hdr;\n    \n    /* Shrink/expand the field */\n    memmove(&hdr[start + field_length], &hdr[end], header_length - end + 1);\n\n    /* Insert the new header at this location */\n    memcpy(&hdr[start], field, field_length);\n\n    return new_header_length;\n}\n\n/***************************************************************************\n ***************************************************************************/\nsize_t\nhttp_change_requestline(unsigned char **hdr, size_t header_length,\n                    const void *field, size_t field_length, int item)\n{\n    size_t offset;\n    size_t start;\n\n    /* If no length given, calculate length */\n    if (field_length == ~(size_t)0)\n        field_length = strlen((const char *)field);\n\n    /*  GET /example.html HTTP/1.0 \n     * 0111233333333333334\n     * #0 skip leading whitespace\n     * #1 skip past method\n     * #2 skip past space after method\n     * #3 skip past URL field\n     * #4 skip past space after URL\n     * #5 skip past version\n     */\n\n    /* #0 Skip leading whitespace */\n    offset = 0;\n    offset = _skip(spaces, *hdr, offset, header_length);\n\n    /* #1 Method */\n    start = offset;\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \"GET\");\n    offset = _skip(notspaces, *hdr, offset, header_length);\n    if (item == 0) {\n        return _http_insert(hdr, start, offset, header_length, field_length, field);\n    }\n\n    /* #2 Method space */\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \" \");\n    offset = _skip(spaces, *hdr, offset, header_length);\n\n    /* #3 URL */\n    start = offset;\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \"/\");\n    offset = _skip(notspaces, *hdr, offset, header_length);\n    if (item == 1) {\n        return _http_insert(hdr, start, offset, header_length, field_length, field);\n    }\n\n    /* #4 Space after URL */\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \" \");\n    offset = _skip(spaces, *hdr, offset, header_length);\n\n    /* #5 version */\n    start = offset;\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \"HTTP/1.0\");\n    offset = _skip(notspaces, *hdr, offset, header_length);\n    if (item == 2) {\n        return _http_insert(hdr, start, offset, header_length, field_length, field);\n    }\n\n    /* ending line */\n    if (offset == header_length)\n        header_length += _http_append(hdr, header_length, field_length, \"\\r\\n\");\n    offset = _skip(spaces, *hdr, offset, header_length);\n    offset = _skip(end_of_line, *hdr, offset, header_length);\n\n    /* now find a blank line */\n    for (;;) {\n        /* make sure there's at least one line left */\n        if (offset == header_length)\n            header_length += _http_append(hdr, header_length, field_length, \"\\r\\n\");\n        if (offset + 1 == header_length && (*hdr)[offset] == '\\r')\n            header_length += _http_append(hdr, header_length, field_length, \"\\n\");\n\n        start = offset;\n        offset = _skip(end_of_field, *hdr, offset, header_length);\n        if (start == offset) {\n            /* We've reached the end of the header*/\n            offset = _skip(end_of_line, *hdr, offset, header_length);\n            break;\n        }\n\n        if (offset == header_length)\n            header_length += _http_append(hdr, header_length, field_length, \"\\r\\n\");\n        if (offset + 1 == header_length && (*hdr)[offset] == '\\r')\n            header_length += _http_append(hdr, header_length, field_length, \"\\n\");\n        offset = _skip(end_of_line, *hdr, offset, header_length);\n    }\n\n    start = offset;\n    offset = header_length;\n    if (item == 3) {\n        return _http_insert(hdr, start, offset, header_length, field_length, field);\n    }\n    \n\n    return header_length;\n}\n\nstatic size_t\n_field_length(const unsigned char *hdr, size_t offset, size_t hdr_length)\n{\n    size_t original_offset = offset;\n\n    /* Find newline */\n    while (offset < hdr_length && hdr[offset] != '\\n')\n        offset++;\n\n    /* Trim trailing whitespace */\n    while (offset > original_offset && isspace(hdr[offset-1]&0xFF))\n        offset--;\n\n    return offset - original_offset;\n}\n\nstatic size_t _next_field(const unsigned char *hdr, size_t offset, size_t hdr_length)\n{\n    size_t original_offset = offset;\n\n    /* Find newline */\n    while (offset < hdr_length && hdr[offset] != '\\n')\n        offset++;\n\n    /* Remove newline too*/\n    if (offset > original_offset && isspace(hdr[offset-1]&0xFF))\n        offset++;\n\n    return offset;\n}\n\nstatic bool \n_has_field_name(const char *name, size_t name_length, const unsigned char *hdr, size_t offset, size_t hdr_length)\n{\n    size_t x;\n    bool found_colon = false;\n\n    /* Trim leading whitespace */\n    while (offset < hdr_length && isspace(hdr[offset]&0xFF) && hdr[offset] != '\\n')\n        offset++;\n\n    /* Make sure there's enough space left */\n    if (hdr_length - offset < name_length)\n        return false;\n\n    /* Make sure there's colon after */\n    for (x = offset + name_length; x<hdr_length; x++) {\n        unsigned char c = hdr[x] & 0xFF;\n        if (isspace(c))\n            continue;\n        else if (c == ':') {\n            found_colon = true;\n            break;\n        } else {\n            /* some unexpected character was found in the name */\n            return false;\n        }\n    }\n    if (!found_colon)\n        return false;\n\n    /* Compare the name (case insensitive) */\n    return memcasecmp(name, hdr + offset, name_length) == 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nsize_t\nhttp_change_field(unsigned char **inout_header, size_t header_length,\n                    const char *name,\n                    const unsigned char *value, size_t value_length,\n                    int what)\n{\n    unsigned char *hdr = *inout_header;\n    size_t name_length = strlen(name);\n    size_t offset;\n    size_t next_offset;\n\n    /* If field 'name' ends in a colon, trim that. Also, trim whitespace */\n    while (name_length) {\n        unsigned char c = name[name_length-1];\n        if (c == ':' || isspace(c & 0xFF))\n            name_length--;\n        else\n            break;\n    }\n\n    /* If length of the fiend value not specified, then assume\n     * nul-terminated string */\n    if (value_length == ~(size_t)0)\n        value_length = strlen((const char *)value);\n\n    /* Find our field */\n    for (offset = _next_field(hdr, 0, header_length); \n        offset < header_length; \n        offset = _next_field(hdr, offset, header_length)) {\n\n        if (_has_field_name(name, name_length, hdr, offset, header_length)) {\n            break;\n        } else if (_field_length(hdr, offset, header_length) == 0) {\n            /* We reached end without finding field, so insert before end\n             * instead of replacing an existing header. */\n            if (what == http_field_remove)\n                return header_length;\n            what = http_field_add;\n            break;\n        }\n    }\n\n    /* Allocate a new header to replace the old one. We'll allocated\n     * more space than we actually need */\n    *inout_header = REALLOC(*inout_header, header_length + name_length + 2 + value_length + 2 + 1 + 2);\n    hdr = *inout_header;\n\n    /* If we reached the end without finding proper termination, then add\n     * it */\n    if (offset == header_length) {\n        if (offset == 0 || hdr[offset-1] != '\\n') {\n            if (hdr[offset-1] == '\\r')\n                header_length = _http_append(&hdr, header_length, value_length+2, \"\\n\");\n            else\n                header_length = _http_append(&hdr, header_length, value_length+2, \"\\r\\n\");\n        }\n    }\n\n\n    /* Make room for the new header */\n    next_offset = _next_field(hdr, offset, header_length);\n    if (value == NULL || what == http_field_remove) {\n        memmove(&hdr[offset + 0],\n                &hdr[next_offset],\n                header_length - next_offset + 1);\n        header_length += 0 - (next_offset - offset);\n        return header_length;\n    } else if (what == http_field_replace) {\n        /* Replace existing field */\n        memmove(&hdr[offset + name_length + 2 + value_length + 2],\n                &hdr[next_offset],\n                header_length - offset + 1);\n        header_length += (name_length + 2 + value_length + 2) - (next_offset - offset);\n    } else {\n        /* Add a new field onto the end */\n        memmove(&hdr[offset + name_length + 2 + value_length + 2],\n                &hdr[offset],\n                header_length - offset + 1);\n        header_length += (name_length + 2 + value_length + 2);\n    }\n    hdr[header_length] = '\\0';\n\n    /* Copy the new header */\n    memcpy(&hdr[offset], name, name_length);\n    memcpy(&hdr[offset + name_length], \": \", 2);\n    memcpy(&hdr[offset + name_length + 2], value, value_length);\n    memcpy(&hdr[offset + name_length + 2 + value_length], \"\\r\\n\", 2);\n\n    return header_length;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic const char\nhttp_hello[] =      \"GET / HTTP/1.0\\r\\n\"\n#ifdef IVRE_BUILD\n                    \"User-Agent: ivre-masscan/1.3 https://ivre.rocks/\\r\\n\"\n#else\n                    \"User-Agent: ivre-masscan/1.3 https://github.com/robertdavidgraham/\\r\\n\"\n#endif\n                    \"Accept: */*\\r\\n\"\n                    //\"Connection: Keep-Alive\\r\\n\"\n                    //\"Content-Length: 0\\r\\n\"\n                    \"\\r\\n\";\n\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nfield_name(struct BannerOutput *banout, size_t id,\n           struct Patterns *xhttp_fields);\nvoid\nfield_name(struct BannerOutput *banout, size_t id,\n           struct Patterns *xhttp_fields)\n{\n    unsigned i;\n    if (id == HTTPFIELD_INCOMPLETE)\n        return;\n    if (id == HTTPFIELD_UNKNOWN)\n        return;\n    if (id == HTTPFIELD_NEWLINE)\n        return;\n    for (i=0; xhttp_fields[i].pattern; i++) {\n        if (xhttp_fields[i].id == id) {\n            banout_newline(banout, PROTO_HTTP);\n            banout_append(  banout, PROTO_HTTP,\n                            (const unsigned char*)xhttp_fields[i].pattern\n                                + ((xhttp_fields[i].pattern[0]=='<')?1:0), /* bah. hack. ugly. */\n                            xhttp_fields[i].pattern_length\n                                - ((xhttp_fields[i].pattern[0]=='<')?1:0) /* bah. hack. ugly. */\n                          );\n            return;\n        }\n    }\n}\n\n/*****************************************************************************\n * Initialize some stuff that's part of the HTTP state-machine-parser.\n *****************************************************************************/\nstatic void *\nhttp_init(struct Banner1 *b)\n{\n    unsigned i;\n\n    /*\n     * These match HTTP Header-Field: names\n     */\n    b->http_fields = smack_create(\"http\", SMACK_CASE_INSENSITIVE);\n    for (i=0; http_fields[i].pattern; i++)\n        smack_add_pattern(\n                          b->http_fields,\n                          http_fields[i].pattern,\n                          http_fields[i].pattern_length,\n                          http_fields[i].id,\n                          http_fields[i].is_anchored);\n    smack_compile(b->http_fields);\n\n    /*\n     * These match HTML <tag names\n     */\n    b->html_fields = smack_create(\"html\", SMACK_CASE_INSENSITIVE);\n    for (i=0; html_fields[i].pattern; i++)\n        smack_add_pattern(\n                          b->html_fields,\n                          html_fields[i].pattern,\n                          html_fields[i].pattern_length,\n                          html_fields[i].id,\n                          html_fields[i].is_anchored);\n    smack_compile(b->html_fields);\n\n    banner_http.hello = MALLOC(banner_http.hello_length);\n    memcpy((char*)banner_http.hello, http_hello, banner_http.hello_length);\n\n    return b->http_fields;\n}\n\n/***************************************************************************\n * BIZARRE CODE ALERT!\n *\n * This uses a \"byte-by-byte state-machine\" to parse the response HTTP\n * header. This is standard practice for high-performance network\n * devices, but is probably unfamiliar to the average network engineer.\n *\n * The way this works is that each byte of input causes a transition to\n * the next state. That means we can parse the response from a server\n * without having to buffer packets. The server can send the response\n * one byte at a time (one packet for each byte) or in one entire packet.\n * Either way, we don't. We don't need to buffer the entire response\n * header waiting for the final packet to arrive, but handle each packet\n * individually.\n *\n * This is especially useful with our custom TCP stack, which simply\n * rejects out-of-order packets.\n ***************************************************************************/\nstatic void\nhttp_parse(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    unsigned state2;\n    unsigned log_begin = 0;\n    unsigned log_end = 0;\n    size_t id;\n    enum {\n        FIELD_START = 9,\n        FIELD_NAME,\n        FIELD_COLON,\n        FIELD_VALUE,\n        CONTENT,\n        CONTENT_TAG,\n        CONTENT_FIELD,\n        \n        DONE_PARSING\n    };\n\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(socket);\n\n    state2 = (state>>16) & 0xFFFF;\n    id = (state>>8) & 0xFF;\n    state = (state>>0) & 0xFF;\n\n    for (i=0; i<length; i++)\n    switch (state) {\n    case 0: case 1: case 2: case 3: case 4:\n        if (toupper(px[i]) != \"HTTP/\"[state]) {\n            state = DONE_PARSING;\n            tcpapi_close(socket);\n        } else\n            state++;\n        break;\n    case 5:\n        if (px[i] == '.')\n            state++;\n        else if (!isdigit(px[i])) {\n            state = DONE_PARSING;\n            tcpapi_close(socket);\n        }\n        break;\n    case 6:\n        if (isspace(px[i]))\n            state++;\n        else if (!isdigit(px[i])) {\n            state = DONE_PARSING;\n            tcpapi_close(socket);\n        }\n        break;\n    case 7:\n        /* TODO: look for 1xx response code */\n        if (px[i] == '\\n')\n            state = FIELD_START;\n        break;\n    case FIELD_START:\n        if (px[i] == '\\r')\n            break;\n        else if (px[i] == '\\n') {\n            state2 = 0;\n            state = CONTENT;\n            log_end = i;\n            banout_append(banout, PROTO_HTTP, px+log_begin, log_end-log_begin);\n            log_begin = log_end;\n            break;\n        } else {\n            state2 = 0;\n            state = FIELD_NAME;\n            /* drop down */\n        }\n\n    case FIELD_NAME:\n        if (px[i] == '\\r')\n            break;\n        id = smack_search_next(\n                        banner1->http_fields,\n                        &state2,\n                        px, &i, (unsigned)length);\n        i--;\n        if (id == HTTPFIELD_NEWLINE) {\n            state2 = 0;\n            state = FIELD_START;\n        } else if (id == SMACK_NOT_FOUND)\n            ; /* continue here */\n        else if (id == HTTPFIELD_UNKNOWN) {\n            /* Oops, at this point, both \":\" and \"Server:\" will match.\n             * Therefore, we need to make sure \":\" was found, and not\n             * a known field like \"Server:\" */\n            size_t id2;\n\n            id2 = smack_next_match(banner1->http_fields, &state2);\n            if (id2 != SMACK_NOT_FOUND)\n                id = id2;\n\n            state = FIELD_COLON;\n        } else\n            state = FIELD_COLON;\n        break;\n    case FIELD_COLON:\n        if (px[i] == '\\n') {\n            state = FIELD_START;\n            break;\n        } else if (isspace(px[i])) {\n            break;\n        } else {\n            //field_name(banout, id, http_fields);\n            state = FIELD_VALUE;\n            /* drop down */\n        }\n\n    case FIELD_VALUE:\n        if (px[i] == '\\r')\n            break;\n        else if (px[i] == '\\n') {\n            state = FIELD_START;\n            break;\n        }\n        switch (id) {\n        case HTTPFIELD_SERVER:\n            banout_append(banout, PROTO_HTTP_SERVER, &px[i], 1);\n            break;\n        case HTTPFIELD_LOCATION:\n        case HTTPFIELD_VIA:\n            //banner_append(&px[i], 1, banout);\n            break;\n        case HTTPFIELD_CONTENT_LENGTH:\n                if (isdigit(px[i]&0xFF)) {\n                    ; /* TODO: add content length parsing */\n                } else {\n                    id = 0;\n                }\n            break;\n        }\n        break;\n    case CONTENT:\n        {\n            unsigned next = i;\n\n            id = smack_search_next(\n                                   banner1->html_fields,\n                                   &state2,\n                                   px, &next, (unsigned)length);\n\n            if (banner1->is_capture_html) {\n                banout_append(banout, PROTO_HTML_FULL, &px[i], next-i);\n            }\n\n            if (id != SMACK_NOT_FOUND) {\n                state = CONTENT_TAG;\n            }\n\n            i = next - 1;\n        }\n        break;\n    case CONTENT_TAG:\n        for (; i<length; i++) {\n            if (banner1->is_capture_html) {\n                banout_append_char(banout, PROTO_HTML_FULL, px[i]);\n            }\n\n            if (px[i] == '>') {\n                state = CONTENT_FIELD;\n                break;\n            }\n        }\n        break;\n    case CONTENT_FIELD:\n        if (banner1->is_capture_html) {\n            banout_append_char(banout, PROTO_HTML_FULL, px[i]);\n        }\n        if (px[i] == '<')\n            state = CONTENT;\n        else {\n            banout_append_char(banout, PROTO_HTML_TITLE, px[i]);\n        }\n        break;\n    case DONE_PARSING:\n    default:\n        i = (unsigned)length;\n        break;\n    }\n\n    if (log_end == 0 && state < CONTENT)\n        log_end = i;\n    if (log_begin < log_end)\n        banout_append(banout, PROTO_HTTP, px + log_begin, log_end-log_begin);\n\n\n\n    if (state == DONE_PARSING)\n        pstate->state = state;\n    else\n        pstate->state = (state2 & 0xFFFF) << 16\n                | ((unsigned)id & 0xFF) << 8\n                | (state & 0xFF);\n}\n\nstatic const char *test_response =\n    \"HTTP/1.0 200 OK\\r\\n\"\n    \"Date: Wed, 13 Jan 2021 18:18:25 GMT\\r\\n\"\n    \"Expires: -1\\r\\n\"\n    \"Cache-Control: private, max-age=0\\r\\n\"\n    \"Content-Type: text/html; charset=ISO-8859-1\\r\\n\"\n    \"P3P: CP=\\x22This is not a P3P policy! See g.co/p3phelp for more info.\\x22\\r\\n\"\n    \"Server: gws\\r\\n\"\n    \"X-XSS-Protection: 0\\r\\n\"\n    \"X-Frame-Options: SAMEORIGIN\\r\\n\"\n    \"Set-Cookie: 1P_JAR=2021-01-13-18; expires=Fri, 12-Feb-2021 18:18:25 GMT; path=/; domain=.google.com; Secure\\r\\n\"\n    \"Set-Cookie: NID=207=QioO2ZqRsR6k1wtvXjuuhLrXYtl6ki8SQhf56doo_wcADvldNoHfnKvFk1YXdxSVTWnmqHQVPC6ZudGneMs7vDftJ6vB36B0OCDy_KetZ3sOT_ZAHcmi1pAGeO0VekZ0SYt_UXMjcDhuvNVW7hbuHEeXQFSgBywyzB6mF2EVN00; expires=Thu, 15-Jul-2021 18:18:25 GMT; path=/; domain=.google.com; HttpOnly\\r\\n\"\n    \"Accept-Ranges: none\\r\\n\"\n    \"Vary: Accept-Encoding\\r\\n\"\n    \"\\r\\n\";\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nhttp_selftest_parser(void)\n{\n    struct Banner1 *banner1 = NULL;\n    struct StreamState pstate[1];\n    struct BannerOutput banout[1];\n\n    \n    memset(pstate, 0, sizeof(pstate[0]));\n    memset(banout, 0, sizeof(banout[0]));\n\n    /*\n     * Test start\n     */\n    banner1 = banner1_create();\n    banner1->is_capture_servername = 1;\n    memset(pstate, 0, sizeof(pstate[0]));\n    banout_init(banout);\n\n    /*\n     * Run Test\n     */\n    http_parse(banner1, 0, pstate, (const unsigned  char *)test_response, strlen(test_response), banout, 0);\n    \n    \n    /*\n     * Verify results\n     */\n    {\n        const unsigned char *string;\n        size_t length;\n        \n        string = banout_string(banout, PROTO_HTTP_SERVER);\n        length = banout_string_length(banout, PROTO_HTTP_SERVER);\n        \n        if (length != 3 || memcmp(string, \"gws\", 3) != 0) {\n            fprintf(stderr, \"[-] HTTP parser failed: %s %u\\n\", __FILE__, __LINE__);\n            return 1; /* failure */\n        }\n    }\n\n    /*\n     * Test end\n     */\n    banner1_destroy(banner1);\n    banout_release(banout);\n    \n    return 0; /* success */\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nhttp_selftest_config(void)\n{\n    size_t i;\n    static const struct {const char *from; const char *to;} urlsamples[] = {\n        {\"\", \"GET /foo.html\"},\n        {\"GET / HTTP/1.0\\r\\n\\r\\n\", \"GET /foo.html HTTP/1.0\\r\\n\\r\\n\"},\n        {\"GET  /longerthan HTTP/1.0\\r\\n\\r\\n\", \"GET  /foo.html HTTP/1.0\\r\\n\\r\\n\"},\n        {0,0}\n    };\n    static const struct {const char *from; const char *to;} methodsamples[] = {\n        {\"\", \"POST\"},\n        {\"GET / HTTP/1.0\\r\\n\\r\\n\", \"POST / HTTP/1.0\\r\\n\\r\\n\"},\n        {\"O  /  HTTP/1.0\\r\\n\\r\\n\", \"POST  /  HTTP/1.0\\r\\n\\r\\n\"},\n        {0,0}\n    };\n    static const struct {const char *from; const char *to;} versionsamples[] = {\n        {\"\", \"GET / HTTP/1.1\"},\n        {\"GET / FOO\\r\\n\\r\\n\", \"GET / HTTP/1.1\\r\\n\\r\\n\"},\n        {\"GET  /  XXXXXXXXXXXX\\r\\n\\r\\n\", \"GET  /  HTTP/1.1\\r\\n\\r\\n\"},\n        {0,0}\n    };\n    static const struct {const char *from; const char *to;} fieldsamples[] = {\n        {\"GET / HTTP/1.0\\r\\nfoobar: a\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nfoobar: a\\r\\nHost: xyz\\r\\nfoo: bar\\r\\n\\r\\n\"},\n        {\"GET / HTTP/1.0\\r\\nfoo:abc\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nfoo: bar\\r\\nHost: xyz\\r\\n\\r\\n\"},\n        {\"GET / HTTP/1.0\\r\\nfoo: abcdef\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nfoo: bar\\r\\nHost: xyz\\r\\n\\r\\n\"},\n        {\"GET / HTTP/1.0\\r\\nfoo: a\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nfoo: bar\\r\\nHost: xyz\\r\\n\\r\\n\"},\n        {\"GET / HTTP/1.0\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nHost: xyz\\r\\nfoo: bar\\r\\n\\r\\n\"},\n        {0,0}\n    };\n    static const struct {const char *from; const char *to;} removesamples[] = {\n        {\"GET / HTTP/1.0\\r\\nfoo: a\\r\\nHost: xyz\\r\\n\\r\\n\",  \"GET / HTTP/1.0\\r\\nHost: xyz\\r\\n\\r\\n\"},\n        {\"GET / HTTP/1.0\\r\\nfooa: a\\r\\nHost: xyz\\r\\n\\r\\n\", \"GET / HTTP/1.0\\r\\nfooa: a\\r\\nHost: xyz\\r\\n\\r\\n\"},\n        {0,0}\n    };\n    static const struct {const char *from; const char *to;} payloadsamples[] = {\n        {\"\",  \"GET / HTTP/1.0\\r\\n\\r\\nfoo\"},\n        {\"GET / HTTP/1.0\\r\\nHost: xyz\\r\\n\\r\\nbar\", \"GET / HTTP/1.0\\r\\nHost: xyz\\r\\n\\r\\nfoo\"},\n        {0,0}\n    };\n\n    /* Test replacing URL */\n    for (i=0; urlsamples[i].from; i++) {\n        unsigned char *x = (unsigned char*)STRDUP(urlsamples[i].from);\n        size_t len1 = strlen((const char *)x);\n        size_t len2;\n        size_t len3 = strlen(urlsamples[i].to);\n        \n        /* Replace whatever URL is in the header with this new one */\n        len2 = http_change_requestline(&x, len1, \"/foo.html\", ~(size_t)0, 1);\n\n        if (len2 != len3 && memcmp(urlsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config URL sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n    }\n\n    /* Test replacing method */\n    for (i=0; methodsamples[i].from; i++) {\n        unsigned char *x = (unsigned char*)STRDUP(methodsamples[i].from);\n        size_t len1 = strlen((const char *)x);\n        size_t len2;\n        size_t len3 = strlen(methodsamples[i].to);\n        \n        len2 = http_change_requestline(&x, len1, \"POST\", ~(size_t)0, 0);\n\n        if (len2 != len3 && memcmp(methodsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config method sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n    }\n\n    /* Test replacing version */\n    for (i=0; versionsamples[i].from; i++) {\n        unsigned char *x = (unsigned char*)STRDUP(versionsamples[i].from);\n        size_t len1 = strlen((const char *)x);\n        size_t len2;\n        size_t len3 = strlen(versionsamples[i].to);\n        \n        len2 = http_change_requestline(&x, len1, \"HTTP/1.1\", ~(size_t)0, 2);\n\n        if (len2 != len3 && memcmp(versionsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config version sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n    }\n\n    /* Test payload */\n    for (i=0; payloadsamples[i].from; i++) {\n        unsigned char *x = (unsigned char*)STRDUP(payloadsamples[i].from);\n        size_t len1 = strlen((const char *)x);\n        size_t len2;\n        size_t len3 = strlen(payloadsamples[i].to);\n        \n        len2 = http_change_requestline(&x, len1, \"foo\", ~(size_t)0, 3);\n\n        if (len2 != len3 && memcmp(payloadsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config payload sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n    }\n\n    /* Test adding fields */\n    for (i=0; fieldsamples[i].from; i++) {\n        unsigned char *x;\n        size_t len1 = strlen((const char *)fieldsamples[i].from);\n        size_t len2;\n        size_t len3 = strlen(fieldsamples[i].to);\n        \n        /* Replace whatever URL is in the header with this new one */\n        x = (unsigned char*)STRDUP(fieldsamples[i].from);\n        len2 = http_change_field(&x, len1, \"foo\", (const unsigned char *)\"bar\", ~(size_t)0, http_field_replace);\n        if (len2 != len3 || memcmp(fieldsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config header field sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n        free(x);\n\n        /* Same test as above, but when name specified with a colon */\n        x = (unsigned char*)STRDUP(fieldsamples[i].from);\n        len2 = http_change_field(&x, len1, \"foo:\", (const unsigned char *)\"bar\", ~(size_t)0, http_field_replace);\n        if (len2 != len3 || memcmp(fieldsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config header field sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n        free(x);\n\n        /* Same test as above, but with name having additional space */\n        x = (unsigned char*)STRDUP(fieldsamples[i].from);\n        len2 = http_change_field(&x, len1, \"foo : : \", (const unsigned char *)\"bar\", ~(size_t)0, http_field_replace);\n        if (len2 != len3 || memcmp(fieldsamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config header field sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n        free(x);\n\n    }\n\n    /* Removing fields */\n    for (i=0; removesamples[i].from; i++) {\n        unsigned char *x = (unsigned char*)STRDUP(removesamples[i].from);\n        size_t len1 = strlen((const char *)x);\n        size_t len2;\n        size_t len3 = strlen(removesamples[i].to);\n        \n        /* Replace whatever URL is in the header with this new one */\n        len2 = http_change_field(&x, len1, \"foo\", (const unsigned char *)\"bar\", ~(size_t)0, http_field_remove);\n\n        if (len2 != len3 || memcmp(removesamples[i].to, x, len3) != 0) {\n            fprintf(stderr, \"[-] HTTP.selftest: config remove field sample #%u\\n\", (unsigned)i);\n            return 1;\n        }\n        free(x);\n    }\n\n    return 0;\n}\n\n/***************************************************************************\n * Called when `--selftest` command-line parameter in order to do some\n * basic unit testing of this module.\n ***************************************************************************/\nstatic int\nhttp_selftest(void)\n{\n    int err;\n\n    /* Test parsing HTTP responses */\n    err = http_selftest_parser();\n    if (err)\n        return 1; /* failure */\n\n    /* Test configuring HTTP requests */\n    err = http_selftest_config();\n    if (err)\n        return 1; /* failure */\n\n    return 0; /* success */\n}\n\n/***************************************************************************\n ***************************************************************************/\nstruct ProtocolParserStream banner_http = {\n    \"http\", 80, http_hello, sizeof(http_hello)-1, 0,\n    http_selftest,\n    http_init,\n    http_parse,\n};\n\n"
  },
  {
    "path": "src/proto-http.h",
    "content": "#ifndef PROTO_HTTP_H\n#define PROTO_HTTP_H\n#include \"proto-banner1.h\"\n#include \"util-bool.h\"\n\nextern struct ProtocolParserStream banner_http;\n\n\n/**\n * Called during configuration when processing a command-line option\n * like \"--http-field <name=value>\" to add/change a field in the HTTP \n * header.\n */\nsize_t\nhttp_change_field(unsigned char **inout_header, size_t header_length,\n                    const char *field_name,\n                    const unsigned char *field_value, size_t field_value_len,\n                    int what);\n\n\n/**\n * Called during configuration when processing a command-line option\n * like \"--http-url /foo.html\". This replaces whatever the existing\n * URL is into the new one. \n * @param item\n *      0=method, 1=url, 2=version\n * @return\n *   the new length of the header (expanded or shrunk)\n */\nsize_t\nhttp_change_requestline(unsigned char **inout_header, size_t header_length,\n                    const void *url, size_t url_length, int item);\n\n#endif\n\n"
  },
  {
    "path": "src/proto-icmp.c",
    "content": "#include \"proto-icmp.h\"\n#include \"proto-preprocess.h\"\n#include \"syn-cookie.h\"\n#include \"util-logger.h\"\n#include \"output.h\"\n#include \"masscan-status.h\"\n#include \"massip-port.h\"\n#include \"main-dedup.h\"\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nmatches_me(struct Output *out, ipaddress ip, unsigned port)\n{\n    unsigned i;\n\n    for (i=0; i<8; i++) {\n        if (is_myself(&out->src[i], ip, port))\n            return 1;\n    }\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nparse_port_unreachable(const unsigned char *px, unsigned length,\n        unsigned *r_ip_me, unsigned *r_ip_them,\n        unsigned *r_port_me, unsigned *r_port_them,\n        unsigned *r_ip_proto)\n{\n    if (length < 24)\n        return -1;\n    *r_ip_me = px[12]<<24 | px[13]<<16 | px[14]<<8 | px[15];\n    *r_ip_them = px[16]<<24 | px[17]<<16 | px[18]<<8 | px[19];\n    *r_ip_proto = px[9]; /* TCP=6, UDP=17 */\n\n    px += (px[0]&0xF)<<2;\n    length -= (px[0]&0xF)<<2;\n\n    if (length < 4)\n        return -1;\n\n    *r_port_me = px[0]<<8 | px[1];\n    *r_port_them = px[2]<<8 | px[3];\n\n    return 0;\n}\n\n/***************************************************************************\n * This is where we handle all incoming ICMP packets. Some of these packets\n * will be due to scans we are doing, like pings (echoes). Some will\n * be inadvertent, such as \"destination unreachable\" messages.\n ***************************************************************************/\nvoid\nhandle_icmp(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy)\n{\n    unsigned type = parsed->port_src;\n    unsigned code = parsed->port_dst;\n    unsigned seqno_me;\n    ipaddress ip_me = parsed->dst_ip;\n    ipaddress ip_them = parsed->src_ip;\n    unsigned cookie;\n\n    /* dedup ICMP echo replies as well as SYN/ACK replies */\n    static struct DedupTable *echo_reply_dedup = NULL;\n\n\n    if (!echo_reply_dedup)\n        echo_reply_dedup = dedup_create();\n\n    seqno_me = px[parsed->transport_offset+4]<<24\n                | px[parsed->transport_offset+5]<<16\n                | px[parsed->transport_offset+6]<<8\n                | px[parsed->transport_offset+7]<<0;\n\n    switch (type) {\n    case 0: /* ICMP echo reply */\n    case 129:\n        cookie = (unsigned)syn_cookie(ip_them, Templ_ICMP_echo, ip_me, 0, entropy);\n        if ((cookie & 0xFFFFFFFF) != seqno_me)\n            return; /* not my response */\n\n        if (dedup_is_duplicate(echo_reply_dedup, ip_them, 0, ip_me, 0))\n            break;\n\n        //if (syn_hash(ip_them, Templ_ICMP_echo) != seqno_me)\n        //    return; /* not my response */\n\n        /*\n         * Report \"open\" or \"existence\" of host\n         */\n        output_report_status(\n                            out,\n                            timestamp,\n                            PortStatus_Open,\n                            ip_them,\n                            1, /* ip proto */\n                            0,\n                            0,\n                            parsed->ip_ttl,\n                            parsed->mac_src);\n        break;\n    case 3: /* destination unreachable */\n        switch (code) {\n        case 0: /* net unreachable */\n            /* We get these a lot while port scanning, often a flood coming\n             * back from broken/misconfigured networks */\n            break;\n        case 1: /* host unreachable */\n            /* This means the router doesn't exist */\n            break;\n        case 2: /* protocol unreachable */\n            /* The host exists, but it doesn't support SCTP */\n            break;\n        case 3: /* port unreachable */\n            if (length - parsed->transport_offset > 8) {\n                ipaddress ip_me2;\n                ipaddress ip_them2;\n                unsigned port_me2, port_them2;\n                unsigned ip_proto;\n                int err;\n\n                ip_me2.version = 4;\n                ip_them2.version = 4;\n\n                err = parse_port_unreachable(\n                    px + parsed->transport_offset + 8,\n                    length - parsed->transport_offset + 8,\n                    &ip_me2.ipv4, &ip_them2.ipv4, &port_me2, &port_them2,\n                    &ip_proto);\n\n                if (err)\n                    return;\n\n                if (!matches_me(out, ip_me2, port_me2))\n                    return;\n\n                switch (ip_proto) {\n                case 6:\n                    output_report_status(\n                                        out,\n                                        timestamp,\n                                        PortStatus_Closed,\n                                        ip_them2,\n                                        ip_proto,\n                                        port_them2,\n                                        0,\n                                        parsed->ip_ttl,\n                                        parsed->mac_src);\n                    break;\n                case 17:\n                    output_report_status(\n                                        out,\n                                        timestamp,\n                                        PortStatus_Closed,\n                                        ip_them2,\n                                        ip_proto,\n                                        port_them2,\n                                        0,\n                                        parsed->ip_ttl,\n                                        parsed->mac_src);\n                    break;\n                case 132:\n                    output_report_status(\n                                        out,\n                                        timestamp,\n                                        PortStatus_Closed,\n                                        ip_them2,\n                                        ip_proto,\n                                        port_them2,\n                                        0,\n                                        parsed->ip_ttl,\n                                        parsed->mac_src);\n                    break;\n                }\n            }\n\n        }\n        break;\n    default:\n    ;\n    }\n\n}\n\n"
  },
  {
    "path": "src/proto-icmp.h",
    "content": "#ifndef PROTO_ICMP_H\n#define PROTO_ICMP_H\n#include <time.h>\n#include <stdint.h>\nstruct PreprocessedInfo;\nstruct Output;\n\nvoid handle_icmp(struct Output *out, time_t timestamp,\n        const unsigned char *px, unsigned length, \n        struct PreprocessedInfo *parsed,\n        uint64_t entropy);\n\n#endif\n"
  },
  {
    "path": "src/proto-imap4.c",
    "content": "/*\n \n imap4 banner checker\n \n \n */\n\n#include \"proto-imap4.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-ssl.h\"\n#include <ctype.h>\n#include <string.h>\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nimap4_parse(  const struct Banner1 *banner1,\n           void *banner1_private,\n           struct StreamState *pstate,\n           const unsigned char *px, size_t length,\n           struct BannerOutput *banout,\n           struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    \n    \n    for (i=0; i<length; i++) {\n        if (px[i] == '\\r')\n            continue;\n        \n        switch (state) {\n            case 0:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '*')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 1:\n                if (px[i] == ' ') {\n                    banout_append_char(banout, PROTO_IMAP4, px[i]);\n                    continue;\n                } else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                /* fall through */\n            case 2:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == 'O')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 3:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == 'K')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 4:\n                if (px[i] == ' ') {\n                    banout_append_char(banout, PROTO_IMAP4, px[i]);\n                    state++;\n                    break;\n                } else if (px[i] != '\\n') {\n                    banout_append_char(banout, PROTO_IMAP4, px[i]);\n                    /* no transition */\n                    break;\n                } else {\n                    state++;\n                    /* fall through */\n                }\n            case 5:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '\\n') {\n                    tcpapi_send(socket, \"a001 CAPABILITY\\r\\n\", 17, 0);\n                    state = 100;\n                }\n                break;\n            case 100:\n            case 300:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '*')\n                    state += 100;\n                else if (px[i] == 'a')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 101:\n            case 301:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '0')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 102:\n            case 302:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '0')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 103:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '1')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 303:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '2')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 104:\n            case 304:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == ' ')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 105:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '\\n') {\n                    tcpapi_send(socket, \"a002 STARTTLS\\r\\n\", 15, 0);\n                    state = 300;\n                }\n                break;\n                \n            case 200:\n            case 400:\n                banout_append_char(banout, PROTO_IMAP4, px[i]);\n                if (px[i] == '\\n')\n                    state -= 100;\n                break;\n                \n            case 305:\n                if (px[i] == '\\n') {\n                    /* change the state here to SSL */\n                    unsigned port = pstate->port;\n                    memset(pstate, 0, sizeof(*pstate));\n                    pstate->app_proto = PROTO_SSL3;\n                    pstate->is_sent_sslhello = 1;\n                    pstate->port = (unsigned short)port;\n                    state = 0;\n                    \n                    tcpapi_send(socket, banner_ssl.hello, banner_ssl.hello_length, 0);\n                    break;\n                }\n                break;\n                \n            case 0xffffffff:\n            default:\n                i = (unsigned)length;\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nimap4_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nimap4_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_imap4 = {\n    \"imap4\", 21, 0, 0, 0,\n    imap4_selftest,\n    imap4_init,\n    imap4_parse,\n};\n"
  },
  {
    "path": "src/proto-imap4.h",
    "content": "#ifndef PROTO_IMAP4_H\n#define PROTO_IMAP4_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_imap4;\n\n#endif\n"
  },
  {
    "path": "src/proto-isakmp.c",
    "content": "/* ISAKMP protocol support \n \n 1                   2                   3\n0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n!                          Initiator                            !\n!                            Cookie                             !\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n!                          Responder                            !\n!                            Cookie                             !\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n!  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n!                          Message ID                           !\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n!                            Length                             !\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n\n */\n\n#include \"proto-isakmp.h\"\n#include \"proto-banout.h\"\n#include \"proto-preprocess.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n#include \"output.h\"\n#include \"util-extract.h\"\n#include \"util-logger.h\"\n#include <stdarg.h>\n#include <string.h>\n\ntypedef struct payload_t {\n    unsigned char next;\n    unsigned char reserved;\n    size_t length;\n    struct ebuf_t ebuf;\n} payload_t;\n\nstatic payload_t\n_get_payload(const struct ebuf_t *ebuf) {\n    payload_t result = {0};\n    result.ebuf = *ebuf;\n    result.next = e_next_byte(&result.ebuf);\n    result.reserved = e_next_byte(&result.ebuf);\n    result.length = e_next_short16(&result.ebuf, EBUF_BE);\n    \n    if (result.length >= 4) {\n        result.ebuf.max = result.ebuf.offset + result.length - 4;\n    }\n    return result;\n}\n\nstatic unsigned\n_parse_transform(struct BannerOutput *banout,\n                unsigned proto,\n               struct ebuf_t in_ebuf) {\n    struct ebuf_t *ebuf = &in_ebuf;\n    unsigned transform_id;\n\n\n    e_next_byte(ebuf); /* transform number */\n    transform_id = e_next_byte(ebuf);\n    switch (transform_id) {\n        case 1: {\n            banout_printf(banout, proto, \"trans=IKE \");\n            e_next_short16(ebuf, EBUF_BE); /* reserved */\n            while (ebuf->offset < ebuf->max) {\n                unsigned x = e_next_short16(ebuf, EBUF_BE);\n                unsigned val = e_next_short16(ebuf, EBUF_BE);\n                if ((x & 0x8000) == 0)\n                    return 1;\n                switch (x&0x7fff) {\n                    case 1: /* encryption algorithm */\n                        switch (val) {\n                            case 5:\n                                banout_printf(banout, proto, \"%s \", \"3DES-CBC\");\n                                break;\n                            case 7:\n                                banout_printf(banout, proto, \"%s \", \"AES-CBC\");\n                                break;\n                            default:\n                                banout_printf(banout, proto, \"encrypt=0x%x \", val);\n                                break;\n                        }\n                        break;\n                    case 2: /* hash algorithm */\n                        switch (val) {\n                            case 2:\n                                banout_printf(banout, proto, \"%s \", \"SHA\");\n                                break;\n                            default:\n                                banout_printf(banout, proto, \"hash=0x%x \", val);\n                                break;\n                        }\n                        break;\n                    case 3: /* auth */\n                        switch (val) {\n                            case 1:\n                                banout_printf(banout, proto, \"%s \", \"PSK\");\n                                break;\n                            case 5:\n                                banout_printf(banout, proto, \"%s \", \"PSK\");\n                                break;\n                            default:\n                                banout_printf(banout, proto, \"auth=0x%x \", val);\n                                break;\n                        }\n                        break;\n                    case 4: /* group */\n                        break;\n                    case 11: /* life type */\n                        break;\n                    case 12: /* life duration*/\n                        break;\n                    case 14: /* key length */\n                        banout_printf(banout, proto, \"key=%ubits \", val);\n                        break;\n                    default:\n                        banout_printf(banout, proto, \"val=0x%04x%04x \", x&0x7fff, val);\n                        break;\n                        \n                }\n            }\n        }\n            break;\n        default:\n            banout_printf(banout, proto, \"trans=%u \", transform_id);\n            break;\n    }\n    return 1;\n}\n\nstatic unsigned\n_parse_transforms(struct BannerOutput *banout,\n                unsigned proto,\n               struct ebuf_t ebuf,\n               unsigned next_payload\n                 ) {\n    \n    while (ebuf.offset + 4 <= ebuf.max) {\n        payload_t payload = _get_payload(&ebuf);\n        _parse_transform(banout, proto, payload.ebuf);\n\n        /* loop around */\n        ebuf.offset += payload.length;\n        next_payload = payload.next;\n        if (next_payload == 0)\n            break;\n    }\n    return 0;\n}\n\nstatic unsigned\n_parse_proposal(struct BannerOutput *banout,\n                unsigned proto,\n               struct ebuf_t ebuf) {\n    unsigned proto_id;\n\n        \n    banout_printf(banout, proto, \"%u \", e_next_byte(&ebuf));\n    proto_id = e_next_byte(&ebuf);\n    switch (proto_id) {\n        case 1:\n            banout_printf(banout, proto, \"id=ISAKMP \");\n            break;\n        default:\n            banout_printf(banout, proto, \"id=%u \", proto_id);\n            break;\n    }\n    e_next_byte(&ebuf); /* spi size */\n    e_next_byte(&ebuf); /* proposal transforms */\n    \n    _parse_transforms(banout, proto, ebuf, 0);\n    \n    return 1;\n}\n\nstatic unsigned\n_parse_proposals(struct BannerOutput *banout,\n                unsigned proto,\n               struct ebuf_t ebuf,\n               unsigned next_payload\n                 ) {\n    \n    while (ebuf.offset + 4 <= ebuf.max) {\n        payload_t payload = _get_payload(&ebuf);\n        _parse_proposal(banout, proto, payload.ebuf);\n\n        /* loop around */\n        ebuf.offset += payload.length;\n        next_payload = payload.next;\n        if (next_payload == 0)\n            break;\n    }\n    return 0;\n}\n\nstatic unsigned\n_payload_security_association(struct BannerOutput *banout, unsigned proto, struct ebuf_t ebuf) {\n    unsigned doi;\n    unsigned bitmap;\n\n    doi = e_next_int32(&ebuf, EBUF_BE);\n    bitmap = e_next_int32(&ebuf, EBUF_BE);\n    switch (doi) {\n        case 0: /* generic */\n            banout_printf(banout, proto, \"DOI=generic \");\n            break;\n        case 1: /* IPsec */\n            banout_printf(banout, proto, \"DOI=ipsec \");\n            if (bitmap & 0x00000001)\n                banout_printf(banout, proto, \"IDENTITY \");\n            if (bitmap & 0x00000002)\n                banout_printf(banout, proto, \"SECRECY \");\n            if (bitmap & 0x00000004)\n                banout_printf(banout, proto, \"INTEGRITY \");\n            _parse_proposals(banout, proto, ebuf, 0);\n            break;\n        default:\n            banout_printf(banout, proto, \"DOI=%u \", doi);\n            break;\n    }\n    return 1;\n}\n\nstatic unsigned\n_payload_vendor_id(struct BannerOutput *banout, unsigned proto, struct ebuf_t ebuf) {\n    size_t i;\n    size_t length = ebuf.max - ebuf.offset;\n    struct {\n        unsigned length;\n        const char *vendor;\n        const char *name;\n    } vendors[] = {\n        {16, \"\\x4a\\x13\\x1c\\x81\\x07\\x03\\x58\\x45\\x5c\\x57\\x28\\xf2\\x0e\\x95\\x45\\x2f\", \"RFC-39947-NAT\"},\n        {16, \"\\x12\\xf5\\xf2\\x8c\\x45\\x71\\x68\\xa9\\x70\\x2d\\x9f\\xe2\\x74\\xcc\\x01\\x00\", \"CISCO-UNITY\"},\n        {16, \"\\xaf\\xca\\xd7\\x13\\x68\\xa1\\xf1\\xc9\\x6b\\x86\\x96\\xfc\\x77\\x57\\x01\\x00\", \"RFC3706-DPD\"},\n        {8, \"\\x09\\x00\" \"&\\x89\\xdf\\xd6\\xb7\\x12\", \"XAUTH\"},\n        {0,0}\n    };\n    \n    for (i=0; vendors[i].length; i++) {\n        if (length != vendors[i].length)\n            continue;\n        if (memcmp(vendors[i].vendor, ebuf.buf + ebuf.offset, length) == 0) {\n            banout_printf(banout, proto, \"{%s} \", vendors[i].name);\n            break;\n        }\n    }\n    return 1;\n}\n\n\nstatic unsigned\n_parse_response(struct BannerOutput *banout, unsigned proto,\n                    const unsigned char *px, size_t length\n                    ) {\n    struct ebuf_t ebuf[1] = {{px, 0, length}};\n    unsigned next_payload;\n    unsigned version;\n    unsigned flags;\n    unsigned exchange_type;\n    unsigned my_length;\n    static const char *payload_names[] = {\n        \"[0]\", \"[SEC-ASSOC]\", \"[2]\", \"[3]\",\n        \"[KEY-XCHG]\", \"[5]\", \"[6]\", \"[7]\",\n        \"[8]\", \"[9]\", \"[NONCE]\", \"[11]\",\n        \"[12]\", \"\"/*vendor-id*/, \"[14]\", \"[15]\",\n        \"[16]\", \"[17]\", \"[18]\", \"[19]\",\n        \"[NAT-D]\", \"[21]\", \"[22]\", \"[23]\",\n        \"[24]\", \"[25]\", \"[26]\", \"[27]\",\n        \"[28]\", \"[29]\", \"[30]\", \"[31]\",\n    };\n    \n    \n    \n    /*\n                          1                   2                   3\n      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     !                          Initiator                            !\n     !                            Cookie                             !\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     !                          Responder                            !\n     !                            Cookie                             !\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     !                          Message ID                           !\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     !                            Length                             !\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     */\n\n    /* Skip the cookies */\n    e_next_long64(ebuf, EBUF_BE);\n    e_next_long64(ebuf, EBUF_BE);\n    \n    /* Parse the header */\n    next_payload = e_next_byte(ebuf);\n    version = e_next_byte(ebuf);\n    exchange_type = e_next_byte(ebuf);\n    flags = e_next_byte(ebuf); /* flags */\n    e_next_int32(ebuf, 0);\n    my_length = e_next_int32(ebuf, EBUF_BE);\n    if (ebuf->max >= my_length)\n        ebuf->max = my_length;\n    banout_printf(banout, proto, \"v%u.%u \", (version>>4)&0xF, version&0xF);\n    switch (exchange_type) {\n        case 2:\n            banout_printf(banout, proto, \"xchg=id-prot \");\n            break;\n        default:\n            banout_printf(banout, proto, \"xchg=%u \", exchange_type);\n            break;\n    }\n    \n    if (flags & 1) {\n        banout_printf(banout, proto, \"ENCRYPTED \", exchange_type);\n        return 1;\n    }\n    \n    /*\n     * Enumerate all the payloads\n     */\n    while (next_payload && ebuf->offset + 4 <= ebuf->max) {\n        \n        /*\n         * Parse this payload-header\n         */\n        payload_t payload = _get_payload(ebuf);\n\n        \n        /* \n         * Print the payload name if it's in our list of known names,\n         * or print a number if it isn't\n         */\n        if (next_payload < sizeof(payload_names)/sizeof(payload_names[0]))\n            banout_printf(banout, proto, \"%s \", payload_names[next_payload]);\n        else\n            banout_printf(banout, proto, \"[%u] \", next_payload);\n        \n        \n        /*\n         * Handle the individual payload if it's a known type\n         */\n        switch (next_payload) {\n            case 1:\n                _payload_security_association(banout, proto, payload.ebuf);\n                break;\n            case 4: /* key exchange */\n                //banout_printf(banout, proto, \"KEY-EXCH \");\n                break;\n            case 10: /* nonce */\n                //banout_printf(banout, proto, \"NONCE \");\n                break;\n            case 13: /* vendir id */\n                _payload_vendor_id(banout, proto, payload.ebuf);\n                break;\n            case 20:\n                //banout_printf(banout, proto, \"NAT-D \");\n                break;\n            default:\n                break;\n            \n        }\n        \n        /*\n         * Loop around to the next payload\n         */\n        ebuf->offset += payload.length;\n        next_payload = payload.next;\n    }\n    return 1;\n}\n\nunsigned\nisakmp_parse(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            )\n{\n    ipaddress ip_them;\n    ipaddress ip_me;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    uint64_t cookie;\n    uint64_t resp_cookie;\n    \n    /* All responses will be at least 8 bytes */\n    if (length < 16)\n        return 0;\n    \n    /* Grab IP addresses */\n    ip_them = parsed->src_ip;\n    ip_me = parsed->dst_ip;\n    \n    /* Calculate the expected SYN-cookie */\n    cookie = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n    \n    /* Extract the SYN-cookie from the response. We just do this byte-by-byte */\n    resp_cookie = (uint64_t)px[0] << 56ull;\n    resp_cookie |= (uint64_t)px[1] << 48ull;\n    resp_cookie |= (uint64_t)px[2] << 40ull;\n    resp_cookie |= (uint64_t)px[3] << 32ull;\n    resp_cookie |= (uint64_t)px[4] << 24ull;\n    resp_cookie |= (uint64_t)px[5] << 16ull;\n    resp_cookie |= (uint64_t)px[6] << 8ull;\n    resp_cookie |= (uint64_t)px[7] << 0ull;\n\n    if (resp_cookie != cookie) {\n        /* If they aren't equal, then this is some other protocol.\n         * TODO: we should use a heuristic on these bytes to\n         * discover what the protocol probably is */\n        /*output_report_banner(out, timestamp, ip_them, 17, port_them,\n                             PROTO_ERROR, parsed->ip_ttl,\n                             (unsigned char *) \"IP-MISSMATCH\", 12);*/\n        return 0;\n    } else {\n        /* We've found our protocol, so report the banner \n         * TODO: we should parse this better. */\n        struct BannerOutput banout[1];\n        banout_init(banout);\n\n        /* Parse the packet and generate strings */\n        _parse_response(banout, PROTO_ISAKMP, px, length);\n        \n        /* Print the banner to the output */\n        output_report_banner(\n            out, timestamp,\n            ip_them, 17, port_them,\n            PROTO_ISAKMP,\n            parsed->ip_ttl,\n            banout_string(banout, PROTO_ISAKMP),\n            banout_string_length(banout, PROTO_ISAKMP));\n        \n        banout_release(banout);\n        return 1;\n    }\n\n}\n\nunsigned\nisakmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    /*\n    The frame header starts with an 8 bytes init cookie, which is just\n    fine for us\n    */\n\n    unsigned char i;\n\n    if (length < 8)\n        return 0;\n\n    for(i = 0; i < 8; i++)\n        px[i] = (unsigned char)(seqno >> (56 - 8 * i));\n\n    return 0;\n}\n\nstatic const unsigned char\nsample1[] =\n    \"\\x00\\x00\\x00\\x00\\xc1\\x18\"\n    \"\\x84\\xda\\xbe\\x3d\\xc6\\x8e\\xea\\xf2\\xda\\xac\\x01\\x10\\x02\\x00\\x00\\x00\"\n    \"\\x00\\x00\\x00\\x00\\x00\\x50\\x00\\x00\\x00\\x34\\x00\\x00\\x00\\x01\\x00\\x00\"\n    \"\\x00\\x01\\x00\\x00\\x00\\x28\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x20\\x01\\x01\"\n    \"\\x00\\x00\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x04\\x00\\x02\\x80\\x03\"\n    \"\\x00\\x01\\x80\\x0b\\x00\\x01\\x80\\x0c\\x00\\x01\";\n\nstatic const unsigned char\nsample2[] = \"\\xe4\\x7a\\x59\\x1f\\xd0\\x57\"\n    \"\\x58\\x7f\\xa0\\x0b\\x8e\\xf0\\x90\\x2b\\xb8\\xec\\x01\\x10\\x02\\x00\\x00\\x00\"\n    \"\\x00\\x00\\x00\\x00\\x00\\x6c\\x0d\\x00\\x00\\x3c\\x00\\x00\\x00\\x01\\x00\\x00\"\n    \"\\x00\\x01\\x00\\x00\\x00\\x30\\x01\\x01\\x00\\x01\\x00\\x00\\x00\\x28\\x01\\x01\"\n    \"\\x00\\x00\\x80\\x01\\x00\\x07\\x80\\x0e\\x00\\x80\\x80\\x02\\x00\\x02\\x80\\x04\"\n    \"\\x00\\x02\\x80\\x03\\x00\\x01\\x80\\x0b\\x00\\x01\\x00\\x0c\\x00\\x04\\x00\\x01\"\n    \"\\x51\\x80\\x00\\x00\\x00\\x14\\x4a\\x13\\x1c\\x81\\x07\\x03\\x58\\x45\\x5c\\x57\"\n    \"\\x28\\xf2\\x0e\\x95\\x45\\x2f\";\n\nstatic const unsigned char sample3[] =\n\"\\xe4\\x7a\\x59\\x1f\\xd0\\x57\\x58\\x7f\\xa0\\x0b\\x8e\\xf0\\x90\\x2b\\xb8\\xec\"\n\"\\x04\\x10\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x30\\x0a\\x00\\x00\\x84\"\n\"\\x6d\\x02\\x6d\\x56\\x16\\xc4\\x5b\\xe0\\x5e\\x5b\\x89\\x84\\x11\\xe9\\xf9\\x5d\"\n\"\\x19\\x5c\\xea\\x00\\x9a\\xd2\\x2c\\x62\\xbe\\xf0\\x6c\\x57\\x1b\\x7c\\xfb\\xc4\"\n\"\\x79\\x2f\\x45\\x56\\x4e\\xc7\\x10\\xac\\x58\\x4a\\xa1\\x8d\\x20\\xcb\\xc8\\xf5\"\n\"\\xf8\\x91\\x06\\x66\\xb8\\x9e\\x4e\\xe2\\xf9\\x5a\\xbc\\x02\\x30\\xe2\\xcb\\xa1\"\n\"\\xb8\\x8a\\xc4\\xbb\\xa7\\xfc\\xc8\\x18\\xa9\\x86\\xc0\\x1a\\x4c\\xa8\\x65\\xa5\"\n\"\\xeb\\x82\\x88\\x4d\\xbe\\xc8\\x5b\\xfd\\x7d\\x1a\\x30\\x3b\\x09\\x89\\x4d\\xcf\"\n\"\\x2e\\x37\\x85\\xfd\\x79\\xdb\\xa2\\x25\\x37\\x7c\\xf8\\xcc\\xa0\\x09\\xce\\xff\"\n\"\\xbb\\x6a\\xa3\\x8b\\x64\\x8c\\x4b\\x05\\x40\\x4f\\x1c\\xfa\\xac\\x36\\x1a\\xff\"\n\"\\x0d\\x00\\x00\\x18\\x15\\xb6\\x88\\x42\\x1e\\xd5\\xc3\\xdd\\x92\\xd3\\xb8\\x6e\"\n\"\\x47\\xa7\\x6f\\x0d\\x39\\xcc\\x09\\xe0\\x0d\\x00\\x00\\x14\\x12\\xf5\\xf2\\x8c\"\n\"\\x45\\x71\\x68\\xa9\\x70\\x2d\\x9f\\xe2\\x74\\xcc\\x01\\x00\\x0d\\x00\\x00\\x14\"\n\"\\xaf\\xca\\xd7\\x13\\x68\\xa1\\xf1\\xc9\\x6b\\x86\\x96\\xfc\\x77\\x57\\x01\\x00\"\n\"\\x0d\\x00\\x00\\x14\\x55\\xcc\\x29\\xed\\x90\\x2a\\xb8\\xec\\x53\\xb1\\xdf\\x86\"\n\"\\x7c\\x61\\x09\\x29\\x14\\x00\\x00\\x0c\\x09\\x00\\x26\\x89\\xdf\\xd6\\xb7\\x12\"\n\"\\x14\\x00\\x00\\x18\\xfe\\xbf\\x46\\x2f\\x1c\\xd7\\x58\\x05\\xa7\\xba\\xa2\\x87\"\n\"\\x47\\xe7\\x69\\xd6\\x74\\xf8\\x56\\x00\\x00\\x00\\x00\\x18\\x15\\x74\\xd6\\x4c\"\n\"\\x01\\x65\\xba\\xd1\\x6a\\x02\\x3f\\x03\\x8d\\x45\\xa0\\x74\\x98\\xd8\\xd0\\x51\";\n\nconst char sample4[] =\n\"\\xe4\\x7a\\x59\\x1f\\xd0\\x57\\x58\\x7f\\xa0\\x0b\\x8e\\xf0\\x90\\x2b\\xb8\\xec\"\n\"\\x05\\x10\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x4c\\xb0\\x32\\xaa\\xa6\"\n\"\\x2a\\x70\\x71\\x8e\\xf2\\xf0\\x99\\xcd\\xd8\\xbf\\x6e\\xb9\\x04\\x42\\xed\\x9d\"\n\"\\x72\\x6d\\xaa\\x6b\\x6d\\xad\\x62\\x40\\x26\\xf5\\xfb\\xb1\\x73\\xd9\\xf7\\x75\"\n\"\\x71\\xc2\\x32\\xa5\\x6a\\xcf\\xe1\\x2c\\x74\\x03\\xe9\\x53\";\n\nstatic int\n_test_sample(const void *sample, size_t sizeof_sample, const char *expected) {\n    int is_valid;\n    struct BannerOutput banout[1];\n    \n    /* Initialize printing banners */\n    banout_init(banout);\n    \n    /* Parse the sample */\n    is_valid = _parse_response(banout, PROTO_ISAKMP,\n                               (const unsigned char*)sample,\n                               sizeof_sample);\n    \n    /* If there was a parse error, then*/\n    if (!is_valid)\n        goto fail;\n    \n    \n    {\n        const unsigned char *str = banout_string(banout, PROTO_ISAKMP);\n        size_t str_length = banout_string_length(banout, PROTO_ISAKMP);\n        //printf(\"%.*s\\n\", (unsigned)str_length, str);\n        if (str_length < strlen(expected) || memcmp(str, expected, strlen(expected)) != 0)\n            goto fail;\n    }\n    \n    banout_release(banout);\n    return 0;\nfail:\n    banout_release(banout);\n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nproto_isakmp_selftest(void)\n{\n    unsigned fail_count = 0;\n    \n    LOG(1, \"[ ] ISAKMP: selftesting...\\n\");\n    \n    \n    fail_count += _test_sample(\n                               sample1, sizeof(sample1)-1,\n                               \"v1.0 xchg=id-prot [SEC-ASSOC] DOI=ipsec IDENTITY 1 id=ISAKMP trans=IKE 3DES-CBC SHA PSK\");\n    fail_count += _test_sample(\n                               sample2, sizeof(sample2)-1,\n                               \"v1.0 xchg=id-prot [SEC-ASSOC] DOI=ipsec IDENTITY 1 id=ISAKMP trans=IKE AES-CBC key=128bits SHA PSK  {RFC-39947-NAT}\");\n     \n    \n    fail_count += _test_sample(\n                               sample3, sizeof(sample3)-1,\n                               \"v1.0 xchg=id-prot [KEY-XCHG] [NONCE]  {CISCO-UNITY}  {RFC3706-DPD}   {XAUTH} [NAT-D] [NAT-D]\");\n     \n    fail_count += _test_sample(\n                               sample4, sizeof(sample4)-1,\n                               \"v1.0 xchg=id-prot ENCRYPTED\");\n    \n\n    if (fail_count)\n        goto fail;\n\n    LOG(1, \"[-] ISAKMP: success\\n\");\n    return 0;\nfail:\n    LOG(1, \"[-] ISAKMP: fail\\n\");\n    return 1;\n}\n\n"
  },
  {
    "path": "src/proto-isakmp.h",
    "content": "#ifndef PROTO_ISAKMP_H\n#define PROTO_ISAKMP_H\n#include <time.h>\n#include <stdint.h>\n#include <stdlib.h>\nstruct Output;\nstruct PreprocessedInfo;\n\nunsigned isakmp_parse(struct Output *out, time_t timestamp,\n    const unsigned char *px, unsigned length,\n    struct PreprocessedInfo *parsed, uint64_t entropy);\n\nunsigned isakmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\nint\nproto_isakmp_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/proto-mc.c",
    "content": "#include \"proto-mc.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"output.h\"\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n\nstatic unsigned char hand_shake_ptr[128];\n\nstatic unsigned char *\nhand_shake(uint16_t port, const char* ip, size_t ip_len)\n{\n    size_t tlen = 10+ip_len;\n    unsigned char * ret = (unsigned char *)calloc(1,tlen);\n    ret[0] = (unsigned char)(7+ip_len);\n    ret[2] = 0xf7;\n    ret[3] = 5;\n    ret[4] = (unsigned char)ip_len;\n    memcpy(ret+5,ip,ip_len);\n    ret[tlen-5] = (unsigned char)(port>>8);\n    ret[tlen-4] = (unsigned char)(port&0xff);\n    ret[tlen-3] = 1;\n    ret[tlen-2] = 1;\n    ret[tlen-1] = 0;\n    return ret;\n}\n\nstatic void *\nmemstr(void * mem, size_t len, char * str)\n{\n    size_t i;\n    size_t stlen = strlen(str);\n    if(len < stlen)\n        return 0;\n    for(i = 0; i < len-stlen; i++) {\n        if(!memcmp((char*)mem+i,str,stlen))\n            return (char*)mem+i;\n    }\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nmc_parse(  const struct Banner1 *banner1,\n          void *banner1_private,\n          struct StreamState *pstate,\n          const unsigned char *px, size_t length,\n          struct BannerOutput *banout,\n          struct stack_handle_t *socket)\n{\n    size_t i;\n    struct MCSTUFF *mc = &pstate->sub.mc;\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    for(i = 0; i < length; i++) {\n        if(px[i] == '{')\n            mc->brackcount++;\n        if(px[i] == '}')\n            mc->brackcount--;\n    }\n    if(mc->brackcount <= 0)\n        tcpapi_close(socket);\n\n    if((mc->imgstart&&mc->imgend) || mc->brackcount <= 0) { // we already found and removed image data\n        banout_append(banout, PROTO_MC,px,length);\n    } else {\n        mc->banmem = realloc(mc->banmem,mc->totalLen+length+1); // expand to add new memory for added paket\n        memcpy(mc->banmem+mc->totalLen,px,length); // copy in new packet\n        mc->banmem[mc->totalLen] = 0; // add ending 0 for str\n        mc->totalLen+=length;\n        if(!mc->imgstart) { // dont search again if we found start\n            mc->imgstart = (size_t)memstr(mc->banmem,mc->totalLen,\"data:image/png;base64\");\n            if(mc->imgstart)\n                mc->imgstart-=(size_t)mc->banmem;\n        } else { // we found start but not the end\n            mc->imgend = (size_t)memchr(mc->banmem+mc->imgstart,'\\\"',mc->totalLen-mc->imgstart);\n            if(mc->imgend){ // we found the end\n                mc->imgend-=(size_t)mc->banmem;\n                memcpy(mc->banmem+mc->imgstart,mc->banmem+mc->imgend,(mc->totalLen-mc->imgend)+1); // copy data after B64\n                mc->totalLen=mc->imgstart+(mc->totalLen-mc->imgend); // shrink length to subtract B64 image\n                banout_append(banout, PROTO_MC,mc->banmem,mc->totalLen); // print out banner minus image data\n                free(mc->banmem); // we dont need to keep track of this any more.\n            }\n        }\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nmc_init(struct Banner1 *banner1)\n{\n    unsigned char * tmp = hand_shake(25565,\"localhost\",9);\n    memcpy(hand_shake_ptr,tmp,tmp[0]+3);\n    free(tmp);\n    banner_mc.hello = hand_shake_ptr;\n    banner_mc.hello_length = hand_shake_ptr[0]+3;\n    banner1->payloads.tcp[25565] = (void*)&banner_mc;\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nmc_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstruct ProtocolParserStream banner_mc = {\n    \"mc\", 25565, 0, 0, 0,\n    mc_selftest,\n    mc_init,\n    mc_parse,\n};\n"
  },
  {
    "path": "src/proto-mc.h",
    "content": "#ifndef PROTO_MC_H\n#define PROTO_MC_H\n#include \"proto-banner1.h\"\n#include \"util-bool.h\"\n\nextern struct ProtocolParserStream banner_mc;\n\n#endif\n"
  },
  {
    "path": "src/proto-memcached.c",
    "content": "/*\n    memcached banner check \n*/\n\n#include \"proto-memcached.h\"\n#include \"proto-banner1.h\"\n#include \"smack.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"output.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-ssl.h\"\n#include \"proto-udp.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n#include \"util-malloc.h\"\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n\nstruct SMACK *sm_memcached_responses;\nstruct SMACK *sm_memcached_stats;\n\nenum {\n    MC_ERROR,\n    MC_CLIENT_ERROR,\n    MC_SERVER_ERROR,\n    MC_STORED,\n    MC_NOT_STORED,\n    MC_EXISTS,\n    MC_NOT_FOUND,\n    MC_END,\n    MC_VALUE,\n    MC_DELETED,\n    MC_TOUCHED,\n    MC_OK,\n    MC_BUSY,\n    MC_BADCLASS,\n    MC_NOSPARE,\n    MC_NOTFULL,\n    MC_UNSAFE,\n    MC_SAME,\n    MC_STAT,\n    MC_empty,\n};\nstatic struct Patterns memcached_responses[] = {\n    {\"ERROR\",          0, MC_ERROR,          SMACK_ANCHOR_BEGIN},\n    {\"CLIENT_ERROR\",   0, MC_CLIENT_ERROR,   SMACK_ANCHOR_BEGIN},\n    {\"SERVER_ERROR\",   0, MC_SERVER_ERROR,   SMACK_ANCHOR_BEGIN},\n    {\"STORED\",         0, MC_STORED,         SMACK_ANCHOR_BEGIN},\n    {\"NOT_STORED\",     0, MC_NOT_STORED,     SMACK_ANCHOR_BEGIN},\n    {\"EXISTS\",         0, MC_EXISTS,         SMACK_ANCHOR_BEGIN},\n    {\"NOT_FOUND\",      0, MC_NOT_FOUND,      SMACK_ANCHOR_BEGIN},\n    {\"END\",            0, MC_END,            SMACK_ANCHOR_BEGIN},\n    {\"VALUE\",          0, MC_VALUE,          SMACK_ANCHOR_BEGIN},\n    {\"DELETED\",        0, MC_DELETED,        SMACK_ANCHOR_BEGIN},\n    {\"TOUCHED\",        0, MC_TOUCHED,        SMACK_ANCHOR_BEGIN},\n    {\"OK\",             0, MC_OK,             SMACK_ANCHOR_BEGIN},\n    {\"BUSY\",           0, MC_BUSY,           SMACK_ANCHOR_BEGIN},\n    {\"BADCLASS\",       0, MC_BADCLASS,       SMACK_ANCHOR_BEGIN},\n    {\"NOSPARE\",        0, MC_NOSPARE,        SMACK_ANCHOR_BEGIN},\n    {\"NOTFULL\",        0, MC_NOTFULL,        SMACK_ANCHOR_BEGIN},\n    {\"UNSAFE\",         0, MC_UNSAFE,         SMACK_ANCHOR_BEGIN},\n    {\"SAME\",           0, MC_SAME,           SMACK_ANCHOR_BEGIN},\n    {\"STAT\",           0, MC_STAT,           SMACK_ANCHOR_BEGIN},\n    {\"\",               0, MC_empty,          SMACK_ANCHOR_BEGIN},\n    {0,0,0,0}\n};\n\nenum {\n    MS_PID,\n    MS_UPTIME,\n    MS_TIME,\n    MS_VERSION,\n    MS_POINTER_SIZE,\n    MS_RUSAGE_USER,\n    MS_RUSAGE_SYSTEM,\n    MS_CURR_TIMES,\n    MS_TOTAL_ITEMS,\n    MS_BYTES,\n    MS_MAX_CONNECTIONS,\n    MS_CURR_CONNECTIONS,\n    MS_TOTAL_CONNECTIONS,\n};\n\nstatic struct Patterns memcached_stats[] = {\n{\"pid\",                  0, MS_PID,                SMACK_ANCHOR_BEGIN},\n{\"uptime\",               0, MS_UPTIME,             SMACK_ANCHOR_BEGIN},\n{\"time\",                 0, MS_TIME,               SMACK_ANCHOR_BEGIN},\n{\"version\",              0, MS_VERSION,            SMACK_ANCHOR_BEGIN},\n{\"pointer_size\",         0, MS_POINTER_SIZE,       SMACK_ANCHOR_BEGIN},\n{\"rusage_user\",          0, MS_RUSAGE_USER,        SMACK_ANCHOR_BEGIN},\n{\"rusage_system\",        0, MS_RUSAGE_SYSTEM,      SMACK_ANCHOR_BEGIN},\n{\"curr_items\",           0, MS_CURR_TIMES,         SMACK_ANCHOR_BEGIN},\n{\"total_items\",          0, MS_TOTAL_ITEMS,        SMACK_ANCHOR_BEGIN},\n{\"bytes\",                0, MS_BYTES,              SMACK_ANCHOR_BEGIN},\n{\"max_connections\",      0, MS_MAX_CONNECTIONS,    SMACK_ANCHOR_BEGIN},\n{\"curr_connections\",     0, MS_CURR_CONNECTIONS,   SMACK_ANCHOR_BEGIN},\n{\"total_connections\",    0, MS_TOTAL_CONNECTIONS,  SMACK_ANCHOR_BEGIN},\n{0,0,0,0}\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nmemcached_tcp_parse(  \n          const struct Banner1 *banner1,\n          void *banner1_private,\n          struct StreamState *pstate,\n          const unsigned char *px, size_t length,\n          struct BannerOutput *banout,\n          struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    struct MEMCACHEDSTUFF *memcached = &pstate->sub.memcached;\n    size_t id;\n\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n\n    if (sm_memcached_responses == 0)\n        return;\n\n    for (i=0; i<length; i++) {\n        switch (state) {\n            case 0: /* command */\n                memcached->match = 0;\n                /* drop through */\n            case 1:\n                id = smack_search_next(\n                        sm_memcached_responses,\n                        &memcached->match,\n                        px, &i, (unsigned)length);\n                i--;\n                switch (id) {\n                case SMACK_NOT_FOUND:\n                    /* continue processing */\n                    break;\n                case MC_STAT:\n                    if (px[i] == '\\n')\n                        state = 2; /* premature end of line */\n                    else\n                        state = 100;\n                    break;\n                case MC_END:\n                    state = 3;\n                    break;\n                default:\n                    state = 2;\n                }\n                break;\n\n            /* We've reached the end of input */\n            case 3:\n                i = (unsigned)length;\n                break;\n\n            /* Ignore until end of line */\n            case 2:\n                while (i < length && px[i] != '\\n')\n                    i++;\n                if (px[i] == '\\n')\n                    state = 0;\n                break;\n            \n            /* process stat */\n            case 100:\n            case 200:\n                if (px[i] == '\\n')\n                    state = 0;\n                else if (isspace(px[i]))\n                    continue; /* stay in this space until end of whitespace */\n                else {\n                    state++;\n                    memcached->match = 0;\n                    i--;\n                }\n                break;\n            case 101:\n                id = smack_search_next(\n                        sm_memcached_stats,\n                        &memcached->match,\n                        px, &i, (unsigned)length);\n                i--;\n                switch (id) {\n                case SMACK_NOT_FOUND:\n                    /* continue processing */\n                    break;\n                case MS_UPTIME:\n                case MS_TIME:\n                case MS_VERSION:\n                    banout_append(banout, PROTO_MEMCACHED, memcached_stats[id].pattern, AUTO_LEN);\n                    if (px[i] == '\\n')\n                        state = 0;\n                    else\n                        state = 200;\n                    banout_append_char(banout, PROTO_MEMCACHED, '=');\n                    break;\n                default:\n                    if (px[i] == '\\n')\n                        state = 0;\n                    else\n                        state = 2;\n                }\n                break;\n\n            case 201:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    banout_append_char(banout, PROTO_MEMCACHED, ' ');\n                    state = 0;\n                    break;\n                } else\n                    banout_append_char(banout, PROTO_MEMCACHED, px[i]);\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nmemcached_init(struct Banner1 *b)\n{\n    unsigned i;\n\n    /*\n     * These match response codes\n     */\n    b->memcached_responses = smack_create(\"memcached-responses\", SMACK_CASE_INSENSITIVE);\n    for (i=0; memcached_responses[i].pattern; i++) {\n        char *tmp;\n        unsigned j;\n        size_t len;\n\n        len = strlen(memcached_responses[i].pattern);\n        tmp = MALLOC(len + 2);\n        memcpy(tmp, memcached_responses[i].pattern, len);\n        tmp[len+1] = '\\0';\n\n        /* Add all patterns 4 times, once each for the possible whitespace */\n        for (j=0; j<4; j++) {\n            tmp[len] = \" \\t\\r\\n\"[j];\n            smack_add_pattern(\n                          b->memcached_responses,\n                          tmp,\n                          (unsigned)len+1,\n                          memcached_responses[i].id,\n                          memcached_responses[i].is_anchored);\n        }\n\n        free(tmp);\n    }\n    smack_compile(b->memcached_responses);\n    sm_memcached_responses = b->memcached_responses;\n\n    /*\n     * These match stats we might be interested in\n     */\n    b->memcached_stats = smack_create(\"memcached-stats\", SMACK_CASE_INSENSITIVE);\n    for (i=0; memcached_stats[i].pattern; i++) {\n        char *tmp;\n        unsigned j;\n        size_t len;\n\n        len = strlen(memcached_stats[i].pattern);\n        tmp = MALLOC(len + 2);\n        memcpy(tmp, memcached_stats[i].pattern, len);\n        tmp[len+1] = '\\0';\n\n        /* Add all patterns 4 times, once each for the possible whitespace */\n        for (j=0; j<4; j++) {\n            tmp[len] = \" \\t\\r\\n\"[j];\n            smack_add_pattern(\n                          b->memcached_stats,\n                          tmp,\n                          (unsigned)len+1,\n                          memcached_stats[i].id,\n                          memcached_stats[i].is_anchored);\n        }\n\n        free(tmp);\n    }\n    smack_compile(b->memcached_stats);\n    sm_memcached_stats = b->memcached_stats;\n\n    return b->http_fields;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nmemcached_udp_parse(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            )\n{\n    ipaddress ip_them;\n    ipaddress ip_me;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    unsigned request_id = 0;\n    unsigned sequence_num = 0;\n    unsigned total_dgrams = 0;\n    unsigned reserved = 0;\n    unsigned cookie = 0;\n    struct BannerOutput banout[1];\n\n    /* All memcached responses will be at least 8 bytes */\n    if (length < 8)\n        return 0;\n\n    /*\n    The frame header is 8 bytes long, as follows (all values are 16-bit integers\n    in network byte order, high byte first):\n\n    0-1 Request ID\n    2-3 Sequence number\n    4-5 Total number of datagrams in this message\n    6-7 Reserved for future use; must be 0\n    */\n    request_id = px[0]<<8 | px[1];\n    sequence_num = px[2]<<8 | px[3];\n    total_dgrams = px[4]<<8 | px[5];\n    reserved = px[6]<<8 | px[7];\n\n    /* Ignore high sequence numbers. This should be zero normally */\n    if (sequence_num > 100)\n        goto not_memcached;\n\n    /* Ignore too many dgrams, should be one normally */\n    if (total_dgrams > 100)\n        goto not_memcached;\n\n    /* Make sure reserved field is zero */\n    if (reserved != 0)\n        goto not_memcached;\n\n    /* Grab IP addresses */\n    ip_them = parsed->src_ip;\n    ip_me = parsed->dst_ip;\n\n    /* Validate the \"syn-cookie\" style information. In the case of SNMP,\n     * this will be held in the \"request-id\" field. If the cookie isn't\n     * a good one, then we'll ignore the response */\n    cookie = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n    /*if ((seqno&0xffff) != request_id)\n        return 1;*/\n\n    /* Initialize the \"banner output\" module that we'll use to print\n     * pretty text in place of the raw packet */\n    banout_init(banout);\n\n    /* Parse the remainder of the packet as if this were TCP */\n    {\n        struct StreamState stuff[1];\n\n        memset(stuff, 0, sizeof(stuff[0]));\n\n        memcached_tcp_parse(\n            0, 0,\n            stuff, px+8, length-8, banout, \n            0);\n    }\n\n    if ((cookie&0xffff) != request_id)\n        banout_append(banout, PROTO_MEMCACHED, \" IP-MISMATCH\", AUTO_LEN);\n            \n    /* Print the banner information, or save to a file, depending */\n    output_report_banner(\n        out, timestamp,\n        ip_them, 17 /*UDP*/, parsed->port_src,\n        PROTO_MEMCACHED,\n        parsed->ip_ttl,\n        banout_string(banout, PROTO_MEMCACHED),\n        banout_string_length(banout, PROTO_MEMCACHED));\n\n    /* Free memory for the banner, if there was any allocated */\n    banout_release(banout);\n\n    return 0;\n    \nnot_memcached:\n    return default_udp_parse(out, timestamp, px, length, parsed, entropy);\n}\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\nmemcached_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    /*\n    The frame header is 8 bytes long, as follows (all values are 16-bit integers\n    in network byte order, high byte first):\n\n    0-1 Request ID\n    2-3 Sequence number\n    4-5 Total number of datagrams in this message\n    6-7 Reserved for future use; must be 0\n    */\n\n    if (length < 2)\n        return 0;\n\n    px[0] = (unsigned char)(seqno >> 8);\n    px[1] = (unsigned char)(seqno >> 0);\n\n\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nmemcached_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_memcached = {\n    \"memcached\", 11211, \"stats\\r\\n\", 7, 0,\n    memcached_selftest,\n    memcached_init,\n    memcached_tcp_parse,\n};\n                             \n"
  },
  {
    "path": "src/proto-memcached.h",
    "content": "#ifndef PROTO_MEMCACHED_H\n#define PROTO_MEMCACHED_H\n#include \"proto-banner1.h\"\nstruct Output;\nstruct PreprocessedInfo;\n\n/*\n * For sending TCP requests and parsing TCP responses.\n */\nextern const struct ProtocolParserStream banner_memcached;\n\n/*\n * For parsing UDP responses\n */\nunsigned\nmemcached_udp_parse(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            );\n\n/* \n * For creating UDP request\n */\nunsigned\nmemcached_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\n#endif\n"
  },
  {
    "path": "src/proto-netbios.c",
    "content": "#include \"proto-netbios.h\"\n#include \"proto-udp.h\"\n#include \"proto-dns-parse.h\"\n#include \"proto-preprocess.h\"\n#include \"syn-cookie.h\"\n#include \"util-logger.h\"\n#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"proto-banner1.h\"\n#include \"massip-port.h\"\n#include \"masscan.h\"\n#include \"unusedparm.h\"\n\n#include <ctype.h>\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nappend_char(unsigned char *banner, size_t banner_max, unsigned *banner_length, char c)\n{\n    if (*banner_length < banner_max)\n        banner[(*banner_length)++] = c;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nappend_name(unsigned char *banner, size_t banner_max, unsigned *banner_length, const unsigned char *name)\n{\n    unsigned i;\n    unsigned char c;\n\n    for (i=0; i<15; i++) {\n        c = name[i];\n\n        if (c == 0x20 || c == '\\0')\n            append_char(banner, banner_max, banner_length, ' ');\n        else if (isalnum(c) || ispunct(c))\n            append_char(banner, banner_max, banner_length, c);\n        else {\n            append_char(banner, banner_max, banner_length, '<');\n            append_char(banner, banner_max, banner_length, \"0123456789ABCDEF\"[c>>4]);\n            append_char(banner, banner_max, banner_length, \"0123456789ABCDEF\"[c&0xF]);\n            append_char(banner, banner_max, banner_length, '>');\n        }\n    }\n\n    c = name[i];\n    append_char(banner, banner_max, banner_length, '<');\n    append_char(banner, banner_max, banner_length, \"0123456789ABCDEF\"[c>>4]);\n    append_char(banner, banner_max, banner_length, \"0123456789ABCDEF\"[c&0xF]);\n    append_char(banner, banner_max, banner_length, '>');\n    append_char(banner, banner_max, banner_length, '\\n');\n}\n\n/*****************************************************************************\n * Process one of them many \"resource-records\" within the NBTSTAT response\n *****************************************************************************/\nstatic unsigned\nhandle_nbtstat_rr(struct Output *out, time_t timestamp, unsigned ttl,\n                  const unsigned char *px, unsigned length,\n                  ipaddress ip_them, unsigned port_them)\n{\n    unsigned char banner[65536];\n    unsigned banner_length = 0;\n    unsigned offset = 0;\n    unsigned name_count;\n\n    if (offset >= length)\n        return 0;\n    name_count = px[offset++];\n\n    /* Report all the names */\n    while (offset + 18 <= length && name_count) {\n        append_name(banner, sizeof(banner), &banner_length, &px[offset]);\n        offset += 18;\n        name_count--;\n    }\n\n    /* Report the MAC address at the end */\n    {\n        unsigned i;\n\n        for (i=0; i<6; i++) {\n            if (offset + i < length) {\n                unsigned char c = px[offset];\n                append_char(banner, sizeof(banner), &banner_length, \"0123456789ABCDEF\"[c>>4]);\n                append_char(banner, sizeof(banner), &banner_length, \"0123456789ABCDEF\"[c&0xF]);\n                if (i < 5)\n                    append_char(banner, sizeof(banner), &banner_length, '-');\n            }\n        }\n    }\n\n\n    output_report_banner(\n            out, timestamp,\n            ip_them, 17, port_them,\n            PROTO_NBTSTAT,\n            ttl,\n            banner, banner_length);\n    return 0;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nhandle_nbtstat(struct Output *out, time_t timestamp,\n    const unsigned char *px, unsigned length, \n    struct PreprocessedInfo *parsed,\n    uint64_t entropy)\n{\n    ipaddress ip_them = parsed->src_ip;\n    ipaddress ip_me = parsed->dst_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    struct DNS_Incoming dns[1];\n    unsigned offset;\n    uint64_t seqno;\n\n\n    seqno = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n\n    proto_dns_parse(dns, px, parsed->app_offset, parsed->app_offset + parsed->app_length);\n\n    if ((seqno & 0xFFFF) != dns->id)\n        return 1;\n\n    if (dns->qr != 1)\n        return 0;\n    if (dns->rcode != 0)\n        return 0;\n    if (dns->qdcount > 1)\n        return 0;\n    if (dns->ancount < 1)\n        return 0;\n    if (dns->rr_count < 1)\n        return 0;\n\n\n    offset = dns->rr_offset[dns->qdcount];\n    offset = dns_name_skip(px, offset, length);\n    if (offset + 10 >= length)\n        return 0;\n\n    {\n        unsigned type = px[offset+0]<<8 | px[offset+1];\n        unsigned xclass = px[offset+2]<<8 | px[offset+3];\n        unsigned rrlen = px[offset+8]<<8 | px[offset+9];\n        unsigned txtlen = px[offset+10];\n\n        if (rrlen == 0 || txtlen > rrlen-1)\n            return 0;\n        if (type != 0x21 || xclass != 1)\n            return 0;\n\n        offset += 10;\n\n        return handle_nbtstat_rr(out, timestamp, parsed->ip_ttl,\n                                    px + offset,\n                                    length - offset,\n                                    ip_them,\n                                    port_them);\n    }\n\n}\n"
  },
  {
    "path": "src/proto-netbios.h",
    "content": "#ifndef PROTO_NETBIOS_H\n#define PROTO_NETBIOS_H\n#include <time.h>\n#include <stdint.h>\nstruct PreprocessedInfo;\nstruct Output;\n\nunsigned handle_nbtstat(struct Output *out, time_t timestamp,\n    const unsigned char *px, unsigned length, \n    struct PreprocessedInfo *parsed,\n    uint64_t entropy);\n\n#endif\n"
  },
  {
    "path": "src/proto-ntlmssp.c",
    "content": "#include \"proto-ntlmssp.h\"\n#include \"masscan-app.h\"\n#include \"proto-banout.h\"\n#include \"util-safefunc.h\"\n#include \"util-malloc.h\"\n#include <string.h>\n#include <stdlib.h>\n\n/*\n +--------+--------+--------+--------+\n |  'N'   |  'T'   |  'L'   |  'M'   |\n +-      -+-      -+-      -+-      -+\n |  'S'   |  'S'   |  'P'   | '\\0'   |\n +--------+--------+--------+--------+\n |           MessageType             |\n +--------+--------+--------+--------+\n |  TargetNameLen  | TargetNameMaxLen| TagetName fields set to zero if\n +--------+--------+--------+--------+ NTLMSSP_REQUEST_TARGET  flag not set\n |           TargetNameOffset        |\n +--------+--------+--------+--------+\n |            NegotiateFlags         |\n +--------+--------+--------+--------+\n |                                   |\n +-          ServerChallenge        -+\n |                                   |\n +--------+--------+--------+--------+\n |                                   |\n +-             Reserved            -+\n |                                   |\n +--------+--------+--------+--------+\n |  TargetInfoLen  | TargetInfoMaxLen| TagetInfo fields set to zero if\n +--------+--------+--------+--------+ NTLMSSP_NEGOTIATE_TARGET_INFO  flag not set\n |           TargetInfoOffset        |\n +--------+--------+--------+--------+\n |MajorVer|MinorVer|   ProductBuild  |\n +--------+--------+--------+--------+\n |          Reserved        |NTLMver |\n +--------+--------+--------+--------+\n |                                   |\n +-      -+-      -+-      -+-      -+\n . . . . . . . . . . . . . . . . . . .\n +-      -+-      -+-      -+-      -+\n |        |        |        |        |\n +--------+--------+--------+--------+\n\n \n Signature (8 bytes):\n    \"An 8-byte character array that MUST contain the ASCII string\n    ('N', 'T', 'L', 'M', 'S', 'S', 'P', '\\0').\"\n MessageType (4 bytes):\n    \"A 32-bit unsigned integer that indicates the message type. This field MUST\n    be set to 0x00000002.\"\n \n \n TargetNameLen (2 bytes):\n    \"A 16-bit unsigned integer that defines the size, in bytes, of\n    TargetName in Payload.\"\n    Zero if NTLMSSP_REQUEST_TARGET not set.\n TargetNameMaxLen (2 bytes):\n    \"A 16-bit unsigned integer that SHOULD be set to the value\n    of TargetNameLen and MUST be ignored on receipt.\"\n    Zero if NTLMSSP_REQUEST_TARGET not set.\n TargetNameBufferOffset (4 bytes):\n    \"A 32-bit unsigned integer that defines the offset, in\n    bytes, from the beginning of the CHALLENGE_MESSAGE to TargetName in Payload. If\n    TargetName is a Unicode string, the values of TargetNameBufferOffset and\n    TargetNameLen MUST be multiples of 2.\"\n \n \n \n VERSION FIELDS:\n    These fields are valid only if \"NTLMSSP_NEGOTIATE_VERSION\" flag is set.\n \n  MajorVer [ProductMajorVersion] (1 byte):\n    \"An 8-bit unsigned integer that SHOULD contain the major\n    version number of the operating system in use.\"\n  MinorVer [ProductMinorVersion] (1 byte):\n    \"An 8-bit unsigned integer that SHOULD<34> contain the minor\n    version number of the operating system in use.\"\n  ProductBuild (2 bytes):\n    \"A 16-bit unsigned integer that contains the build number of the operating\n    system in use. This field SHOULD be set to a 16-bit quantity that identifies the operating system\n    build number.\"\n  NTLMRevisionCurrent (1 byte):\n    \"An 8-bit unsigned integer that contains a value indicating the\n    current revision of the NTLMSSP in use. This field SHOULD contain the following value:\"\n        \"NTLMSSP_REVISION_W2K3 (0x0F): Version 15 of the NTLMSSP is in use.\"\n \n \n */\n\nstatic void\nappend_unicode_string(struct BannerOutput *banout, unsigned proto, const char *name, const unsigned char *value, size_t value_length)\n{\n    unsigned j;\n    banout_append_char(banout, proto, ' ');\n    banout_append(banout, PROTO_SMB, name, AUTO_LEN);\n    banout_append_char(banout, proto, '=');\n    for (j=0; j<value_length; j += 2) {\n        unsigned c = value[j] | value[j+1]<<8;\n        banout_append_unicode(banout, PROTO_SMB, c);\n    }\n}\n\nvoid\nntlmssp_decode(struct NtlmsspDecode *x,\n              const unsigned char *px, size_t length,\n              struct BannerOutput *banout)\n{\n    unsigned message_type;\n    unsigned name_offset;\n    unsigned name_length;\n    unsigned info_offset;\n    unsigned info_length;\n    //unsigned flags;\n    unsigned i;\n    \n    if (length > x->length - x->offset)\n        length = x->length - x->offset;\n    \n    /* See if we have a fragment, in which case we need to allocate a buffer\n     * to contain it */\n    if (x->offset == 0 && x->length > length) {\n        x->buf = MALLOC(x->length);\n        memcpy(x->buf, px, length);\n        x->offset = (unsigned)length;\n        return;\n    } else if (x->offset) {\n        memcpy(x->buf + x->offset, px, length);\n        x->offset += (unsigned)length;\n        if (x->offset < x->length)\n            return;\n        \n        /* now reset the input to point to our buffer instead */\n        px = x->buf;\n        length = x->length;\n    }\n    \n    if (length < 56)\n        goto end;\n    \n    /* Verify the signature. There are other protocols that we could possibly\n     * detect at this point and do something else useful with, but for right now,\n     * we are just doing NTLM */\n    if (memcmp(\"NTLMSSP\", px, 8) != 0)\n        goto end;\n    \n    /* Verify this is a \"challenge\" packet, which has all the interesting\n     * fields. */\n    message_type = px[8] | px[9]<<8 | px[10]<<16 | px[11]<<24;\n    if (message_type != 2)\n        goto end;\n    \n    /* Grab the Domain field. This is a pointer in these 8 bytes here\n     * that points into the payload section of the chunk */\n    name_length = px[12] | px[13]<<8;\n    name_offset = px[16] | px[17]<<8 | px[18]<<16 | px[19]<<24;\n    if (name_length && name_length + name_offset < length) {\n        append_unicode_string(banout, PROTO_SMB, \"domain\", px+name_offset, name_length);\n    }\n    \n    /* Grab flags */\n    //flags = px[20] | px[21]<<8 | px[22]<<16 | px[23]<<24;\n    \n    /* Info field */\n    info_length = px[40] | px[41]<<8;\n    info_offset = px[44] | px[45]<<8 | px[46]<<16 | px[47]<<24;\n\n    /* Version field */\n    {\n        char buf[64];\n        snprintf(buf, sizeof(buf), \" version=%u.%u.%u ntlm-ver=%u\",\n                  px[48],\n                  px[49],\n                  px[50] | px[51]<<8,\n                  px[55]\n                  );\n        banout_append(banout, PROTO_SMB, buf, AUTO_LEN);\n    }\n\n    /* Parse all the fields */\n    for (i=info_offset; i+4<info_offset+info_length && i+4<length; ) {\n        unsigned type = px[i] | px[i+1]<<8;\n        size_t len = px[i+2] | px[i+3]<<8;\n        i += 4;\n        \n        if (len > info_offset + info_length - i)\n            len = info_offset + info_length - i;\n        if (len > length - i)\n            len = length - i;\n        \n        switch (type) {\n            case 0x00: /* MsvAvEOL */\n                i = info_offset + info_length;\n                continue;\n            case 1: /* MsvAvNbComputerName */\n                append_unicode_string(banout, PROTO_SMB, \"name\", px+i, len);\n                break;\n            case 2: /* MsvAvNbDomainName */\n                append_unicode_string(banout, PROTO_SMB, \"domain\", px+i, len);\n                break;\n            case 3: /* MsvAvDnsComputerName */\n                append_unicode_string(banout, PROTO_SMB, \"name-dns\", px+i, len);\n                break;\n            case 4: /* MsvAvDnsDomainName */\n                append_unicode_string(banout, PROTO_SMB, \"domain-dns\", px+i, len);\n                break;\n            case 5: /* MsvAvDnsTreeName */\n                append_unicode_string(banout, PROTO_SMB, \"forest\", px+i, len);\n                break;\n            case 6: /* MsvAvFlags */\n                break;\n            case 7: /* MsvAvTimestamp */\n                break;\n            case 8: /* MsvAvSingleHost */\n                break;\n            case 9: /* MsvAvTargetName */\n                append_unicode_string(banout, PROTO_SMB, \"target\", px+i, len);\n                break;\n            case 10: /* MsvChannelBindings */\n                break;\n            default:\n                break;\n        }\n        i += (unsigned)len;\n    }\n\n    \n    \n    /* Grab the other fields. This*/\n    \nend:\n    /*\n     * Free the buffer if needed\n     */\n    if (x->buf) {\n        free(x->buf);\n        x->buf = 0;\n    }\n    \n}\n\nvoid\nntlmssp_cleanup(struct NtlmsspDecode *x)\n{\n    if (x->buf) {\n        free(x->buf);\n        x->buf = 0;\n    }\n}\n\nvoid\nntlmssp_decode_init(struct NtlmsspDecode *x, size_t length)\n{\n    memset(x, 0, sizeof(*x));\n    \n    /* [security] Double-check this input, since it's ultimately driven by user-input.\n     * The code that leads to here should already have double-checked this, but I'm\n     * doing it again just in case. This is larger than any input that should be\n     * seen in the real world that a hacker isn't messing with.\n     */\n    if (length > 65536)\n        length = 65536;\n    \n    x->length = (unsigned)length;\n    x->offset = 0;\n    x->buf = NULL;\n    \n}\n\n"
  },
  {
    "path": "src/proto-ntlmssp.h",
    "content": "#ifndef PROTO_NTLMSSP_H\n#define PROTO_NTLMSSP_H\n#include <stdio.h>\nstruct BannerOutput;\n\nstruct NtlmsspDecode\n{\n    unsigned length;\n    unsigned offset;\n    unsigned char *buf;\n};\n\nvoid\nntlmssp_decode_init(struct NtlmsspDecode *x, size_t length);\n\nvoid\nntlmssp_cleanup(struct NtlmsspDecode *x);\n\nvoid\nntlmssp_decode(struct NtlmsspDecode *x,\n              const unsigned char *px, size_t length,\n              struct BannerOutput *banout);\n\n#endif\n\n"
  },
  {
    "path": "src/proto-ntp.c",
    "content": "/*\n    NTP protocol handler\n*/\n#include \"proto-ntp.h\"\n#include <stdint.h>\n#include <stdlib.h>\n#include \"smack.h\"\n#include \"util-safefunc.h\"\n#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-banner1.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n#include \"unusedparm.h\"\n\n\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\nntp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n    UNUSEDPARM(seqno);\n    return 0;\n}\nstruct Val2String {\n    unsigned value;\n    const char *string;\n};\n\nstatic const struct Val2String request_codes[] = {\n\t{ 0,\t\t\"PEER_LIST\" },\n\t{ 1,\t\t\"PEER_LIST_SUM\" },\n\t{ 2,\t\t\"PEER_INFO\" },\n\t{ 3,\t\t\"PEER_STATS\" },\n\t{ 4,\t\t\"SYS_INFO\" },\n\t{ 5,\t\t\"SYS_STATS\" },\n\t{ 6,\t\t\"IO_STATS\" },\n\t{ 7,\t\t\"MEM_STATS\" },\n\t{ 8,\t\t\"LOOP_INFO\" },\n\t{ 9,\t\t\"TIMER_STATS\" },\n\t{ 10,\t\t\"CONFIG\" },\n\t{ 11,\t\t\"UNCONFIG\" },\n\t{ 12,\t\t\"SET_SYS_FLAG\" },\n\t{ 13,\t\t\"CLR_SYS_FLAG\" },\n\t{ 16,\t\t\"GET_RESTRICT\" },\n\t{ 17,\t\t\"RESADDFLAGS\" },\n\t{ 18,\t\t\"RESSUBFLAGS\" },\n\t{ 19,\t\t\"UNRESTRICT\" },\n\t{ 20,\t\t\"MON_GETLIST\" },\n\t{ 21,\t\t\"RESET_STATS\" },\n\t{ 22,\t\t\"RESET_PEER\" },\n\t{ 23,\t\t\"REREAD_KEYS\" },\n\t{ 26,\t\t\"TRUSTKEY\" },\n\t{ 27,\t\t\"UNTRUSTKEY\" },\n\t{ 28,\t\t\"AUTHINFO\" },\n\t{ 29,\t\t\"TRAPS\" },\n\t{ 30,\t\t\"ADD_TRAP\" },\n\t{ 31,\t\t\"CLR_TRAP\" },\n\t{ 32,\t\t\"REQUEST_KEY\" },\n\t{ 33,\t\t\"CONTROL_KEY\" },\n\t{ 34,\t\t\"GET_CTLSTATS\" },\n\t{ 36,\t\t\"GET_CLOCKINFO\" },\n\t{ 37,\t\t\"SET_CLKFUDGE\" },\n\t{ 38,\t\t\"GET_KERNEL\" },\n\t{ 39,\t\t\"GET_CLKBUGINFO\" },\n\t{ 42,\t\t\"MON_GETLIST_1\" },\n\t{ 43,\t\t\"HOSTNAME_ASSOCID\" },\n    { 0, 0}\n};\n\nstruct Val2String error_codes[] = {\n    {0, \"No Error\"},\n    {1, \"Incompatible Implementation Number\"},\n    {2, \"Unimplemented Request Code\"},\n    {3, \"Format Error\"},\n    {4, \"No Data Available\"},\n    {7, \"Authentication Failure\"},\n    {0,0}\n};\n\n/*****************************************************************************\n *****************************************************************************/\nstatic const char *\nval2string_lookup(const struct Val2String *list, unsigned val)\n{\n    unsigned i;\n    for (i=0; list[i].string; i++) {\n        if (list[i].value == val)\n            return list[i].string;\n    }\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nntp_modlist_parse(const unsigned char *px,\n             unsigned length,\n             struct BannerOutput *banout,\n             unsigned *request_id)\n{\n    unsigned offset = 4;\n    unsigned errcode;\n    unsigned record_count;\n    unsigned record_size;\n \n    UNUSEDPARM(request_id);\n\n    if (offset + 4 >= length)\n        return;\n    \n    errcode = (px[offset]>>4)&0xF;\n    record_count = (px[offset+0]&0xF) << 8 | px[offset+1];\n    record_size = (px[offset+2]&0xF) << 8 | px[offset+3];\n\n    if (errcode) {\n        char foo[12];\n        const char *errmsg = val2string_lookup(error_codes, errcode);\n        if (errmsg == 0)\n            errmsg = \"Bogus Error Code\";\n        snprintf(foo, sizeof(foo), \"%u\", errcode);\n        banout_append(banout, PROTO_NTP, \"Response was NTP Error Code \", AUTO_LEN);\n        banout_append(banout, PROTO_NTP, foo, AUTO_LEN);\n        banout_append(banout, PROTO_NTP, \" - \\\"\", AUTO_LEN);\n        banout_append(banout, PROTO_NTP, errmsg, AUTO_LEN);\n        banout_append(banout, PROTO_NTP, \"\\\"\", AUTO_LEN);\n        return;\n    }\n\n    if (4 + record_count * record_size > length) {\n        banout_append(banout, PROTO_NTP, \"response-too-big\", AUTO_LEN);\n        return;\n    }\n    if (record_count * record_size > 500) {\n        banout_append(banout, PROTO_NTP, \"response-too-big\", AUTO_LEN);\n        return;\n    }\n\n    //offset += 4;\n\n    {\n        char msg[128];\n\n        snprintf(msg, sizeof(msg), \" response-size=%u-bytes more=%s\",\n            record_count * record_size, ((px[0]>>6)&1)?\"true\":\"false\");\n\n        banout_append(banout, PROTO_NTP, msg, AUTO_LEN);\n    }\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nntp_priv(const unsigned char *px,\n             unsigned length,\n             struct BannerOutput *banout,\n             unsigned *request_id)\n{\n    unsigned implementation = px[2];\n    unsigned request_code = px[3];\n    const char *request_string;\n    \n    switch (implementation) {\n        case 0: banout_append(banout, PROTO_NTP, \"UNIV\", 4); return;\n        case 2: banout_append(banout, PROTO_NTP, \"XNTPD-OLD\", 9); return;\n        case 3: banout_append(banout, PROTO_NTP, \"XNTPD\", 5); break;\n        default:\n            return;\n    }\n    \n    request_string = val2string_lookup(request_codes, request_code);\n    if (request_string) {\n        banout_append(banout, PROTO_NTP, \" \", 1);\n        banout_append(banout, PROTO_NTP, request_string, strlen(request_string));\n    }\n    \n    switch (request_code) {\n        case 42:\n            ntp_modlist_parse(px, length, banout, request_id);\n            break;\n    }    \n    \n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nntp_v2_parse(const unsigned char *px,\n           unsigned length,\n           struct BannerOutput *banout,\n           unsigned *request_id)\n{\n    unsigned mode;\n    \n    if (length < 4)\n        return;\n    \n    /* Validate: response bit is set */\n    if ((px[0]>>7) != 1)\n        return;\n        \n    /* Validate: this is version 2 */\n    if (((px[0]>>3)&7) != 2)\n        return;\n    \n    /* Extract: mode */\n    mode = px[0] & 7;\n    switch (mode) {\n        case 6: /* control */\n            break;\n        case 7:\n            ntp_priv(px, length, banout, request_id);\n            break;\n    }\n    \n    \n    \n}\n\n\n/*****************************************************************************\n * Handles an NTP response.\n *****************************************************************************/\nunsigned\nntp_handle_response(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            )\n{\n    ipaddress ip_them = parsed->src_ip;\n    unsigned request_id = 0;\n    struct BannerOutput banout[1];\n    unsigned offset = parsed->app_offset;\n    \n    UNUSEDPARM(length);\n    UNUSEDPARM(entropy);\n    \n    if (parsed->app_length < 4)\n        return 0;\n    \n    /* Initialize the \"banner output\" module that we'll use to print\n     * pretty text in place of the raw packet */\n    banout_init(banout);\n    \n    /* Parse the packet */\n    switch ((px[offset]>>3)&7) {\n        case 2:\n            ntp_v2_parse(\n               px + parsed->app_offset,    /* incoming  response */\n               parsed->app_length,         /* length of  response */\n               banout,                     /* banner printing */\n               &request_id);               /* syn-cookie info */\n            break;\n        default:\n            banout_release(banout);\n            return 0;\n    }\n    \n    /* Validate the \"syn-cookie\" style information. */\n    //seqno = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me);\n    //if ((seqno&0x7FFFffff) != request_id)\n    //    return 1;\n    \n    /* Print the banner information, or save to a file, depending */\n    output_report_banner(\n                         out, timestamp,\n                         ip_them, 17, parsed->port_src,\n                         PROTO_NTP,\n                         parsed->ip_ttl,\n                         banout_string(banout, PROTO_NTP),\n                         banout_string_length(banout, PROTO_NTP));\n    \n    /* Free memory for the banner, if there was any allocated */\n    banout_release(banout);\n    \n    return 0;\n}\n\n\n\n/****************************************************************************\n ****************************************************************************/\nint\nntp_selftest(void)\n{\n    \n    \n    return 0;\n}\n\n\n\n\n\n"
  },
  {
    "path": "src/proto-ntp.h",
    "content": "#ifndef PROTO_NTP_H\n#define PROTO_NTP_H\n#include <time.h>\n#include <stdint.h>\nstruct Output;\nstruct PreprocessedInfo;\n\n/**\n * Does a regression test.\n * @return\n *     0 if success, 1 if failure\n */\nint ntp_selftest(void);\n\n/**\n * Sets a cookie on the packet, if possible.\n */\nunsigned \nntp_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\n/**\n * Parse NTP responses looking for any \"banner\" information\n */\nunsigned\nntp_handle_response(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy);\n\n#endif\n"
  },
  {
    "path": "src/proto-oproto.c",
    "content": "#include \"proto-oproto.h\"\n#include \"unusedparm.h\"\n\nvoid\nhandle_oproto(struct Output *out, time_t timestamp,\n              const unsigned char *px, unsigned length,\n              struct PreprocessedInfo *parsed,\n              uint64_t entropy)\n{\n    UNUSEDPARM(entropy);\n    UNUSEDPARM(parsed);\n    UNUSEDPARM(length);\n    UNUSEDPARM(px);\n    UNUSEDPARM(timestamp);\n    UNUSEDPARM(out);\n}\n"
  },
  {
    "path": "src/proto-oproto.h",
    "content": "/*\n Other IP protocol (not TCP, UDP, TCP, ICMP\n Specifically for scanning things like GRE.\n */\n#ifndef PROTO_OPROTO_H\n#define PROTO_OPROTO_H\n#include <stdint.h>\n#include <time.h>\nstruct Output;\nstruct PreprocessedInfo;\n\n\n/**\n * Parse an incoming response.\n * @param entropy\n *      The random seed, used in calculating syn-cookies.\n */\nvoid\nhandle_oproto(struct Output *out, time_t timestamp,\n           const unsigned char *px, unsigned length,\n           struct PreprocessedInfo *parsed,\n           uint64_t entropy);\n\n#endif\n\n"
  },
  {
    "path": "src/proto-pop3.c",
    "content": "/*\n \n    POP3 banner checker\n \n \n */\n\n#include \"proto-pop3.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-ssl.h\"\n#include <ctype.h>\n#include <string.h>\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\npop3_parse(  const struct Banner1 *banner1,\n           void *banner1_private,\n           struct StreamState *pstate,\n           const unsigned char *px, size_t length,\n           struct BannerOutput *banout,\n           struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    \n    \n    for (i=0; i<length; i++) {\n        if (px[i] == '\\r')\n            continue;\n\n       \n        switch (state) {\n            case 0: case 1: case 2:\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (\"+OK\"[state] != px[i]) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                } else\n                    state++;\n                break;\n            case 3:\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '\\n') {\n                    tcpapi_send(socket, \"CAPA\\r\\n\", 6, 0);\n                    state++;\n                }\n                break;\n            case 4:\n            case 204:\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '-')\n                    state = 100;\n                else if (px[i] == '+')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 5:\n            case 205:\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == 'O')\n                    state++;\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 6:\n            case 206:\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == 'K')\n                    state += 2; /* oops, I had too many states here */\n                else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 8:\n                if (px[i] == '\\r')\n                    continue;\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '\\n')\n                    state++;\n                break;\n            case 9:\n                if (px[i] == '\\r')\n                    continue;\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '.')\n                    state++;\n                else if (px[i] == '\\n')\n                    continue;\n                else\n                    state--;\n                break;\n            case 10:\n                if (px[i] == '\\r')\n                    continue;\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '\\n') {\n                    tcpapi_send(socket, \"STLS\\r\\n\", 6, 0);\n                    state = 204;\n                } else {\n                    state = 8;\n                }\n                break;\n            \n            case 208:\n                if (px[i] == '\\r')\n                    continue;\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '\\n') {\n                    /* change the state here to SSL */\n                    unsigned port = pstate->port;\n                    memset(pstate, 0, sizeof(*pstate));\n                    pstate->app_proto = PROTO_SSL3;\n                    pstate->is_sent_sslhello = 1;\n                    pstate->port = (unsigned short)port;\n                    state = 0;\n                    \n                    tcpapi_send(socket, banner_ssl.hello, banner_ssl.hello_length, 0);\n                    \n                    break;\n                }\n                break;\n\n            case 100:\n                if (px[i] == '\\r')\n                    continue;\n                banout_append_char(banout, PROTO_POP3, px[i]);\n                if (px[i] == '\\n') {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            default:\n                i = (unsigned)length;\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\npop3_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\npop3_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_pop3 = {\n    \"pop3\", 110, 0, 0, 0,\n    pop3_selftest,\n    pop3_init,\n    pop3_parse,\n};\n"
  },
  {
    "path": "src/proto-pop3.h",
    "content": "#ifndef PROTO_POP3_H\n#define PROTO_POP3_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_pop3;\n\n#endif\n"
  },
  {
    "path": "src/proto-preprocess.c",
    "content": "/* Copyright: (c) 2009-2010 by Robert David Graham */\n/****************************************************************************\n\n        PREPROCESS PACKETS\n\n  This function parses the entire TCP/IP stack looking for IP addresses and\n  ports. The intent is that this is the minimal parsing necessary to find\n  address/port information. While it does basic checking (to confirm length\n  information, for example), it does not do more extensive checking (like\n  whether the checksum is correct).\n\n ****************************************************************************/\n#include \"proto-preprocess.h\"\n#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#define ex32be(px)  (   *((unsigned char*)(px)+0)<<24 \\\n                    |   *((unsigned char*)(px)+1)<<16 \\\n                    |   *((unsigned char*)(px)+2)<< 8 \\\n                    |   *((unsigned char*)(px)+3)<< 0 )\n#define ex32le(px)  (   *((unsigned char*)(px)+0)<< 0 \\\n                    |   *((unsigned char*)(px)+1)<< 8 \\\n                    |   *((unsigned char*)(px)+2)<<16 \\\n                    |   *((unsigned char*)(px)+3)<<24 )\n#define ex16be(px)  (   *((unsigned char*)(px)+0)<< 8 \\\n                    |   *((unsigned char*)(px)+1)<< 0 )\n#define ex16le(px)  (   *((unsigned char*)(px)+0)<< 0 \\\n                    |   *((unsigned char*)(px)+1)<< 8 )\n\n#define ex24be(px)  (   *((unsigned char*)(px)+0)<<16 \\\n                    |   *((unsigned char*)(px)+1)<< 8 \\\n                    |   *((unsigned char*)(px)+2)<< 0 )\n#define ex24le(px)  (   *((unsigned char*)(px)+0)<< 0 \\\n                    |   *((unsigned char*)(px)+1)<< 8 \\\n                    |   *((unsigned char*)(px)+2)<<16 )\n\n#define ex64be(px)  ( (((uint64_t)ex32be(px))<<32L) + ((uint64_t)ex32be((px)+4)) )\n#define ex64le(px)  ( ((uint64_t)ex32be(px)) + (((uint64_t)ex32be((px)+4))<<32L) )\n\n/**\n *  Call this frequently while parsing through the headers to make sure that\n *  we don't go past the end of a packet. Remember that 1 byte past the\n *  end can cause a crash.\n **/\n#define VERIFY_REMAINING(n,f) if (offset+(n) > length) return 0; else {info->found_offset=offset; info->found=f;}\n\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\npreprocess_frame(const unsigned char *px, unsigned length, unsigned link_type,\n                 struct PreprocessedInfo *info)\n{\n    unsigned offset = 0;\n    unsigned ethertype = 0;\n\n    info->transport_offset = 0;\n    info->found = FOUND_NOTHING;\n    info->found_offset = 0;\n\n    /* If not standard Ethernet, go do something else */\n    if (link_type != 1)\n        goto parse_linktype;\n\nparse_ethernet:\n    VERIFY_REMAINING(14, FOUND_ETHERNET);\n\n    info->mac_dst = px+offset+0;\n    info->mac_src = px+offset+6;\n    ethertype = ex16be(px+offset+12);\n    offset += 14;\n    if (ethertype < 2000)\n        goto parse_llc;\n    if (ethertype != 0x0800)\n        goto parse_ethertype;\n\nparse_ipv4:\n    {\n        unsigned header_length;\n        unsigned flags;\n        unsigned fragment_offset;\n        unsigned total_length;\n\n        info->ip_offset = offset;\n        VERIFY_REMAINING(20, FOUND_IPV4);\n\n        /* Check version */\n        if ((px[offset]>>4) != 4)\n            return 0; /* not IPv4 or corrupt */\n\n        /* Check header length */\n        header_length = (px[offset] & 0x0F) * 4;\n        VERIFY_REMAINING(header_length, FOUND_IPV4);\n\n        /*TODO: verify checksum */\n\n        /* Check for fragmentation */\n        flags = px[offset+6]&0xE0;\n        fragment_offset = (ex16be(px+offset+6) & 0x3FFF) << 3;\n        if (fragment_offset != 0 || (flags & 0x20))\n            return 0; /* fragmented */\n\n        /* Check for total-length */\n        total_length = ex16be(px+offset+2);\n        VERIFY_REMAINING(total_length, FOUND_IPV4);\n        if (total_length < header_length)\n            return 0; /* weird corruption */\n        length = offset + total_length; /* reduce the max length */\n\n\n        /* Save off pseudo header for checksum calculation */\n        info->ip_version = (px[offset]>>4)&0xF;\n        info->_ip_src = px+offset+12;\n        info->_ip_dst = px+offset+16;\n        info->src_ip.ipv4 = px[offset+12] << 24\n                            | px[offset+13] << 16\n                            | px[offset+14] << 8\n                            | px[offset+15] << 0;\n        info->src_ip.version = 4;\n        info->dst_ip.ipv4 = px[offset+16] << 24\n                            | px[offset+17] << 16\n                            | px[offset+18] << 8\n                            | px[offset+19] << 0;\n        info->dst_ip.version = 4;\n        \n        info->ip_ttl = px[offset+8];\n        info->ip_protocol = px[offset+9];\n        info->ip_length = total_length;\n        if (info->ip_version != 4)\n            return 0;\n\n        /* next protocol */\n        offset += header_length;\n        info->transport_offset = offset;\n        info->transport_length = length - info->transport_offset;\n\n        switch (info->ip_protocol) {\n        case   1: goto parse_icmp;\n        case   2: goto parse_igmp;\n        case   6: goto parse_tcp;\n        case  17: goto parse_udp;\n        case 132: goto parse_sctp;\n        default:\n                VERIFY_REMAINING(0, FOUND_OPROTO);\n                return 0; /* TODO: should add more protocols, like ICMP */\n        }\n    }\n\nparse_tcp:\n    {\n        unsigned tcp_length;\n        VERIFY_REMAINING(20, FOUND_TCP);\n        tcp_length = px[offset + 12]>>2;\n        VERIFY_REMAINING(tcp_length, FOUND_TCP);\n        info->port_src = ex16be(px+offset+0);\n        info->port_dst = ex16be(px+offset+2);\n        info->app_offset = offset + tcp_length;\n        info->app_length = length - info->app_offset;\n        //assert(info->app_length < 2000);\n\n        return 1;\n    }\n\nparse_udp:\n    {\n        VERIFY_REMAINING(8, FOUND_UDP);\n        \n        info->port_src = ex16be(px+offset+0);\n        info->port_dst = ex16be(px+offset+2);\n        offset += 8;\n        info->app_offset = offset;\n        info->app_length = length - info->app_offset;\n        assert(info->app_length < 2000);\n\n        if (info->port_dst == 53 || info->port_src == 53) {\n            goto parse_dns;\n        }\n        return 1;\n    }\n\nparse_icmp:\n    {\n        VERIFY_REMAINING(4, FOUND_ICMP);\n        info->port_src = px[offset+0];\n        info->port_dst = px[offset+1];\n        return 1;\n    }\n\nparse_igmp:\n    {\n        VERIFY_REMAINING(4, FOUND_IGMP);\n        info->port_src = 0;\n        info->port_dst = px[offset+0];\n        return 1;\n    }\n\nparse_sctp:\n    {\n        VERIFY_REMAINING(12, FOUND_SCTP);\n        info->port_src = ex16be(px+offset+0);\n        info->port_dst = ex16be(px+offset+2);\n        info->app_offset = offset + 12;\n        info->app_length = length - info->app_offset;\n        assert(info->app_length < 2000);\n        return 1;\n    }\n\nparse_dns:\n    {\n        VERIFY_REMAINING(8, FOUND_DNS);\n        return 1;\n    }\n\nparse_ipv6:\n    {\n        unsigned payload_length;\n\n        info->ip_offset = offset;\n        VERIFY_REMAINING(40, FOUND_IPV6);\n\n        /* Check version */\n        if ((px[offset]>>4) != 6)\n            return 0; /* not IPv4 or corrupt */\n\n        /* Payload length */\n        payload_length = ex16be(px+offset+4);\n        VERIFY_REMAINING(40+payload_length, FOUND_IPV6);\n        if (length > offset + 40 + payload_length)\n            length = offset + 40 + payload_length;\n\n        /* Save off pseudo header for checksum calculation */\n        info->ip_version = (px[offset]>>4)&0xF;\n        info->_ip_src = px+offset+8;\n        info->_ip_dst = px+offset+8+16;\n        info->ip_protocol = px[offset+6];\n\n        info->src_ip.version = 6;\n        info->src_ip.ipv6.hi = 0ULL\n                            | (uint64_t)px[offset +  8] << 56ULL\n                            | (uint64_t)px[offset +  9] << 48ULL\n                            | (uint64_t)px[offset + 10] << 40ULL\n                            | (uint64_t)px[offset + 11] << 32ULL\n                            | (uint64_t)px[offset + 12] << 24ULL\n                            | (uint64_t)px[offset + 13] << 16ULL\n                            | (uint64_t)px[offset + 14] <<  8ULL\n                            | (uint64_t)px[offset + 15] <<  0ULL;\n        info->src_ip.ipv6.lo = 0ULL\n                            | (uint64_t)px[offset + 16] << 56ULL\n                            | (uint64_t)px[offset + 17] << 48ULL\n                            | (uint64_t)px[offset + 18] << 40ULL\n                            | (uint64_t)px[offset + 19] << 32ULL\n                            | (uint64_t)px[offset + 20] << 24ULL\n                            | (uint64_t)px[offset + 21] << 16ULL\n                            | (uint64_t)px[offset + 22] <<  8ULL\n                            | (uint64_t)px[offset + 23] <<  0ULL;\n\n        info->dst_ip.version = 6;\n        info->dst_ip.ipv6.hi = 0ULL\n                            | (uint64_t)px[offset + 24] << 56ULL\n                            | (uint64_t)px[offset + 25] << 48ULL\n                            | (uint64_t)px[offset + 26] << 40ULL\n                            | (uint64_t)px[offset + 27] << 32ULL\n                            | (uint64_t)px[offset + 28] << 24ULL\n                            | (uint64_t)px[offset + 29] << 16ULL\n                            | (uint64_t)px[offset + 30] <<  8ULL\n                            | (uint64_t)px[offset + 31] <<  0ULL;\n        info->dst_ip.ipv6.lo = 0ULL\n                            | (uint64_t)px[offset + 32] << 56ULL\n                            | (uint64_t)px[offset + 33] << 48ULL\n                            | (uint64_t)px[offset + 34] << 40ULL\n                            | (uint64_t)px[offset + 35] << 32ULL\n                            | (uint64_t)px[offset + 36] << 24ULL\n                            | (uint64_t)px[offset + 37] << 16ULL\n                            | (uint64_t)px[offset + 38] <<  8ULL\n                            | (uint64_t)px[offset + 39] <<  0ULL;\n\n\n\n        /* next protocol */\n        offset += 40;\n        info->transport_offset = offset;\n        info->transport_length = length - info->transport_offset;\n\nparse_ipv6_next:\n        switch (info->ip_protocol) {\n        case 0: goto parse_ipv6_hop_by_hop;\n        case 6: goto parse_tcp;\n        case 17: goto parse_udp;\n        case 58: goto parse_icmpv6;\n        case 132: goto parse_sctp;\n        case 0x2c: /* IPv6 fragment */\n            return 0;\n        default:\n            //printf(\"***** test me ******\\n\");\n            return 0; /* TODO: should add more protocols, like ICMP */\n        }\n    }\n\nparse_ipv6_hop_by_hop:\n    {\n        unsigned len;\n\n        VERIFY_REMAINING(8, FOUND_IPV6_HOP);\n        info->ip_protocol = px[offset];\n        len = px[offset+1] + 8;\n\n        VERIFY_REMAINING(len, FOUND_IPV6_HOP);\n        offset += len;\n        info->transport_offset = offset;\n        info->transport_length = length - info->transport_offset;\n    }\n    goto parse_ipv6_next;\n\nparse_icmpv6:\n    {\n        unsigned icmp_type;\n        unsigned icmp_code;\n\n        VERIFY_REMAINING(4, FOUND_ICMP);\n        \n        icmp_type = px[offset+0];\n        icmp_code = px[offset+1];\n\n        info->port_src = icmp_type;\n        info->port_dst = icmp_code;\n\n        if (133 <= icmp_type && icmp_type <= 136) {\n            info->found = FOUND_NDPv6;\n        }\n    }\n    return 1;\n\nparse_vlan8021q:\n    VERIFY_REMAINING(4, FOUND_8021Q);\n    ethertype = ex16be(px+offset+2);\n    offset += 4;\n    goto parse_ethertype;\n\nparse_vlanmpls:\n    /* MULTILEVEL:\n     * Regress: wireshark/mpls-twolevel.cap(9)\n     * There can be multiple layers of MPLS tags. This is marked by a\n     * flag in the header whether the current header is the \"final\"\n     * header in the stack*/\n    while (offset + 4 < length && !(px[offset+2] & 1))\n        offset += 4;\n\n    VERIFY_REMAINING(4, FOUND_MPLS);\n    offset += 4;\n\n    if (px[offset-4+2]&1) {\n        goto parse_ipv4;\n    } else\n        return 0;\n\n\n\nwifi_data:\n    {\n        unsigned flag;\n        VERIFY_REMAINING(24, FOUND_WIFI_DATA);\n\n        flag = px[offset];\n\n        switch (px[offset+1]&0x03) {\n        case 0:\n        case 2:\n            info->mac_dst = px+offset+4;\n            info->mac_bss = px+offset+10;\n            info->mac_src = px+offset+16;\n            break;\n        case 1:\n            info->mac_bss = px+offset+4;\n            info->mac_src = px+offset+10;\n            info->mac_dst = px+offset+16;\n            break;\n        case 3:\n            info->mac_bss = (const unsigned char*)\"\\0\\0\\0\\0\\0\\0\";\n            info->mac_dst = px+offset+16;\n            info->mac_src = px+offset+24;\n            offset += 6;\n            break;\n        }\n\n\n        if ((px[offset+1]&0x04) != 0 || (px[offset+22]&0xF) != 0)\n            return 0;\n\n        offset += 24;\n        if (flag == 0x88) {\n            offset += 2;\n        }\n\n        goto parse_llc;\n    }\n\nparse_wifi:\n    VERIFY_REMAINING(2, FOUND_WIFI);\n    switch (px[offset]) {\n    case 0x08:\n    case 0x88: /* QoS data */\n        if (px[1] & 0x40)\n            return 0;\n        goto wifi_data;\n        break;\n    default:\n        return 0;\n    }\n\nparse_radiotap_header:\n    /* Radiotap headers for WiFi. http://www.radiotap.org/\n     *\n     *   struct ieee80211_radiotap_header {\n     *           u_int8_t        it_version;     // set to 0\n     *           u_int8_t        it_pad;\n     *           u_int16_t       it_len;         // entire length\n     *           u_int32_t       it_present;     // fields present\n     *   };\n     */\n    {\n        unsigned header_length;\n        unsigned features;\n\n        VERIFY_REMAINING(8, FOUND_RADIOTAP);\n        if (px[offset] != 0)\n            return 0;\n        header_length = ex16le(px+offset+2);\n        features = ex32le(px+offset+4);\n\n        VERIFY_REMAINING(header_length, FOUND_RADIOTAP);\n\n        /* If FCS is present at the end of the packet, then change\n         * the length to remove it */\n        if (features & 0x4000) {\n            unsigned fcs_header = ex32le(px+offset+header_length-4);\n            unsigned fcs_frame = ex32le(px+length-4);\n            if (fcs_header == fcs_frame)\n                length -= 4;\n            VERIFY_REMAINING(header_length, FOUND_RADIOTAP);\n        }\n        offset += header_length;\n        goto parse_wifi;\n    }\n\n\nparse_prism_header:\n    /* DLT_PRISM_HEADER */\n    /* This was original created to handle Prism II cards, but now we see this\n     * from other cards as well, such as the 'madwifi' drivers using Atheros\n     * chipsets.\n     *\n     * This starts with a \"TLV\" format, a 4-byte little-endian tag, followed by\n     * a 4-byte little-endian length. This TLV should contain the entire Prism\n     * header, after which we'll find the real header. Therefore, we should just\n     * be able to parse the 'length', and skip that many bytes. I'm told it's more\n     * complicated than that, but it seems to work right now, so I'm keeping it\n     * this way.\n     */\n    {\n        unsigned header_length;\n        VERIFY_REMAINING(8, FOUND_PRISM);\n\n        if (ex32le(px+offset+0) != 0x00000044)\n            return 0;\n        header_length = ex32le(px+offset+4);\n        if (header_length > 0xFFFFF)\n            return 0;\n        VERIFY_REMAINING(header_length, FOUND_PRISM);\n        offset += header_length;\n        goto parse_wifi;\n    }\n\nparse_llc:\n    {\n        unsigned oui;\n\n        VERIFY_REMAINING(3, FOUND_LLC);\n\n        switch (ex24be(px+offset)) {\n        case 0x0000aa: offset += 2; goto parse_llc;\n        default: return 0;\n        case 0xaaaa03: break;\n        }\n\n        offset +=3 ;\n\n        VERIFY_REMAINING(5, FOUND_LLC);\n\n        oui = ex24be(px+offset);\n        ethertype = ex16be(px+offset+3);\n        offset += 5;\n\n        switch (oui){\n        case 0x000000: goto parse_ethertype;\n        default: return 0;\n        }\n\n    }\n\nparse_ethertype:\n    switch (ethertype) {\n    case 0x0800: goto parse_ipv4;\n    case 0x0806: goto parse_arp;\n    case 0x86dd: goto parse_ipv6;\n    case 0x8100: goto parse_vlan8021q;\n    case 0x8847: goto parse_vlanmpls;\n    default: return 0;\n    }\n\nparse_linktype:\n    /*\n     * The \"link-type\" is the same as specified in \"libpcap\" headers\n     */\n    switch (link_type) {\n        case 0:\n            offset += 4;\n            switch (ex32be(px)) {\n                case 0x02000000:\n                case 0x00000002:\n                    goto parse_ipv4;\n                /* Depending on operating system, these can have\n                 different values: 24, 28, or 30 */\n                case 0x18000000:\n                case 0x00000018:\n                case 0x1c000000:\n                case 0x0000001c:\n                case 0x1e000000:\n                case 0x0000001e:\n                    goto parse_ipv6;\n            }\n            return 0;\n        case 1:     goto parse_ethernet;\n        case 12:\n            switch (px[offset]>>4) {\n\t\tcase 4: goto parse_ipv4;\n                case 6: goto parse_ipv6;\n            }\n            return 0;\n        case 0x69:  goto parse_wifi;\n        case 113:   goto parse_linux_sll; /* LINKTYPE_LINUX_SLL DLT_LINUX_SLL */\n        case 119:   goto parse_prism_header;\n        case 127:   goto parse_radiotap_header;\n        default:    return 0;\n    }\n    \nparse_linux_sll:\n    /*\n     +--------+--------+\n     |    packet type  |\n     +--------+--------+\n     |   ARPHRD_ type  |\n     +--------+--------+\n     |   addr length   |\n     +--------+--------+\n     |                 |\n     +  first 8 bytes  +\n     |     of the      |\n     +  hardware/MAC   +\n     |     address     |\n     +                 +\n     |                 |\n     +--------+--------+\n     |     ethertype   |\n     +--------+--------+\n     */\n    {\n        struct {\n            unsigned packet_type;\n            unsigned arp_type;\n            unsigned addr_length;\n            unsigned char mac_address[8];\n            unsigned ethertype;\n        } sll;\n        \n        VERIFY_REMAINING(16, FOUND_SLL);\n        \n        sll.packet_type = ex16be(px+offset+0);\n        sll.arp_type = ex16be(px+offset+2);\n        sll.addr_length = ex16be(px+offset+4);\n        memcpy(sll.mac_address, px+offset+6, 8);\n        sll.ethertype = ex16be(px+offset+14);\n   \n        offset += 16;\n        \n        goto parse_ethertype;\n    }\n    \nparse_arp:\n    info->ip_version = 256;\n    info->ip_offset = offset;\n    {\n        //unsigned hardware_type;\n        //unsigned protocol_type;\n        unsigned hardware_length;\n        unsigned protocol_length;\n        unsigned opcode;\n\n        VERIFY_REMAINING(8, FOUND_ARP);\n        //hardware_type = px[offset]<<8 | px[offset+1];\n        //protocol_type = px[offset+2]<<8 | px[offset+3];\n        hardware_length = px[offset+4];\n        protocol_length = px[offset+5];\n        opcode = px[offset+6]<<8 | px[offset+7];\n        info->opcode = opcode;\n        info->ip_protocol = opcode;\n        offset += 8;\n\n        VERIFY_REMAINING(2*hardware_length + 2*protocol_length, FOUND_ARP);\n\n        info->_ip_src = px + offset + hardware_length;\n        info->_ip_dst = px + offset + 2*hardware_length + protocol_length;\n\n        info->src_ip.version = 4;\n        info->src_ip.ipv4 = px[offset + hardware_length + 0] << 24\n                            | px[offset + hardware_length + 1] << 16\n                            | px[offset + hardware_length + 2] << 8\n                            | px[offset + hardware_length + 3] << 0;\n        info->dst_ip.version = 4;\n        info->dst_ip.ipv4 = px[offset + 2*hardware_length + protocol_length + 0] << 24\n                            | px[offset + 2*hardware_length + protocol_length + 1] << 16\n                            | px[offset + 2*hardware_length + protocol_length + 2] << 8\n                            | px[offset + 2*hardware_length + protocol_length + 3] << 0;\n        \n        info->found_offset = info->ip_offset;\n        return 1;\n    }\n\n}\n"
  },
  {
    "path": "src/proto-preprocess.h",
    "content": "/* Copyright: (c) 2009-2010 by Robert David Graham */\n#ifndef PREPROCESS_H\n#define PREPROCESS_H\n#include \"massip-addr.h\"\n\n\nenum {\n    FOUND_NOTHING=0,\n    FOUND_ETHERNET,\n    FOUND_IPV4,\n    FOUND_IPV6,\n    FOUND_ICMP,\n    FOUND_TCP,\n    FOUND_UDP,\n    FOUND_SCTP,\n    FOUND_DNS,\n    FOUND_IPV6_HOP,\n    FOUND_8021Q,\n    FOUND_MPLS,\n    FOUND_WIFI_DATA,\n    FOUND_WIFI,\n    FOUND_RADIOTAP,\n    FOUND_PRISM,\n    FOUND_LLC,\n    FOUND_ARP,\n    FOUND_SLL, /* Linux SLL */\n    FOUND_OPROTO, /* some other IP protocol */\n    FOUND_IGMP,\n    FOUND_NDPv6,\n};\nstruct PreprocessedInfo {\n    const unsigned char *mac_src;\n    const unsigned char *mac_dst;\n    const unsigned char *mac_bss;\n    unsigned ip_offset;     /* 14 for normal Ethernet */\n    unsigned ip_version;    /* 4 or 6 */\n    unsigned ip_protocol;   /* 6 for TCP, 11 for UDP */\n    unsigned ip_length;     /* length of total packet */\n    unsigned ip_ttl;\n    const unsigned char *_ip_src;\n    const unsigned char *_ip_dst;\n    ipaddress src_ip;\n    ipaddress dst_ip;\n    unsigned transport_offset;  /* 34 for normal Ethernet */\n    unsigned transport_length;\n    union {\n        unsigned port_src;\n        unsigned opcode;\n    };\n    unsigned port_dst;\n\n    unsigned app_offset; /* start of TCP payload */\n    unsigned app_length; /* length of TCP payload */\n\n    int found;\n    int found_offset;\n};\n\n/**\n * @return 1 if useful stuff found, 0 otherwise\n */\nunsigned\npreprocess_frame(const unsigned char *px, unsigned length, unsigned link_type, struct PreprocessedInfo *info);\n\n#endif\n"
  },
  {
    "path": "src/proto-sctp.c",
    "content": "#include \"proto-sctp.h\"\n#include \"proto-preprocess.h\"\n#include \"masscan-status.h\"\n#include \"output.h\"\n#include <stdio.h>\n#include <stdlib.h>\n\n\n#define CRC32C_POLY 0x1EDC6F41\n#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n\nstatic unsigned   crc_c[256] =\n{\n0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,\n0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,\n0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,\n0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,\n0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,\n0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,\n0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,\n0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,\n0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,\n0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,\n0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,\n0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,\n0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,\n0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,\n0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,\n0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,\n0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,\n0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,\n0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,\n0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,\n0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,\n0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,\n0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,\n0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,\n0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,\n0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,\n0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,\n0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,\n0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,\n0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,\n0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,\n0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,\n0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,\n0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,\n0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,\n0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,\n0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,\n0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,\n0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,\n0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,\n0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,\n0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,\n0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,\n0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,\n0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,\n0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,\n0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,\n0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,\n0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,\n0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,\n0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,\n0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,\n0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,\n0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,\n0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,\n0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,\n0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,\n0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,\n0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,\n0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,\n0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,\n0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,\n0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,\n0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,\n};\n\n\n\n\n\nunsigned\nsctp_checksum(const void *vbuffer, size_t length)\n{\n    const unsigned char *buffer = (const unsigned char *)vbuffer;\n    unsigned i;\n    unsigned crc32 = (unsigned)~0;\n    unsigned result;\n    unsigned char byte0,byte1,byte2,byte3;\n\n    for (i = 0; i < 8; i++) {\n        CRC32C(crc32, buffer[i]);\n    }\n\n    CRC32C(crc32, 0);\n    CRC32C(crc32, 0);\n    CRC32C(crc32, 0);\n    CRC32C(crc32, 0);\n\n    for (i = 12; i < length; i++) {\n        CRC32C(crc32, buffer[i]);\n    }\n    result = ~crc32;\n\n    /*  result  now holds the negated polynomial remainder;\n    *  since the table and algorithm is \"reflected\" [williams95].\n    *  That is,  result has the same value as if we mapped the message\n    *  to a polynomial, computed the host-bit-order polynomial\n    *  remainder, performed final negation, then did an end-for-end\n    *  bit-reversal.\n    *  Note that a 32-bit bit-reversal is identical to four in-place\n    *  8-bit reversals followed by an end-for-end byte swap.\n    *  In other words, the bytes of each bit are in the right order,\n    *  but the bytes have been byte swapped.  So we now do an explicit\n    *  byte swap.  On a little-endian machine, this byte swap and\n    *  the final ntohl cancel out and could be elided.\n    */\n\n    byte0 = result & 0xff;\n    byte1 = (result>>8) & 0xff;\n    byte2 = (result>>16) & 0xff;\n    byte3 = (result>>24) & 0xff;\n\n    crc32 = ((byte0 << 24) |\n            (byte1 << 16) |\n            (byte2 << 8)  |\n            byte3);\n    return ( crc32 );\n}\n\n  \n/*****************************************************************************\n *****************************************************************************/\nvoid\nhandle_sctp(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length, \n            unsigned cookie,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy)\n{\n    ipaddress ip_them = parsed->src_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned verification_tag;\n    unsigned offset = parsed->transport_offset;\n\n    UNUSEDPARM(entropy);\n\n    verification_tag = px[offset + 4] << 24 | px[offset + 5] << 16 |\n                        px[offset + 6] << 8 | px[offset + 7];\n    if (cookie != verification_tag)\n        return;\n\n    if (offset + 16 > length)\n        return;\n\n    switch (px[offset + 12]) {\n    case 2: /* init ACK */\n        output_report_status(\n                        out,\n                        timestamp,\n                        PortStatus_Open,\n                        ip_them,\n                        132, /* ip proto = sctp */\n                        port_them,\n                        0,\n                        parsed->ip_ttl,\n                        parsed->mac_src);\n        break;\n    case 6: /* abort */\n        output_report_status(\n                        out,\n                        timestamp,\n                        PortStatus_Closed,\n                        ip_them,\n                        132, /* ip proto = sctp */\n                        port_them,\n                        0,\n                        parsed->ip_ttl,\n                        parsed->mac_src);\n        break;\n    default:\n        ;\n    }\n\n\n\n}\n\n\n/*****************************************************************************\n *****************************************************************************/\nint\nsctp_selftest(void)\n{\n    const char testcase[] = \n        \"\\xd1\\x60\\x00\\x50\\x00\\x00\\x00\\x00\\x58\\xe4\\x5d\\x36\\x01\\x00\\x00\\x14\"\n        \"\\x9e\\x8d\\x52\\x25\\x00\\x00\\x80\\x00\\x00\\x0a\\x08\\x00\\x46\\x1a\\xdf\\x3d\";\n\n    unsigned xsum;\n\n    xsum = sctp_checksum(testcase, 32);\n    \n    if (xsum != 0x58e45d36)\n        return 1;\n\n    return 0;\n}\n"
  },
  {
    "path": "src/proto-sctp.h",
    "content": "#ifndef PROTO_SCTP_H\n#define PROTO_SCTP_H\n#include <time.h>\n#include <stdint.h>\n\nstruct PreprocessedInfo;\nstruct Output;\n\n/**\n * Calculate the \"CRC32c\" checksum used in SCTP. This is a non-destructive\n * checksum that skips the checksum field itself.\n */\nunsigned\nsctp_checksum(const void *vbuffer, size_t length);\n\n/**\n * Handle incoming SCTP response\n */\nvoid\nhandle_sctp(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            unsigned cookie,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy);\n\nint\nsctp_selftest(void);\n\n\n#endif\n"
  },
  {
    "path": "src/proto-smb.c",
    "content": "/*\n    SMB parser\n \n */\n#include \"proto-smb.h\"\n#include \"stack-tcp-api.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"crypto-siphash24.h\"\n#include \"util-safefunc.h\"\n#include \"unusedparm.h\"\n#include <string.h>\n#include <ctype.h>\n#include <assert.h>\n#include <stddef.h>\n\n\n/*\n    \"NT LM 0.12\"    -   Win2k\n    \"SMB 2.002\"     0x0202      Vista\n    \"SMB 2.???\"     0x02FF      Win7, Windows 2008\n    \"PC NETWORK PROGRAM 1.0\"    MS-DOS\n    \"MICROSOFT NETWORKS 1.03\"   MS-DOS\n    \"MICROSOFT NETWORKS 3.0\"    MS-DOS\n    \"LANMAN 1.0\"                OS/2\n    \"LM1.2X002\"                 OS/2\n */\n/*\nPC NETWORK PROGRAM 1.0\nLANMAN1.0\nWindows for Workgroups 3.1a\nLM1.2X002\nLANMAN2.1\nNT LM 0.12\nSMB 2.002\nSMB 2.???\nSamba\nXENIX CORE\n*/\n/*\n  References:\n http://pubs.opengroup.org/onlinepubs/9697999099/toc.pdf\n */\n\nstruct SmbParams {\n    unsigned short command;\n    unsigned short external_offset;\n    unsigned char external_length;\n    unsigned char internal_type;\n    unsigned short internal_offset;\n};\n\nenum InternalType {\n    IT_uint0,\n    IT_uint8,\n    IT_uint16,\n    IT_uint32,\n    IT_uint64,\n};\n\nstruct SmbParams params[] = {\n/*\n USHORT DialectIndex;\n UCHAR SecurityMode;\n USHORT MaxMpxCount;\n USHORT MaxNumberVcs;\n ULONG MaxBufferSize;\n ULONG MaxRawSize;\n ULONG SessionKey;\n ULONG Capabilities;\n FILETIME SystemTime;\n SHORT ServerTimeZone;\n UCHAR ChallengeLength;\n */\n    {0x72,  0,   2, IT_uint16, offsetof(struct Smb72_Negotiate, DialectIndex)},\n    {0x72,  2,   1, IT_uint8,  offsetof(struct Smb72_Negotiate, SecurityMode)},\n    //{0x72,  3,   2, IT_uint16, offsetof(struct Smb72_Negotiate, MaxMpxCount)},\n    //{0x72,  5,   2, IT_uint16, offsetof(struct Smb72_Negotiate, MaxNumberVcs)},\n    //{0x72,  7,   4, IT_uint32, offsetof(struct Smb72_Negotiate, MaxBufferSize)},\n    //{0x72, 11,   4, IT_uint32, offsetof(struct Smb72_Negotiate, MaxRawSize)},\n    {0x72, 15,   4, IT_uint32, offsetof(struct Smb72_Negotiate, SessionKey)},\n    {0x72, 19,   4, IT_uint32, offsetof(struct Smb72_Negotiate, Capabilities)},\n    {0x72, 23,   8, IT_uint64, offsetof(struct Smb72_Negotiate, SystemTime)},\n    {0x72, 31,   2, IT_uint16, offsetof(struct Smb72_Negotiate, ServerTimeZone)},\n    {0x72, 33,   1, IT_uint8,  offsetof(struct Smb72_Negotiate, ChallengeLength)},\n    \n    {0x73,  6,   2, IT_uint16, offsetof(struct Smb73_Setup, BlobLength)},\n    \n    {0xFF, 0,  0xFF, IT_uint0,  0},\n    \n};\n\n#define memberat(t, s, offset) (t*)((char*)(s)+(offset))\n\n\nstatic const char\nsmb1_hello_template[] = {\n    0x00, 0x00, 0x00, 0x45, 0xff, 0x53, 0x4d, 0x42,\n    0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc8,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n    0xff, 0xff, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02,\n    0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e,\n    0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20,\n    0x32, 0x2e, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53,\n    0x4d, 0x42, 0x20, 0x32, 0x2e, 0x3f, 0x3f, 0x3f,\n    0x00\n    \n};\n\nstatic const char\nsmb1_hello_template_v1[] = {\n    0x00, 0x00, 0x00, 0x45, 0xff, 0x53, 0x4d, 0x42,\n    0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc8,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n    0xff, 0xff, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02,\n    0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e,\n    0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20,\n    0x32, 0x2e, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53,\n    0x4d, 0x42, 0x20, 0x32, 0x2e, 0x3f, 0x3f, 0x3f,\n    0x00\n    \n};\n\nvoid smb_set_hello_v1(struct ProtocolParserStream *smb)\n{\n    smb->hello = smb1_hello_template_v1;\n    smb->hello_length = sizeof(smb1_hello_template_v1);\n}\n\nstatic unsigned char smb1_null_session_setup[] = {\n    0x00, 0x00, 0x00, 0x7e, 0xff, 0x53, 0x4d, 0x42,\n    0x73, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc0,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n    0xff, 0xff, 0x01, 0x00, 0x0d, 0xff, 0x00, 0x00,\n    0x00, 0x04, 0x41, 0x32, 0x00, 0xef, 0x00, 0x53,\n    0x45, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x5c, 0xc0, 0x80, 0x00, 0x41,\n    0x00, 0x00, 0x47, 0x00, 0x55, 0x00, 0x45, 0x00,\n    0x53, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x4d, 0x00, 0x61, 0x00, 0x63, 0x00, 0x20, 0x00,\n    0x4f, 0x00, 0x53, 0x00, 0x20, 0x00, 0x58, 0x00,\n    0x20, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00,\n    0x31, 0x00, 0x33, 0x00, 0x00, 0x00, 0x53, 0x00,\n    0x4d, 0x00, 0x42, 0x00, 0x46, 0x00, 0x53, 0x00,\n    0x20, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x32, 0x00,\n    0x00, 0x00\n};\n\nstatic char smb1_null_session_setup_ex[] = {\n    0x00, 0x00, 0x00, 0xb8, 0xff, 0x53, 0x4d, 0x42,\n    0x73, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc8,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n    0x00, 0x00, 0x01, 0x00, 0x0c, 0xff, 0x00, 0x00,\n    0x00, 0x04, 0x41, 0x32, 0x00, 0xf1, 0x00, 0xa5,\n    0x12, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x5c, 0xc0, 0x80, 0x80, 0x7d, 0x00, 0x60,\n    0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05,\n    0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e, 0x30,\n    0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,\n    0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x2a, 0x04,\n    0x28, 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50,\n    0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x02, 0x88,\n    0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x06, 0x01, 0xb0, 0x1d, 0x0f, 0x00, 0x00,\n    0x00, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x63, 0x00,\n    0x20, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x20, 0x00,\n    0x58, 0x00, 0x20, 0x00, 0x31, 0x00, 0x30, 0x00,\n    0x2e, 0x00, 0x31, 0x00, 0x33, 0x00, 0x00, 0x00,\n    0x53, 0x00, 0x4d, 0x00, 0x42, 0x00, 0x46, 0x00,\n    0x53, 0x00, 0x20, 0x00, 0x33, 0x00, 0x2e, 0x00,\n    0x32, 0x00, 0x00, 0x00\n};\n\nchar smb2_negotiate_request[] = {\n    0x00, 0x00, 0x00, 0x6c, 0xfe, 0x53, 0x4d, 0x42,\n    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00,\n    0x02, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,\n    0x17, 0x97, 0x90, 0x40, 0xcd, 0xf0, 0x5e, 0x31,\n    0x8d, 0xea, 0xef, 0x98, 0xcd, 0xa5, 0x08, 0xda,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x02, 0x02, 0x10, 0x02, 0x00, 0x03, 0x02, 0x03\n};\nchar smb2_null_session_setup[] = {\n    0x00, 0x00, 0x00, 0xa2, 0xfe, 0x53, 0x4d, 0x42,\n    0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x02,\n    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x58, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x60, 0x48, 0x06, 0x06,\n    0x2b, 0x06, 0x01, 0x05, 0x05, 0x02, 0xa0, 0x3e,\n    0x30, 0x3c, 0xa0, 0x0e, 0x30, 0x0c, 0x06, 0x0a,\n    0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02,\n    0x02, 0x0a, 0xa2, 0x2a, 0x04, 0x28, 0x4e, 0x54,\n    0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00,\n    0x00, 0x00, 0x15, 0x82, 0x88, 0x62, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01,\n    0xb0, 0x1d, 0x0f, 0x00, 0x00, 0x00\n};\n\n/*****************************************************************************\n *\n * ****** WARNING: UGLY HACK !!!! ******\n *\n * This code is an ugly hack so I can express SMB parameters (word_count)\n * headers as a structure instead of writing individual parsers for them.\n * This code makes no sense. If you find a bug in it, it's probably worth\n * rewriting rather than figure out its convoluted logic. No really, I mean\n * this.\n *\n *****************************************************************************/\nstatic size_t\nsmb_params_parse(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max)\n{\n    size_t original_offset = offset;\n    size_t c;\n    \n    if (max > offset + (smb->hdr.smb1.param_length - smb->hdr.smb1.param_offset))\n        max = offset + (smb->hdr.smb1.param_length - smb->hdr.smb1.param_offset);\n    \n    \n    /* Find the correct header */\n    for (c=0; params[c].command != smb->hdr.smb1.command && params[c].command != 0xFF; c++)\n        ;\n    \n    for (; offset < max; offset++, smb->hdr.smb1.param_offset++) {\n        again:\n        \n        //printf(\"\\n%u/%u %u\\n\", (unsigned)smb->hdr.smb1.param_offset, (unsigned)smb->hdr.smb1.param_length, (unsigned)c);\n        \n        /* If we've gone past our header, just continue consuming bytes */\n        if (params[c].command != smb->hdr.smb1.command)\n            continue;\n        \n        /* If we've gone past the end of this field, goto next field */\n        if (params[c].external_offset + params[c].external_length <= smb->hdr.smb1.param_offset) {\n            c++;\n            goto again;\n        }\n        /* Haven't reached the next field yet */\n        if (params[c].external_offset > smb->hdr.smb1.param_offset)\n            continue;\n        \n        //printf(\"\\n%u/%u %u [%02x]\\n\", (unsigned)smb->hdr.smb1.param_offset, (unsigned)smb->hdr.smb1.param_length, (unsigned)c, px[offset]);\n        \n        /* Shift the type, because all fields little-endian */\n        switch (params[c].internal_type) {\n            case IT_uint0:\n            default:\n                break;\n            case IT_uint8:\n            {\n                uint8_t *x = memberat(uint8_t, &smb->parms, params[c].internal_offset);\n                *x = px[offset];\n            }\n                break;\n            case IT_uint16:\n            {\n                uint16_t *x = memberat(uint16_t, &smb->parms, params[c].internal_offset);\n                //*x <<= 8;\n                *x |= px[offset] << ((smb->hdr.smb1.param_offset - params[c].external_offset)*8);\n            }\n                break;\n            case IT_uint32:\n            {\n                uint32_t *x = memberat(uint32_t, &smb->parms, params[c].internal_offset);\n                //*x <<= 8;\n                *x |= px[offset] << ((smb->hdr.smb1.param_offset - params[c].external_offset)*8);\n            }\n                break;\n            case IT_uint64:\n            {\n                uint64_t *x = memberat(uint64_t, &smb->parms, params[c].internal_offset);\n                //*x <<= 8;\n                *x |= (uint64_t)px[offset] << (uint64_t)((smb->hdr.smb1.param_offset - params[c].external_offset)*8);\n            }\n                break;\n        }\n        \n    }\n    \n    /* Return the number of bytes processed */\n    return offset - original_offset;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic const unsigned long long TICKS_PER_SECOND = 10000000LL;\nstatic const unsigned long long EPOCH_DIFFERENCE = 11644473600LL;\nstatic time_t\nconvert_windows_time(long long int filetime)\n{\n    unsigned long long seconds = filetime / TICKS_PER_SECOND;\n    seconds -= EPOCH_DIFFERENCE;\n    return (time_t)seconds;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb1_parse_negotiate1(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb1.byte_state;\n    enum {\n        D_NEGOT_CHALLENGE,\n        D_NEGOT_DOMAINA_PRE,\n        D_NEGOT_NAMEA_PRE,\n        D_NEGOT_DOMAINA,\n        D_NEGOT_NAMEA,\n        D_NEGOT_ENDA,\n        D_NEGOT_DOMAINU1,\n        D_NEGOT_DOMAINU2,\n        D_NEGOT_DOMAIN1,\n        D_NEGOT_DOMAIN2,\n        D_NEGOT_NAMEU1,\n        D_NEGOT_NAMEU2,\n        D_NEGOT_NAME1,\n        D_NEGOT_NAME2,\n        D_NEGOT_END,\n        \n        D_UNKNOWN,\n    };\n    \n    if (max > offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset))\n        max = offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset);\n    \n    for (;offset<max; offset++)\n    switch (state) {\n        case D_NEGOT_CHALLENGE:\n            if (smb->parms.negotiate.ChallengeLength == 0) {\n                if (smb->hdr.smb1.flags2 & 0x8000) {\n                    state = D_NEGOT_DOMAINU1;\n                } else {\n                    state = D_NEGOT_DOMAINA_PRE;\n                }\n                offset--;\n            } else\n                smb->parms.negotiate.ChallengeLength--;\n            break;\n        case D_NEGOT_DOMAINU1:\n        case D_NEGOT_NAMEU1:\n            smb->hdr.smb1.unicode_char = px[offset];\n            state++;\n            break;\n        case D_NEGOT_DOMAINU2:\n            smb->hdr.smb1.unicode_char |= px[offset]<<8;\n            if (smb->hdr.smb1.unicode_char == 0) {\n                state = D_NEGOT_NAMEU1;\n            } else {\n                banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                state++;\n            }\n            break;\n        case D_NEGOT_NAMEU2:\n            smb->hdr.smb1.unicode_char |= px[offset]<<8;\n            if (smb->hdr.smb1.unicode_char == 0) {\n                state = D_NEGOT_END;\n            } else {\n                banout_append(banout, PROTO_SMB, \" name=\", AUTO_LEN);\n                banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                state++;\n            }\n            break;\n        case D_NEGOT_DOMAIN1:\n        case D_NEGOT_NAME1:\n            smb->hdr.smb1.unicode_char = px[offset];\n            state++;\n            break;\n        case D_NEGOT_DOMAIN2:\n        case D_NEGOT_NAME2:\n            smb->hdr.smb1.unicode_char |= px[offset]<<8;\n            if (smb->hdr.smb1.unicode_char == 0) {\n                state++;\n            } else {\n                banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                state--;\n            }\n            break;\n            \n        case D_NEGOT_DOMAINA_PRE:\n            if (px[offset] == 0) {\n                state = D_NEGOT_NAMEA_PRE;\n            } else {\n                banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                banout_append_char(banout, PROTO_SMB, px[offset]);\n                state = D_NEGOT_DOMAINA;\n            }\n            break;\n        case D_NEGOT_NAMEA_PRE:\n            if (px[offset] == 0) {\n                state = D_NEGOT_END;\n            } else {\n                banout_append(banout, PROTO_SMB, \" name=\", AUTO_LEN);\n                banout_append_char(banout, PROTO_SMB, px[offset]);\n                state = D_NEGOT_NAMEA;\n            }\n            break;\n        case D_NEGOT_DOMAINA:\n        case D_NEGOT_NAMEA:\n            if (px[offset] == 0) {\n                state++;\n            } else {\n                banout_append_char(banout, PROTO_SMB, px[offset]);\n            }\n            break;\n            \n        default:\n            break;\n    }\n    \n    smb->hdr.smb1.byte_state = (unsigned short)state;\n    smb->hdr.smb1.byte_offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb1_parse_setup1(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb1.byte_state;\n    enum {\n        D_PADDING,\n        D_OSA1,\n        D_OSA2,\n        D_VERSIONA1,\n        D_VERSIONA2,\n        D_DOMAINA1,\n        D_DOMAINA2,\n        D_ENDA,\n        \n        D_OSU1,\n        D_OSU2,\n        D_OSU3,\n        D_OSU4,\n        D_VERSION1,\n        D_VERSION2,\n        D_VERSION3,\n        D_VERSION4,\n        D_DOMAIN1,\n        D_DOMAIN2,\n        D_DOMAIN3,\n        D_DOMAIN4,\n        \n        D_UNKNOWN,\n    };\n    \n    if (max > offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset))\n        max = offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset);\n    \n    for (;offset<max; offset++) {\n        \n        switch (state) {\n            case D_PADDING:\n                if (smb->hdr.smb1.flags2 & 0x8000) {\n                    state = D_OSU1;\n                } else {\n                    state = D_OSA1;\n                }\n                break;\n            case D_OSA1:\n                if (px[offset] == 0)\n                    state = D_VERSIONA1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" os=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_OSA2;\n                }\n                break;\n            case D_OSA2:\n                if (px[offset] == 0)\n                    state = D_VERSIONA1;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n\n            case D_VERSIONA1:\n                if (px[offset] == 0)\n                    state = D_DOMAINA1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" ver=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_VERSIONA2;\n                }\n                break;\n            case D_VERSIONA2:\n                if (px[offset] == 0)\n                    state = D_DOMAINA1;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n            case D_DOMAINA1:\n                if (px[offset] == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_DOMAINA2;\n                }\n                break;\n            case D_DOMAINA2:\n                if (px[offset] == 0)\n                    state = D_UNKNOWN;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n\n            case D_OSU1:\n            case D_OSU3:\n            case D_VERSION1:\n            case D_VERSION3:\n            case D_DOMAIN1:\n            case D_DOMAIN3:\n                smb->hdr.smb1.unicode_char = px[offset];\n                state++;\n                break;\n                \n            case D_OSU2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_VERSION1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" os=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_OSU3;\n                }\n                break;\n                \n            case D_OSU4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_VERSION1;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n                \n\n            case D_VERSION2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_DOMAIN1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" ver=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_VERSION3;\n                }\n                break;\n\n            case D_VERSION4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_DOMAIN1;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n\n            case D_DOMAIN2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_DOMAIN3;\n                }\n                break;\n\n            case D_DOMAIN4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n          default:\n                break;\n        }\n    }\n    \n    smb->hdr.smb1.byte_state = (unsigned short)state;\n    smb->hdr.smb1.byte_offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb1_parse_setup2(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb1.byte_state;\n    enum {\n        D_BLOB,\n        D_PADDING,\n        D_PADDING2,\n        D_OSA1,\n        D_OSA2,\n        D_VERSIONA1,\n        D_VERSIONA2,\n        D_DOMAINA1,\n        D_DOMAINA2,\n        D_ENDA,\n        \n        D_OSU1,\n        D_OSU2,\n        D_OSU3,\n        D_OSU4,\n        D_VERSION1,\n        D_VERSION2,\n        D_VERSION3,\n        D_VERSION4,\n        D_DOMAIN1,\n        D_DOMAIN2,\n        D_DOMAIN3,\n        D_DOMAIN4,\n        \n        D_UNKNOWN,\n    };\n    \n    if (max > offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset))\n        max = offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset);\n    \n    for (;offset<max; offset++) {\n        \n        switch (state) {\n            case D_BLOB:\n                if (smb->parms.setup.BlobOffset == 0) {\n                    spnego_decode_init(&smb->spnego, smb->parms.setup.BlobLength);\n                }\n            {\n                size_t new_max = max;\n                if (new_max > offset + smb->parms.setup.BlobLength - smb->parms.setup.BlobOffset)\n                    new_max = offset + smb->parms.setup.BlobLength - smb->parms.setup.BlobOffset;\n                spnego_decode(&smb->spnego, px+offset, new_max-offset, banout);\n                \n                smb->parms.setup.BlobOffset += (uint16_t)(new_max-offset);\n                offset = new_max;\n                if (smb->parms.setup.BlobLength - smb->parms.setup.BlobOffset == 0) {\n                    offset--;\n                    state = D_PADDING;\n                }\n            }\n                break;\n            case D_PADDING:\n                /* If the blog length is odd, then there is no padding. Otherwise,\n                 * there is one byte of padding */\n                //if (smb->parms.setup.BlobLength & 1)\n                    offset--;\n                state = D_PADDING2;\n                break;\n            case D_PADDING2:\n                if (smb->hdr.smb1.flags2 & 0x8000) {\n                    state = D_OSU1;\n                } else {\n                    state = D_OSA1;\n                }\n                offset--;\n                break;\n            case D_OSA1:\n                if (px[offset] == 0)\n                    state = D_VERSIONA1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" os=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_OSA2;\n                }\n                break;\n            case D_OSA2:\n                if (px[offset] == 0)\n                    state = D_VERSIONA1;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n                \n            case D_VERSIONA1:\n                if (px[offset] == 0)\n                    state = D_DOMAINA1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" ver=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_VERSIONA2;\n                }\n                break;\n            case D_VERSIONA2:\n                if (px[offset] == 0)\n                    state = D_DOMAINA1;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n            case D_DOMAINA1:\n                if (px[offset] == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                    state = D_DOMAINA2;\n                }\n                break;\n            case D_DOMAINA2:\n                if (px[offset] == 0)\n                    state = D_UNKNOWN;\n                else\n                    banout_append_char(banout, PROTO_SMB, px[offset]);\n                break;\n                \n            case D_OSU1:\n            case D_OSU3:\n            case D_VERSION1:\n            case D_VERSION3:\n            case D_DOMAIN1:\n            case D_DOMAIN3:\n                smb->hdr.smb1.unicode_char = px[offset];\n                state++;\n                break;\n                \n            case D_OSU2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_VERSION1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" os=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_OSU3;\n                }\n                break;\n                \n            case D_OSU4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_VERSION1;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n                \n                \n            case D_VERSION2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_DOMAIN1;\n                else {\n                    banout_append(banout, PROTO_SMB, \" ver=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_VERSION3;\n                }\n                break;\n                \n            case D_VERSION4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_DOMAIN1;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n                \n            case D_DOMAIN2:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append(banout, PROTO_SMB, \" domain=\", AUTO_LEN);\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state = D_DOMAIN3;\n                }\n                break;\n                \n            case D_DOMAIN4:\n                smb->hdr.smb1.unicode_char |= px[offset]<<8;\n                if (smb->hdr.smb1.unicode_char == 0)\n                    state = D_UNKNOWN;\n                else {\n                    banout_append_unicode(banout, PROTO_SMB, smb->hdr.smb1.unicode_char);\n                    state--;\n                }\n                break;\n            default:\n                break;\n        }\n    }\n    \n    smb->hdr.smb1.byte_state = (unsigned short)state;\n    smb->hdr.smb1.byte_offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb1_parse_negotiate2(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb1.byte_state;\n    \n    UNUSEDPARM(banout); UNUSEDPARM(px);\n\n    if (max > offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset))\n        max = offset + (smb->hdr.smb1.byte_count - smb->hdr.smb1.byte_offset);\n    \n    for (;offset<max; offset++)\n        switch (state) {\n            case 0:\n                state = 1;\n                break;\n            default:\n                break;\n        }\n    \n    smb->hdr.smb1.byte_state = (unsigned short)state;\n    smb->hdr.smb1.byte_offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n\n/*****************************************************************************\n * A default parser for SMBv2 structs. The simplest implementation would be\n * to simply skip the \"struct_length\" bytes. However, we have all this\n * extra code to serve as a template for creating additional functions.\n *****************************************************************************/\nstatic size_t\nsmb2_parse_response(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb2.state;\n    \n    UNUSEDPARM(banout);\n    UNUSEDPARM(px);\n\n    if (max > offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset))\n        max = offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset);\n    \n    for (;offset<max; offset++)\n        switch (state) {\n            default:\n                break;\n        }\n    \n    smb->hdr.smb2.state = (unsigned short)state;\n    smb->hdr.smb2.offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb2_parse_negotiate(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb2.state;\n    \n    enum {\n        N_SECMOD1, N_SECMOD2,\n        N_DIALECT1, N_DIALECT2,\n        N_CONTEXTS1, N_CONTEXTS2,\n        N_GUID01, N_GUID02, N_GUID03, N_GUID04,\n        N_GUID05, N_GUID06, N_GUID07, N_GUID08,\n        N_GUID09, N_GUID10, N_GUID11, N_GUID12,\n        N_GUID13, N_GUID14, N_GUID15, N_GUID16,\n        N_CAP1, N_CAP2, N_CAP3, N_CAP4,\n        N_TRANSACTSIZE1, N_TRANSACTSIZE2, N_TRANSACTSIZE3, N_TRANSACTSIZE4,\n        N_READSIZE1, N_READSIZE2, N_READSIZE3, N_READSIZE4,\n        N_WRITESIZE1, N_WRITESIZE2, N_WRITESIZE3, N_WRITESIZE4,\n        N_TIME1, N_TIME2, N_TIME3, N_TIME4,\n        N_TIME5, N_TIME6, N_TIME7, N_TIME8,\n        N_BOOT1, N_BOOT2, N_BOOT3, N_BOOT4,\n        N_BOOT5, N_BOOT6, N_BOOT7, N_BOOT8,\n        N_BLOB_OFFSET1, N_BLOB_OFFSET2,\n        N_BLOB_LENGTH1, N_BLOB_LENGTH2,\n    };\n    /*\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |          Buffer Code          |                               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |                                                               |\n    +-+-+-+-+                                               +-+-+-+-+\n    |                             Server                            |\n    +-+-+-+-+                      GUID                     +-+-+-+-+\n    |                                                               |\n    +-+-+-+-+                                               +-+-+-+-+\n    |                                                               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |                                                               |\n    +-+-+-+-+                  Current Time                 +-+-+-+-+\n    |                                                               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |                                                               |\n    +-+-+-+-+                   Boot Time                   +-+-+-+-+\n    |                                                               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |        Sec Blob Offset        |        Sec Blob Length        |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |               |               |               |               |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    | Sec Blob  ANS.1/DER encoded blob containing supported authentication mechanisms\n    +-+-+-+-+...\n    */\n    \n    if (max > offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset))\n        max = offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset);\n    \n    for (;offset<max; offset++)\n        switch (state) {\n            case N_SECMOD1: case N_SECMOD2:\n            case N_DIALECT1: case N_DIALECT2:\n            case N_CONTEXTS1:\n                state++;\n                break;\n            case N_CONTEXTS2:\n                if (!smb->is_printed_guid)\n                    banout_append(banout, PROTO_SMB, \" guid=\", AUTO_LEN);\n                state++;\n                break;\n            case N_GUID01:\n            case N_GUID05:\n            case N_GUID07:\n                smb->hdr.smb2.number = px[offset];\n                state++;\n                break;\n            case N_GUID02: case N_GUID03: case N_GUID04:\n                smb->hdr.smb2.number |= px[offset] << (8*(state-N_GUID01));\n                if (state == N_GUID04 && !smb->is_printed_guid) {\n                    banout_append_hexint(banout, PROTO_SMB, smb->hdr.smb2.number, 8);\n                    banout_append_char(banout, PROTO_SMB, '-');\n                }\n                state++;\n                break;\n            case N_GUID06:\n            case N_GUID08:\n                smb->hdr.smb2.number |= px[offset] << 8;\n                if (!smb->is_printed_guid) {\n                    banout_append_hexint(banout, PROTO_SMB, smb->hdr.smb2.number, 4);\n                    banout_append_char(banout, PROTO_SMB, '-');\n                }\n                state++;\n                break;\n            case N_GUID10:\n                if (!smb->is_printed_guid) {\n                    banout_append_hexint(banout, PROTO_SMB, px[offset], 2);\n                    banout_append_char(banout, PROTO_SMB, '-');\n                }\n                state++;\n                break;\n            case N_GUID09: case N_GUID11: case N_GUID12:\n            case N_GUID13: case N_GUID14: case N_GUID15: case N_GUID16:\n                if (!smb->is_printed_guid)\n                    banout_append_hexint(banout, PROTO_SMB, px[offset], 2);\n                if (state == N_GUID16)\n                    smb->is_printed_guid = 1;\n                state++;\n                break;\n            case N_CAP1: case N_CAP2: case N_CAP3: case N_CAP4:\n            case N_TRANSACTSIZE1: case N_TRANSACTSIZE2: case N_TRANSACTSIZE3: case N_TRANSACTSIZE4:\n            case N_READSIZE1: case N_READSIZE2: case N_READSIZE3: case N_READSIZE4:\n            case N_WRITESIZE1: case N_WRITESIZE2: case N_WRITESIZE3: case N_WRITESIZE4:\n                state++;\n                break;\n            case N_TIME1: case N_TIME2: case N_TIME3: case N_TIME4:\n            case N_TIME5: case N_TIME6: case N_TIME7: case N_TIME8:\n                smb->parms.negotiate2.current_time |= ((uint64_t)px[offset]<<(uint64_t)((state-N_TIME1)*8));\n                if (state == N_TIME8 && !smb->is_printed_time) {\n                    char str[64] = \"(err)\";\n                    time_t timestamp = convert_windows_time(smb->parms.negotiate2.current_time);\n                    struct tm tm = {0};\n                    size_t len;\n                    \n                    safe_gmtime(&tm, &timestamp);\n                    len = strftime(str, sizeof(str), \" time=%Y-%m-%d %H:%M:%S \", &tm);\n                    banout_append(banout, PROTO_SMB, str, len);\n                    smb->is_printed_time = 1;\n                }\n                state++;\n                break;\n            case N_BOOT1: case N_BOOT2: case N_BOOT3: case N_BOOT4:\n            case N_BOOT5: case N_BOOT6: case N_BOOT7: case N_BOOT8:\n                smb->parms.negotiate2.boot_time |= ((uint64_t)px[offset]<<(uint64_t)((state-N_BOOT1)*8));\n                if (state == N_BOOT8 && !smb->is_printed_boottime) {\n                    char str[64] = \"(err)\";\n                    time_t timestamp = convert_windows_time(smb->parms.negotiate2.boot_time);\n                    struct tm tm = {0};\n                    size_t len;\n                    \n                    safe_gmtime(&tm, &timestamp);\n                    len = strftime(str, sizeof(str), \" boottime=%Y-%m-%d %H:%M:%S \", &tm);\n                    banout_append(banout, PROTO_SMB, str, len);\n                    smb->is_printed_boottime = 1;\n                }\n                state++;\n                break;\n            case N_BLOB_OFFSET1:\n                smb->hdr.smb2.blob_offset = px[offset];\n                state++;\n                break;\n            case N_BLOB_OFFSET2:\n                smb->hdr.smb2.blob_offset |= (px[offset]<<8);\n                state++;\n                break;\n            case N_BLOB_LENGTH1:\n                smb->hdr.smb2.blob_length = px[offset];\n                state++;\n                break;\n            case N_BLOB_LENGTH2:\n                smb->hdr.smb2.blob_length |= (px[offset]<<8);\n                state++;\n                break;\n            default:\n                break;\n        }\n    \n    smb->hdr.smb2.state = (unsigned short)state;\n    smb->hdr.smb2.offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb2_parse_setup(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb2.state;\n    \n    /*\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |          Buffer Code          |           Flags               |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |        Sec Blob Offset        |        Sec Blob Length        |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     | Sec Blob\n     +-+-+-+-+...\n     */\n    enum {\n        N_FLAGS1, N_FLAGS2,\n        N_BLOB_OFFSET1, N_BLOB_OFFSET2,\n        N_BLOB_LENGTH1, N_BLOB_LENGTH2,\n\n    };\n\n    UNUSEDPARM(banout);\n\n    if (max > offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset))\n        max = offset + (smb->hdr.smb2.struct_length - smb->hdr.smb2.offset);\n    \n    for (;offset<max; offset++)\n        switch (state) {\n            case N_FLAGS1: case N_FLAGS2:\n                state++;\n                break;\n            case N_BLOB_OFFSET1:\n                smb->hdr.smb2.blob_offset = px[offset];\n                state++;\n                break;\n            case N_BLOB_OFFSET2:\n                smb->hdr.smb2.blob_offset |= (px[offset]<<8);\n                state++;\n                break;\n            case N_BLOB_LENGTH1:\n                smb->hdr.smb2.blob_length = px[offset];\n                state++;\n                break;\n            case N_BLOB_LENGTH2:\n                smb->hdr.smb2.blob_length |= (px[offset]<<8);\n                state++;\n                break;\n            default:\n                break;\n        }\n    \n    smb->hdr.smb2.state = (unsigned short)state;\n    smb->hdr.smb2.offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb2_parse_header(struct SMBSTUFF *smb, const unsigned char *px, size_t offset, size_t max, struct BannerOutput *banout)\n{\n    size_t original_offset = offset;\n    unsigned state = smb->hdr.smb2.state;\n    enum {\n        SMB2_CRED_CHARGE1, SMB2_CRED_CHARG2,\n        SMB2_STATUS1, SMB2_STATUS2, SMB2_STATUS3, SMB2_STATUS4,\n        SMB2_OPCODE1, SMB2_OPCODE2,\n        SMB2_CRED_GRANT1, SMB2_CRED_GRANT2,\n        SMB2_FLAGS1, SMB2_FLAGS2, SMB2_FLAGS3, SMB2_FLAGS4,\n        SMB2_CHAIN_OFFSET1, SMB2_CHAIN_OFFSET2,\n        SMB2_CHAIN_OFFSET3, SMB2_CHAIN_OFFSET4,\n        SMB2_MSGID1, SMB2_MSGID2, SMB2_MSGID3, SMB2_MSGID4,\n        SMB2_MSGID5, SMB2_MSGID6, SMB2_MSGID7, SMB2_MSGID8,\n        SMB2_PID1, SMB2_PID2, SMB2_PID3, SMB2_PID4,\n        SMB2_TID1, SMB2_TID2, SMB2_TID3, SMB2_TID4,\n        SMB2_SESSID1, SMB2_SESSID2, SMB2_SESSID3, SMB2_SESSID4,\n        SMB2_SIG01, SMB2_SIG02, SMB2_SIG03, SMB2_SIG04,\n        SMB2_SIG05, SMB2_SIG06, SMB2_SIG07, SMB2_SIG08,\n        SMB2_SIG09, SMB2_SIG10, SMB2_SIG11, SMB2_SIG12,\n        SMB2_SIG13, SMB2_SIG14, SMB2_SIG15, SMB2_SIG16,\n        SMB2_ERROR\n    };\n    /*\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |     0xFE      |      'S'      |      'M'      |      'B'      |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |          Header Length        |           (padding)           |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                          NT_Status                            |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |            Opcode             |            (padding)          |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |       :S:C:P:R|               |               |               |    Flags\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                          Chain Offset                         |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                        Command Sequence-                      |\n     +-+-+-+-+-+-+                                     +-+-+-+-+-+-+-+\n     |                             Number                            |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                           Process ID                          |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                            Tree ID                            |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                                                               |\n     +-+-+-+-+                    User ID                    +-+-+-+-+\n     |                                                               |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     |                                                               |\n     +-+-+-+-+                                               +-+-+-+-+\n     |                                                               |\n     +-+-+-+-+                   Signature                   +-+-+-+-+\n     |                                                               |\n     +-+-+-+-+                                               +-+-+-+-+\n     |                                                               |\n     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n     */\n    \n    if (max > offset + (smb->hdr.smb2.header_length - smb->hdr.smb2.offset))\n        max = offset + (smb->hdr.smb2.header_length - smb->hdr.smb2.offset);\n    \n    for (;offset<max; offset++)\n        switch (state) {\n            case SMB2_CRED_CHARGE1: case SMB2_CRED_CHARG2:\n                state++;\n                break;\n            case SMB2_STATUS1: case SMB2_STATUS2:\n            case SMB2_STATUS3: case SMB2_STATUS4:\n                smb->hdr.smb2.ntstatus |= (px[offset] << ((state - SMB2_STATUS1)*8));\n                state++;\n                break;\n            case SMB2_OPCODE1: case SMB2_OPCODE2:\n                smb->hdr.smb2.opcode |= (px[offset] << ((state - SMB2_OPCODE1)*8));\n                state++;\n                break;\n            case SMB2_CRED_GRANT1: case SMB2_CRED_GRANT2:\n                state++;\n                break;\n            case SMB2_FLAGS1:\n                smb->hdr.smb2.flags = px[offset];\n                if ((smb->hdr.smb2.flags & 1) == 0) {\n                    banout_append(banout, PROTO_SMB, \" PARSERROR[flags] \", AUTO_LEN);\n                    state = SMB2_ERROR;\n                } else\n                    state++;\n                break;\n            case SMB2_FLAGS2: case SMB2_FLAGS3: case SMB2_FLAGS4:\n            case SMB2_CHAIN_OFFSET1: case SMB2_CHAIN_OFFSET2:\n            case SMB2_CHAIN_OFFSET3: case SMB2_CHAIN_OFFSET4:\n                state++;\n                break;\n            case SMB2_MSGID1:\n            case SMB2_MSGID2: case SMB2_MSGID3: case SMB2_MSGID4:\n            case SMB2_MSGID5: case SMB2_MSGID6: case SMB2_MSGID7: case SMB2_MSGID8:\n                smb->hdr.smb2.seqno |= (px[offset] << ((state - SMB2_MSGID1)*8));\n                state++;\n                break;\n            case SMB2_PID1: case SMB2_PID2: case SMB2_PID3: case SMB2_PID4:\n            case SMB2_TID1: case SMB2_TID2: case SMB2_TID3: case SMB2_TID4:\n            case SMB2_SESSID1: case SMB2_SESSID2: case SMB2_SESSID3: case SMB2_SESSID4:\n            case SMB2_SIG01: case SMB2_SIG02: case SMB2_SIG03: case SMB2_SIG04:\n            case SMB2_SIG05: case SMB2_SIG06: case SMB2_SIG07: case SMB2_SIG08:\n            case SMB2_SIG09: case SMB2_SIG10: case SMB2_SIG11: case SMB2_SIG12:\n            case SMB2_SIG13: case SMB2_SIG14: case SMB2_SIG15: case SMB2_SIG16:\n                state++;\n                break;\n                \n            default:\n                break;\n        }\n    \n    smb->hdr.smb2.state = (unsigned short)state;\n    smb->hdr.smb2.offset += (unsigned short)(offset - original_offset);\n    return offset - original_offset;\n}\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\nsmb_parse_smb(struct SMBSTUFF *smb, const unsigned char *px, size_t max, struct BannerOutput *banout,\n                 struct stack_handle_t *socket)\n{\n    size_t len; /*scratch variables used in a couple places */\n    unsigned state = smb->nbt_state;\n    size_t i = 0;\n    enum {\n        SMB_VER,\n        SMB1_VER_S, SMB1_VER_M, SMB1_VER_B,\n        \n        SMB1_CMD,\n        SMB1_STATUS1, SMB1_STATUS2, SMB1_STATUS3, SMB1_STATUS4,\n        SMB1_FLAGS1,\n        SMB1_FLAGS2,\n        SMB1_FLAGS3,\n        SMB1_PID1, SMB1_PID2,\n        SMB1_SIG1, SMB1_SIG2, SMB1_SIG3, SMB1_SIG4,\n        SMB1_SIG5, SMB1_SIG6, SMB1_SIG7, SMB1_SIG8,\n        SMB1_RSVD1,SMB1_RSVD2,\n        SMB1_TID1, SMB1_TID2,\n        SMB1_PID3, SMB1_PID4,\n        SMB1_UID1, SMB1_UID2,\n        SMB1_MID1, SMB1_MID2,\n        SMB1_WORD_COUNT,\n        SMB1_PARAMETERS,\n        SMB1_BYTE_COUNT1,\n        SMB1_BYTE_COUNT2,\n        SMB1_DATA,\n        SMB1_DATA_AFTER,\n        /*\n            UCHAR Protocol[4];\n            UCHAR Command;\n            SMB_ERROR Status;\n            UCHAR Flags;\n            USHORT Flags2;\n            USHORT PIDHigh;\n            UCHAR SecurityFeatures[8];\n            USHORT Reserved;\n            USHORT TID;\n            USHORT PIDLow;\n            USHORT UID;\n            USHORT MID;\n        */\n        \n        \n        SMB2_VER_S, SMB2_VER_M, SMB2_VER_B,\n        SMB2_HDR_LEN1, SMB2_HDR_LEN2,\n        SMB2_PARSE_HEADER,\n        SMB2_STRUCT_LEN1, SMB2_STRUCT_LEN2,\n        SMB2_PARSE_STRUCT,\n        SMB2_UNTIL_BLOB,\n        SMB2_PARSE_BLOB,\n        SMB2_PARSE_REMAINDER,\n        \n        SMB_ERROR,\n     };\n    \n    if (max > i + smb->nbt_length)\n        max = i + smb->nbt_length;\n\n    \n    /*\n     * `for all bytes in the segment`\n     *   `do a state transition for that byte `\n     */\n    for (; i<max; i++)\n    switch (state) {\n        case SMB_VER:\n            switch (px[i]) {\n                case 0xFF:\n                    if (!smb->is_printed_ver)\n                        banout_append(banout, PROTO_SMB, \"SMBv1 \", AUTO_LEN);\n                    smb->is_printed_ver = 1;\n                    state = SMB1_VER_S;\n                    break;\n                case 0xFE:\n                    if (!smb->is_printed_ver)\n                        banout_append(banout, PROTO_SMB, \"SMBv2 \", AUTO_LEN);\n                    smb->is_printed_ver = 1;\n                    state = SMB2_VER_S;\n                    break;\n                default:\n                    if (!smb->is_printed_ver)\n                        banout_append(banout, PROTO_SMB, \"SMBv? \", AUTO_LEN);\n                    smb->is_printed_ver = 1;\n                    state = SMB_ERROR;\n            }\n            break;\n        case SMB1_VER_S:\n        case SMB2_VER_S:\n            if (px[i] != 'S')\n                state = SMB_ERROR;\n            else\n                state++;\n            break;\n        case SMB1_VER_M:\n        case SMB2_VER_M:\n            if (px[i] != 'M')\n                state = SMB_ERROR;\n            else\n                state++;\n            break;\n        case SMB1_VER_B:\n        case SMB2_VER_B:\n            if (px[i] != 'B')\n                state = SMB_ERROR;\n            else\n                state++;\n            break;\n            \n        case SMB1_CMD:\n            memset(&smb->hdr, 0, sizeof(smb->hdr));\n            smb->hdr.smb1.command = px[i];\n            state++;\n            break;\n        case SMB1_STATUS1: case SMB1_STATUS2: case SMB1_STATUS3: case SMB1_STATUS4:\n            smb->hdr.smb1.status <<= 8;\n            smb->hdr.smb1.status |= px[i];\n            state++;\n            break;\n        case SMB1_FLAGS1:\n            smb->hdr.smb1.flags1 = px[i];\n            state++;\n            break;\n        case SMB1_FLAGS2:\n            smb->hdr.smb1.flags2 = px[i];\n            state++;\n            break;\n        case SMB1_FLAGS3:\n            smb->hdr.smb1.flags2 |= px[i]<<8;\n            state++;\n            break;\n        case SMB1_PID1: case SMB1_PID2:\n            smb->hdr.smb1.pid <<= 8;\n            smb->hdr.smb1.pid |= px[i];\n            state++;\n            break;\n        case SMB1_SIG1: case SMB1_SIG2: case SMB1_SIG3: case SMB1_SIG4:\n        case SMB1_SIG5: case SMB1_SIG6: case SMB1_SIG7: case SMB1_SIG8:\n            state++;\n            break;\n        case SMB1_RSVD1:case SMB1_RSVD2:\n            state++;\n            break;\n        case SMB1_TID1: case SMB1_TID2:\n            smb->hdr.smb1.tid <<= 8;\n            smb->hdr.smb1.tid |= px[i];\n            state++;\n            break;\n        case SMB1_PID3: case SMB1_PID4:\n            smb->hdr.smb1.pid <<= 8;\n            smb->hdr.smb1.pid |= px[i];\n            state++;\n            break;\n        case SMB1_UID1: case SMB1_UID2:\n            smb->hdr.smb1.uid <<= 8;\n            smb->hdr.smb1.uid |= px[i];\n            state++;\n            break;\n        case SMB1_MID1: case SMB1_MID2:\n            smb->hdr.smb1.mid <<= 8;\n            smb->hdr.smb1.mid |= px[i];\n            state++;\n            break;\n        case SMB1_WORD_COUNT:\n            smb->hdr.smb1.param_length = px[i]*2;\n            memset(&smb->parms, 0, sizeof(smb->parms));\n            state++;\n            break;\n        case SMB1_PARAMETERS:\n            /* Transfer control to a sub-parser, which may consume zero\n             * or greater bytes, up to the end of the parameters field\n             * (meaning, up to word_count*2 bytes) */\n            len = smb_params_parse(smb, px, i, max);\n            i += len;\n            if (smb->hdr.smb1.param_offset < smb->hdr.smb1.param_length)\n                break;\n            \n            /* We've reached the end of the parameters field, so go onto \n             * read the byte-count/data field */\n            state = SMB1_BYTE_COUNT1;\n            \n            /* Unconsume the next byte. The \"word-count\" field may have been\n             * zero when we get to this state, so therefore the logic needs\n             * to be written to handle this. That means when we loop around\n             * again, we need to counter-act the fact that we will automatically\n             * increment the index, so we subtract one from it here. */\n            i--;\n            \n            /* Process the parameter/word-count field according to what it\n             * actually contained\n             * TODO: I should make this a function, but I'm lazy \n             */\n            switch (smb->hdr.smb1.command) {\n                case 0x72:\n                    if (!smb->is_printed_time) {\n                        char str[64] = \"(err)\";\n                        time_t timestamp = convert_windows_time(smb->parms.negotiate.SystemTime);\n                        struct tm tm = {0};\n                        \n                        safe_gmtime(&tm, &timestamp);\n                        \n                        len = strftime(str, sizeof(str), \" time=%Y-%m-%d %H:%M:%S\", &tm);\n                        banout_append(banout, PROTO_SMB, str, len);\n                        snprintf(str, sizeof(str), \" TZ=%+d \", (short)smb->parms.negotiate.ServerTimeZone);\n                        banout_append(banout, PROTO_SMB, str, AUTO_LEN);\n                        \n                        smb->is_printed_time = 1;\n                    }\n                    smb->hdr.smb1.byte_state = 0;\n                    \n                    if (smb->hdr.smb1.flags2 & 0x0800) {\n                        tcpapi_send(socket, smb1_null_session_setup_ex, sizeof(smb1_null_session_setup_ex), 0);\n                    } else {\n                        if (smb->parms.negotiate.SessionKey) {\n                            unsigned char *buf;\n                            \n                            buf = malloc(sizeof(smb1_null_session_setup));\n                            \n                            memcpy(buf, smb1_null_session_setup, sizeof(smb1_null_session_setup));\n                            buf[0x2f] = (unsigned char)(smb->parms.negotiate.SessionKey>> 0) & 0xFF;\n                            buf[0x30] = (unsigned char)(smb->parms.negotiate.SessionKey>> 8) & 0xFF;\n                            buf[0x31] = (unsigned char)(smb->parms.negotiate.SessionKey>>16) & 0xFF;\n                            buf[0x32] = (unsigned char)(smb->parms.negotiate.SessionKey>>24) & 0xFF;\n                            tcpapi_send(socket, buf, sizeof(smb1_null_session_setup), TCP__copy);\n                            free(buf);\n                        } else {\n                            tcpapi_send(socket,\n                                        smb1_null_session_setup, sizeof(smb1_null_session_setup), TCP__static);\n                        }\n                    }\n                \n                    break;\n                case 0x73: /* session setup and x */\n                    break;\n                default:\n                    banout_append(banout, PROTO_SMB, \" PARSERR(unknown-resonse) \", AUTO_LEN);\n                    smb->hdr.smb1.byte_state = 0;\n            }\n            \n            break;\n            \n        case SMB1_BYTE_COUNT1:\n            smb->hdr.smb1.byte_count = px[i];\n            state++;\n            break;\n        case SMB1_BYTE_COUNT2:\n            smb->hdr.smb1.byte_count |= px[i]<<8;\n            state++;\n            break;\n        case SMB1_DATA:\n            switch (smb->hdr.smb1.command) {\n                case 0x72:\n                    if ((smb->hdr.smb1.flags2 & 0x0800) > 0 && smb->parms.negotiate.ChallengeLength == 0)\n                        i += smb1_parse_negotiate2(smb, px, i, max, banout);\n                    else\n                        i += smb1_parse_negotiate1(smb, px, i, max, banout);\n                    break;\n                case 0x73: /* session setup and x */\n                    if ((smb->hdr.smb1.flags2 & 0x0800) > 0 || smb->parms.setup.BlobLength)\n                        i += smb1_parse_setup2(smb, px, i, max, banout);\n                    else\n                        i += smb1_parse_setup1(smb, px, i, max, banout);\n                    break;\n                default:\n                    ;\n            }\n            if (smb->hdr.smb1.byte_offset >= smb->hdr.smb1.byte_count) {\n                state = SMB1_DATA_AFTER;\n                i--; /* unconsume byte because of auto-increment */\n                \n                /* close the connection, we've found all we can */\n                if (smb->hdr.smb1.command == 0x73)\n                    tcpapi_close(socket);\n            }\n            break;\n            \n        case SMB1_DATA_AFTER:\n            if (i < max) {\n                ;\n            } else {\n                state = 0;\n                i--;\n            }\n            break;\n    \n        case SMB2_HDR_LEN1:\n            memset(&smb->hdr, 0, sizeof(smb->hdr));\n            smb->hdr.smb2.header_length = px[i];\n            state++;\n            break;\n            \n        case SMB2_HDR_LEN2:\n            smb->hdr.smb2.header_length |= (px[i]<<8);\n            if (smb->hdr.smb2.header_length < 12) {\n                banout_append(banout, PROTO_SMB, \" PARSERROR[hdrlen] \", AUTO_LEN);\n                state = SMB_ERROR;\n            } else {\n                smb->hdr.smb2.offset = 6;\n                state++;\n            }\n            break;\n            \n        case SMB2_PARSE_HEADER:\n            i += smb2_parse_header(smb, px, i, max, banout);\n            if (smb->hdr.smb2.offset >= smb->hdr.smb2.header_length) {\n                state++;\n                i--;\n            }\n            break;\n        case SMB2_STRUCT_LEN1:\n            smb->hdr.smb2.struct_length = px[i];\n            state++;\n            break;\n            \n        case SMB2_STRUCT_LEN2:\n            smb->hdr.smb2.struct_length |= (px[i]<<8);\n            smb->hdr.smb2.is_dynamic = (smb->hdr.smb2.struct_length&1);\n            smb->hdr.smb2.struct_length &= 0xFFFe;\n            smb->hdr.smb2.state = 0;\n            smb->hdr.smb2.offset = 2;\n            memset(&smb->parms, 0, sizeof(smb->parms));\n            if (smb->hdr.smb2.struct_length < 2) {\n                banout_append(banout, PROTO_SMB, \" PARSERROR[structlen] \", AUTO_LEN);\n                state = SMB_ERROR;\n            } else\n                state++;\n            break;\n        case SMB2_PARSE_STRUCT:\n            /*\n             * Parse the data portion\n             */\n            switch (smb->hdr.smb2.opcode) {\n                case 0x00: /* Negotiate Response */\n                    i += smb2_parse_negotiate(smb, px, i, max, banout);\n                    break;\n                case 0x01: /* Session Setup */\n                    i += smb2_parse_setup(smb, px, i, max, banout);\n                    break;\n                default:\n                    i += smb2_parse_response(smb, px, i, max, banout);\n                    break;\n            }\n            \n            /*\n             * Respond if necessary\n             */\n            if (smb->hdr.smb2.offset >= smb->hdr.smb2.struct_length) {\n                switch (smb->hdr.smb2.opcode) {\n                    case 0x00: /* negotiate response */\n                        if (smb->hdr.smb2.seqno == 0) {\n                            tcpapi_send(socket, smb2_negotiate_request, sizeof(smb2_negotiate_request), 0);\n                        } else if (smb->hdr.smb2.seqno == 1) {\n                            tcpapi_send(socket, smb2_null_session_setup, sizeof(smb2_null_session_setup), 0);\n                        }\n                        break;\n                    default:\n                        ;\n                }\n                i--;\n                \n                /*\n                 * Process security blob\n                 */\n                if (smb->hdr.smb2.blob_length == 0)\n                    state = SMB2_PARSE_REMAINDER;\n                else if (smb->hdr.smb2.blob_offset < smb->hdr.smb2.header_length + smb->hdr.smb2.struct_length) {\n                    printf(\"\\n***** parse error *****\\n\");\n                    state = SMB2_PARSE_REMAINDER;\n                } else {\n                    smb->hdr.smb2.blob_offset -= smb->hdr.smb2.header_length;\n                    smb->hdr.smb2.blob_offset -= smb->hdr.smb2.struct_length;\n                    state = SMB2_UNTIL_BLOB;\n                }\n                \n            }\n            break;\n        case SMB2_UNTIL_BLOB:\n            if (smb->hdr.smb2.blob_offset == 0) {\n                spnego_decode_init(&smb->spnego, smb->hdr.smb2.blob_length);\n                i--;\n                state = SMB2_PARSE_BLOB;\n            } else\n                smb->hdr.smb2.blob_offset--;\n            break;\n        case SMB2_PARSE_BLOB:\n        {\n            size_t new_max = max;\n            if (new_max > i + smb->hdr.smb2.blob_length)\n                new_max = i + smb->hdr.smb2.blob_length;\n            spnego_decode(&smb->spnego, px+i, new_max-i, banout);\n            \n            smb->hdr.smb2.blob_length -= (unsigned short)(new_max-i);\n            i = new_max;\n            if (smb->hdr.smb2.blob_length == 0) {\n                i--;\n                state = SMB2_PARSE_REMAINDER;\n                \n                /* Close the connection when we get a SessionSetup response */\n                if (smb->hdr.smb2.opcode == 1)\n                    tcpapi_close(socket);\n            }\n        }\n            break;\n        case SMB2_PARSE_REMAINDER:\n        case SMB_ERROR:\n        default:\n            break;\n    }\n\n    smb->nbt_length -= (unsigned)i;\n    smb->nbt_state = state;\n    return i;\n}\n\n\n/*****************************************************************************\n\n 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |      TYPE     |     FLAGS     |            LENGTH             |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |                                                               |\n /               TRAILER (Packet Type Dependent)                 /\n |                                                               |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n *****************************************************************************/\nstatic void\nsmb_parse_record(\n                 const struct Banner1 *banner1,\n                 void *banner1_private,\n                 struct StreamState *pstate,\n                 const unsigned char *px, size_t max,\n                 struct BannerOutput *banout,\n                 struct stack_handle_t *socket)\n{\n    size_t i;\n    unsigned state = pstate->state;\n    struct SMBSTUFF *smb = &pstate->sub.smb;\n\n    enum {\n        NBT_TYPE,\n        NBT_FLAGS,\n        NBT_LEN1,\n        NBT_LEN2,\n        NBT_ERR,\n        NBT_SMB,\n        NBT_DRAIN,\n        NBT_UNKNOWN,\n    };\n\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n\n    for (i=0; i<max; i++)\n        switch (state) {\n            case NBT_TYPE:\n                if (smb->spnego.ntlmssp.buf)\n                    ntlmssp_cleanup(&smb->spnego.ntlmssp);\n                smb->nbt_type = px[i];\n                state++;\n                break;\n            case NBT_FLAGS:\n                smb->nbt_flags = px[i] & 0xFE;\n                smb->nbt_length = px[i] & 0x01;\n                state++;\n                break;\n            case NBT_LEN1:\n                smb->nbt_length <<= 8;\n                smb->nbt_length |= px[i];\n                state++;\n                break;\n            case NBT_LEN2:\n                smb->nbt_length <<= 8;\n                smb->nbt_length |= px[i];\n                state++;\n                \n                \n                \n                /*\n                 00 -  SESSION MESSAGE\n                 81 -  SESSION REQUEST\n                 82 -  POSITIVE SESSION RESPONSE\n                 83 -  NEGATIVE SESSION RESPONSE\n                 84 -  RETARGET SESSION RESPONSE\n                 85 -  SESSION KEEP ALIVE\n                 */\n                switch (smb->nbt_type) {\n                    case 0x00:\n                        state = NBT_SMB;\n                        smb->nbt_state = 0;\n                        break;\n                    case 0x81:\n                        banout_append(banout, PROTO_SMB, \" PARSERR(nbt-sess) \", AUTO_LEN);\n                        state = NBT_UNKNOWN;\n                        break;\n                    case 0x82:\n                    tcpapi_send(socket, smb1_hello_template, sizeof(smb1_hello_template), 0);\n                        state = NBT_DRAIN;\n                        break;\n                    case 0x85:\n                        state = NBT_DRAIN;\n                        break;\n                    case 0x83:\n                        state = NBT_ERR;\n                        break;\n                    case 0x84:\n                        banout_append(banout, PROTO_SMB, \" PARSERR(nbt-retarget) \", AUTO_LEN);\n                        state = NBT_UNKNOWN;\n                        break;\n                    default:\n                        banout_append(banout, PROTO_SMB, \"ERR unknown response\", AUTO_LEN);\n                        break;\n                }\n                break;\n            case NBT_ERR:\n                smb->nbt_err = px[i];\n                /*\n                 80 -  Not listening on called name\n                 81 -  Not listening for calling name\n                 82 -  Called name not present\n                 83 -  Called name present, but insufficient resources\n                 8F -  Unspecified error\n                 */\n                switch (smb->nbt_err) {\n                    case 0x80:\n                        banout_append(banout, PROTO_SMB, \"ERROR(Not listening on called name)\", AUTO_LEN);\n                        break;\n                    case 0x81:\n                        banout_append(banout, PROTO_SMB, \"ERROR(Not listening for calling name)\", AUTO_LEN);\n                        break;\n                    case 0x82:\n                        banout_append(banout, PROTO_SMB, \"ERROR(Called name not present)\", AUTO_LEN);\n                        break;\n                    case 0x83:\n                        banout_append(banout, PROTO_SMB, \"ERROR(Called name present, but insufficient resources)\", AUTO_LEN);\n                        break;\n                    case 0x8F:\n                        banout_append(banout, PROTO_SMB, \"ERROR(Unspecified error)\", AUTO_LEN);\n                        break;\n                    default:\n                        banout_append(banout, PROTO_SMB, \"ERROR(UNKNOWN)\", AUTO_LEN);\n                        break;\n                        \n                }\n                state = NBT_DRAIN;\n                break;\n                \n            case NBT_SMB:\n                i += smb_parse_smb(smb, px+i, max-i, banout, socket);\n                if (smb->nbt_length == 0) {\n                    state = 0;\n                    i--;\n                }\n                break;\n            \n            case NBT_DRAIN:\n                if (smb->nbt_length == 0) {\n                    state = 0;\n                    i--;\n                } else\n                    smb->nbt_length--;\n                break;\n            case NBT_UNKNOWN:\n            default:\n                break;\n        }\n    \n    pstate->state = state;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#if 0\nstatic int\nnegot_add_dialect(unsigned char *buf, size_t sizeof_buf, const char *dialect)\n{\n    size_t nbt_length;\n    size_t dialect_length = strlen(dialect) + 1;\n    size_t word_count;\n    //size_t byte_count;\n    \n    /* Parse NetBIOS header */\n    if (sizeof_buf < 4 || sizeof_buf + 4 < dialect_length)\n        return -1;\n    if (buf[0] != 0)\n        return -1;\n    nbt_length = buf[2]<<8 | buf[3];\n    if (nbt_length <= 4 || nbt_length >= sizeof_buf - dialect_length)\n        return -1;\n    \n    /* Parse SMB header */\n    if (memcmp(buf+4, \"\\xFF\" \"SMB\" \"\\x72\", 5) != 0)\n        return -1;\n    if (nbt_length < 39)\n        return -1;\n    word_count = buf[36];\n    if (word_count != 0)\n        return -1;\n    //byte_count = buf[37] | buf[38]<<8;\n    \n    \n    \n    return 0;\n}\n#endif\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void *\nsmb_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n\nstatic const char\nsmb0_hello_template[] = {\n    0x81, 0x00, 0x00, 0x44, 0x20, 0x43, 0x4b, 0x46,\n    0x44, 0x45, 0x4e, 0x45, 0x43, 0x46, 0x44, 0x45,\n    0x46, 0x46, 0x43, 0x46, 0x47, 0x45, 0x46, 0x46,\n    0x43, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43,\n    0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x20, 0x45,\n    0x44, 0x46, 0x43, 0x45, 0x46, 0x45, 0x46, 0x45,\n    0x44, 0x45, 0x49, 0x45, 0x46, 0x46, 0x43, 0x43,\n    0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43,\n    0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00,\n\n    /*0x00, 0x00, 0x00, 0x45, 0xff, 0x53, 0x4d, 0x42,\n    0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc8,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n    0xff, 0xff, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02,\n    0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e,\n    0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20,\n    0x32, 0x2e, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53,\n    0x4d, 0x42, 0x20, 0x32, 0x2e, 0x3f, 0x3f, 0x3f,\n    0x00*/\n};\n\n\n\n/*****************************************************************************\n * Do a single test of response packets\n *****************************************************************************/\nstatic int\nsmb_do_test(const char *substring, const unsigned char *packet_bytes, size_t length)\n{\n    struct Banner1 *banner1;\n    struct StreamState state[1];\n    struct BannerOutput banout1[1];\n    struct stack_handle_t socket = {0};\n    int x;\n    \n    banner1 = banner1_create();\n    banout_init(banout1);\n    memset(&state[0], 0, sizeof(state[0]));\n    \n    smb_parse_record(banner1,\n                     0,\n                     state,\n                     packet_bytes,\n                     length,\n                     banout1,\n                     &socket);\n    x = banout_is_contains(banout1, PROTO_SMB, substring);\n    if (x == 0)\n        printf(\"smb parser failure: %s\\n\", substring);\n    banner1_destroy(banner1);\n    banout_release(banout1);\n    \n    return x?0:1;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int\nsmb_selftest(void)\n{\n    int x = 0;\n\n    /*****************************************************************************\n     *****************************************************************************/\n    {\n        static const unsigned char packet_bytes[] = {\n            0x00, 0x00, 0x00, 0x9f, 0xff, 0x53, 0x4d, 0x42,\n            0x72, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0xc8,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n            0xff, 0xff, 0x00, 0x00, 0x11, 0x00, 0x00, 0x03,\n            0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,\n            0x00, 0x00, 0x01, 0x00, 0xad, 0xa0, 0x03, 0x0a,\n            0x7c, 0xe0, 0x00, 0x80, 0x00, 0x1d, 0xbd, 0xd5,\n            0xe2, 0x0f, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x5a,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01,\n            0x05, 0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0,\n            0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01,\n            0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3,\n            0x2a, 0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e,\n            0x6f, 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e,\n            0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46,\n            0x43, 0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c,\n            0x65, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e,\n            0x6f, 0x72, 0x65,\n            \n            0x00, 0x00, 0x01, 0x2a, 0xff, 0x53, 0x4d, 0x42,\n            0x73, 0x16, 0x00, 0x00, 0xc0, 0x88, 0x01, 0xc0,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,\n            0x00, 0x00, 0x01, 0x00, 0x04, 0xff, 0x00, 0x2a,\n            0x01, 0x00, 0x00, 0xb3, 0x00, 0xff, 0x00, 0xa1,\n            0x81, 0xb0, 0x30, 0x81, 0xad, 0xa0, 0x03, 0x0a,\n            0x01, 0x01, 0xa1, 0x0c, 0x06, 0x0a, 0x2b, 0x06,\n            0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a,\n            0xa2, 0x81, 0x97, 0x04, 0x81, 0x94, 0x4e, 0x54,\n            0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,\n            0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x30, 0x00,\n            0x00, 0x00, 0x31, 0x02, 0x89, 0xe0, 0x31, 0x6a,\n            0x74, 0x8f, 0xb5, 0xf1, 0xe1, 0x56, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,\n            0x52, 0x00, 0x42, 0x00, 0x00, 0x00, 0x57, 0x00,\n            0x4f, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x47, 0x00,\n            0x52, 0x00, 0x4f, 0x00, 0x55, 0x00, 0x50, 0x00,\n            0x02, 0x00, 0x12, 0x00, 0x57, 0x00, 0x4f, 0x00,\n            0x52, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x52, 0x00,\n            0x4f, 0x00, 0x55, 0x00, 0x50, 0x00, 0x01, 0x00,\n            0x16, 0x00, 0x45, 0x00, 0x50, 0x00, 0x53, 0x00,\n            0x4f, 0x00, 0x4e, 0x00, 0x38, 0x00, 0x38, 0x00,\n            0x33, 0x00, 0x31, 0x00, 0x46, 0x00, 0x45, 0x00,\n            0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x16, 0x00,\n            0x45, 0x00, 0x50, 0x00, 0x53, 0x00, 0x4f, 0x00,\n            0x4e, 0x00, 0x38, 0x00, 0x38, 0x00, 0x33, 0x00,\n            0x31, 0x00, 0x46, 0x00, 0x45, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x45, 0x00, 0x50, 0x00, 0x53, 0x00,\n            0x4f, 0x00, 0x4e, 0x00, 0x20, 0x00, 0x53, 0x00,\n            0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00,\n            0x67, 0x00, 0x65, 0x00, 0x20, 0x00, 0x53, 0x00,\n            0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00,\n            0x72, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x51, 0x00,\n            0x20, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x32, 0x00,\n            0x00, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x52, 0x00,\n            0x4b, 0x00, 0x47, 0x00, 0x52, 0x00, 0x4f, 0x00,\n            0x55, 0x00, 0x50, 0x00, 0x00, 0x00\n        };\n        x += smb_do_test(\"os=EPSON\", packet_bytes, sizeof(packet_bytes));\n    }\n\n    /*****************************************************************************\n     *****************************************************************************/\n    {\n        static const unsigned char packet_bytes[] = {\n            0x00, 0x00, 0x00, 0x56, 0xff, 0x53, 0x4d, 0x42,\n            0x72, 0x00, 0x00, 0x00, 0x00, 0x98, 0x45, 0x60,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x07,\n            0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x03,\n            0x05, 0x00, 0x01, 0x00, 0x04, 0x11, 0x00, 0x00,\n            0x00, 0x00, 0x01, 0x00, 0xa9, 0x00, 0x00, 0x00,\n            0x1d, 0xc2, 0x00, 0x00, 0x00, 0x83, 0xa9, 0xe2,\n            0x31, 0x02, 0xd4, 0x01, 0x00, 0x00, 0x08, 0x11,\n            0x00, 0x77, 0x6d, 0x78, 0x8f, 0x06, 0x52, 0x8f,\n            0xb8, 0x53, 0x36, 0x35, 0x39, 0x43, 0x32, 0x37,\n            0x44, 0x00\n        };\n        x += smb_do_test(\"domain=S659C27D\", packet_bytes, sizeof(packet_bytes));\n    }\n    \n    \n    if (x) {\n        printf(\"smb parser failure: google.com\\n\");\n        return 1;\n    }\n    \n    return 0;\n\n#if 0\n    {\n        struct Banner1 *banner1;\n        struct ProtocolState state[1];\n        struct BannerOutput banout1[1];\n        struct InteractiveData socket;\n        size_t i;\n\n        /*\n         *  LET'S FUZZ THIS CRAP!!!\n         *\n         * We are going to re-parse the response packet as many times as needed,\n         * each time flipping one bit in the packet. This should crash the\n         * parser if it has such a bug that will crash it.\n         */\n        for (i=2; i< 5 && i<sizeof(packet_bytes); i++) {\n            size_t j;\n            \n            for (j=0; j<8; j++) {\n                size_t flip = 1<<j;\n                \n                packet_bytes[i] ^= flip;\n                \n                banner1 = banner1_create();\n                banout_init(banout1);\n                memset(&state[0], 0, sizeof(state[0]));\n                \n                smb_parse_record(banner1,\n                                 0,\n                                 state,\n                                 packet_bytes,\n                                 sizeof(packet_bytes),\n                                 banout1,\n                                 &socket);\n                banner1_destroy(banner1);\n                banout_release(banout1);\n                \n                packet_bytes[i] ^= flip;\n                \n            }\n        }\n    }\n    return 0;\n#endif\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nsmb_cleanup(struct StreamState *pstate)\n{\n    struct SMBSTUFF *smb = &pstate->sub.smb;\n    if (smb->spnego.ntlmssp.buf)\n        ntlmssp_cleanup(&smb->spnego.ntlmssp);\n}\n\n/*****************************************************************************\n * This is the 'plugin' structure that registers callbacks for this parser in\n * the main system.\n *****************************************************************************/\nstruct ProtocolParserStream banner_smb0 = {\n    \"smb\", 139, smb0_hello_template, sizeof(smb0_hello_template), 0,\n    smb_selftest,\n    smb_init,\n    smb_parse_record,\n    smb_cleanup\n};\nstruct ProtocolParserStream banner_smb1 = {\n    \"smb\", 445, smb1_hello_template, sizeof(smb1_hello_template), 0,\n    smb_selftest,\n    smb_init,\n    smb_parse_record,\n    smb_cleanup\n};\n\n"
  },
  {
    "path": "src/proto-smb.h",
    "content": "#ifndef PROTO_SMB_H\n#define PROTO_SMB_H\n#include \"proto-banner1.h\"\n\nextern struct ProtocolParserStream banner_smb0;\nextern struct ProtocolParserStream banner_smb1;\n\n/**\n * Called when command line parameter:\n *   --hello smbv1\n * is set, in order to force negotiation down to SMBv1. This is because some machines\n * have faulty SMBv2 implementations. SMBv2, though, is the default negotiation\n * because Win10 disables SMBv1 by default.\n */\nvoid smb_set_hello_v1(struct ProtocolParserStream *smb);\n\n#endif\n"
  },
  {
    "path": "src/proto-smtp.c",
    "content": "/*\n\n    SMTP banner checker\n \n This file interacts with an SMTP server when it finds a connection on\n an SMTP port like 25 with a \"220 \" as the banner.\n \n Firstly, SMTP requires that the client send a \"EHLO\" command in order to\n announce its presence. This command will tell us about some optional\n features of the server, which we'll record as part of the [smtp] banner.\n \n Secondly, we'll attempt to do a STARTTLS command, regardless whether the\n server advertised the capability. This should either get back an \"OK\" \n message or an error, which we also record as part of the banner.\n \n If we get an OK, then we switch the parser to SSL, and continue as if \n this were an SSL connection. Any SSL data will show up as an [ssl] protocol\n rather than an SMTP protocol.\n \n*/\n\n#include \"proto-smtp.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-ssl.h\"\n#include <ctype.h>\n#include <string.h>\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nsmtp_parse(  const struct Banner1 *banner1,\n          void *banner1_private,\n          struct StreamState *pstate,\n          const unsigned char *px, size_t length,\n          struct BannerOutput *banout,\n          struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    struct SMTPSTUFF *smtp = &pstate->sub.smtp;\n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    \n    \n    for (i=0; i<length; i++) {\n        \n        switch (state) {\n            case 0:\n            case 100:\n            case 200:\n                smtp->code = 0;\n                state++;\n                /* fall through */\n            case 1:\n            case 2:\n            case 3:\n            case 101:\n            case 102:\n            case 103:\n            case 201:\n            case 202:\n            case 203:\n                if (!isdigit(px[i]&0xFF)) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                } else {\n                    smtp->code *= 10;\n                    smtp->code += (px[i] - '0');\n                    state++;\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                }\n                break;\n            case 4:\n            case 104:\n            case 204:\n                if (px[i] == ' ') {\n                    smtp->is_last = 1;\n                    state++;\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                } else if (px[i] == '-') {\n                    smtp->is_last = 0;\n                    state++;\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                } else {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                }\n                break;\n            case 5:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    if (smtp->is_last) {\n                        tcpapi_send(socket, \"EHLO masscan\\r\\n\", 14, 0);\n                        state = 100;\n                        banout_append_char(banout, PROTO_SMTP, px[i]);\n                    } else {\n                        banout_append_char(banout, PROTO_SMTP, px[i]);\n                        state = 0;\n                    }\n                } else if (px[i] == '\\0' || !isprint(px[i])) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                    continue;\n                } else {\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                }\n                break;\n            case 105:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    if (smtp->is_last) {\n                        tcpapi_send(socket, \"STARTTLS\\r\\n\", 10, 0);\n                        state = 200;\n                        banout_append_char(banout, PROTO_SMTP, px[i]);\n                    } else {\n                        banout_append_char(banout, PROTO_SMTP, px[i]);\n                        state = 100;\n                    }\n                } else if (px[i] == '\\0' || !isprint(px[i])) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                    continue;\n                } else {\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                }\n                break;\n            case 205:\n                if (px[i] == '\\r')\n                    continue;\n                else if (px[i] == '\\n') {\n                    \n                    if (smtp->code == 220) {\n                        \n                        /* change the state here to SSL */\n                        unsigned port = pstate->port;\n                        memset(pstate, 0, sizeof(*pstate));\n                        pstate->app_proto = PROTO_SSL3;\n                        pstate->is_sent_sslhello = 1;\n                        pstate->port = (unsigned short)port;\n                        state = 0;\n                        \n                        tcpapi_send(socket, banner_ssl.hello, banner_ssl.hello_length, 0);\n                        \n                    } else {\n                        state = 0xffffffff;\n                        tcpapi_close(socket);\n                    }\n                } else if (px[i] == '\\0' || !isprint(px[i])) {\n                    state = 0xffffffff;\n                    tcpapi_close(socket);\n                    continue;\n                } else {\n                    banout_append_char(banout, PROTO_SMTP, px[i]);\n                }\n                break;\n            default:\n                i = (unsigned)length;\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nsmtp_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nsmtp_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_smtp = {\n    \"smtp\", 25, 0, 0, 0,\n    smtp_selftest,\n    smtp_init,\n    smtp_parse,\n};\n"
  },
  {
    "path": "src/proto-smtp.h",
    "content": "#ifndef PROTO_SMTP_H\n#define PROTO_SMTP_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_smtp;\n\n#endif\n"
  },
  {
    "path": "src/proto-snmp.c",
    "content": "/*\n    SNMP protocol handler\n\n    This module does two primary things:\n\n    #1 track sequence number\n\n        Like TCP, we can use seqno-cookies to match requrests with\n        replies. All SNMP packets have a \"request-id\" field to match\n        requests with replies, so we can fill this in with our cookies\n        This requires any SNMP template to reserve 4 bytes for this\n        field.\n\n    #2 parse the response\n\n        This code will report any OIDs in the response along with\n        their values. However, you should probably hard-code a\n        \"MIB\" so that we can translate OIDs into shorter names\n        as well as format their values correctly. You can look\n        at sysName and sysDescr for an example of how this works.\n\n    NOTES for IDS LULZ:\n\n        The default template packet is designed to evade IDS that looks\n        for OIDS, but inserting \"nul\" bytes into the OID. This is the\n        difference between \"pattern-matching\" IDS and \"protocol-analysis\"\n        IDS: those using protocol-analysis decodes the entire protocol,\n        whereas pattern-matchers don't. How protocol-analysis works is\n        demonstrated in this module, as it has to analyze the SNMP\n        protocol itself in order to decode responses. It can handle\n        responses that that have the deliberate \"nul\" insertion technique,\n        as shown in the self-test.\n\n        One of the useful tricks is to exploit DFA pattern matches. In\n        this case, the DFA pattern-matcher that ultimately matches on\n        the OIDs has been tweaked to handle the nuls as part of the\n        pattern-matching process.\n\n*/\n#include \"proto-snmp.h\"\n#include <stdint.h>\n#include <stdlib.h>\n#include \"smack.h\"\n#include \"util-safefunc.h\"\n#include \"output.h\"\n#include \"masscan-app.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-banner1.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n\nstatic struct SMACK *global_mib;\n\n\n/****************************************************************************\n * We parse an SNMP packet into this structure\n ****************************************************************************/\nstruct SNMP\n{\n    uint64_t version;\n    uint64_t pdu_tag;\n    const unsigned char *community;\n    uint64_t community_length;\n    uint64_t request_id;\n    uint64_t error_index;\n    uint64_t error_status;\n};\n\n/****************************************************************************\n * This is the \"compiled MIB\" essentially. At program startup, we compile\n * this into an OID tree. We use this to replace OIDs with names.\n ****************************************************************************/\nstatic struct SnmpOid {\n    const char *oid;\n    const char *name;\n} mib[] = {\n    {\"43.1006.51.341332\", \"selftest\"}, /* for regression test */\n    {\"43\", \"iso.org\"},\n    {\"43.6\", \"dod\"},\n    {\"43.6.1\", \"inet\"},\n    {\"43.6.1.2\", \"mgmt\"},\n    {\"43.6.1.2.1\", \"mib2\"},\n    {\"43.6.1.2.1.\", \"sys\"},\n    {\"43.6.1.2.1.1.1\", \"sysDescr\"},\n    {\"43.6.1.2.1.1.2\", \"sysObjectID\"},\n    {\"43.6.1.2.1.1.3\", \"sysUpTime\"},\n    {\"43.6.1.2.1.1.4\", \"sysContact\"},\n    {\"43.6.1.2.1.1.5\", \"sysName\"},\n    {\"43.6.1.2.1.1.6\", \"sysLocation\"},\n    {\"43.6.1.2.1.1.7\", \"sysServices\"},\n    {\"43.6.1.4\", \"priv\"},\n    {\"43.6.1.4.1\", \"enterprise\"},\n    {\"43.6.1.4.1.2001\", \"okidata\"},\n    {0,0},\n};\n\n/****************************************************************************\n * An ASN.1 length field has two formats.\n *  - if the high-order bit of the length byte is clear, then it\n *    encodes a length between 0 and 127.\n *  - if the high-order bit is set, then the length byte is a\n *    length-of-length, where the low order bits dictate the number of\n *    remaining bytes to be used in the length.\n ****************************************************************************/\nstatic uint64_t\nasn1_length(const unsigned char *px, uint64_t length, uint64_t *r_offset)\n{\n    uint64_t result;\n\n    /* check for errors */\n    if ( (*r_offset >= length)\n        || ((px[*r_offset] & 0x80)\n        && ((*r_offset) + (px[*r_offset]&0x7F) >= length))) {\n        *r_offset = length;\n        return 0xFFFFffff;\n    }\n\n    /* grab the byte's value */\n    result = px[(*r_offset)++];\n\n\n    if (result & 0x80) {\n        unsigned length_of_length = result & 0x7F;\n        if (length_of_length == 0) {\n            *r_offset = length;\n            return 0xFFFFffff;\n        }\n        result = 0;\n        while (length_of_length) {\n            result = result * 256 + px[(*r_offset)++];\n            if (result > 0x10000) {\n                *r_offset = length;\n                return 0xFFFFffff;\n            }\n            length_of_length--;\n        }\n    }\n    return result;\n}\n\n\n/****************************************************************************\n * Extract an integer. Note\n ****************************************************************************/\nstatic uint64_t\nasn1_integer(const unsigned char *px, uint64_t length, uint64_t *r_offset)\n{\n    uint64_t int_length;\n    uint64_t result;\n\n    if (px[(*r_offset)++] != 0x02) {\n        *r_offset = length;\n        return 0xFFFFffff;\n    }\n\n    int_length = asn1_length(px, length, r_offset);\n    if (int_length == 0xFFFFffff) {\n        *r_offset = length;\n        return 0xFFFFffff;\n    }\n    if (*r_offset + int_length > length) {\n        *r_offset = length;\n        return 0xFFFFffff;\n    }\n    if (int_length > 20) {\n        *r_offset = length;\n        return 0xFFFFffff;\n    }\n\n    result = 0;\n    while (int_length--)\n        result = result * 256 + px[(*r_offset)++];\n\n    return result;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic unsigned\nasn1_tag(const unsigned char *px, uint64_t length, uint64_t *r_offset)\n{\n    if (*r_offset >= length)\n        return 0;\n    return px[(*r_offset)++];\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic uint64_t\nnext_id(const unsigned char *oid, unsigned *offset, uint64_t oid_length)\n{\n    uint64_t result = 0;\n    while (*offset < oid_length && (oid[*offset] & 0x80)) {\n        result <<= 7;\n        result |= oid[(*offset)++]&0x7F;\n    }\n    if (*offset < oid_length) {\n        result <<= 7;\n        result |= oid[(*offset)++]&0x7F;\n    }\n    return result;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsnmp_banner_oid(const unsigned char *oid, size_t oid_length,\n            struct BannerOutput *banout)\n{\n    unsigned i;\n    size_t id;\n    unsigned offset;\n    unsigned state;\n    size_t found_id = SMACK_NOT_FOUND;\n    size_t found_offset = 0;\n\n    /*\n     * Find the var name\n     */\n    state = 0;\n    for (offset=0; offset<oid_length; ) {\n\n        id = smack_search_next( global_mib,\n                                &state,\n                                oid,\n                                &offset,\n                                (unsigned)oid_length);\n        if (id != SMACK_NOT_FOUND) {\n            found_id = id;\n            found_offset = offset;\n        }\n    }\n\n    /* Do the string */\n    if (found_id != SMACK_NOT_FOUND) {\n        const char *str = mib[found_id].name;\n        banout_append(banout, PROTO_SNMP, str, strlen(str));\n    }\n\n    /* Do remaining OIDs */\n    for (i=(unsigned)found_offset; i<oid_length; ) {\n        char foo[32] = {0};\n        uint64_t x = next_id(oid, &i, oid_length);\n\n        if (x == 0 && i >= oid_length)\n            break;\n\n        snprintf(foo, sizeof(foo), \".%\" PRIu64 \"\", x);\n        banout_append(banout, PROTO_SNMP, foo, strlen(foo));\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsnmp_banner(const unsigned char *oid, size_t oid_length,\n            uint64_t var_tag,\n            const unsigned char *var, size_t var_length,\n            struct BannerOutput *banout)\n{\n    size_t i;\n\n    banout_newline(banout, PROTO_SNMP);\n\n    /* print the OID */\n    snmp_banner_oid(oid, oid_length,\n                    banout);\n\n    banout_append_char(banout, PROTO_SNMP, ':');\n\n    switch (var_tag) {\n    case 2:\n        {\n            char foo[32];\n            uint64_t result = 0;\n            for (i=0; i<var_length; i++)\n                result = result<<8 | var[i];\n            snprintf(foo, sizeof(foo), \"%\" PRIu64 \"\", result);\n            banout_append(banout, PROTO_SNMP, foo, strlen(foo));\n        }\n        break;\n    case 6:\n        snmp_banner_oid(var, var_length,\n                        banout);\n        break;\n    case 4:\n    default:\n        /* TODO: this needs to be normalized */\n        banout_append(banout, PROTO_SNMP, var, var_length);\n        break;\n    }\n}\n\n\n/****************************************************************************\n * This is a parser for SNMP packets.\n *\n * TODO: only SNMPv0 is supported, the parser will have to be extended for\n * newer SNMP.\n ****************************************************************************/\nstatic void\nsnmp_parse(const unsigned char *px, uint64_t length,\n    struct BannerOutput *banout,\n    unsigned *request_id)\n{\n    uint64_t offset=0;\n    uint64_t outer_length;\n    struct SNMP snmp[1];\n\n    memset(&snmp, 0, sizeof(*snmp));\n\n    /* tag */\n    if (asn1_tag(px, length, &offset) != 0x30)\n        return;\n\n    /* length */\n    outer_length = asn1_length(px, length, &offset);\n    if (length > outer_length + offset)\n        length = outer_length + offset;\n\n    /* Version */\n    snmp->version = asn1_integer(px, length, &offset);\n    if (snmp->version != 0)\n        return;\n\n    /* Community */\n    if (asn1_tag(px, length, &offset) != 0x04)\n        return;\n    snmp->community_length = asn1_length(px, length, &offset);\n    snmp->community = px+offset;\n    offset += snmp->community_length;\n\n    /* PDU */\n    snmp->pdu_tag = asn1_tag(px, length, &offset);\n    if (snmp->pdu_tag < 0xA0 || 0xA5 < snmp->pdu_tag)\n        return;\n    outer_length = asn1_length(px, length, &offset);\n    if (length > outer_length + offset)\n        length = outer_length + offset;\n\n    /* Request ID */\n    snmp->request_id = asn1_integer(px, length, &offset);\n    *request_id = (unsigned)snmp->request_id;\n    snmp->error_status = asn1_integer(px, length, &offset);\n    snmp->error_index = asn1_integer(px, length, &offset);\n\n    /* Varbind List */\n    if (asn1_tag(px, length, &offset) != 0x30)\n        return;\n    outer_length = asn1_length(px, length, &offset);\n    if (length > outer_length + offset)\n        length = outer_length + offset;\n\n\n    /* Var-bind list */\n    while (offset < length) {\n        uint64_t varbind_length;\n        uint64_t varbind_end;\n        if (px[offset++] != 0x30) {\n            break;\n        }\n        varbind_length = asn1_length(px, length, &offset);\n        if (varbind_length == 0xFFFFffff)\n            break;\n        varbind_end = offset + varbind_length;\n        if (varbind_end > length) {\n            return;\n        }\n\n        /* OID */\n        if (asn1_tag(px,length,&offset) != 6)\n            return;\n        else {\n            uint64_t oid_length = asn1_length(px, length, &offset);\n            const unsigned char *oid = px+offset;\n            uint64_t var_tag;\n            uint64_t var_length;\n            const unsigned char *var;\n\n            offset += oid_length;\n            if (offset > length)\n                return;\n\n            var_tag = asn1_tag(px,length,&offset);\n            var_length = asn1_length(px, length, &offset);\n            var = px+offset;\n\n            offset += var_length;\n            if (offset > length)\n                return;\n\n            if (var_tag == 5)\n                continue; /* null */\n\n            snmp_banner(oid, (size_t)oid_length, var_tag, var, (size_t)var_length, banout);\n        }\n    }\n}\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\nsnmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    uint64_t offset=0;\n    uint64_t outer_length;\n    uint64_t version;\n    uint64_t tag;\n    uint64_t len;\n\n\n    /* tag */\n    if (asn1_tag(px, length, &offset) != 0x30)\n        return 0;\n\n    /* length */\n    outer_length = asn1_length(px, length, &offset);\n    if (length > outer_length + offset)\n        length = (size_t)(outer_length + offset);\n\n    /* Version */\n    version = asn1_integer(px, length, &offset);\n    if (version != 0)\n        return 0;\n\n    /* Community */\n    if (asn1_tag(px, length, &offset) != 0x04)\n        return 0;\n    offset += asn1_length(px, length, &offset);\n\n    /* PDU */\n    tag = asn1_tag(px, length, &offset);\n    if (tag < 0xA0 || 0xA5 < tag)\n        return 0;\n    outer_length = asn1_length(px, length, &offset);\n    if (length > outer_length + offset)\n        length = (size_t)(outer_length + offset);\n\n    /* Request ID */\n    asn1_tag(px, length, &offset);\n    len = asn1_length(px, length, &offset);\n    switch (len) {\n    case 0:\n        return 0;\n    case 1:\n        px[offset+0] = (unsigned char)(seqno>>0)&0x7F;\n        return seqno & 0x7F;\n    case 2:\n        px[offset+0] = (unsigned char)(seqno>>8)&0x7F;\n        px[offset+1] = (unsigned char)(seqno>>0);\n        return seqno & 0x7fff;\n    case 3:\n        px[offset+0] = (unsigned char)(seqno>>16)&0x7F;\n        px[offset+1] = (unsigned char)(seqno>>8);\n        px[offset+2] = (unsigned char)(seqno>>0);\n        return seqno & 0x7fffFF;\n    case 4:\n        px[offset+0] = (unsigned char)(seqno>>24)&0x7F;\n        px[offset+1] = (unsigned char)(seqno>>16);\n        px[offset+2] = (unsigned char)(seqno>>8);\n        px[offset+3] = (unsigned char)(seqno>>0);\n        return seqno & 0x7fffFFFF;\n    case 5:\n        px[offset+0] = 0;\n        px[offset+1] = (unsigned char)(seqno>>24);\n        px[offset+2] = (unsigned char)(seqno>>16);\n        px[offset+3] = (unsigned char)(seqno>>8);\n        px[offset+4] = (unsigned char)(seqno>>0);\n        return seqno & 0xffffFFFF;\n    }\n    return 0;\n}\n\n#define TWO_BYTE       ((unsigned long long)(~0)<<7)\n#define THREE_BYTE     ((unsigned long long)(~0)<<14)\n#define FOUR_BYTE      ((unsigned long long)(~0)<<21)\n#define FIVE_BYTE      ((unsigned long long)(~0)<<28)\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic unsigned\nid_prefix_count(unsigned id)\n{\n    if (id & FIVE_BYTE)\n        return 4;\n    if (id & FOUR_BYTE)\n        return 3;\n    if (id & THREE_BYTE)\n        return 2;\n    if (id & TWO_BYTE)\n        return 1;\n    return 0;\n}\n\n/****************************************************************************\n * Convert text OID to binary\n ****************************************************************************/\nstatic unsigned\nconvert_oid(unsigned char *dst, size_t sizeof_dst, const char *src)\n{\n    size_t offset = 0;\n\n    while (*src) {\n        const char *next_src;\n        unsigned id;\n        unsigned count;\n        unsigned i;\n\n        while (*src == '.')\n            src++;\n\n        id = (unsigned)strtoul(src, (char**)&next_src, 0);\n        if (src == next_src)\n            break;\n        else\n            src = next_src;\n\n        count = id_prefix_count(id);\n        for (i=count; i>0; i--) {\n            if (offset < sizeof_dst)\n                dst[offset++] = ((id>>(7*i)) & 0x7F) | 0x80;\n        }\n        if (offset < sizeof_dst)\n            dst[offset++] = (id & 0x7F);\n\n\n    }\n\n    return (unsigned)offset;\n}\n\n/****************************************************************************\n * Handles an SNMP response.\n ****************************************************************************/\nunsigned\nhandle_snmp(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy\n            )\n{\n    ipaddress ip_them = parsed->src_ip;\n    ipaddress ip_me = parsed->dst_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    unsigned seqno;\n    unsigned request_id = 0;\n    struct BannerOutput banout[1];\n\n    UNUSEDPARM(length);\n\n    /* Initialize the \"banner output\" module that we'll use to print\n     * pretty text in place of the raw packet */\n    banout_init(banout);\n\n    /* Parse the SNMP packet */\n    snmp_parse(\n        px + parsed->app_offset,    /* incoming SNMP response */\n        parsed->app_length,         /* length of SNMP response */\n        banout,                     /* banner printing */\n        &request_id);               /* syn-cookie info */\n\n    /* Validate the \"syn-cookie\" style information. In the case of SNMP,\n     * this will be held in the \"request-id\" field. If the cookie isn't\n     * a good one, then we'll ignore the response */\n    seqno = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);\n    if ((seqno&0x7FFFffff) != request_id)\n        return 1;\n\n    /* Print the banner information, or save to a file, depending */\n    output_report_banner(\n        out, timestamp,\n        ip_them, 17, parsed->port_src,\n        PROTO_SNMP,\n        parsed->ip_ttl,\n        banout_string(banout, PROTO_SNMP),\n        banout_string_length(banout, PROTO_SNMP));\n\n    /* Free memory for the banner, if there was any allocated */\n    banout_release(banout);\n\n    return 0;\n}\n\n\n/****************************************************************************\n * We need to initialize the OID/MIB parser\n * This should be called on program startup.\n * This is so that we can show short names, like \"sysName\", rather than\n * the entire OID.\n ****************************************************************************/\nvoid\nsnmp_init(void)\n{\n    unsigned i;\n\n    /* We use an Aho-Corasick pattern matcher for this. Not necessarily\n     * the most efficient, but also not bad */\n    global_mib = smack_create(\"snmp-mib\", 0);\n\n    /* We just go through the table of OIDs and add them all one by\n     * one */\n    for (i=0; mib[i].name; i++) {\n        unsigned char pattern[256];\n        unsigned len;\n\n        len = convert_oid(pattern, sizeof(pattern), mib[i].oid);\n\n        smack_add_pattern(  global_mib,\n                            pattern,\n                            len,\n                            i,\n                            SMACK_ANCHOR_BEGIN | SMACK_SNMP_HACK\n                            );\n    }\n\n    /* Now that we've added all the OIDs, we need to compile this into\n     * an efficient data structure. Later, when we get packets, we'll\n     * use this for searching */\n    smack_compile(global_mib);\n\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic int\nsnmp_selftest_banner()\n{\n    static const unsigned char snmp_response[] = {\n        0x30, 0x39,\n         0x02, 0x01, 0x00,\n         0x04, 0x06, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63,\n         0xA2, 0x2C,\n           0x02, 0x01, 0x26,\n           0x02, 0x01, 0x00,\n           0x02, 0x01, 0x00,\n           0x30, 0x21,\n            0x30, 0x1F,\n              0x06, 0x09,\n                0x2B, 0x06, 0x01, 0x80, 0x02, 0x01, 0x01, 0x02, 0x00,\n              0x06, 0x12,\n                0x2B, 0x06, 0x01, 0x04, 0x01, 0x8F, 0x51, 0x01, 0x01, 0x01, 0x82, 0x29, 0x5D, 0x01, 0x1B, 0x02, 0x02, 0x01,\n    };\n    unsigned request_id = 0;\n    struct BannerOutput banout[1];\n    banout_init(banout);\n\n    /* parse a test packet */\n    snmp_parse( snmp_response, \n                sizeof(snmp_response),\n                banout,\n                &request_id\n                );\n    \n    \n    if (request_id != 0x26)\n        return 1;\n\n    {\n        const unsigned char *str = banout_string(banout, PROTO_SNMP);\n        size_t str_length = banout_string_length(banout, PROTO_SNMP);\n        if (memcmp(str, \"sysObjectID:okidata.1.1.1.297.93.1.27.2.2.1\", str_length) != 0)\n            return 1;\n    }\n\n    banout_release(banout);\n\n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nsnmp_selftest(void)\n{\n    static const unsigned char xx[] = {\n        43, 0x80|7, 110, 51, 0x80|20, 0x80|106, 84,\n    };\n    size_t i;\n    unsigned state;\n    unsigned offset;\n    size_t found_id = SMACK_NOT_FOUND;\n\n\n    if (snmp_selftest_banner())\n        return 1;\n\n    /*\n     * test of searching OIDs\n     */\n    state = 0;\n    offset = 0;\n    while (offset < sizeof(xx)) {\n        i = smack_search_next(  global_mib,\n                                &state,\n                                xx,\n                                &offset,\n                                (unsigned)sizeof(xx)\n                                );\n        if (i != SMACK_NOT_FOUND)\n            found_id = i;\n    }\n    if (found_id == SMACK_NOT_FOUND) {\n        fprintf(stderr, \"snmp: oid parser failed\\n\");\n        return 1;\n    }\n    if (strcmp(mib[found_id].name, \"selftest\") != 0) {\n        fprintf(stderr, \"snmp: oid parser failed\\n\");\n        return 1;\n    }\n\n\n\n    return 0;\n}\n\n\n\n\n\n"
  },
  {
    "path": "src/proto-snmp.h",
    "content": "#ifndef PROTO_SNMP_H\n#define PROTO_SNMP_H\n#include <time.h>\n#include <stdint.h>\nstruct Output;\nstruct PreprocessedInfo;\n\n/**\n * Need to call this on startup to compile the internal MIB.\n */\nvoid snmp_init(void);\n\n/**\n * Does a regression test.\n * @return\n *     0 if success, 1 if failure\n */\nint snmp_selftest(void);\n\nunsigned snmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno);\n\nunsigned\nhandle_snmp(struct Output *out, time_t timestamp,\n            const unsigned char *px, unsigned length,\n            struct PreprocessedInfo *parsed,\n            uint64_t entropy);\n#endif\n"
  },
  {
    "path": "src/proto-spnego.h",
    "content": "#ifndef PROTO_SPNEGO_H\n#define PROTO_SPNEGO_H\n\n#include \"proto-x509.h\"\n#include \"proto-ntlmssp.h\"\n\nstruct SpnegoDecode\n{\n    /*\n     * ====== KLUDGE ALERT: there's no generic ASN.1 encoding, it's specific to\n     * ====== x.509 parsing, so therefore we are just going to overload that\n     * ====== a bit until we move the code out into it's own ASN.1 module\n     */\n    struct CertDecode x509[1];\n    \n    struct NtlmsspDecode ntlmssp;\n};\n\nvoid\nspnego_decode_init(struct SpnegoDecode *x, size_t length);\n\nvoid\nspnego_decode(struct SpnegoDecode *x,\n            const unsigned char *px, size_t length,\n            struct BannerOutput *banout);\n\n#endif\n\n"
  },
  {
    "path": "src/proto-ssh.c",
    "content": "#include \"proto-ssh.h\"\n#include \"proto-banner1.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"stack-tcp-api.h\"\n#include <ctype.h>\n\n#define PAYLOAD_BANNER  \"SSH-2.0-OPENSSH_7.9\\r\\n\"\n#define SIZE_BANNER 21\n#define PAYLOAD_KEY_EXHANGE_INIT    \"\\x00\\x00\\x04\\x4c\" /* packet length: 1100 */ \\\n                                    \"\\x04\" /* padding_length (this value is include in the packet length) */ \\\n                                    \"\\x14\" /* message_code = 20 */ \\\n                                    \"\\xf3\\xca\\xd2\\x90\\xec\\xf4\\x7c\\x47\\x55\\x4c\\x88\\xcf\\x3a\\x72\\x2b\\xb2\" /*cookie */ \\\n                                    \"\\x00\\x00\\x00\\xd8\" /* kex_algorithms_length */ \\\n                                    \"diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256\" /* kex_algorithms_string */ \\\n                                    \"\\x00\\x00\\x00\\x21\" /* server_host_key_algorithms_length */ \\\n                                    \"ssh-rsa,rsa-sha2-512,rsa-sha2-256\" /* server_host_key_algorithms_string */ \\\n                                    \"\\x00\\x00\\x00\\xaf\" /* encryption_algorithms_client_to_server_length */ \\\n                                    \"chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,cast128-cbc,3des-cbc\" /* encryption_algorithms_client_to_server_string */ \\\n                                    \"\\x00\\x00\\x00\\xaf\" /* encryption_algorithms_server_to_client_length */ \\\n                                    \"chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,cast128-cbc,3des-cbc\" /* encryption_algorithms_server_to_client_string */ \\\n                                    \"\\x00\\x00\\x00\\xd5\" /* mac_algorithms_client_to_server_length */ \\\n                                    \"umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1\" /* mac_algorithms_client_to_server_string */ \\\n                                    \"\\x00\\x00\\x00\\xd5\" /* mac_algorithms_server_to_client_length */ \\\n                                    \"umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1\" /* mac_algorithms_server_to_client_string */ \\\n                                    \"\\x00\\x00\\x00\\x04\" /* compression_algorithms_client_to_server_length */ \\\n                                    \"none\" /* compression_algorithms_client_to_server_string */ \\\n                                    \"\\x00\\x00\\x00\\x04\" /* compression_algorithms_server_to_client_length */ \\\n                                    \"none\" /* compression_algorithms_server_to_client_string */ \\\n                                    \"\\x00\\x00\\x00\\x00\" /* languages_client_to_server_length */ \\\n                                    \"\\x00\\x00\\x00\\x00\" /* languages_server_to_client_length */ \\\n                                    \"\\x00\" /* first_KEX_Packet_Follows */ \\\n                                    \"\\x00\\x00\\x00\\x00\" /* reserved */ \\\n                                    \"\\x00\\x00\\x00\\x00\" /* Padding_String */ \\\n                                    \"\\x00\\x00\\x00\\x8c\" /* DH_packet_length */ \\\n                                    \"\\x05\" /* DH_padding_length */ \\\n                                    \"\\x1e\" /* DH_message_code */ \\\n                                    \"\\x00\\x00\\x00\\x81\" /* DH_multiprecision_integer_length */ \\\n                                    \"\\x00\\xd4\\x6e\\xe0\\x12\\xa6\\x56\\x95\\x37\\xa0\\x14\\x2e\\x4e\\x4d\\x57\\x48\\x1d\\x4b\\x80\\x90\\x1e\\x61\\x6f\\x5c\\xc4\\xd7\\xbc\\x17\\x25\\xb7\\x41\\x8c\\x6c\\x8b\\xed\\x74\\x2d\\xc0\\x54\\xeb\\x08\\x3a\\x79\\x5e\\x0c\\xad\\x04\\xe8\\xb7\\xfb\\xa1\\x68\\x62\\x66\\xd3\\x9a\\x26\\x39\\xaa\\x6c\\x89\\x2f\\x5c\\x99\\xab\\xd2\\x43\\xda\\xa7\\xef\\x1c\\x19\\xdc\\xa6\\x03\\xc9\\x8a\\x56\\x19\\x74\\xd1\\xb8\\x08\\xdc\\x76\\x14\\xe7\\x86\\x50\\x74\\x01\\xed\\xd4\\xfb\\x1a\\x1a\\x25\\x5d\\x1a\\xc7\\x5f\\x0c\\xb3\\xcc\\x58\\x5a\\x40\\xd5\\x04\\xa5\\xc1\\x30\\x14\\x86\\xf0\\xb8\\x33\\x17\\xb4\\x23\\x9d\\x43\\x6d\\x38\\x87\\xec\\xa9\\xbc\\x3b\" /* DH_padding_string */ \\\n                                    \"\\x00\\x00\\x00\\x00\\x00\" /* DH_padding_string */\n#define SIZE_KEY_EXCHANGE_INIT (1100+4+140+4)    //length_of_the_first_packet(packet_length + length of the packet_length_field(4)) + DH_packet_length (including the DH_padding_length) + the length of the DH_length_field (4).\n#define PAYLOAD_NEWKEYS \"\\x00\\x00\\x00\\x0c\" /* packet length */ \\\n                        \"\\x0a\" /* padding length */ \\\n                        \"\\x15\" /* message code */ \\\n                        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* padding string */\n#define SIZE_NEWKEYS (12+4)\n\n#define DEADSTORE(x) x=x\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nssh_parse(  const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    size_t packet_length = pstate -> sub.ssh.packet_length;\n    unsigned i;\n    enum{\n        BANNER = 0,\n        MSG_KEY_EXCHANGE_INIT = 1,\n        MSG_NEW_KEYS = 2,\n        MSG_UNKNOWN = 9,\n        PADDING_LENGTH = 10,\n        MESSAGE_CODE = 11,\n        CHECK_LENGTH = 20,\n        LENGTH_1 = 21,\n        LENGTH_2 = 22,\n        LENGTH_3 = 23,\n        LENGTH_4 = 24,\n        BEFORE_END = 29,\n        END = 30,\n        ERROR = 31,\n    };\n\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n\n    for (i=0; i<length; i++) {\n        banout_append_char(banout, PROTO_SSH2, px[i]);\n        switch (state) {\n        case BANNER:\n            if (px[i] == '\\n') {\n                tcpapi_send(socket, PAYLOAD_BANNER, SIZE_BANNER, 0);\n                packet_length = 0;\n                state = LENGTH_1;\n            }\n            if (px[i] == '\\0' || !(isspace(px[i]) || isprint(px[i]))) {\n                state = ERROR;\n                tcpapi_close(socket);\n                continue;\n            }\n            break;\n\n        case LENGTH_1:\n            /*\n             * Compute the length of the message (padding_length_field,\n             * message_code, payload, padding).\n             * The length doesn't include the packet_length_field (+4).\n             */\n            packet_length = px[i] << 24;\n            state++;\n            break;\n        case LENGTH_2:\n            packet_length += px[i] << 16;\n            state++;\n            break;\n        case LENGTH_3:\n            packet_length += px[i] << 8;\n            state++;\n            break;\n        case LENGTH_4:\n            packet_length += px[i];\n            state = PADDING_LENGTH;\n            break;\n\n        case PADDING_LENGTH:\n            packet_length--;\n            state = MESSAGE_CODE;\n            break;\n\n        case MESSAGE_CODE:\n            /*\n             * The state will depend on the message code\n             */\n            packet_length--;\n            switch(px[i]) {\n            case '\\x14':\n                state = MSG_KEY_EXCHANGE_INIT;\n                DEADSTORE(state); /*remove warning*/\n            case '\\x15':\n                state = MSG_NEW_KEYS;\n                DEADSTORE(state); /*remove warning*/\n                break;\n            default:\n                state = CHECK_LENGTH; /* read & discard this message */\n                DEADSTORE(state); /*remove warning*/\n                break;\n            }\n\n        case MSG_KEY_EXCHANGE_INIT:\n            packet_length--;\n            tcpapi_send(socket, PAYLOAD_KEY_EXHANGE_INIT, SIZE_KEY_EXCHANGE_INIT, 0);\n            state = CHECK_LENGTH;\n            break;\n\n        case MSG_NEW_KEYS:\n            packet_length--;\n            tcpapi_send(socket, PAYLOAD_NEWKEYS, SIZE_NEWKEYS,0);\n            state = BEFORE_END;\n            break;\n\n        case CHECK_LENGTH:\n            if (! --packet_length)\n                state = LENGTH_1;\n            break;\n\n        case BEFORE_END:\n            if (! --packet_length)\n                state = END;\n            break;\n\n        case END:\n            tcpapi_close(socket);\n            state = 0xffffffff;\n            break;\n\n        default:\n            i = (unsigned)length;\n        }\n    }\n    pstate->state = state;\n    pstate->sub.ssh.packet_length = packet_length;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nssh_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nssh_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_ssh = {\n    \"ssh\", 22, 0, 0, 0,\n    ssh_selftest,\n    ssh_init,\n    ssh_parse,\n};\n"
  },
  {
    "path": "src/proto-ssh.h",
    "content": "#ifndef PROTO_SSH_H\n#define PROTO_SSH_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_ssh;\n\n#endif\n"
  },
  {
    "path": "src/proto-ssl-test.c",
    "content": "#include <stddef.h>\nconst char ssl_test_case_1[] =\n\"\\x16\\x03\\x03\\x00\\x50\\x02\\x00\\x00\\x4c\\x03\\x03\\x52\\x78\\x1e\\x3f\\x6d\"\n\"\\x3a\\xd1\\xa3\\xe3\\xa8\\x1c\\xc6\\x08\\xc8\\x0a\\xe2\\x4b\\x53\\x68\\x79\\xa6\"\n\"\\xe8\\xeb\\x25\\x4c\\xfd\\x8a\\x3a\\x87\\x40\\xee\\xa1\\x00\\xc0\\x07\\x00\\x00\"\n\"\\x24\\x00\\x00\\x00\\x00\\xff\\x01\\x00\\x01\\x00\\x00\\x0b\\x00\\x04\\x03\\x00\"\n\"\\x01\\x02\\x00\\x23\\x00\\x00\\x00\\x10\\x00\\x0b\\x00\\x09\\x08\\x73\\x70\\x64\"\n\"\\x79\\x2f\\x33\\x2e\\x31\\x16\\x03\\x03\\x0d\\xff\\x0b\\x00\\x0d\\xfb\\x00\\x0d\"\n\"\\xf8\\x00\\x06\\x66\\x30\\x82\\x06\\x62\\x30\\x82\\x05\\x4a\\xa0\\x03\\x02\\x01\"\n\"\\x02\\x02\\x08\\x59\\x09\\xaa\\x30\\xa2\\xb3\\xfc\\xf6\\x30\\x0d\\x06\\x09\\x2a\"\n\"\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\\x30\\x49\\x31\\x0b\\x30\\x09\"\n\"\\x06\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x13\\x30\\x11\\x06\\x03\\x55\"\n\"\\x04\\x0a\\x13\\x0a\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\\x49\\x6e\\x63\\x31\\x25\"\n\"\\x30\\x23\\x06\\x03\\x55\\x04\\x03\\x13\\x1c\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\"\n\"\\x49\\x6e\\x74\\x65\\x72\\x6e\\x65\\x74\\x20\\x41\\x75\\x74\\x68\\x6f\\x72\\x69\"\n\"\\x74\\x79\\x20\\x47\\x32\\x30\\x1e\\x17\\x0d\\x31\\x33\\x31\\x30\\x30\\x39\\x31\"\n\"\\x30\\x33\\x38\\x35\\x38\\x5a\\x17\\x0d\\x31\\x34\\x31\\x30\\x30\\x39\\x31\\x30\"\n\"\\x33\\x38\\x35\\x38\\x5a\\x30\\x66\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\\x06\"\n\"\\x13\\x02\\x55\\x53\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x08\\x0c\\x0a\\x43\"\n\"\\x61\\x6c\\x69\\x66\\x6f\\x72\\x6e\\x69\\x61\\x31\\x16\\x30\\x14\\x06\\x03\\x55\"\n\"\\x04\\x07\\x0c\\x0d\\x4d\\x6f\\x75\\x6e\\x74\\x61\\x69\\x6e\\x20\\x56\\x69\\x65\"\n\"\\x77\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x0a\\x0c\\x0a\\x47\\x6f\\x6f\\x67\"\n\"\\x6c\\x65\\x20\\x49\\x6e\\x63\\x31\\x15\\x30\\x13\\x06\\x03\\x55\\x04\\x03\\x0c\"\n\"\\x0c\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x30\\x59\\x30\"\n\"\\x13\\x06\\x07\\x2a\\x86\\x48\\xce\\x3d\\x02\\x01\\x06\\x08\\x2a\\x86\\x48\\xce\"\n\"\\x3d\\x03\\x01\\x07\\x03\\x42\\x00\\x04\\xde\\x41\\xd4\\x06\\xbe\\x15\\x57\\x70\"\n\"\\x57\\xa0\\xe8\\x14\\xac\\x8c\\xd0\\x8c\\xf7\\xb9\\x23\\x33\\xae\\xb2\\x11\\xa4\"\n\"\\xa8\\x79\\x52\\x86\\xba\\x99\\xdc\\x85\\x88\\x03\\x0c\\xc1\\xa0\\xc3\\x3c\\xeb\"\n\"\\xe1\\xe3\\xaa\\x8d\\xde\\x6d\\x7c\\x3b\\x4c\\xcb\\x51\\x75\\xa7\\xbc\\x51\\xce\"\n\"\\x44\\xc2\\x83\\xee\\x88\\x64\\x94\\xea\\xa3\\x82\\x03\\xfa\\x30\\x82\\x03\\xf6\"\n\"\\x30\\x1d\\x06\\x03\\x55\\x1d\\x25\\x04\\x16\\x30\\x14\\x06\\x08\\x2b\\x06\\x01\"\n\"\\x05\\x05\\x07\\x03\\x01\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x03\\x02\\x30\"\n\"\\x82\\x02\\xc3\\x06\\x03\\x55\\x1d\\x11\\x04\\x82\\x02\\xba\\x30\\x82\\x02\\xb6\"\n\"\\x82\\x0c\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x0d\"\n\"\\x2a\\x2e\\x61\\x6e\\x64\\x72\\x6f\\x69\\x64\\x2e\\x63\\x6f\\x6d\\x82\\x16\\x2a\"\n\"\\x2e\\x61\\x70\\x70\\x65\\x6e\\x67\\x69\\x6e\\x65\\x2e\\x67\\x6f\\x6f\\x67\\x6c\"\n\"\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x12\\x2a\\x2e\\x63\\x6c\\x6f\\x75\\x64\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x16\\x2a\\x2e\\x67\\x6f\\x6f\"\n\"\\x67\\x6c\\x65\\x2d\\x61\\x6e\\x61\\x6c\\x79\\x74\\x69\\x63\\x73\\x2e\\x63\\x6f\"\n\"\\x6d\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x61\\x82\\x0b\"\n\"\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6c\\x82\\x0e\\x2a\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x2e\\x69\\x6e\\x82\\x0e\\x2a\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x2e\\x6a\\x70\\x82\\x0e\\x2a\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x2e\\x75\\x6b\\x82\\x0f\\x2a\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x61\\x72\\x82\\x0f\\x2a\\x2e\"\n\"\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x61\\x75\\x82\\x0f\\x2a\"\n\"\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x62\\x72\\x82\\x0f\"\n\"\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x63\\x6f\\x82\"\n\"\\x0f\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x6d\\x78\"\n\"\\x82\\x0f\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\\x74\"\n\"\\x72\\x82\\x0f\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2e\"\n\"\\x76\\x6e\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x64\\x65\\x82\"\n\"\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x65\\x73\\x82\\x0b\\x2a\\x2e\"\n\"\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x66\\x72\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\"\n\"\\x67\\x6c\\x65\\x2e\\x68\\x75\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\"\n\"\\x2e\\x69\\x74\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x6e\\x6c\"\n\"\\x82\\x0b\\x2a\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x70\\x6c\\x82\\x0b\\x2a\"\n\"\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x70\\x74\\x82\\x0f\\x2a\\x2e\\x67\\x6f\"\n\"\\x6f\\x67\\x6c\\x65\\x61\\x70\\x69\\x73\\x2e\\x63\\x6e\\x82\\x14\\x2a\\x2e\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x63\\x6f\\x6d\\x6d\\x65\\x72\\x63\\x65\\x2e\\x63\\x6f\"\n\"\\x6d\\x82\\x0d\\x2a\\x2e\\x67\\x73\\x74\\x61\\x74\\x69\\x63\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x0c\\x2a\\x2e\\x75\\x72\\x63\\x68\\x69\\x6e\\x2e\\x63\\x6f\\x6d\\x82\\x10\"\n\"\\x2a\\x2e\\x75\\x72\\x6c\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x16\\x2a\\x2e\\x79\\x6f\\x75\\x74\\x75\\x62\\x65\\x2d\\x6e\\x6f\\x63\\x6f\"\n\"\\x6f\\x6b\\x69\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x0d\\x2a\\x2e\\x79\\x6f\\x75\\x74\"\n\"\\x75\\x62\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x16\\x2a\\x2e\\x79\\x6f\\x75\\x74\\x75\"\n\"\\x62\\x65\\x65\\x64\\x75\\x63\\x61\\x74\\x69\\x6f\\x6e\\x2e\\x63\\x6f\\x6d\\x82\"\n\"\\x0b\\x2a\\x2e\\x79\\x74\\x69\\x6d\\x67\\x2e\\x63\\x6f\\x6d\\x82\\x0b\\x61\\x6e\"\n\"\\x64\\x72\\x6f\\x69\\x64\\x2e\\x63\\x6f\\x6d\\x82\\x04\\x67\\x2e\\x63\\x6f\\x82\"\n\"\\x06\\x67\\x6f\\x6f\\x2e\\x67\\x6c\\x82\\x14\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2d\"\n\"\\x61\\x6e\\x61\\x6c\\x79\\x74\\x69\\x63\\x73\\x2e\\x63\\x6f\\x6d\\x82\\x0a\\x67\"\n\"\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x12\\x67\\x6f\\x6f\\x67\\x6c\"\n\"\\x65\\x63\\x6f\\x6d\\x6d\\x65\\x72\\x63\\x65\\x2e\\x63\\x6f\\x6d\\x82\\x0a\\x75\"\n\"\\x72\\x63\\x68\\x69\\x6e\\x2e\\x63\\x6f\\x6d\\x82\\x08\\x79\\x6f\\x75\\x74\\x75\"\n\"\\x2e\\x62\\x65\\x82\\x0b\\x79\\x6f\\x75\\x74\\x75\\x62\\x65\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x14\\x79\\x6f\\x75\\x74\\x75\\x62\\x65\\x65\\x64\\x75\\x63\\x61\\x74\\x69\"\n\"\\x6f\\x6e\\x2e\\x63\\x6f\\x6d\\x30\\x0b\\x06\\x03\\x55\\x1d\\x0f\\x04\\x04\\x03\"\n\"\\x02\\x07\\x80\\x30\\x68\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x01\\x01\\x04\"\n\"\\x5c\\x30\\x5a\\x30\\x2b\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x30\\x02\\x86\"\n\"\\x1f\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x70\\x6b\\x69\\x2e\\x67\\x6f\\x6f\\x67\"\n\"\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x47\\x49\\x41\\x47\\x32\\x2e\\x63\\x72\\x74\"\n\"\\x30\\x2b\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x30\\x01\\x86\\x1f\\x68\\x74\"\n\"\\x74\\x70\\x3a\\x2f\\x2f\\x63\\x6c\\x69\\x65\\x6e\\x74\\x73\\x31\\x2e\\x67\\x6f\"\n\"\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x6f\\x63\\x73\\x70\\x30\\x1d\\x06\"\n\"\\x03\\x55\\x1d\\x0e\\x04\\x16\\x04\\x14\\x28\\xfd\\x66\\x74\\xc2\\xd5\\x2f\\xcb\"\n\"\\xeb\\x62\\x19\\x57\\xcc\\xc4\\xe5\\xed\\xf7\\x8a\\x50\\x7a\\x30\\x0c\\x06\\x03\"\n\"\\x55\\x1d\\x13\\x01\\x01\\xff\\x04\\x02\\x30\\x00\\x30\\x1f\\x06\\x03\\x55\\x1d\"\n\"\\x23\\x04\\x18\\x30\\x16\\x80\\x14\\x4a\\xdd\\x06\\x16\\x1b\\xbc\\xf6\\x68\\xb5\"\n\"\\x76\\xf5\\x81\\xb6\\xbb\\x62\\x1a\\xba\\x5a\\x81\\x2f\\x30\\x17\\x06\\x03\\x55\"\n\"\\x1d\\x20\\x04\\x10\\x30\\x0e\\x30\\x0c\\x06\\x0a\\x2b\\x06\\x01\\x04\\x01\\xd6\"\n\"\\x79\\x02\\x05\\x01\\x30\\x30\\x06\\x03\\x55\\x1d\\x1f\\x04\\x29\\x30\\x27\\x30\"\n\"\\x25\\xa0\\x23\\xa0\\x21\\x86\\x1f\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x70\\x6b\"\n\"\\x69\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x47\\x49\\x41\"\n\"\\x47\\x32\\x2e\\x63\\x72\\x6c\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\"\n\"\\x01\\x01\\x05\\x05\\x00\\x03\\x82\\x01\\x01\\x00\\x7f\\x5d\\x95\\x04\\xe5\\xdc\"\n\"\\xbb\\x74\\xae\\x2e\\x62\\x52\\xe8\\x30\\x58\\xed\\x57\\x6e\\xc3\\x7b\\xff\\x6c\"\n\"\\x73\\xf2\\xe1\\xab\\x80\\xd0\\xc4\\x02\\x28\\xee\\x41\\xe5\\x01\\x46\\xec\\x64\"\n\"\\x6d\\xd3\\x4f\\x62\\x95\\xa2\\xbb\\xd3\\x4e\\x02\\x8e\\x7d\\xd3\\xfe\\x37\\xbb\"\n\"\\xab\\x9f\\x03\\x45\\x58\\x98\\xd8\\x4d\\x11\\x99\\xab\\x7c\\x6d\\x45\\xa2\\xa6\"\n\"\\xa4\\xf1\\xca\\x1c\\x1f\\xd5\\xf4\\x56\\xdc\\x99\\x86\\xf5\\xbf\\x33\\xc6\\xb3\"\n\"\\x77\\x9d\\x0b\\x4d\\x33\\x89\\x57\\x1d\\x9c\\x3a\\x4d\\xb0\\x5f\\xe2\\x5d\\x77\"\n\"\\xab\\x7b\\xd5\\x5b\\x88\\xe8\\x32\\x61\\x92\\x44\\xfa\\xe1\\xc7\\x94\\x29\\x28\"\n\"\\xcd\\xc8\\xee\\xc1\\xd7\\x89\\xe6\\xda\\x49\\x28\\x98\\xfd\\x80\\x73\\x2b\\xf1\"\n\"\\xba\\x54\\x0c\\x3d\\xe0\\x36\\xc9\\xb6\\xe2\\xe9\\x2f\\x24\\x32\\x96\\x63\\x1c\"\n\"\\xc1\\x19\\xfb\\xad\\xc9\\xab\\x2f\\x10\\xb6\\x18\\x22\\xdf\\x7d\\xef\\x0f\\x10\"\n\"\\x9a\\x3f\\x63\\x60\\x1a\\xb6\\xa5\\xe6\\x8f\\xe2\\x3e\\x0c\\x5a\\x70\\x0f\\x4a\"\n\"\\xac\\xe4\\x6b\\xd8\\x68\\xcd\\x47\\xe5\\x41\\x06\\x5c\\x1a\\xb9\\x28\\x4d\\x67\"\n\"\\x91\\x9b\\x28\\x67\\xfb\\x3a\\x77\\x34\\x07\\x0e\\xd7\\x84\\x5b\\xe3\\xbb\\x16\"\n\"\\x6c\\xd9\\x61\\x1c\\x60\\xfa\\xd4\\x2f\\xab\\x97\\xcc\\x46\\x34\\x5b\\xc5\\x35\"\n\"\\x30\\xca\\xde\\x01\\xa2\\x27\\x61\\x97\\x5c\\x8a\\x4f\\xbd\\x85\\xce\\x1a\\x25\"\n\"\\xa2\\x45\\xdd\\xe7\\x4a\\x15\\x48\\x1c\\x8f\\xd0\\x00\\x04\\x08\\x30\\x82\\x04\"\n\"\\x04\\x30\\x82\\x02\\xec\\xa0\\x03\\x02\\x01\\x02\\x02\\x03\\x02\\x3a\\x69\\x30\"\n\"\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\\x30\\x42\"\n\"\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x16\\x30\"\n\"\\x14\\x06\\x03\\x55\\x04\\x0a\\x13\\x0d\\x47\\x65\\x6f\\x54\\x72\\x75\\x73\\x74\"\n\"\\x20\\x49\\x6e\\x63\\x2e\\x31\\x1b\\x30\\x19\\x06\\x03\\x55\\x04\\x03\\x13\\x12\"\n\"\\x47\\x65\\x6f\\x54\\x72\\x75\\x73\\x74\\x20\\x47\\x6c\\x6f\\x62\\x61\\x6c\\x20\"\n\"\\x43\\x41\\x30\\x1e\\x17\\x0d\\x31\\x33\\x30\\x34\\x30\\x35\\x31\\x35\\x31\\x35\"\n\"\\x35\\x35\\x5a\\x17\\x0d\\x31\\x35\\x30\\x34\\x30\\x34\\x31\\x35\\x31\\x35\\x35\"\n\"\\x35\\x5a\\x30\\x49\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\\x06\\x13\\x02\\x55\"\n\"\\x53\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x0a\\x13\\x0a\\x47\\x6f\\x6f\\x67\"\n\"\\x6c\\x65\\x20\\x49\\x6e\\x63\\x31\\x25\\x30\\x23\\x06\\x03\\x55\\x04\\x03\\x13\"\n\"\\x1c\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\\x49\\x6e\\x74\\x65\\x72\\x6e\\x65\\x74\"\n\"\\x20\\x41\\x75\\x74\\x68\\x6f\\x72\\x69\\x74\\x79\\x20\\x47\\x32\\x30\\x82\\x01\"\n\"\\x22\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x01\\x05\\x00\"\n\"\\x03\\x82\\x01\\x0f\\x00\\x30\\x82\\x01\\x0a\\x02\\x82\\x01\\x01\\x00\\x9c\\x2a\"\n\"\\x04\\x77\\x5c\\xd8\\x50\\x91\\x3a\\x06\\xa3\\x82\\xe0\\xd8\\x50\\x48\\xbc\\x89\"\n\"\\x3f\\xf1\\x19\\x70\\x1a\\x88\\x46\\x7e\\xe0\\x8f\\xc5\\xf1\\x89\\xce\\x21\\xee\"\n\"\\x5a\\xfe\\x61\\x0d\\xb7\\x32\\x44\\x89\\xa0\\x74\\x0b\\x53\\x4f\\x55\\xa4\\xce\"\n\"\\x82\\x62\\x95\\xee\\xeb\\x59\\x5f\\xc6\\xe1\\x05\\x80\\x12\\xc4\\x5e\\x94\\x3f\"\n\"\\xbc\\x5b\\x48\\x38\\xf4\\x53\\xf7\\x24\\xe6\\xfb\\x91\\xe9\\x15\\xc4\\xcf\\xf4\"\n\"\\x53\\x0d\\xf4\\x4a\\xfc\\x9f\\x54\\xde\\x7d\\xbe\\xa0\\x6b\\x6f\\x87\\xc0\\xd0\"\n\"\\x50\\x1f\\x28\\x30\\x03\\x40\\xda\\x08\\x73\\x51\\x6c\\x7f\\xff\\x3a\\x3c\\xa7\"\n\"\\x37\\x06\\x8e\\xbd\\x4b\\x11\\x04\\xeb\\x7d\\x24\\xde\\xe6\\xf9\\xfc\\x31\\x71\"\n\"\\xfb\\x94\\xd5\\x60\\xf3\\x2e\\x4a\\xaf\\x42\\xd2\\xcb\\xea\\xc4\\x6a\\x1a\\xb2\"\n\"\\xcc\\x53\\xdd\\x15\\x4b\\x8b\\x1f\\xc8\\x19\\x61\\x1f\\xcd\\x9d\\xa8\\x3e\\x63\"\n\"\\x2b\\x84\\x35\\x69\\x65\\x84\\xc8\\x19\\xc5\\x46\\x22\\xf8\\x53\\x95\\xbe\\xe3\"\n\"\\x80\\x4a\\x10\\xc6\\x2a\\xec\\xba\\x97\\x20\\x11\\xc7\\x39\\x99\\x10\\x04\\xa0\"\n\"\\xf0\\x61\\x7a\\x95\\x25\\x8c\\x4e\\x52\\x75\\xe2\\xb6\\xed\\x08\\xca\\x14\\xfc\"\n\"\\xce\\x22\\x6a\\xb3\\x4e\\xcf\\x46\\x03\\x97\\x97\\x03\\x7e\\xc0\\xb1\\xde\\x7b\"\n\"\\xaf\\x45\\x33\\xcf\\xba\\x3e\\x71\\xb7\\xde\\xf4\\x25\\x25\\xc2\\x0d\\x35\\x89\"\n\"\\x9d\\x9d\\xfb\\x0e\\x11\\x79\\x89\\x1e\\x37\\xc5\\xaf\\x8e\\x72\\x69\\x02\\x03\"\n\"\\x01\\x00\\x01\\xa3\\x81\\xfb\\x30\\x81\\xf8\\x30\\x1f\\x06\\x03\\x55\\x1d\\x23\"\n\"\\x04\\x18\\x30\\x16\\x80\\x14\\xc0\\x7a\\x98\\x68\\x8d\\x89\\xfb\\xab\\x05\\x64\"\n\"\\x0c\\x11\\x7d\\xaa\\x7d\\x65\\xb8\\xca\\xcc\\x4e\\x30\\x1d\\x06\\x03\\x55\\x1d\"\n\"\\x0e\\x04\\x16\\x04\\x14\\x4a\\xdd\\x06\\x16\\x1b\\xbc\\xf6\\x68\\xb5\\x76\\xf5\"\n\"\\x81\\xb6\\xbb\\x62\\x1a\\xba\\x5a\\x81\\x2f\\x30\\x12\\x06\\x03\\x55\\x1d\\x13\"\n\"\\x01\\x01\\xff\\x04\\x08\\x30\\x06\\x01\\x01\\xff\\x02\\x01\\x00\\x30\\x0e\\x06\"\n\"\\x03\\x55\\x1d\\x0f\\x01\\x01\\xff\\x04\\x04\\x03\\x02\\x01\\x06\\x30\\x3a\\x06\"\n\"\\x03\\x55\\x1d\\x1f\\x04\\x33\\x30\\x31\\x30\\x2f\\xa0\\x2d\\xa0\\x2b\\x86\\x29\"\n\"\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x63\\x72\\x6c\\x2e\\x67\\x65\\x6f\\x74\\x72\"\n\"\\x75\\x73\\x74\\x2e\\x63\\x6f\\x6d\\x2f\\x63\\x72\\x6c\\x73\\x2f\\x67\\x74\\x67\"\n\"\\x6c\\x6f\\x62\\x61\\x6c\\x2e\\x63\\x72\\x6c\\x30\\x3d\\x06\\x08\\x2b\\x06\\x01\"\n\"\\x05\\x05\\x07\\x01\\x01\\x04\\x31\\x30\\x2f\\x30\\x2d\\x06\\x08\\x2b\\x06\\x01\"\n\"\\x05\\x05\\x07\\x30\\x01\\x86\\x21\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x67\\x74\"\n\"\\x67\\x6c\\x6f\\x62\\x61\\x6c\\x2d\\x6f\\x63\\x73\\x70\\x2e\\x67\\x65\\x6f\\x74\"\n\"\\x72\\x75\\x73\\x74\\x2e\\x63\\x6f\\x6d\\x30\\x17\\x06\\x03\\x55\\x1d\\x20\\x04\"\n\"\\x10\\x30\\x0e\\x30\\x0c\\x06\\x0a\\x2b\\x06\\x01\\x04\\x01\\xd6\\x79\\x02\\x05\"\n\"\\x01\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\"\n\"\\x03\\x82\\x01\\x01\\x00\\x36\\xd7\\x06\\x80\\x11\\x27\\xad\\x2a\\x14\\x9b\\x38\"\n\"\\x77\\xb3\\x23\\xa0\\x75\\x58\\xbb\\xb1\\x7e\\x83\\x42\\xba\\x72\\xda\\x1e\\xd8\"\n\"\\x8e\\x36\\x06\\x97\\xe0\\xf0\\x95\\x3b\\x37\\xfd\\x1b\\x42\\x58\\xfe\\x22\\xc8\"\n\"\\x6b\\xbd\\x38\\x5e\\xd1\\x3b\\x25\\x6e\\x12\\xeb\\x5e\\x67\\x76\\x46\\x40\\x90\"\n\"\\xda\\x14\\xc8\\x78\\x0d\\xed\\x95\\x66\\xda\\x8e\\x86\\x6f\\x80\\xa1\\xba\\x56\"\n\"\\x32\\x95\\x86\\xdc\\xdc\\x6a\\xca\\x04\\x8c\\x5b\\x7f\\xf6\\xbf\\xcc\\x6f\\x85\"\n\"\\x03\\x58\\xc3\\x68\\x51\\x13\\xcd\\xfd\\xc8\\xf7\\x79\\x3d\\x99\\x35\\xf0\\x56\"\n\"\\xa3\\xbd\\xe0\\x59\\xed\\x4f\\x44\\x09\\xa3\\x9e\\x38\\x7a\\xf6\\x46\\xd1\\x1d\"\n\"\\x12\\x9d\\x4f\\xbe\\xd0\\x40\\xfc\\x55\\xfe\\x06\\x5e\\x3c\\xda\\x1c\\x56\\xbd\"\n\"\\x96\\x51\\x7b\\x6f\\x57\\x2a\\xdb\\xa2\\xaa\\x96\\xdc\\x8c\\x74\\xc2\\x95\\xbe\"\n\"\\xf0\\x6e\\x95\\x13\\xff\\x17\\xf0\\x3c\\xac\\xb2\\x10\\x8d\\xcc\\x73\\xfb\\xe8\"\n\"\\x8f\\x02\\xc6\\xf0\\xfb\\x33\\xb3\\x95\\x3b\\xe3\\xc2\\xcb\\x68\\x58\\x73\\xdb\"\n\"\\xa8\\x24\\x62\\x3b\\x06\\x35\\x9d\\x0d\\xa9\\x33\\xbd\\x78\\x03\\x90\\x2e\\x4c\"\n\"\\x78\\x5d\\x50\\x3a\\x81\\xd4\\xee\\xa0\\xc8\\x70\\x38\\xdc\\xb2\\xf9\\x67\\xfa\"\n\"\\x87\\x40\\x5d\\x61\\xc0\\x51\\x8f\\x6b\\x83\\x6b\\xcd\\x05\\x3a\\xca\\xe1\\xa7\"\n\"\\x05\\x78\\xfc\\xca\\xda\\x94\\xd0\\x2c\\x08\\x3d\\x7e\\x16\\x79\\xc8\\xa0\\x50\"\n\"\\x20\\x24\\x54\\x33\\x71\\x00\\x03\\x81\\x30\\x82\\x03\\x7d\\x30\\x82\\x02\\xe6\"\n\"\\xa0\\x03\\x02\\x01\\x02\\x02\\x03\\x12\\xbb\\xe6\\x30\\x0d\\x06\\x09\\x2a\\x86\"\n\"\\x48\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\\x30\\x4e\\x31\\x0b\\x30\\x09\\x06\"\n\"\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x10\\x30\\x0e\\x06\\x03\\x55\\x04\"\n\"\\x0a\\x13\\x07\\x45\\x71\\x75\\x69\\x66\\x61\\x78\\x31\\x2d\\x30\\x2b\\x06\\x03\"\n\"\\x55\\x04\\x0b\\x13\\x24\\x45\\x71\\x75\\x69\\x66\\x61\\x78\\x20\\x53\\x65\\x63\"\n\"\\x75\\x72\\x65\\x20\\x43\\x65\\x72\\x74\\x69\\x66\\x69\\x63\\x61\\x74\\x65\\x20\"\n\"\\x41\\x75\\x74\\x68\\x6f\\x72\\x69\\x74\\x79\\x30\\x1e\\x17\\x0d\\x30\\x32\\x30\"\n\"\\x35\\x32\\x31\\x30\\x34\\x30\\x30\\x30\\x30\\x5a\\x17\\x0d\\x31\\x38\\x30\\x38\"\n\"\\x32\\x31\\x30\\x34\\x30\\x30\\x30\\x30\\x5a\\x30\\x42\\x31\\x0b\\x30\\x09\\x06\"\n\"\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x16\\x30\\x14\\x06\\x03\\x55\\x04\"\n\"\\x0a\\x13\\x0d\\x47\\x65\\x6f\\x54\\x72\\x75\\x73\\x74\\x20\\x49\\x6e\\x63\\x2e\"\n\"\\x31\\x1b\\x30\\x19\\x06\\x03\\x55\\x04\\x03\\x13\\x12\\x47\\x65\\x6f\\x54\\x72\"\n\"\\x75\\x73\\x74\\x20\\x47\\x6c\\x6f\\x62\\x61\\x6c\\x20\\x43\\x41\\x30\\x82\\x01\"\n\"\\x22\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x01\\x05\\x00\"\n\"\\x03\\x82\\x01\\x0f\\x00\\x30\\x82\\x01\\x0a\\x02\\x82\\x01\\x01\\x00\\xda\\xcc\"\n\"\\x18\\x63\\x30\\xfd\\xf4\\x17\\x23\\x1a\\x56\\x7e\\x5b\\xdf\\x3c\\x6c\\x38\\xe4\"\n\"\\x71\\xb7\\x78\\x91\\xd4\\xbc\\xa1\\xd8\\x4c\\xf8\\xa8\\x43\\xb6\\x03\\xe9\\x4d\"\n\"\\x21\\x07\\x08\\x88\\xda\\x58\\x2f\\x66\\x39\\x29\\xbd\\x05\\x78\\x8b\\x9d\\x38\"\n\"\\xe8\\x05\\xb7\\x6a\\x7e\\x71\\xa4\\xe6\\xc4\\x60\\xa6\\xb0\\xef\\x80\\xe4\\x89\"\n\"\\x28\\x0f\\x9e\\x25\\xd6\\xed\\x83\\xf3\\xad\\xa6\\x91\\xc7\\x98\\xc9\\x42\\x18\"\n\"\\x35\\x14\\x9d\\xad\\x98\\x46\\x92\\x2e\\x4f\\xca\\xf1\\x87\\x43\\xc1\\x16\\x95\"\n\"\\x57\\x2d\\x50\\xef\\x89\\x2d\\x80\\x7a\\x57\\xad\\xf2\\xee\\x5f\\x6b\\xd2\\x00\"\n\"\\x8d\\xb9\\x14\\xf8\\x14\\x15\\x35\\xd9\\xc0\\x46\\xa3\\x7b\\x72\\xc8\\x91\\xbf\"\n\"\\xc9\\x55\\x2b\\xcd\\xd0\\x97\\x3e\\x9c\\x26\\x64\\xcc\\xdf\\xce\\x83\\x19\\x71\"\n\"\\xca\\x4e\\xe6\\xd4\\xd5\\x7b\\xa9\\x19\\xcd\\x55\\xde\\xc8\\xec\\xd2\\x5e\\x38\"\n\"\\x53\\xe5\\x5c\\x4f\\x8c\\x2d\\xfe\\x50\\x23\\x36\\xfc\\x66\\xe6\\xcb\\x8e\\xa4\"\n\"\\x39\\x19\\x00\\xb7\\x95\\x02\\x39\\x91\\x0b\\x0e\\xfe\\x38\\x2e\\xd1\\x1d\\x05\"\n\"\\x9a\\xf6\\x4d\\x3e\\x6f\\x0f\\x07\\x1d\\xaf\\x2c\\x1e\\x8f\\x60\\x39\\xe2\\xfa\"\n\"\\x36\\x53\\x13\\x39\\xd4\\x5e\\x26\\x2b\\xdb\\x3d\\xa8\\x14\\xbd\\x32\\xeb\\x18\"\n\"\\x03\\x28\\x52\\x04\\x71\\xe5\\xab\\x33\\x3d\\xe1\\x38\\xbb\\x07\\x36\\x84\\x62\"\n\"\\x9c\\x79\\xea\\x16\\x30\\xf4\\x5f\\xc0\\x2b\\xe8\\x71\\x6b\\xe4\\xf9\\x02\\x03\"\n\"\\x01\\x00\\x01\\xa3\\x81\\xf0\\x30\\x81\\xed\\x30\\x1f\\x06\\x03\\x55\\x1d\\x23\"\n\"\\x04\\x18\\x30\\x16\\x80\\x14\\x48\\xe6\\x68\\xf9\\x2b\\xd2\\xb2\\x95\\xd7\\x47\"\n\"\\xd8\\x23\\x20\\x10\\x4f\\x33\\x98\\x90\\x9f\\xd4\\x30\\x1d\\x06\\x03\\x55\\x1d\"\n\"\\x0e\\x04\\x16\\x04\\x14\\xc0\\x7a\\x98\\x68\\x8d\\x89\\xfb\\xab\\x05\\x64\\x0c\"\n\"\\x11\\x7d\\xaa\\x7d\\x65\\xb8\\xca\\xcc\\x4e\\x30\\x0f\\x06\\x03\\x55\\x1d\\x13\"\n\"\\x01\\x01\\xff\\x04\\x05\\x30\\x03\\x01\\x01\\xff\\x30\\x0e\\x06\\x03\\x55\\x1d\"\n\"\\x0f\\x01\\x01\\xff\\x04\\x04\\x03\\x02\\x01\\x06\\x30\\x3a\\x06\\x03\\x55\\x1d\"\n\"\\x1f\\x04\\x33\\x30\\x31\\x30\\x2f\\xa0\\x2d\\xa0\\x2b\\x86\\x29\\x68\\x74\\x74\"\n\"\\x70\\x3a\\x2f\\x2f\\x63\\x72\\x6c\\x2e\\x67\\x65\\x6f\\x74\\x72\\x75\\x73\\x74\"\n\"\\x2e\\x63\\x6f\\x6d\\x2f\\x63\\x72\\x6c\\x73\\x2f\\x73\\x65\\x63\\x75\\x72\\x65\"\n\"\\x63\\x61\\x2e\\x63\\x72\\x6c\\x30\\x4e\\x06\\x03\\x55\\x1d\\x20\\x04\\x47\\x30\"\n\"\\x45\\x30\\x43\\x06\\x04\\x55\\x1d\\x20\\x00\\x30\\x3b\\x30\\x39\\x06\\x08\\x2b\"\n\"\\x06\\x01\\x05\\x05\\x07\\x02\\x01\\x16\\x2d\\x68\\x74\\x74\\x70\\x73\\x3a\\x2f\"\n\"\\x2f\\x77\\x77\\x77\\x2e\\x67\\x65\\x6f\\x74\\x72\\x75\\x73\\x74\\x2e\\x63\\x6f\"\n\"\\x6d\\x2f\\x72\\x65\\x73\\x6f\\x75\\x72\\x63\\x65\\x73\\x2f\\x72\\x65\\x70\\x6f\"\n\"\\x73\\x69\\x74\\x6f\\x72\\x79\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\"\n\"\\x01\\x01\\x05\\x05\\x00\\x03\\x81\\x81\\x00\\x76\\xe1\\x12\\x6e\\x4e\\x4b\\x16\"\n\"\\x12\\x86\\x30\\x06\\xb2\\x81\\x08\\xcf\\xf0\\x08\\xc7\\xc7\\x71\\x7e\\x66\\xee\"\n\"\\xc2\\xed\\xd4\\x3b\\x1f\\xff\\xf0\\xf0\\xc8\\x4e\\xd6\\x43\\x38\\xb0\\xb9\\x30\"\n\"\\x7d\\x18\\xd0\\x55\\x83\\xa2\\x6a\\xcb\\x36\\x11\\x9c\\xe8\\x48\\x66\\xa3\\x6d\"\n\"\\x7f\\xb8\\x13\\xd4\\x47\\xfe\\x8b\\x5a\\x5c\\x73\\xfc\\xae\\xd9\\x1b\\x32\\x19\"\n\"\\x38\\xab\\x97\\x34\\x14\\xaa\\x96\\xd2\\xeb\\xa3\\x1c\\x14\\x08\\x49\\xb6\\xbb\"\n\"\\xe5\\x91\\xef\\x83\\x36\\xeb\\x1d\\x56\\x6f\\xca\\xda\\xbc\\x73\\x63\\x90\\xe4\"\n\"\\x7f\\x7b\\x3e\\x22\\xcb\\x3d\\x07\\xed\\x5f\\x38\\x74\\x9c\\xe3\\x03\\x50\\x4e\"\n\"\\xa1\\xaf\\x98\\xee\\x61\\xf2\\x84\\x3f\\x12\\x16\\x03\\x03\\x00\\x95\\x0c\\x00\"\n\"\\x00\\x91\\x03\\x00\\x17\\x41\\x04\\x4c\\x17\\x75\\x15\\xc7\\xeb\\x2a\\x7f\\x4b\"\n\"\\xf4\\xe8\\xd9\\xee\\x6c\\x06\\x58\\x2c\\xb3\\x37\\xe6\\xad\\xe4\\x46\\x24\\xfe\"\n\"\\xfe\\x91\\xdd\\x2e\\x87\\x2a\\xde\\xad\\x4d\\xd3\\x85\\x19\\xd1\\xa8\\x21\\xf5\"\n\"\\xb8\\x42\\xa7\\xd8\\x98\\x28\\xbb\\x94\\xeb\\x60\\xe0\\xb9\\x97\\x6c\\x99\\xbb\"\n\"\\x9f\\xd7\\x31\\xac\\x5a\\x1a\\xc0\\x04\\x03\\x00\\x48\\x30\\x46\\x02\\x21\\x00\"\n\"\\xa7\\x25\\x1d\\x54\\x2e\\x5a\\xf9\\x47\\x3f\\x4e\\xb2\\x31\\xd2\\x97\\x4b\\xe9\"\n\"\\xf5\\xe8\\xc1\\xc7\\x51\\xf8\\x39\\x88\\x4b\\x16\\x59\\xbb\\xe5\\x06\\x54\\xe4\"\n\"\\x02\\x21\\x00\\xb4\\xa3\\x31\\x5b\\x4e\\xc5\\x6b\\xf9\\x35\\x52\\xda\\x26\\x22\"\n\"\\x8c\\x2c\\xeb\\xf2\\x8e\\x41\\xec\\xc9\\xeb\\x65\\x03\\xba\\x08\\x91\\x64\\x0f\"\n\"\\x33\\x9e\\x70\\x16\\x03\\x03\\x00\\x04\\x0e\\x00\\x00\\x00\\x16\\x03\\x03\\x00\"\n\"\\xbe\\x04\\x00\\x00\\xba\\x00\\x01\\x89\\xc0\\x00\\xb4\\xdd\\x76\\xa2\\xde\\xd9\"\n\"\\x62\\xc3\\xc9\\x6a\\x16\\x37\\x12\\xd2\\x2a\\x86\\xed\\xc8\\xb3\\x47\\xbb\\xf8\"\n\"\\xf6\\x95\\x1a\\x19\\x99\\x07\\xd3\\xfe\\x60\\x0c\\x67\\xc5\\x44\\x8d\\xe7\\x92\"\n\"\\xa5\\xa5\\x8e\\x29\\x58\\x27\\x2e\\x25\\x69\\x43\\x60\\xe7\\x9f\\x6b\\xdc\\xd7\"\n\"\\x43\\x4a\\xbc\\xf3\\x09\\xe5\\x5c\\x3a\\xfc\\xe1\\xd9\\xd8\\xf4\\x6a\\x93\\x1c\"\n\"\\x47\\x90\\xfc\\xfc\\x35\\x1b\\xfe\\xef\\xd7\\x4f\\xb5\\x03\\x6d\\xab\\xde\\x93\"\n\"\\x12\\x9b\\x34\\xb6\\x8b\\xb8\\xbc\\x45\\x51\\x80\\x38\\xfb\\x66\\x2c\\xca\\xbf\"\n\"\\xd5\\x65\\xe9\\x5d\\x0d\\xa8\\x8c\\x0b\\xe6\\xb2\\x43\\x2e\\xc7\\x86\\x81\\xf4\"\n\"\\x9d\\x2e\\xef\\x17\\x0a\\x5b\\x11\\x9b\\xfa\\x32\\xf5\\xfb\\x0b\\x1e\\x7f\\x1a\"\n\"\\xf0\\xcd\\xe6\\xd4\\x5e\\x97\\xd8\\x11\\x6b\\x05\\x58\\x52\\xd2\\xb4\\x17\\x3a\"\n\"\\x36\\x85\\xa0\\xd9\\x8b\\x7f\\x16\\x47\\x73\\x6a\\x5b\\xbd\\x15\\x24\\xaf\\xe6\"\n\"\\x02\\xed\\x7d\\x98\\xea\\x29\\xde\\x4b\\x12\\x55\\xa4\\x8e\\xd6\\x09\\xe2\\x14\"\n\"\\x03\\x03\\x00\\x01\\x01\\x16\\x03\\x03\\x00\\x24\\xee\\x01\\xaa\\x34\\x2e\\xdf\"\n\"\\x36\\x7a\\x6a\\xb5\\x8f\\x73\\xf1\\x58\\xbe\\xd4\\xc1\\x7f\\x7f\\xc7\\x16\\x4f\"\n\"\\xb7\\x29\\x5b\\xad\\x80\\xe1\\x50\\x34\\xd0\\x75\\x28\\x49\\x65\\xb5\\x17\\x03\"\n\"\\x03\\x00\\x30\\xa8\\x43\\x75\\x45\\xc6\\x7f\\x3b\\xdd\\xc4\\x86\\xa2\\x49\\x65\"\n\"\\xed\\x10\\x5f\\x7d\\xac\\xf0\\x93\\x78\\x09\\xc1\\xdb\\x8f\\xad\\x99\\x5b\\xfd\"\n\"\\xa5\\x40\\x14\\xfd\\x36\\x1f\\x46\\x12\\x77\\xa7\\x4b\\x75\\x22\\xea\\x05\\xb5\"\n\"\\xe1\\xb6\\xa9\\x17\\x03\\x03\\x01\\x19\\x9a\\xc2\\x10\\x16\\xcb\\x08\\xca\\x7b\"\n\"\\x5e\\xde\\x7c\\xb5\\x14\\x85\\x9f\\xf5\\xdc\\xb7\\x5c\\xe2\\xe2\\x4a\\xff\\x7e\"\n\"\\x28\\x71\\xd3\\xc2\\x0d\\xb0\\x65\\xca\\x43\\x7d\\xcf\\xda\\xd5\\x05\\xfd\\xb7\"\n\"\\xa5\\x13\\x5c\\x82\\x40\\x21\\x9b\\xa6\\x22\\x56\\xb9\\x1d\\xe5\\x24\\x73\\x12\"\n\"\\x2d\\x99\\x8b\\x68\\xa5\\x9c\\xee\\x63\\x24\\x07\\xae\\xb7\\x32\\x95\\x6a\\xe6\"\n\"\\x9b\\x59\\x35\\x26\\x74\\xc9\\xde\\x95\\x7f\\x6b\\x00\\xe0\\x62\\xfe\\x66\\x49\"\n\"\\xaa\\xc4\\x8e\\xbb\\xc5\\xef\\x6b\\x21\\x09\\x90\\xb7\\x7f\\x4e\\x06\\x61\\x05\"\n\"\\x7c\\x7c\\x6d\\x8a\\x2c\\x49\\xb3\\xcf\\x08\\xcb\\x59\\xca\\x2e\\x71\\x7d\\x83\"\n\"\\x58\\x30\\x42\\x23\\x0b\\xf7\\xec\\x4b\\x9c\\x9d\\xa9\\x11\\x11\\x34\\x1d\\x2e\"\n\"\\xb6\\xb3\\xee\\x4e\\x35\\x2c\\x87\\xcf\\x37\\xab\\xe2\\xd4\\x33\\x24\\xfc\\x94\"\n\"\\x65\\x62\\x55\\xc0\\x6e\\x5a\\xe9\\xd1\\x96\\xf1\\x6f\\x64\\x2e\\x7f\\x65\\x92\"\n\"\\x86\\x6c\\xe7\\x93\\x11\\x2c\\xe8\\xb0\\x75\\x03\\x18\\x9d\\xe6\\xb2\\x42\\xab\"\n\"\\x45\\x54\\x9a\\xdb\\xee\\xd9\\x84\\x7e\\x1a\\xe6\\x8e\\x00\\xc1\\x02\\x16\\x83\"\n\"\\xc7\\x19\\x17\\x03\\x30\\x2e\\x20\\x6d\\xbe\\x23\\xb1\\x95\\x3c\\x24\\xbe\\x55\"\n\"\\x01\\x9e\\xbb\\xc0\\x2b\\xaf\\xfc\\x71\\xaa\\x35\\x0e\\xd0\\xbd\\x19\\x0c\\xcd\"\n\"\\xfe\\x97\\xf2\\x10\\xe7\\x95\\x16\\x7c\\x43\\x92\\xeb\\x92\\xde\\x4c\\x01\\xed\"\n\"\\x1d\\x4f\\x76\\xc0\\xb7\\xb6\\xe9\\x95\\x40\\xb6\\x26\\x55\\x5a\\x74\\x9e\\xc5\"\n\"\\x8a\\x1d\\xf4\\x56\\xcc\\x58\\x27\\x62\\xbb\\xe1\\x43\\xce\\xb0\\x4a\\x8a\\xb6\"\n\"\\xd3\\x17\\x03\\x03\\x05\\x4b\\xfb\\x08\\xd6\\x6a\\xbf\\xff\\x99\\x61\\x4d\\xb0\"\n\"\\x24\\x0d\\x40\\xd7\\xef\\x0c\\x38\\x00\\x35\\x12\\xf4\\x3d\\x4a\\x0b\\xf9\\x20\"\n\"\\x4d\\x1f\\x72\\x43\\x34\\x17\\x74\\xd3\\x30\\xcc\\x2c\\x95\\xa8\\xde\\x41\\x20\"\n\"\\xb2\\xe0\\x38\\xce\\xd0\\x5f\\xa1\\x92\\xcd\\x99\\x94\\x04\\xf6\\xf5\\x06\\x97\"\n\"\\x9a\\xb5\\x8c\\xa1\\xa6\\xef\\xdd\\x2f\\x7d\\x30\\xba\\xe0\\xc0\\x23\\x07\\x54\"\n\"\\x6f\\x91\\x96\\xd1\\x7c\\xfe\\x7e\\xb3\\xfd\\xf7\\x9a\\xe7\\xfa\\x67\\x1e\\x5c\"\n\"\\x16\\x5a\\xde\\x43\\x49\\x25\\x39\\x52\\x13\\x66\\x29\\xbd\\xb6\\xda\\x59\\x5a\"\n\"\\x13\\xfb\\x76\\xac\\xf3\\x6c\\x1b\\x00\\xf4\\x1e\\x60\\x45\\xf4\\x23\\xca\\x9d\"\n\"\\x02\\x8b\\x88\\x64\\xf2\\xf2\\x86\\x1a\\xa2\\x9c\\xe9\\x6e\\xaa\\x39\\xe5\\x4f\"\n\"\\xc5\\xb6\\x68\\xfd\\x75\\x10\\xec\\xa5\\xd6\\x66\\x24\\xc3\\x85\\xa1\\x17\\xfd\"\n\"\\x46\\x69\\x69\\xaf\\x5f\\x7c\\xa4\\x5f\\x0a\\x8a\\xb1\\xdb\\xeb\\x4c\\x67\\x9b\"\n\"\\xc6\\x33\\x36\\x4b\\xf1\\xdc\\x86\\x95\\x63\\x55\\x13\\x37\\x86\\xf6\\xba\\xf2\"\n\"\\xf2\\xc2\\x89\\x98\\xe9\\x82\\xf6\\x89\\x2c\\xbc\\x91\\x12\\xfb\\x3f\\x42\\x6f\"\n\"\\xfa\\xa4\\xd6\\x9b\\x66\\x67\\x6a\\xb6\\x99\\xb1\\xac\\xe0\\x60\\xc8\\x37\\x71\"\n\"\\xd6\\x4a\\x08\\x71\\xf9\\x26\\x4e\\xa9\\x06\\x76\\x89\\xb3\\xa3\\x91\\xa6\\x5a\"\n\"\\xdf\\xfe\\xc0\\xb9\\xc5\\xf2\\xfa\\x23\\x46\\xe5\\x89\\xd4\\x19\\x76\\xf7\\xef\"\n\"\\xc5\\x2b\\x5a\\x07\\xe4\\x9a\\x81\\xf4\\x39\\x80\\xbd\\xa7\\xc5\\x3d\\x11\\xcd\"\n\"\\xea\\xb9\\x5f\\xe5\\x69\\xe5\\x35\\x4e\\x24\\x6b\\x97\\x8a\\xba\\x7b\\xaf\\x10\"\n\"\\xd0\\x7a\\xc7\\xdf\\x44\\x23\\x0e\\x1a\\x5f\\x6a\\xa4\\xed\\x14\\x79\\xb9\\xd9\"\n\"\\x93\\x38\\xd7\\x50\\xd6\\x6a\\x7b\\x5b\\x99\\xa5\\x49\\xef\\xd1\\x64\\xef\\x35\"\n\"\\xdc\\xef\\x0b\\xd7\\x6c\\xe4\\xe6\\x7b\\x55\\x2c\\x46\\xf8\\x03\\xd2\\xfa\\x67\"\n\"\\x2a\\x64\\xc7\\x7f\\xd4\\xaf\\x32\\x43\\xc0\\x4d\\xf5\\x55\\xc9\\xf6\\x1b\\xc8\"\n\"\\xe9\\x9f\\x7f\\xed\\x7a\\x8f\\xa5\\x59\\x9d\\x60\\x65\\xa4\\x7b\\x6b\\xc6\\x32\"\n\"\\xa4\\x30\\xea\\x2e\\x29\\x9c\\x9b\\x83\\x05\\x80\\x22\\x3a\\xdd\\x04\\x53\\x33\"\n\"\\xef\\xeb\\xd7\\x6d\\x17\\x34\\x4b\\x0f\\x5a\\x6d\\xb7\\xea\\x7c\\x15\\x69\\xdf\"\n\"\\xec\\x65\\xc7\\xa9\\x63\\xc8\\x25\\x19\\xc3\\x13\\xca\\xdf\\x23\\x20\\x27\\xb7\"\n\"\\x29\\xf3\\xa3\\xe5\\x2d\\x6f\\xea\\x91\\x12\\xfa\\xd5\\x71\\x48\\xc7\\x2a\\x5a\"\n\"\\xc8\\x75\\x23\\xcc\\x8f\\xa0\\x4d\\x63\\xb2\\x60\\xe0\\x52\\xd1\\x1e\\x4f\\x44\"\n\"\\x69\\xf7\\xf1\\x63\\x59\\x83\\x79\\x8e\\x53\\x27\\x61\\xa7\\x92\\xe1\\xed\\x4f\"\n\"\\x75\\x8e\\xd9\\x3c\\x88\\x74\\xc7\\x7b\\xb0\\x09\\x0e\\x3b\\x0a\\xad\\xc1\\xbc\"\n\"\\x5d\\x25\\xa6\\xce\\xea\\x98\\xaf\\x27\\xb2\\xc7\\xb1\\x2e\\x26\\xef\\x35\\x81\"\n\"\\x34\\x49\\xfd\\x74\\x45\\x16\\x5f\\x20\\xd6\\x6d\\x54\\xf8\\x97\\x4a\\x7e\\xfe\"\n\"\\x8b\\x24\\x8c\\xa1\\x46\\xa9\\x7d\\x0b\\x32\\xe9\\x0d\\xa9\\x69\\x56\\xad\\x1f\"\n\"\\x95\\xe0\\x7a\\xed\\x6f\\x95\\x5a\\xd7\\xf4\\x25\\xbf\\x79\\xa7\\xa3\\x69\\x43\"\n\"\\xd2\\x41\\x41\\x65\\xeb\\x43\\x13\\xe1\\x42\\xbd\\xde\\x05\\x43\\x01\\x1d\\x20\"\n\"\\x7d\\x54\\xf1\\x92\\xef\\x94\\xc8\\x45\\xba\\xd0\\x83\\x25\\x26\\x47\\x57\\x32\"\n\"\\x63\\x61\\x38\\xa1\\xb9\\x9d\\xa2\\x88\\xb7\\x8e\\x87\\xbb\\x13\\xfc\\xd8\\x3f\"\n\"\\xf9\\x8d\\x68\\xcc\\xa1\\xa3\\xa7\\x35\\xfd\\x5c\\xa1\\x8b\\x6a\\xce\\x36\\x2d\"\n\"\\xca\\x0f\\x05\\x52\\x86\\x86\\x87\\xbe\\x90\\x9c\\x06\\xcb\\x08\\xbe\\xcc\\x42\"\n\"\\x4e\\xda\\xf6\\x8a\\x4e\\x02\\x0f\\x56\\xce\\xad\\x19\\xfd\\x8d\\xb7\\xf1\\xcc\"\n\"\\xb9\\x6c\\x56\\x18\\x48\\x44\\xbe\\x24\\x14\\x00\\x08\\xbe\\x63\\x32\\x15\\x71\"\n\"\\x60\\xd3\\x15\\xa8\\xeb\\xcd\\x69\\xbe\\x6f\\xe9\\x26\\x43\\x89\\x10\\x73\\x67\"\n\"\\xb4\\x1d\\xeb\\x24\\x9b\\x27\\x73\\x20\\xfb\\xab\\xd1\\xe1\\x28\\x06\\xbd\\x36\"\n\"\\x3a\\x8f\\x87\\x05\\x34\\x96\\x4e\\x86\\xaa\\xcb\\xbf\\xd4\\x5d\\x92\\xf8\\xb9\"\n\"\\x08\\x7d\\xcd\\xee\\xc2\\x17\\xac\\xab\\xdd\\xf8\\xc0\\xdc\\xd4\\x24\\x6a\\xa1\"\n\"\\x7b\\xaa\\x60\\x31\\x19\\x5f\\xf5\\xd0\\xc4\\x9a\\xa7\\x8a\\x12\\xd2\\xd9\\x3d\"\n\"\\xae\\x44\\x7a\\x1b\\x07\\x4b\\xf3\\xa5\\x69\\x4e\\xa8\\x51\\x51\\xbe\\xfb\\xfc\"\n\"\\xbc\\xdc\\x27\\x65\\x9e\\x2c\\xa6\\xb1\\xca\\x15\\x25\\x7f\\xc6\\x5f\\x84\\x64\"\n\"\\x79\\x01\\xde\\x7a\\x87\\x00\\x6b\\x83\\x0b\\x8f\\x1c\\xe9\\x6c\\x1a\\xa2\\xb7\"\n\"\\xad\\x33\\x9e\\xe8\\x48\\xbb\\x06\\x60\\xb3\\x26\\x81\\x7e\\x2a\\x58\\xff\\xe5\"\n\"\\x35\\xc8\\x28\\xd0\\x39\\x6a\\x24\\x75\\xba\\xe9\\xe1\\x05\\xb4\\x37\\x36\\xd3\"\n\"\\x61\\x07\\x0b\\x85\\xe9\\x8d\\xd4\\xdc\\x5b\\x96\\x64\\x5f\\x30\\xe7\\x94\\x95\"\n\"\\x72\\x73\\x3f\\x40\\x2c\\x78\\x8b\\xab\\x86\\x0a\\xf9\\x6a\\x2c\\x27\\xdc\\xaa\"\n\"\\xfb\\x95\\x02\\x7e\\x3b\\x28\\x7d\\x99\\xbc\\x07\\xa0\\xb5\\x67\\xa4\\x04\\xaf\"\n\"\\x3d\\x33\\x34\\x09\\x67\\xa3\\x1a\\x28\\x0b\\x21\\xf0\\x45\\xb3\\x93\\x3a\\x77\"\n\"\\x90\\x6f\\xed\\x1f\\xb0\\xf7\\x27\\x5a\\x0b\\xd3\\xc8\\x36\\x6a\\xda\\x6c\\x38\"\n\"\\xe8\\xd7\\xea\\x6e\\x0d\\xad\\x64\\x5b\\xf5\\x53\\x2d\\x9b\\x36\\x95\\x5c\\x6b\"\n\"\\xaf\\xa5\\x12\\x42\\x1b\\x24\\x05\\x2c\\x64\\x45\\x07\\xff\\xb9\\xc3\\xf8\\x62\"\n\"\\x57\\x67\\x53\\x7d\\x34\\xb9\\x47\\x5b\\xaa\\x46\\x8d\\x4b\\x25\\x99\\xfe\\x5c\"\n\"\\xba\\x7e\\xfe\\xc8\\x0c\\x47\\x7a\\x47\\xd2\\xd7\\x3b\\xbe\\x8c\\xaa\\xb4\\x1a\"\n\"\\x56\\xe4\\x08\\xb1\\xac\\x16\\xbe\\x52\\xd5\\xb2\\xd4\\xc5\\xa1\\xe7\\x18\\x12\"\n\"\\x00\\xa9\\x7a\\x7b\\x86\\x6c\\x1e\\x32\\x26\\xc4\\xf2\\x5b\\xb2\\x01\\x65\\x5f\"\n\"\\x33\\x5e\\x7c\\x86\\xae\\x7b\\xf1\\x52\\x2a\\x07\\x56\\x08\\x9b\\xda\\x77\\x9d\"\n\"\\x59\\x4b\\xd6\\xb9\\x8f\\xec\\x43\\xa7\\xc7\\x34\\x42\\x2f\\xa5\\xab\\x4f\\xbf\"\n\"\\x1c\\x58\\x32\\x04\\x53\\x26\\x00\\x38\\xd1\\xfe\\x7b\\xac\\x8e\\xe3\\x96\\x79\"\n\"\\x68\\x7c\\x0a\\x06\\xb4\\x74\\xd4\\xed\\xd6\\xc2\\xe7\\x8d\\xfd\\x62\\xd2\\x9e\"\n\"\\x95\\x64\\xa7\\x13\\x74\\x77\\xff\\x27\\x55\\x88\\x91\\xac\\xc5\\xc7\\xa0\\x70\"\n\"\\x95\\x46\\x12\\x91\\x1b\\xce\\x80\\x6a\\xdc\\xff\\x62\\xb3\\x04\\x0f\\xd0\\x63\"\n\"\\xbc\\xe0\\xec\\xe9\\x0f\\xc4\\xff\\x5d\\xc9\\xad\\x1e\\x71\\xa8\\x16\\x64\\xd3\"\n\"\\x53\\x54\\xd7\\x49\\xc2\\xc9\\x06\\xfc\\xa3\\x5a\\x30\\xc0\\xdd\\xee\\xb2\\x10\"\n\"\\x29\\x3b\\x19\\x6a\\xf0\\xab\\xff\\x7c\\x40\\xc3\\x26\\x19\\x17\\x26\\x5c\\xb5\"\n\"\\x16\\xd9\\xd7\\xa0\\x9b\\xea\\xd5\\x16\\xaa\\xe1\\x3f\\x17\\x0c\\xb2\\xee\\xf1\"\n\"\\xd9\\x34\\x93\\xe8\\x60\\x7e\\x59\\x1c\\xaf\\x29\\x7f\\xf3\\xbd\\x7a\\x62\\xe3\"\n\"\\x55\\x73\\xa4\\x29\\x9b\\x62\\x77\\x6e\\xdc\\x6c\\xce\\xe6\\xad\\x1f\\x7b\\x6d\"\n\"\\xa9\\x68\\x28\\x26\\x81\\x61\\x10\\x42\\x6e\\x5d\\x1e\\x24\\xdf\\xf6\\x75\\x75\"\n\"\\x31\\x6f\\x96\\xe2\\x41\\xc1\\x84\\xae\\x3e\\x0b\\xc5\\xea\\x71\\x45\\xba\\x59\"\n\"\\xe5\\xf3\\xfd\\xa4\\x53\\x98\\x91\\x38\\x5b\\xe5\\x3f\\x2c\\x76\\xb5\\x12\\x77\"\n\"\\x45\\x7e\\x9d\\xa3\\xb2\\x7d\\x5b\\xad\\x23\\xdc\\x7e\\x80\\x02\\x3d\\x19\\x46\"\n\"\\x7a\\xd4\\x3f\\xb5\\x7a\\x50\\xfb\\x24\\x83\\xab\\xa4\\x5a\\xe8\\x0d\\x9f\\xd1\"\n\"\\xf4\\x66\\xdf\\x85\\x42\\xef\\xcc\\x13\\x59\\xed\\x5a\\xa2\\x3a\\x51\\xdc\\x0a\"\n\"\\x88\\x62\\x9a\\x12\\xfe\\x2f\\x71\\x24\\x6c\\xd4\\x11\\x18\\x82\\x01\\x3f\\x06\"\n\"\\xc0\\x1b\\x0a\\xae\\x2f\\xf1\\xc2\\x7a\\xad\\x99\\x2d\\xce\\xf9\\x4d\\x7b\\x1c\"\n\"\\xfb\\xce\\x7c\\x2d\\xa7\\x9f\\x86\\xdd\\x6b\\xcc\\xd1\\x6e\\xc4\\xfd\\x2c\\xfc\"\n\"\\x77\\xd6\\xf5\\xfa\\xf3\\x3c\\x06\\x9a\\x40\\x05\\xd3\\x54\\x80\\xb0\\xe5\\x91\"\n\"\\x17\\xc5\\xa1\\x07\\xc0\\x0d\\x0d\\x31\\x57\\x44\\x50\\xfb\\x46\\x1f\\xf9\\x87\"\n\"\\x8f\\x17\\x03\\x03\\x05\\x4b\\x6e\\x79\\x18\\xa9\\x24\\xf5\\x4b\\x1e\\x7f\\xba\"\n\"\\x08\\x11\\xca\\x4d\\x8a\\x87\\x7d\\x44\\xec\\x5d\\xa2\\xff\\x79\\xbc\\xc5\\x83\"\n\"\\x1a\\x71\\xde\\x28\\x53\\x3f\\x3f\\x53\\xa4\\x4e\\x22\\x1f\\xb2\\x86\\xcd\\x9c\"\n\"\\xe7\\xff\\xbc\\x33\\x45\\x22\\x52\\xac\\x81\\xe8\\x63\\x0f\\x7c\\x15\\xed\\x1d\"\n\"\\xdb\\xf3\\x95\\xed\\x42\\xdb\\x2e\\x3f\\x24\\xee\\x7c\\xd6\\xc3\\xa3\\xa4\\xe6\"\n\"\\xf4\\xdb\\x37\\x2a\\xbe\\x1e\\x5e\\x2f\\xe4\\xe5\\x67\\xde\\x19\\x95\\x1a\\x6c\"\n\"\\x20\\xe6\\x0a\\xc2\\x26\\x5c\\x90\\xd2\\x3b\\x3f\\x87\\xd1\\x78\\x35\\x16\\x40\"\n\"\\x5a\\x21\\xe7\\x42\\x3f\\x4b\\x79\\x21\\xe0\\x03\\x3d\\x61\\x75\\xfe\\x94\\xa5\"\n\"\\x4d\\x85\\xff\\x8d\\xfc\\xc7\\x92\\x88\\x5c\\x5f\\xe2\\xb7\\x9c\\x5e\\x9b\\xa8\"\n\"\\xf9\\xee\\xa7\\xa5\\x57\\x88\\x7e\\xf9\\x9d\\xdc\\xa8\\x10\\xc3\\x17\\x26\\x7d\"\n\"\\x56\\xd2\\x76\\x3b\\x7a\\xe5\\xad\\x4e\\x2a\\x83\\xf5\\x45\\x50\\xea\\xb7\\xad\"\n\"\\x28\\x10\\x80\\x64\\x77\\x6e\\xc7\\x69\\xdf\\x04\\x53\\xc1\\x0f\\x5e\\x7a\\xd3\"\n\"\\x1d\\x7a\\x40\\x44\\x3f\\x04\\x14\\x16\\x38\\x1a\\x03\\x2d\\x42\\x10\\xf6\\x67\"\n\"\\x3e\\x81\\x46\\x6b\\x57\\xaa\\x41\\x42\\x12\\x73\\x20\\x81\\x57\\x40\\x9c\\xc4\"\n\"\\x03\\xbd\\x0b\\x51\\xfd\\x87\\x6e\\xa4\\x78\\x14\\x67\\x11\\xed\\x79\\x92\\x39\"\n\"\\xa0\\xee\\xd1\\x18\\xf6\\x49\\x66\\xc8\\x1b\\x11\\xfd\\x6d\\x84\\x78\\xd6\\x28\"\n\"\\xc3\\xdf\\x35\\x64\\x0a\\x75\\x1f\\x30\\x1e\\x9a\\x58\\xb5\\x6e\\x29\\x75\\xed\"\n\"\\xfe\\x86\\x08\\xd2\\x29\\x4d\\xf2\\x94\\xa0\\x9a\\xa3\\x30\\x9f\\xb2\\x35\\x5b\"\n\"\\x6e\\x13\\x0c\\x40\\xdc\\x00\\x89\\x78\\xea\\xad\\x6b\\x59\\x6e\\xee\\x8d\\x77\"\n\"\\x43\\xd4\\xaa\\x69\\x9f\\x23\\xfd\\x92\\xe9\\xbb\\x3f\\x1e\\xbd\\xdc\\x94\\xdc\"\n\"\\x52\\x35\\xba\\xae\\x8c\\x03\\xf3\\x4f\\x4e\\x1a\\xb4\\xb2\\x70\\x58\\xf8\\xd8\"\n\"\\x01\\x6a\\x0a\\xc6\\xc5\\xc7\\x86\\x6e\\x9a\\x3b\\xd2\\x4a\\xdc\\x68\\xc2\\x7e\"\n\"\\xac\\x23\\x79\\x4c\\x03\\xf9\\x2a\\x04\\xbe\\x57\\x7b\\x2a\\xbf\\xa4\\x1c\\x2e\"\n\"\\x9f\\x0f\\x87\\x78\\x0c\\x06\\x7e\\x35\\x43\\x78\\x94\\xe6\\x79\\x15\\xdc\\x94\"\n\"\\x38\\x80\\x75\\xed\\x25\\xe0\\x9c\\x0e\\xec\\xa5\\x07\\x73\\x19\\xa5\\x08\\x33\"\n\"\\x34\\xbb\\x88\\xc8\\x13\\xad\\x09\\xa8\\x04\\x7f\\x0e\\xf9\\xf2\\x01\\x76\\xf5\"\n\"\\x3d\\xd8\\x25\\xa3\\x8a\\x6b\\xce\\xa6\\xb2\\x91\\x53\\xb6\\x11\\x1d\\xd9\\xd1\"\n\"\\x4d\\x63\\x20\\xd8\\x81\\x0a\\x26\\x50\\xfc\\xd4\\x08\\x8c\\x97\\x8e\\x6a\\xf4\"\n\"\\x8f\\xd2\\x81\\xea\\xcc\\xfd\\x14\\x07\\x76\\xcb\\xcb\\xdc\\x30\\x13\\x6d\\xdd\"\n\"\\x46\\x56\\x90\\x26\\x1f\\xa5\\x72\\x89\\x0f\\xfa\\x63\\x2e\\xd5\\xab\\x7d\\x94\"\n\"\\xe7\\x39\\x1c\\x92\\xd5\\xea\\xcb\\x5e\\x33\\x86\\x7d\\xf6\\x5d\\x1f\\xb9\\x01\"\n\"\\x27\\xb2\\xb3\\xff\\x70\\xd0\\x49\\x07\\x3c\\x3d\\xcf\\xf9\\xb2\\x85\\x2c\\x8b\"\n\"\\x13\\xa4\\x38\\xef\\xfb\\xcb\\x1a\\x2a\\x82\\x3a\\x05\\x4a\\x58\\x3c\\x70\\x9e\"\n\"\\x09\\x74\\xbf\\xd2\\x53\\x69\\xec\\x87\\x18\\xf5\\xd1\\xcc\\x0c\\x6c\\xe7\\x2b\"\n\"\\x10\\x04\\x55\\x85\\xe1\\x68\\x4e\\x65\\x49\\x88\\x11\\x1b\\x00\\xea\\xfa\\xb5\"\n\"\\x9f\\xca\\x6b\\x95\\x6e\\x20\\x59\\xea\\x88\\x9a\\xd3\\xbc\\x6e\\xdd\\x92\\xb9\"\n\"\\x15\\x58\\xf1\\x94\\x52\\x23\\xb5\\x7d\\xd5\\x70\\x83\\x26\\xb5\\x16\\x60\\x61\"\n\"\\x3e\\xe7\\xd7\\x40\\xbc\\x81\\x15\\x65\\xc3\\xe8\\xdb\\xd0\\x1e\\x4f\\xd7\\xe1\"\n\"\\xa6\\x35\\x53\\xf0\\x34\\xbc\\xa6\\xa7\\xf5\\x9c\\x0b\\x5d\\x41\\x49\\xdd\\x74\"\n\"\\xf6\\x35\\xb9\\x20\\x76\\x0a\\x91\\x98\\xf6\\x23\\xc6\\x37\\x22\\xb5\\x47\\xc9\"\n\"\\x78\\x75\\x86\\x6d\\x7b\\xc0\\xbf\\x66\\x5a\\x5e\\x65\\x58\\x79\\xf2\\xf4\\x1e\"\n\"\\x79\\x46\\x83\\xec\\xfc\\xbd\\xae\\x02\\x27\\xe6\\xca\\x66\\xec\\x0c\\x46\\x76\"\n\"\\xb9\\x8b\\xc1\\xb5\\xfd\\x0d\\x92\\x8d\\x1e\\xdc\\x22\\x6a\\xa5\\x4b\\x82\\x54\"\n\"\\xca\\xcc\\xfb\\xe6\\x71\\xba\\x6e\\xce\\x77\\xc7\\x3b\\xab\\xe0\\x3b\\x6f\\x39\"\n\"\\xf0\\xef\\xd7\\x90\\x51\\xb4\\xa7\\xcd\\x36\\xb1\\x54\\x9f\\x39\\x19\\x3d\\x87\"\n\"\\x0f\\xc0\\xf0\\x34\\x49\\xc3\\xf6\\x04\\x0e\\x9e\\x05\\xb7\\xb7\\x69\\xf5\\x44\"\n\"\\x97\\xab\\x6b\\x38\\x6d\\x57\\x82\\x60\\x5c\\x70\\xa5\\x5e\\xc7\\x4e\\xba\\x3f\"\n\"\\xdf\\x0b\\xd5\\x60\\x74\\x76\\x3f\\x44\\xf9\\x23\\x08\\x68\\x02\\x04\\x1a\\x42\"\n\"\\x7a\\xe0\\x68\\xc8\\xb3\\x0c\\x71\\x13\\x29\\xf1\\xf6\\x92\\x35\\xe8\\xd8\\xcd\"\n\"\\xb3\\x0b\\xee\\xaa\\xf7\\x05\\xe7\\xb2\\xd1\\x27\\x5c\\x08\\x10\\x9d\\x51\\x23\"\n\"\\x83\\x7a\\xe6\\xda\\xf5\\xac\\x25\\x03\\xef\\x2e\\x8c\\x6d\\x34\\x04\\x33\\xf2\"\n\"\\x28\\x6f\\x46\\x2e\\xed\\x23\\x12\\x8f\\x50\\xe1\\x14\\xe6\\x1a\\x49\\xc5\\x46\"\n\"\\x50\\x09\\xab\\xb0\\x6e\\x43\\x48\\xaa\\x9e\\xb3\\x91\\x06\\x16\\xc5\\xca\\x52\"\n\"\\x75\\x4a\\x7a\\x79\\x53\\x91\\x3f\\x6e\\x01\\xfd\\xab\\x0e\\xd6\\x84\\x48\\x94\"\n\"\\xa5\\x95\\x11\\x94\\xdd\\x59\\x36\\x75\\x68\\x07\\xbd\\x4e\\x2a\\xa5\\x88\\x7a\"\n\"\\xbc\\x78\\x05\\xec\\x08\\x08\\x71\\xe7\\x93\\x9e\\x2e\\x45\\xbd\\xf7\\x5f\\x86\"\n\"\\x83\\xb2\\x6f\\xfd\\x65\\x1a\\x6c\\x6e\\xab\\x15\\x25\\xa8\\xf7\\x9d\\x6e\\x7b\"\n\"\\x75\\xde\\x2f\\xcb\\xe9\\x15\\x4b\\x3a\\x61\\x97\\x36\\xf3\\xbb\\xa2\\x2d\\x96\"\n\"\\x09\\x99\\x3c\\x6b\\x10\\x9e\\x49\\xdb\\x19\\x4b\\xfb\\xe7\\x71\\x04\\xf0\\xbd\"\n\"\\xb4\\xcd\\x68\\x7e\\xf7\\xa0\\xc5\\x1f\\x09\\x11\\x57\\xc9\\x91\\x19\\x1d\\x91\"\n\"\\xaa\\x28\\xa5\\x6e\\x93\\x04\\x89\\x65\\x59\\xaf\\x75\\x62\\x81\\x53\\x07\\xb4\"\n\"\\xc9\\x42\\x60\\x9f\\x00\\x60\\xb0\\x95\\xfc\\xb1\\xbf\\xf6\\x95\\xc5\\x3a\\xa9\"\n\"\\xf4\\x03\\x4d\\x22\\xbb\\xb8\\x83\\x3c\\x11\\xdb\\xb9\\x58\\x36\\x6f\\xe0\\xa7\"\n\"\\xe3\\x98\\xd6\\xa3\\x0e\\x35\\x82\\xcb\\x4c\\xc9\\x5c\\xd3\\x41\\x3b\\xb6\\x9b\"\n\"\\x48\\x2b\\x34\\xa9\\x0e\\xfd\\xc4\\x5e\\xc8\\x11\\xa6\\xc0\\xdf\\xd7\\x01\\xb9\"\n\"\\xd2\\xab\\x7c\\xd4\\xee\\x09\\x8a\\x5f\\x79\\xb4\\xd2\\x4e\\x59\\x08\\xd4\\xca\"\n\"\\xfc\\x4b\\x8d\\x32\\x14\\x10\\xad\\x1a\\x41\\xb0\\xd0\\x3e\\xce\\xf6\\x5c\\x5d\"\n\"\\xf4\\x90\\x5c\\x5b\\x72\\x52\\x98\\xe0\\xb2\\x1a\\x30\\x2e\\xf6\\x95\\x48\\x36\"\n\"\\x0c\\x9f\\x01\\x20\\x11\\xe2\\x39\\xde\\x5d\\xfd\\x8c\\xfa\\xeb\\xb7\\xcf\\xc1\"\n\"\\x96\\xea\\x70\\x42\\x82\\x1f\\xac\\xa1\\x43\\x85\\x36\\xba\\x5b\\x90\\xc4\\xd5\"\n\"\\xc4\\x98\\xf5\\x63\\x3a\\x39\\xf9\\x15\\xee\\x34\\x26\\x76\\x62\\xf3\\xfe\\xce\"\n\"\\x7c\\x46\\x33\\x8d\\x6a\\x58\\x23\\x11\\xf3\\x55\\x37\\x0d\\x58\\x52\\xef\\x6b\"\n\"\\x25\\x37\\x3d\\xfb\\xe2\\xf6\\x7f\\x0d\\xb8\\xc4\\xcd\\x0e\\x14\\x8b\\x66\\x02\"\n\"\\xf2\\x9f\\x51\\xce\\x8d\\x8c\\x39\\xf7\\x9d\\xe6\\x38\\x55\\x1a\\x24\\xce\\x9d\"\n\"\\x96\\x8a\\x46\\x8f\\x72\\x80\\x0d\\x3f\\x90\\xf5\\x4f\\x2a\\xef\\x66\\x98\\xd0\"\n\"\\x4c\\x1b\\x77\\x73\\xe5\\xa2\\x3d\\x89\\xe5\\x2d\\x14\\x08\\x85\\xe5\\xc5\\x1f\"\n\"\\xc0\\x4d\\x60\\xad\\x5f\\x9d\\x92\\x84\\x45\\x18\\xec\\x0b\\x17\\xc1\\x50\\x22\"\n\"\\x43\\xc4\\x47\\x32\\x7d\\x18\\x2e\\xf0\\x6b\\x53\\xdd\\x02\\x24\\x96\\xc6\\xfa\"\n\"\\x5b\\x3c\\xd8\\x70\\x06\\x71\\xb7\\x4b\\xd2\\xe0\\x45\\xad\\x04\\x80\\x14\\x30\"\n\"\\x7b\\x38\\x9f\\x7c\\x7a\\xf9\\xe8\\x3c\\xac\\x46\\x58\\xb9\\x9f\\xfa\\x3a\\x38\"\n\"\\xdf\\x98\\xc4\\x13\\x28\\x46\\x74\\xa5\\x66\\xf0\\x25\\x3c\\xb2\\xfd\\xcd\\x20\"\n\"\\x5a\\x4e\\x43\\x6c\\x35\\x75\\x1c\\xb2\\x2c\\x69\\x03\\x9f\\x13\\x38\\x04\\xf6\"\n\"\\x87\\x32\\xb9\\x67\\xf6\\x1f\\x86\\x26\\xd4\\xdc\\x0e\\x66\\x4a\\x52\\xa0\\xac\"\n\"\\xb0\\x62\\x7d\\xd1\\xa2\\x48\\x6c\\xfe\\x27\\xe3\\xf6\\x8c\\x9b\\xe7\\x99\\x3d\"\n\"\\x0f\\x0e\\x16\\x04\\xb5\\xa0\\x17\\xe4\\x23\\xe1\\x3c\\xaa\\x25\\x50\\x44\\x45\"\n\"\\x72\\x17\\x03\\x03\\x05\\x4b\\xdf\\xa8\\x14\\xb8\\x38\\xdd\\x78\\x9c\\x0f\\x8e\"\n\"\\x92\\x94\\xb5\\x28\\x7b\\x8e\\xdd\\x08\\xc4\\xb9\\xdb\\x9c\\x2b\\x94\\x2b\\x80\"\n\"\\xd6\\xbe\\x63\\xf2\\x43\\x04\\x55\\xee\\x6f\\x4c\\x6b\\x49\\x32\\x20\\xf3\\x95\"\n\"\\x65\\xee\\x63\\x30\\x0b\\x34\\x3b\\xfe\\x70\\x3a\\x81\\x6e\\x6a\\x61\\x2e\\x46\"\n\"\\x08\\x44\\xdc\\x34\\xf0\\x8f\\xa7\\x6d\\x2e\\xb4\\x23\\xa8\\x6a\\x77\\xd0\\x2a\"\n\"\\x5a\\xbc\\x6b\\x46\\x33\\xf5\\x5a\\xb3\\x16\\x20\\xa4\\xdd\\x39\\xcc\\x1c\\x77\"\n\"\\x54\\x5e\\x86\\x38\\x79\\x7d\\x7b\\xae\\xed\\x1d\\x77\\xc4\\x2c\\x49\\x2f\\xb6\"\n\"\\xc0\\x58\\x62\\x9d\\x2b\\x02\\xf5\\x57\\x10\\xe9\\x39\\x65\\x43\\x99\\x66\\x38\"\n\"\\x5f\\xf7\\xc0\\xa7\\xd0\\x3d\\xdd\\x42\\x88\\xa3\\xd8\\x86\\x01\\xcf\\x07\\x17\"\n\"\\x86\\xa8\\xe5\\xed\\xc7\\xd9\\xdd\\xc4\\xfe\\x43\\x88\\x51\\x56\\x48\\x6b\\x40\"\n\"\\xd0\\x98\\xc2\\xf7\\xb5\\xa5\\x6b\\x3f\\xdd\\xb6\\x56\\x28\\xac\\x45\\x4b\\xd8\"\n\"\\xc5\\x16\\x42\\x2c\\x4e\\x33\\xa8\\x54\\xf3\\xb2\\xac\\xc6\\x24\\xd1\\xeb\\xb0\"\n\"\\x2a\\x06\\x24\\x4b\\x0c\\x1f\\x5a\\xc3\\xa1\\xa5\\x18\\x69\\xad\\x32\\xc2\\xcd\"\n\"\\x29\\x37\\xe8\\x33\\x53\\x04\\x12\\xd7\\xe5\\x26\\x7c\\x8d\\xb0\\x2a\\x40\\x44\"\n\"\\x36\\x0b\\x20\\x60\\x58\\xab\\xb2\\x06\\x8d\\xd3\\x42\\x5d\\x5f\\x85\\x57\\xf6\"\n\"\\x1f\\x88\\x34\\xb6\\xad\\x01\\xd7\\xc8\\x33\\xea\\x96\\x3c\\x09\\x16\\xb5\\x59\"\n\"\\x35\\x13\\xfd\\x5e\\x59\\x2a\\xd9\\x5d\\x89\\x45\\x23\\x63\\x06\\x4e\\x79\\xe9\"\n\"\\x94\\xa0\\x0f\\xe7\\x12\\x74\\xf3\\x38\\x97\\x51\\xb4\\xed\\x48\\xc9\\xcc\\x7a\"\n\"\\xe9\\xd7\\x8d\\x6d\\x5a\\xa3\\x1d\\x36\\xba\\xd8\\xa9\\x58\\x0b\\x05\\x32\\x51\"\n\"\\xc4\\x14\\x04\\x3b\\xbe\\x50\\xf5\\x15\\xcf\\xa6\\xea\\x18\\x06\\xfd\\xde\\x06\"\n\"\\x8a\\xcc\\xed\\x67\\xe3\\x58\\x48\\xd8\\x5c\\xf8\\x60\\x28\\x17\\xcd\\xbf\\x49\"\n\"\\xc8\\xaf\\x7f\\x9e\\x81\\xe7\\x04\\x3e\\x31\\xc6\\xfe\\x32\\x35\\xcb\\xd7\\x39\"\n\"\\x9a\\xc9\\x34\\x9c\\x1f\\x83\\x21\\x66\\x39\\x39\\xc4\\xd2\\x40\\x25\\x06\\x84\"\n\"\\xdc\\xca\\x1a\\x99\\xee\\x88\\xdd\\x81\\x5d\\xea\\x1a\\xda\\xa7\\xa0\\x43\\xa6\"\n\"\\x46\\xa4\\x08\\xbc\\x1c\\x2d\\x99\\x5c\\x71\\xfd\\x31\\xb1\\xd1\\xbb\\xcd\\xba\"\n\"\\x7d\\x7d\\x94\\x8a\\x07\\x38\\x7e\\x69\\x98\\x5e\\xdc\\xb5\\x68\\xe1\\x67\\x24\"\n\"\\x24\\x53\\xe7\\x08\\xf5\\x04\\x09\\xe4\\x75\\xf7\\x4d\\x8a\\x43\\x5f\\x2f\\xe7\"\n\"\\xf1\\x62\\xd5\\x7a\\x67\\xdc\\xf6\\xbc\\x04\\x03\\x75\\xc6\\xf9\\xd4\\xa3\\x49\"\n\"\\x16\\x2c\\x82\\x01\\x27\\x30\\xf7\\x7c\\x1d\\xb5\\xcd\\x72\\xd5\\xc2\\xfe\\x8e\"\n\"\\x3e\\xf2\\xf3\\x1a\\xda\\xc2\\x0a\\xa2\\x30\\xf3\\x3f\\x4b\\xa4\\xf1\\x91\\x27\"\n\"\\x9f\\xe4\\xac\\x1e\\xe6\\xaf\\xaa\\x3f\\x47\\x9d\\x84\\x83\\x79\\xd2\\xe4\\x3f\"\n\"\\xd4\\xf4\\x66\\x1d\\x44\\xea\\xa0\\xd4\\x96\\x2a\\x3a\\xf3\\x5d\\xeb\\x88\\xd3\"\n\"\\x42\\x10\\x79\\xf1\\xb5\\xdc\\xfc\\x48\\xbf\\x18\\x25\\x19\\x40\\x1e\\x9a\\x30\"\n\"\\x40\\xf8\\xc9\\xd4\\xe0\\x4b\\x6a\\x39\\x70\\xa4\\xfe\\x57\\x87\\x69\\x39\\xf3\"\n\"\\x36\\xd9\\xec\\x22\\xfe\\x5d\\x2d\\xdd\\x20\\xe7\\x5b\\x2d\\x6f\\x7f\\x78\\xf4\"\n\"\\x34\\xfb\\xcc\\x32\\x13\\x92\\x6a\\x7f\\xa5\\xe0\\xdb\\x8b\\xf1\\x2d\\xe8\\xbe\"\n\"\\xfd\\x66\\x44\\xad\\x8b\\xc3\\x0d\\x1b\\x25\\x89\\xbe\\x98\\x4b\\x50\\xca\\x56\"\n\"\\x40\\x9d\\xc4\\x96\\x46\\x4f\\x6b\\x65\\x3b\\xae\\x9a\\x8f\\xa9\\x7d\\xde\\xbb\"\n\"\\x71\\xd7\\x84\\x14\\x75\\x39\\xb1\\xa1\\x4d\\x74\\x1f\\xaa\\x25\\x5c\\x04\\xeb\"\n\"\\x35\\x1c\\x5a\\x31\\x21\\x52\\xd4\\x4c\\xc8\\x50\\x9b\\x0e\\x54\\x04\\x71\\xeb\"\n\"\\xe0\\xc2\\x99\\xca\\x87\\xf0\\x9a\\x89\\x68\\x20\\x13\\x71\\x93\\xf0\\xce\\xd1\"\n\"\\x9c\\xd6\\x8d\\x39\\xad\\x4c\\x32\\xad\\xab\\x30\\xb2\\x12\\xbd\\xa7\\xe2\\xe4\"\n\"\\xcd\\x25\\xf1\\x9b\\x5b\\x31\\xe1\\x5e\\x2f\\xd9\\xad\\x08\\x1d\\x10\\x86\\x2f\"\n\"\\x4d\\xc5\\xd1\\xea\\xf9\\xa2\\x91\\x15\\x98\\xa8\\x30\\x05\\x45\\x4d\\xab\\x1e\"\n\"\\x20\\x31\\xef\\xe2\\x3e\\x56\\x7f\\xbb\\xf8\\x02\\xe3\\x84\\x53\\x40\\xaf\\x48\"\n\"\\x8e\\x7c\\xe0\\x91\\x80\\x29\\x9a\\x4c\\x8b\\x8b\\x29\\xbf\\x61\\xa3\\x41\\x01\"\n\"\\x0f\\x95\\x09\\x1c\\x97\\x32\\xd9\\x59\\x13\\x3d\\xd0\\xe7\\x9c\\xbb\\x72\\x9b\"\n\"\\x56\\x10\\x5a\\xcd\\x8d\\x97\\xc3\\xe2\\x52\\xc9\\x23\\xc6\\x65\\x90\\xee\\x4a\"\n\"\\xc3\\xe9\\xea\\x6b\\x17\\x89\\xd8\\xca\\xbb\\x8a\\x4d\\xa5\\x81\\x3b\\x5e\\x6e\"\n\"\\x69\\xf2\\xa0\\x0a\\x5e\\x37\\x90\\xb7\\x89\\xf0\\x1c\\x58\\xbb\\x4e\\xbf\\xaa\"\n\"\\x35\\x86\\xc6\\xf5\\x8d\\x63\\x62\\x5f\\xe9\\xd6\\x62\\x5c\\xba\\xf3\\x0a\\xa1\"\n\"\\x55\\x02\\x33\\x83\\x8e\\x0c\\x7b\\x1b\\xd9\\x66\\xa3\\xed\\x90\\x08\\x6f\\x02\"\n\"\\x05\\x99\\xbf\\xa5\\x96\\x8d\\xe6\\x3f\\x42\\xbd\\x75\\x50\\xc8\\x88\\x0d\\x24\"\n\"\\x9a\\xee\\xbf\\x9e\\x91\\x0f\\x9b\\x89\\x29\\xeb\\x9c\\x82\\x3b\\xf8\\x9a\\x93\"\n\"\\xba\\x91\\xa3\\xaf\\x19\\x25\\xb6\\xcd\\x64\\x89\\x76\\x03\\x3c\\xa0\\xc3\\xeb\"\n\"\\xa2\\x2b\\xc1\\x0a\\xe6\\x3d\\xf4\\x5a\\x47\\xda\\xc7\\x3f\\x88\\x13\\xb6\\x61\"\n\"\\x0f\\x2c\\xed\\x94\\x64\\xde\\x4b\\xab\\xfc\\x48\\x20\\x55\\x27\\x2b\\x08\\x7f\"\n\"\\x72\\x66\\x92\\xa5\\xc5\\x55\\x12\\x72\\x5f\\xb0\\x4f\\x1d\\x08\\x7e\\x8b\\xe0\"\n\"\\x30\\xdd\\x25\\x60\\x13\\x3a\\x45\\x69\\x07\\x42\\xe2\\x5b\\xac\\x7a\\x78\\x39\"\n\"\\x53\\xc2\\xe5\\xd7\\xbb\\x8f\\x7b\\xd4\\x8e\\x09\\xc0\\x54\\xca\\x6b\\xaf\\x0f\"\n\"\\x95\\x67\\xce\\x78\\xc1\\xe7\\x0f\\x8c\\x15\\x20\\xfd\\x61\\x19\\xd7\\xda\\x49\"\n\"\\x0b\\xaf\\x24\\x44\\x7e\\x88\\xb9\\x7d\\x77\\x4a\\x7d\\x64\\xac\\xd5\\x67\\xd5\"\n\"\\xe7\\x05\\xb3\\x90\\xa3\\x68\\xfd\\xf9\\x35\\x6c\\xfc\\x60\\x9e\\x47\\xa6\\xb3\"\n\"\\x2f\\xab\\xe2\\xe7\\x68\\x2a\\xb7\\x0b\\xc0\\x30\\xdf\\x63\\xf3\\x63\\x4b\\xfd\"\n\"\\x8e\\xd4\\x84\\x36\\x84\\x5e\\x9d\\x2a\\xa4\\x56\\x9e\\xb0\\xe4\\x75\\xaa\\xca\"\n\"\\xde\\x1e\\x0c\\x46\\xd7\\xf4\\xf6\\xaa\\xa9\\xd8\\x41\\x9e\\x59\\x36\\xfe\\xac\"\n\"\\xef\\x6f\\x9c\\x46\\x29\\x21\\xc2\\x60\\xf4\\xc0\\x2d\\x67\\x26\\xce\\x19\\x9e\"\n\"\\xa5\\xb9\\xf7\\x35\\x0b\\x33\\x42\\x5b\\xd3\\xb7\\x46\\x25\\x93\\x8d\\x95\\x30\"\n\"\\x0a\\x38\\x5c\\x07\\x7b\\x7a\\x21\\xfa\\xe0\\x3c\\xcd\\x24\\x8a\\x22\\xb0\\x87\"\n\"\\xf5\\x52\\x99\\xcc\\x0a\\x25\\x07\\xef\\xc1\\x18\\xbd\\x55\\xf3\\x66\\x0d\\x20\"\n\"\\x08\\x40\\x7e\\xf1\\xb3\\x90\\x24\\xef\\xf0\\xb0\\xa2\\xc5\\x4f\\xf1\\x91\\x91\"\n\"\\xde\\x69\\xd3\\x27\\x15\\x1c\\x18\\x22\\x06\\x84\\x7f\\x32\\xac\\x07\\xc0\\x4e\"\n\"\\xd2\\xbf\\x6e\\x19\\x01\\xed\\xfc\\x44\\x77\\x61\\x52\\x85\\x83\\x07\\x68\\x25\"\n\"\\x1d\\xde\\xd1\\xea\\xb2\\xb4\\x57\\xa3\\x11\\x0f\\x60\\xa7\\x64\\x64\\x2b\\x12\"\n\"\\x34\\xaf\\xb4\\x51\\x1d\\xeb\\xf4\\x87\\xd9\\x41\\x7b\\xc1\\x20\\xaf\\x41\\xdc\"\n\"\\xe0\\x84\\xc1\\x1c\\xeb\\xd9\\x8d\\x97\\xae\\x37\\x51\\x83\\xcd\\x8c\\xaf\\xef\"\n\"\\xaf\\xfc\\x32\\x6e\\xea\\x9a\\xc4\\xd2\\x1d\\x6d\\x91\\x48\\x6a\\x42\\x9b\\x0d\"\n\"\\xd7\\xe0\\x12\\x79\\xbd\\x48\\xdd\\xde\\xb1\\x02\\xd2\\xbb\\xdc\\x49\\xd9\\x6b\"\n\"\\xd7\\x5b\\x61\\x87\\xeb\\xbd\\x82\\xec\\x28\\x83\\x86\\x43\\x0f\\x1b\\x0a\\x7f\"\n\"\\x31\\x73\\x85\\x89\\x8b\\xd6\\x48\\x1d\\xfa\\xd5\\xdd\\x6d\\x3e\\x39\\x8b\\x9b\"\n\"\\xd6\\x13\\xbf\\xc8\\x54\\x97\\x96\\x47\\x34\\x84\\xb9\\xe5\\x78\\x3c\\xed\\xd8\"\n\"\\xd8\\xb4\\x8e\\x43\\x6b\\xb2\\x9f\\xf2\\xe2\\x72\\x79\\x45\\xc6\\xfb\\xcc\\xe4\"\n\"\\xf7\\x78\\x81\\x72\\x46\\x81\\x89\\xf3\\xf7\\xca\\x9f\\xed\\xd5\\x1c\\xc1\\xf8\"\n\"\\x6d\\x86\\x08\\xdc\\x63\\x5d\\xc5\\x1e\\xd1\\x79\\xec\\x22\\xbc\\xde\\xce\\x67\"\n\"\\x49\\x44\\xf2\\xe4\\xc6\\xdc\\x36\\x64\\x92\\x4e\\x2e\\xf0\\xc0\\x04\\x88\\xc5\"\n\"\\x3d\\x17\\x03\\x03\\x05\\x4b\\x17\\xdc\\x13\\x16\\x8a\\x2f\\x4d\\x2c\\xde\\x49\"\n\"\\x69\\xdd\\x5d\\xd0\\x30\\x98\\x31\\x8a\\x37\\x12\\x38\\xeb\\xb3\\x8a\\x48\\x8e\"\n\"\\x46\\x1a\\x4d\\xab\\xb1\\xba\\xd3\\x89\\x61\\xa2\\x58\\xc3\\xd0\\x78\\x80\\xf1\"\n\"\\x79\\x6c\\xfc\\x58\\x08\\x59\\xeb\\x78\\x3e\\x46\\x3d\\x44\\x66\\xb5\\xaf\\xaf\"\n\"\\x0f\\x07\\xba\\x2c\\x6e\\x3f\\xb9\\x40\\xd8\\xb6\\x4e\\x87\\xc5\\x50\\x35\\x09\"\n\"\\x55\\x3f\\x95\\xfd\\x15\\xa8\\xa5\\x94\\xe0\\xf9\\x71\\xd8\\x6a\\x00\\xa1\\xfd\"\n\"\\x11\\x3a\\xeb\\x1b\\xd1\\xac\\x3b\\xe8\\x35\\x61\\xbe\\xe7\\xcf\\x0e\\x93\\x89\"\n\"\\xe0\\xc6\\xa1\\xf7\\xab\\xe7\\x67\\xc8\\x72\\x07\\x19\\x57\\x54\\x21\\x80\\x38\"\n\"\\x3f\\x20\\x3d\\x23\\x3d\\xa1\\xe3\\x21\\x8b\\x77\\x61\\x5f\\x25\\x15\\xe1\\xc2\"\n\"\\x46\\xb9\\xca\\x0c\\x1d\\x12\\x54\\x8e\\xcb\\xec\\xb8\\x14\\xf4\\xd1\\xac\\x5e\"\n\"\\x08\\xb6\\xc2\\x0e\\xed\\xc4\\x1f\\x43\\xbe\\x2f\\x98\\xa7\\x6e\\x1f\\x02\\xe4\"\n\"\\xfe\\xd2\\x42\\x0b\\x9e\\xd2\\x25\\x8f\\xc2\\x1b\\x1c\\xd6\\x91\\x80\\xe1\\x76\"\n\"\\xc6\\x38\\xc6\\x5a\\x02\\x7a\\x25\\xe2\\x39\\x6f\\x64\\xfc\\xaf\\x58\\xd4\\x1a\"\n\"\\xb1\\x40\\xc4\\x82\\x9f\\x47\\x31\\x2b\\x14\\x08\\xf0\\xc0\\x6d\\x37\\xd5\\x33\"\n\"\\x52\\x1b\\x42\\x69\\x61\\x16\\x81\\x4d\\xa7\\x56\\xe2\\x89\\x46\\x11\\x63\\x03\"\n\"\\x04\\x6a\\x9b\\x2f\\xc5\\xa1\\x2d\\xca\\x6e\\x07\\xf5\\xe8\\x38\\xb9\\xb3\\xfa\"\n\"\\xe4\\x09\\xec\\x01\\x17\\x84\\x7c\\x6b\\x4f\\xce\\x15\\xd4\\x3c\\x57\\x95\\x48\"\n\"\\x2b\\x6f\\x55\\xec\\xb9\\x38\\x8e\\xb1\\xce\\xab\\xde\\x41\\x65\\x38\\xe8\\x5a\"\n\"\\x1f\\xb8\\x91\\x7e\\x64\\x25\\x1c\\x3a\\x29\\xf1\\x38\\x75\\x78\\xd1\\xc3\\x2a\"\n\"\\x07\\x58\\xa4\\xe0\\x19\\x41\\x21\\xf6\\x11\\x33\\x82\\x8a\\x60\\xf4\\x3f\\x75\"\n\"\\xaf\\xae\\x33\\x4b\\xb6\\xcd\\x1f\\xf7\\xee\\x14\\x15\\xef\\x49\\x4b\\xc2\\x72\"\n\"\\x3b\\xab\\x40\\x1e\\x20\\xf0\\xb8\\x8d\\x10\\xc7\\x79\\x28\\x35\\xea\\xad\\x6d\"\n\"\\x2e\\xc0\\xf5\\xec\\x9d\\x8b\\xe6\\x4b\\xd2\\xb9\\xb3\\x29\\xc1\\xc0\\x74\\x15\"\n\"\\xb7\\x24\\x11\\x41\\x03\\x52\\x38\\xc7\\x6b\\xad\\x2f\\x2c\\xac\\x5e\\x1f\\xad\"\n\"\\xd6\\x21\\x5e\\x80\\x13\\x3a\\x90\\x3d\\xcc\\x42\\xf2\\xd3\\x4b\\x4b\\xe0\\xf1\"\n\"\\x03\\x3c\\xef\\xfb\\xa4\\x6e\\xdf\\xe3\\xdc\\x59\\xc8\\x57\\xe6\\x7c\\x08\\x6b\"\n\"\\x98\\x92\\xf0\\xde\\xa7\\x87\\x2a\\x0e\\xb9\\x63\\xa7\\x81\\x9c\\xad\\x52\\xc5\"\n\"\\x8f\\x6a\\x7f\\xc2\\x09\\xec\\xcd\\x23\\x36\\x19\\x57\\x37\\xbe\\x3e\\xa8\\x64\"\n\"\\xd8\\xa3\\x8d\\xbd\\x63\\x2d\\x1d\\x6f\\xd0\\x61\\x1f\\x16\\xd3\\xab\\x76\\x08\"\n\"\\x53\\xa4\\x4e\\x74\\x14\\x62\\x8c\\xc2\\xc8\\xba\\x63\\xd4\\x55\\xf1\\x4a\\xa7\"\n\"\\x48\\x2c\\xc7\\x7b\\x8c\\xa5\\x5d\\x60\\x30\\x8e\\xbe\\x67\\xc3\\xac\\x0c\\x74\"\n\"\\x4c\\x39\\xe8\\x15\\xb9\\xb0\\x71\\xf7\\x86\\x1a\\x46\\xff\\xbe\\x33\\x8f\\x9a\"\n\"\\xa8\\x2a\\x72\\x4a\\x6e\\x01\\x5b\\xe6\\x4b\\x3f\\x52\\x92\\x45\\x33\\x10\\x92\"\n\"\\x64\\xff\\xa0\\xa9\\xc9\\x84\\x7b\\x12\\x51\\x2f\\x09\\xb2\\xbd\\x23\\xda\\x40\"\n\"\\xe1\\x50\\x65\\x3e\\x35\\x69\\x5d\\xc9\\xce\\x97\\x8a\\xc7\\xc8\\xdd\\x28\\x9d\"\n\"\\x38\\x80\\x07\\x37\\x8d\\x5f\\x96\\xf9\\x0c\\xb2\\xb2\\xaa\\x38\\x33\\x29\\x89\"\n\"\\x9f\\xab\\x27\\xba\\x51\\x0c\\xb5\\x5a\\x75\\x7d\\xfd\\x4f\\x8b\\x6a\\xde\\x6f\"\n\"\\x28\\x6b\\x12\\xab\\x7a\\x06\\x4e\\x5a\\xbd\\x2a\\xb8\\x82\\xe0\\x58\\xd6\\x71\"\n\"\\x1c\\xfb\\x2a\\x33\\xf9\\x21\\xd0\\x3a\\x1a\\x7b\\xcd\\x0d\\xcd\\x3b\\x13\\x29\"\n\"\\x93\\x43\\x38\\x7a\\x96\\x59\\x0b\\x44\\x03\\x91\\xe3\\x5e\\xb8\\x4e\\xf8\\x0a\"\n\"\\xe7\\xe4\\x6e\\x91\\x03\\x22\\x25\\xa6\\x22\\x05\\x52\\x11\\xc0\\x43\\xfc\\xe3\"\n\"\\xae\\x92\\x5f\\x9c\\x80\\xe7\\x33\\xf7\\x2d\\xb5\\x6c\\x23\\x36\\x65\\xab\\x74\"\n\"\\xcc\\x37\\xde\\x7a\\x74\\x54\\x3f\\x2e\\x2e\\x38\\x45\\x74\\xcc\\xda\\xa9\\x61\"\n\"\\xf8\\xe8\\x7e\\x62\\x5c\\x8a\\x5c\\xf6\\x0b\\xd1\\xbd\\x1f\\x45\\xce\\x76\\xd9\"\n\"\\xf2\\xa0\\x86\\x72\\xea\\x33\\x62\\xa0\\x01\\x31\\xa5\\x16\\xdd\\xb2\\x54\\x76\"\n\"\\x58\\x59\\x26\\x41\\x43\\x16\\x1e\\x69\\x21\\x79\\xeb\\xe8\\xac\\x66\\xba\\x4b\"\n\"\\xd7\\xd4\\xb6\\x41\\x66\\x1f\\x89\\x89\\x0f\\xf7\\xbc\\x65\\xda\\x8c\\xa1\\x67\"\n\"\\x0f\\x0a\\x37\\xe8\\xa5\\x0c\\xb7\\x2b\\x58\\xb1\\x9e\\xca\\xfe\\x9d\\x73\\xd1\"\n\"\\x83\\xa7\\x5e\\xaf\\x33\\xc4\\xfb\\xff\\x03\\x89\\x2a\\x60\\x55\\x07\\x0b\\x25\"\n\"\\x81\\x5a\\x55\\xba\\x6b\\xcd\\xff\\xf0\\xd1\\x81\\x61\\x0d\\x3e\\x00\\x4c\\x51\"\n\"\\xba\\x29\\xc0\\xaa\\x98\\x33\\x6b\\xff\\x68\\x2c\\xcc\\x0c\\xd3\\x40\\x7c\\x9e\"\n\"\\xe1\\x71\\x0b\\x08\\x03\\xb7\\x29\\x56\\x5e\\x92\\x90\\xc7\\x8f\\xe8\\xd8\\xf4\"\n\"\\xb6\\xe6\\x40\\xf6\\x49\\x7a\\xf9\\x62\\x8d\\xd0\\x83\\xb7\\x76\\x95\\x6e\\x9b\"\n\"\\xc9\\xf4\\x56\\x03\\xe0\\x80\\xca\\x12\\x0f\\xda\\x9e\\x35\\x5a\\xfd\\x9e\\x6e\"\n\"\\x8b\\xd5\\xf6\\x9e\\xab\\xb6\\xd3\\xd5\\xff\\x8a\\xdb\\x7c\\x85\\x4a\\xa0\\xb5\"\n\"\\xd0\\x76\\xb2\\x8e\\x4c\\x73\\x9f\\x53\\x0a\\x9d\\x65\\xd8\\x2e\\xf3\\x95\\xb6\"\n\"\\x9e\\x1a\\xd0\\xb1\\xfb\\xa0\\xcc\\xa6\\xed\\xbc\\xd1\\x59\\xdb\\x43\\x73\\x10\"\n\"\\x80\\xe9\\xd7\\xd4\\x7d\\xa3\\x0c\\x94\\xcc\\x3a\\x19\\xd8\\x25\\xdb\\x9f\\xcc\"\n\"\\x88\\xe1\\x61\\x97\\x81\\x87\\x78\\x83\\x46\\x51\\xbf\\xa1\\x9f\\x8c\\xcb\\x63\"\n\"\\x77\\xfc\\x52\\x67\\x55\\xd3\\x24\\x1d\\xfc\\x4b\\x87\\x74\\x50\\xc0\\xc8\\x34\"\n\"\\x34\\x65\\x04\\x6c\\xda\\xcd\\x8b\\xd6\\x1b\\x01\\x5b\\x09\\x65\\x6b\\x63\\xda\"\n\"\\xac\\x3b\\xad\\x8d\\x02\\xab\\xd3\\x2c\\xd9\\x85\\xdb\\x05\\xb4\\x40\\xf6\\xde\"\n\"\\xc3\\x78\\xf8\\xff\\x23\\x60\\x65\\xd2\\x92\\x28\\xf6\\x1c\\x1b\\x1f\\x4a\\x06\"\n\"\\x1b\\xd6\\x51\\x17\\xb9\\xd7\\x4d\\x74\\xd5\\x7a\\xb3\\x42\\xb3\\xf6\\xbf\\xd9\"\n\"\\xaa\\x80\\x1d\\xd0\\x85\\xeb\\x79\\x24\\x06\\xa3\\xad\\x5a\\x62\\xb9\\x18\\x46\"\n\"\\x5e\\xe3\\x77\\x5c\\x39\\x45\\x69\\x64\\x16\\xd5\\xba\\x3c\\x6c\\xb7\\x02\\x47\"\n\"\\xb3\\xcb\\x95\\xa6\\x47\\x5d\\x5c\\xcd\\xdc\\xd5\\x6e\\xfd\\x9d\\xe2\\x76\\xef\"\n\"\\x1f\\xc7\\x66\\xc3\\xac\\xc9\\x20\\x37\\x14\\xa9\\x13\\x0c\\x6c\\xcf\\x81\\x13\"\n\"\\x95\\xff\\x68\\xf1\\x6d\\x97\\xe4\\x4e\\xc1\\x7f\\x7a\\x73\\x25\\xc3\\xcd\\x72\"\n\"\\x0e\\x59\\x8a\\xb8\\xb3\\xe4\\xd4\\x1b\\x21\\x7a\\x53\\x5a\\xee\\xc9\\x5a\\xdb\"\n\"\\xf1\\x79\\x03\\xd8\\xb8\\xba\\x6e\\x58\\xf9\\x9a\\x72\\xb4\\x62\\xf1\\x40\\xc2\"\n\"\\x28\\x2c\\x10\\xad\\x09\\x86\\xa3\\xda\\xc1\\x7f\\x6b\\xd6\\x94\\x3c\\x8a\\x45\"\n\"\\xbe\\x5a\\xea\\x80\\x79\\x79\\x87\\xd5\\xe7\\xc7\\x67\\x9c\\x85\\x91\\x65\\xf1\"\n\"\\xde\\xcc\\x0e\\x2a\\x6d\\x42\\x62\\x07\\x51\\x3a\\x2c\\xb9\\xc9\\x3f\\x62\\xe5\"\n\"\\x05\\x6c\\xb6\\x6c\\x52\\xf1\\x7d\\xe8\\xf4\\x7b\\xa6\\xf2\\x24\\x3f\\x06\\x6e\"\n\"\\x91\\x38\\x91\\xdf\\x58\\xef\\x04\\x54\\xc6\\x22\\x02\\x70\\x07\\x86\\xe7\\x3a\"\n\"\\x23\\x0d\\xab\\x7e\\x6d\\x20\\x07\\xf1\\x6f\\x15\\x4c\\x82\\xc3\\x9d\\x65\\xb0\"\n\"\\xb0\\x32\\x1f\\x82\\x64\\x10\\xb1\\x75\\x96\\x2d\\xd6\\x32\\x23\\x38\\x39\\xc5\"\n\"\\x60\\x2b\\x7e\\x1c\\xb3\\xd4\\x51\\xf0\\xad\\xfd\\x75\\x76\\xff\\x93\\x18\\xac\"\n\"\\x67\\x12\\xef\\x0b\\xd8\\x1a\\x1e\\xa2\\xfc\\xa2\\x78\\x21\\x56\\x5e\\x91\\x7c\"\n\"\\x66\\x75\\xbc\\xfe\\x99\\xd4\\x47\\x01\\x9d\\x67\\x84\\x6f\\x49\\x66\\x4f\\x1d\"\n\"\\x3d\\xe9\\x66\\x22\\xf3\\xac\\xc0\\xf5\\x69\\xb2\\xe6\\x59\\x21\\xe4\\xf9\\xc9\"\n\"\\x2e\\xc2\\x63\\x5a\\x70\\xf7\\x28\\x74\\xc5\\x2b\\xf9\\xb7\\xce\\x0b\\x7f\\xb7\"\n\"\\x51\\x60\\xe8\\xbc\\xe2\\x7b\\x0d\\x4f\\x2c\\x61\\xe7\\x49\\x04\\x41\\xe7\\xa2\"\n\"\\x04\\xdf\\x40\\x4c\\x7f\\x39\\x4f\\x20\\xc9\\x63\\x9a\\xb7\\x1f\\xbf\\x1a\\xe6\"\n\"\\xc8\\x17\\x03\\x03\\x05\\x4b\\xce\\xec\\x40\\xa0\\x91\\xad\\x95\\x8a\\x8b\\x25\"\n\"\\xfb\\x3f\\xef\\xfd\\x84\\x5e\\xca\\xe4\\x11\\xa3\\x65\\x27\\xf3\\x28\\x48\\x60\"\n\"\\x71\\xad\\x92\\xe7\\x6a\\x9c\\xfc\\xe1\\x0c\\x53\\x1e\\xaa\\xf8\\xe0\\xd7\\x67\"\n\"\\xbd\\x0f\\xaa\\x00\\x73\\x3e\\x67\\x80\\x0f\\x70\\xee\\xec\\x6f\\xe9\\xb6\\xff\"\n\"\\x85\\x6d\\x64\\xc7\\xcb\\xf2\\xb7\\xf3\\x1a\\x29\\x17\\xb3\\xeb\\x8d\\x73\\xba\"\n\"\\xaf\\xaa\\x8b\\x02\\x04\\x23\\xbf\\x89\\x2d\\x7c\\xd6\\x67\\x50\\xa1\\x22\\x5f\"\n\"\\x0e\\xeb\\x87\\xfd\\xd2\\xd7\\x55\\x1e\\xc0\\xb8\\xad\\x99\\xaf\\xb7\\xf6\\x74\"\n\"\\x41\\x7c\\xf6\\xb3\\x51\\xbc\\x90\\xc7\\xd6\\x00\\xca\\x7a\\x72\\x7e\\x2d\\x76\"\n\"\\x1e\\x81\\x9a\\xad\\x8d\\x69\\x4c\\xda\\x2f\\x40\\xa3\\x35\\x29\\x79\\xa8\\x15\"\n\"\\x38\\x6f\\x68\\xcb\\x7d\\xd1\\xe6\\xb3\\x9c\\x0f\\x95\\x4e\\x37\\x8f\\xf2\\xca\"\n\"\\xef\\xf8\\x1c\\xe9\\xda\\x51\\x18\\x60\\x66\\x26\\x3d\\xe1\\x6a\\xa5\\x7f\\x8f\"\n\"\\xce\\x8a\\x6a\\x59\\xef\\x8a\\x06\\xb9\\x67\\xa0\\x2a\\x27\\x9c\\xdd\\x6a\\x6b\"\n\"\\x51\\x31\\xc9\\x24\\x77\\x7c\\x83\\x98\\x82\\x99\\xa2\\x10\\xa7\\xa2\\xcb\\x22\"\n\"\\x00\\xef\\xf3\\x25\\x38\\xa7\\x6c\\x88\\x49\\x22\\xb1\\xd3\\x1b\\xaa\\x50\\xee\"\n\"\\x3b\\xfe\\xfe\\xaa\\x6f\\x03\\xf1\\x10\\x13\\x4e\\xa8\\x43\\x6f\\x9a\\x52\\x8d\"\n\"\\x75\\xba\\x0e\\x2a\\x13\\xbe\\x77\\x68\\x52\\x73\\x14\\x03\\x86\\xea\\x29\\xc0\"\n\"\\xb7\\x2b\\x0a\\x17\\x93\\x01\\x23\\xe4\\xe5\\x5a\\x19\\xcd\\xd1\\x08\\x02\\x6c\"\n\"\\x76\\x20\\xe6\\x62\\x9a\\x37\\x1a\\xb1\\xfc\\xe6\\xc9\\xf1\\xe6\\xab\\xc8\\xcd\"\n\"\\x16\\x89\\x77\\x8d\\xd5\\xb2\\x3e\\xa5\\xfe\\x71\\xb4\\xaf\\xc4\\x4b\\xd0\\x34\"\n\"\\xbd\\x10\\x40\\xe5\\x17\\x19\\x25\\x9d\\x67\\x72\\x0c\\x65\\x9e\\x5f\\xb1\\x9e\"\n\"\\xf0\\x0a\\x0a\\xfc\\x75\\x4b\\x19\\x0f\\xb3\\xc4\\xf1\\x1a\\x48\\xa4\\xe6\\x6d\"\n\"\\x10\\xbb\\x32\\x9d\\xc9\\x67\\xb8\\xad\\x32\\xc9\\x15\\x7f\\xea\\x2e\\xad\\x01\"\n\"\\x7d\\x2a\\x7f\\x73\\xbd\\x15\\x40\\xc2\\x70\\x08\\x57\\x50\\xf8\\xce\\x98\\x2b\"\n\"\\xa1\\xb4\\x26\\xe9\\xc4\\x4c\\x3e\\x54\\x90\\x9e\\xc0\\xb8\\xf0\\xbc\\x77\\x1e\"\n\"\\x0f\\xd9\\x35\\xd0\\x86\\x05\\x89\\x03\\xba\\x9a\\xab\\x0b\\xeb\\x52\\x13\\x95\"\n\"\\xcd\\xcc\\x6d\\x84\\xd4\\x6e\\xbe\\x23\\xf2\\x97\\x45\\xa5\\xfb\\xfc\\xff\\x6d\"\n\"\\x84\\xba\\xc4\\x9d\\x22\\x0e\\x0d\\x5a\\x5a\\x33\\x8a\\x95\\x53\\xdf\\x2d\\x71\"\n\"\\x1e\\x4b\\xea\\xfc\\xb4\\x80\\xd7\\xcb\\xe7\\x35\\x15\\x0d\\x63\\x56\\x99\\xc9\"\n\"\\x4a\\x15\\x0d\\xaa\\xdf\\x5f\\xc0\\xae\\x51\\xab\\x88\\x24\\xa7\\xae\\xd4\\x32\"\n\"\\xba\\xd5\\x0b\\xa9\\x48\\x00\\x79\\x0f\\xb1\\x68\\x5f\\xa6\\x08\\x24\\xdf\\x7c\"\n\"\\xc9\\xd9\\xa9\\x7b\\xe8\\xbd\\xa8\\xe6\\xc1\\x02\\xf3\\x15\\x9b\\xe0\\x79\\x27\"\n\"\\xaa\\xe0\\xbe\\x0d\\x6c\\x41\\x7d\\x5a\\xd4\\x03\\x0b\\x2e\\x80\\x35\\xfb\\xd7\"\n\"\\xba\\x22\\x53\\xf2\\xad\\x53\\x79\\xd1\\xc1\\x8a\\x37\\xaa\\xfb\\x1a\\x9f\\x77\"\n\"\\xa1\\x69\\xdc\\xdf\\x7b\\xa0\\x4f\\x58\\x2e\\x26\\x52\\x59\\xa7\\xe7\\x24\\xe7\"\n\"\\xa2\\xa7\\xf9\\xe9\\x37\\xb1\\x8c\\x4f\\x64\\x8a\\x62\\x7b\\x89\\xa3\\x0e\\x1c\"\n\"\\x55\\xa9\\xa8\\x04\\xd0\\x73\\x70\\xbf\\xa7\\x34\\x51\\xe9\\xcf\\xe1\\xaf\\x47\"\n\"\\x85\\xe8\\x4d\\xc1\\x33\\xc0\\xbb\\x5b\\x9d\\xc6\\xd2\\x29\\x00\\xbb\\x61\\xd2\"\n\"\\x04\\x5b\\x5c\\x07\\x73\\x07\\xf3\\x17\\xd8\\x52\\x16\\xd7\\x3c\\x8e\\xda\\xfb\"\n\"\\xd4\\xd2\\xee\\x7b\\x1a\\x47\\xcb\\xca\\x8a\\xa0\\xf7\\x9f\\x3e\\xa2\\x4d\\xcb\"\n\"\\xaa\\xa4\\x94\\x51\\x3b\\xcf\\xfb\\x45\\x0b\\xb6\\x2a\\xf7\\xfc\\xbe\\x87\\x22\"\n\"\\x6e\\x42\\xd3\\x9d\\xba\\x90\\x72\\xd5\\xd5\\xcc\\x0d\\x04\\x64\\x8f\\xf2\\x7f\"\n\"\\x02\\x2a\\xd6\\xb4\\x07\\x6f\\xe6\\x33\\x8e\\xbf\\x2c\\xfd\\x67\\x12\\xd2\\x5a\"\n\"\\xaf\\x39\\x5e\\x51\\x8e\\x43\\x61\\x66\\x12\\x3f\\x35\\x61\\xba\\x38\\x54\\x07\"\n\"\\x7c\\xd1\\x83\\x4d\\xe5\\x7a\\xde\\xfb\\x7f\\x4c\\xaf\\x21\\x26\\xdb\\x0f\\xfc\"\n\"\\xde\\xea\\x92\\x51\\xb0\\x83\\x41\\xef\\x42\\x8e\\x68\\x56\\xbc\\x28\\x66\\x53\"\n\"\\x59\\xd3\\xde\\x95\\x99\\x46\\x84\\xf6\\xf1\\x28\\x5e\\x67\\xad\\x44\\x8b\\x2e\"\n\"\\xd5\\x36\\x59\\x08\\x4d\\x59\\xfb\\xf7\\x88\\xd2\\x0d\\xc2\\x41\\x53\\x5f\\x01\"\n\"\\x6c\\x86\\x24\\x8e\\x2e\\x0a\\xfc\\x0f\\xfd\\xf5\\x28\\x3e\\xe4\\x70\\x4b\\xbe\"\n\"\\xc3\\x8b\\xe1\\xb5\\x6b\\xdf\\x8d\\x19\\x52\\x9e\\xab\\x65\\xfe\\xb8\\x5e\\x3e\"\n\"\\xc1\\x33\\xf3\\x41\\x20\\xf1\\xf7\\x5b\\x4d\\xd0\\x8b\\x4c\\x1b\\xf0\\xd3\\xe6\"\n\"\\xc0\\xbf\\xc0\\x7a\\x67\\x49\\x43\\x2b\\x64\\xbf\\xe8\\xb5\\x2e\\xa1\\x9d\\x1e\"\n\"\\x35\\xc2\\x3a\\xb5\\x60\\x1f\\x03\\x28\\x8b\\xcd\\x07\\xdd\\x10\\x94\\x68\\x06\"\n\"\\x1b\\xd9\\x8b\\xaf\\xa1\\x6f\\x8d\\x79\\xef\\xc8\\xea\\xeb\\xe3\\x42\\xc9\\xb5\"\n\"\\x3a\\xff\\xf2\\x45\\xa0\\x07\\x4a\\x76\\x26\\xdc\\x46\\x9b\\xe6\\x24\\xbe\\xe6\"\n\"\\x1b\\x34\\xf5\\xff\\x69\\xf2\\x7a\\x39\\x25\\xd3\\xd7\\xe1\\x12\\x7c\\x35\\x1a\"\n\"\\xa1\\x98\\x2a\\x3a\\x99\\x18\\x51\\x7e\\xaa\\xe8\\xfc\\xce\\xe7\\x9f\\x7b\\x08\"\n\"\\x4c\\x47\\xaf\\x71\\xe9\\xd2\\x8e\\x7b\\x5f\\x84\\x7d\\x04\\x70\\x3b\\xda\\xba\"\n\"\\xad\\x9f\\x0e\\xb4\\x7d\\x97\\x77\\x9a\\xaa\\xcc\\xc1\\x70\\xea\\x72\\xe5\\x51\"\n\"\\x16\\x9d\\x56\\x3f\\x42\\x9a\\xaf\\x2e\\x1e\\xe2\\x4e\\x9f\\x92\\x40\\x88\\xaf\"\n\"\\x7a\\x95\\x3a\\xa9\\xc5\\x83\\x77\\xe3\\x97\\x82\\x3d\\x18\\x23\\xc0\\x6f\\x80\"\n\"\\x7c\\xe2\\x4a\\x44\\xcc\\x15\\xc2\\xb8\\x4d\\x7a\\x0e\\x49\\x47\\x73\\x39\\x23\"\n\"\\x0d\\x95\\xed\\x53\\xbf\\x9a\\x0a\\x4e\\xf6\\x54\\x4a\\x2f\\x16\\xa5\\x9c\\xeb\"\n\"\\x60\\xf1\\x65\\x00\\x8f\\x3e\\xcf\\xef\\x6f\\x07\\x76\\x41\\xab\\x07\\x25\\xe4\"\n\"\\x53\\x49\\x83\\x77\\x15\\xd7\\x00\\x64\\x6d\\xc0\\x99\\x63\\xc5\\xbf\\x46\\x27\"\n\"\\xb6\\x24\\x12\\xd1\\x34\\xbf\\x1a\\xd6\\xed\\xfe\\x09\\x69\\x2b\\x06\\x6c\\x32\"\n\"\\x4f\\xc8\\x30\\x51\\xb0\\xd9\\x33\\x8e\\xbe\\x3b\\xc6\\x60\\xf2\\x23\\x7e\\x6f\"\n\"\\x71\\x03\\x4c\\x25\\xc8\\x68\\x0a\\xab\\xec\\x4a\\xdb\\x4c\\x7e\\xa9\\x23\\x74\"\n\"\\x1f\\x34\\xca\\xe9\\x21\\xb1\\x4f\\x97\\x94\\x61\\x20\\x11\\x7e\\x99\\xcf\\xf7\"\n\"\\x76\\x2b\\x05\\xaf\\x6a\\x39\\x33\\x64\\xcd\\x38\\x51\\xfe\\xca\\x5b\\xfb\\x61\"\n\"\\x79\\x65\\x02\\x39\\x05\\x92\\x72\\x2d\\x91\\x91\\x0b\\xd3\\x45\\xa1\\xb6\\x4a\"\n\"\\x2f\\xd9\\x77\\x86\\x91\\x0b\\xa4\\x85\\xb8\\x3e\\x82\\xad\\x7e\\xce\\x48\\x18\"\n\"\\x52\\x85\\xcd\\xb2\\x9c\\x31\\x1d\\x7b\\x25\\x40\\x04\\x75\\x3b\\x2c\\xc8\\xf3\"\n\"\\xa6\\x3c\\x8e\\x21\\x36\\xdc\\xe3\\xf4\\x3f\\x8f\\x9d\\x35\\x77\\x40\\xe0\\x76\"\n\"\\x57\\x3a\\x5e\\xd3\\x6b\\x97\\x76\\xf5\\x33\\x2e\\x26\\x6b\\x45\\xed\\xf3\\x2c\"\n\"\\xe9\\x34\\x24\\x54\\x3f\\x86\\x82\\x29\\x32\\xf9\\x97\\xae\\x1c\\x33\\x87\\x95\"\n\"\\x6d\\xa8\\xfc\\x3f\\x66\\x6a\\x07\\xd5\\x1f\\x0a\\xb1\\x46\\xbd\\x53\\xa5\\x92\"\n\"\\x0e\\x2a\\x55\\x03\\x2b\\xa9\\xfc\\x0d\\xcc\\x90\\xa2\\x47\\x14\\x54\\x63\\xb2\"\n\"\\x6b\\xce\\xff\\x43\\xe1\\x95\\x37\\xdb\\x67\\xc8\\xc4\\x04\\xc7\\x86\\xb2\\xb0\"\n\"\\xaf\\x49\\xd0\\x34\\x4a\\x56\\x3e\\xeb\\xd3\\x32\\xab\\x5e\\x60\\xe5\\x30\\x65\"\n\"\\x87\\x81\\x48\\xae\\x15\\xfc\\xdb\\xbd\\xa9\\x37\\x3a\\x28\\xcb\\x9f\\xf2\\xff\"\n\"\\xe0\\x6c\\x1a\\x9a\\xbb\\x23\\x59\\x5e\\xb7\\x26\\x68\\x8a\\xca\\x74\\xcf\\xfb\"\n\"\\x12\\xf3\\x17\\x37\\x50\\xcf\\x33\\xda\\xbf\\x3a\\x87\\xda\\x44\\xc9\\xdc\\xcc\"\n\"\\xbc\\xd9\\x53\\xe3\\x3e\\xa0\\x83\\x3c\\xe9\\xe2\\xd6\\x62\\x58\\x95\\x6c\\x4d\"\n\"\\xcb\\x1d\\x87\\xf7\\x5e\\x03\\xcf\\xbf\\xf8\\x92\\xb1\\xce\\xe8\\x21\\xe8\\x37\"\n\"\\xf2\\x20\\x95\\x4d\\x05\\x84\\x51\\x51\\x58\\x23\\xb2\\x84\\x0b\\x2a\\x22\\xc9\"\n\"\\x39\\x17\\x03\\x03\\x05\\x4b\\x4f\\xe0\\x92\\xa8\\xe8\\xe5\\x5f\\x20\\xd4\\xb3\"\n\"\\x34\\xe7\\x1a\\x87\\xbf\\x9d\\x57\\x83\\x44\\x50\\x53\\xcc\\x5f\\x0b\\xc3\\x7b\"\n\"\\x1c\\x56\\xd6\\x32\\xa1\\x22\\x90\\xeb\\x34\\xa6\\xb6\\xb3\\xb2\\x2e\\x7e\\x8c\"\n\"\\xbb\\x5f\\x98\\x80\\x32\\x2c\\x0e\\x5c\\x9a\\x2a\\xed\\x13\\x1b\\x57\\x51\\xa8\"\n\"\\xdd\\x87\\xbd\\x94\\x38\\x96\\x92\\x5e\\xd5\\x0e\\x58\\x61\\x12\\x5e\\xc6\\xe2\"\n\"\\xe1\\x78\\x62\\x5c\\x7f\\x03\\x12\\x37\\x31\\x0a\\x80\\xca\\xcf\\x60\\x33\\x53\"\n\"\\x4d\\x9c\\x3f\\xbe\\xaf\\x0f\\x45\\x52\\x2c\\x34\\x43\\x7b\\xc3\\xc7\\xa3\\x85\"\n\"\\xb5\\x21\\x9c\\xb7\\xd1\\x2a\\x43\\x5b\\x68\\x63\\xc1\\xd6\\x4f\\xe2\\xc0\\x72\"\n\"\\x3a\\xa1\\xa8\\xe7\\xec\\x81\\x91\\xb0\\x14\\x77\\xb4\\xa4\\x3f\\x5f\\x1b\\x2e\"\n\"\\x44\\xb1\\x4d\\x55\\xef\\x25\\x76\\xd0\\x45\\xa3\\xcb\\x10\\xe7\\x47\\x33\\xd6\"\n\"\\xeb\\xd9\\x58\\x07\\xc4\\xc7\\x78\\x24\\xc7\\x4f\\xc9\\xbc\\xd1\\xa2\\x44\\x97\"\n\"\\x77\\x2b\\xb0\\x19\\x37\\x4d\\x39\\x41\\x9f\\x55\\x27\\x16\\xa0\\x74\\xc9\\x9d\"\n\"\\xba\\xd1\\x71\\x53\\x22\\x1a\\x5c\\xd6\\x6d\\xe8\\x24\\x19\\xd6\\x30\\xee\\x30\"\n\"\\x0a\\x8f\\x3d\\x06\\xa6\\xbe\\xd1\\xda\\x8a\\x2c\\x06\\x6a\\xf8\\x51\\x18\\x70\"\n\"\\x36\\x6f\\x98\\xd2\\x8b\\x7a\\xa1\\x18\\xe9\\x5b\\x06\\x6c\\x6b\\x8e\\x70\\xf5\"\n\"\\xf8\\xff\\x9d\\xf3\\x58\\x6e\\x7e\\x1e\\x45\\xfd\\xf4\\xe1\\x25\\xf7\\x1e\\xe1\"\n\"\\xa4\\x6c\\xab\\xf7\\x1b\\x86\\xc9\\xe9\\x49\\xeb\\xf4\\x67\\x06\\x6e\\x7e\\xea\"\n\"\\xf4\\x97\\xfc\\x20\\xc7\\x9c\\xbf\\xd2\\x3d\\xe6\\xd5\\x1d\\x6d\\xed\\xae\\x08\"\n\"\\xb6\\x99\\x7a\\x5e\\xd3\\x3c\\xaa\\xc6\\x00\\x76\\xae\\xe1\\x47\\xf1\\x81\\xe9\"\n\"\\x09\\x20\\x93\\x92\\xfc\\xb9\\xed\\x09\\x83\\x74\\x76\\xeb\\x32\\x38\\x36\\xcf\"\n\"\\xf3\\x0c\\xbb\\x2c\\xcf\\x8e\\x0f\\x15\\x30\\x32\\xae\\x0d\\x75\\xd1\\xfe\\x29\"\n\"\\x28\\x18\\x00\\x93\\x9b\\xfb\\xdb\\x6d\\xb3\\xc1\\xfb\\xe2\\x2c\\xe1\\x2f\\xf4\"\n\"\\xc0\\xdb\\x12\\xc6\\x14\\xb8\\xca\\xeb\\x3e\\x49\\xc0\\xe1\\xcd\\x42\\xa6\\x04\"\n\"\\xc2\\x0f\\x48\\x45\\x6b\\xac\\x45\\x48\\x3d\\x82\\x02\\xe9\\xad\\x6b\\x2e\\x38\"\n\"\\xad\\xd6\\x90\\x93\\x50\\xb9\\x66\\xc9\\x17\\x40\\x6e\\x6f\\x0d\\x4f\\x16\\xe7\"\n\"\\xad\\xae\\x97\\x0c\\x5d\\x08\\x0f\\x6a\\x99\\x14\\x98\\x88\\xc0\\xf2\\xe4\\xaa\"\n\"\\x87\\x02\\x6f\\x49\\x55\\xf9\\x4e\\x43\\x29\\xb4\\x53\\xbf\\xb8\\x29\\xf7\\x45\"\n\"\\x37\\xd1\\x12\\x84\\xd1\\x35\\xaf\\x91\\x39\\x20\\xfc\\x4e\\x3e\\xa1\\xc6\\xe7\"\n\"\\x0f\\xc1\\x75\\x15\\x42\\xee\\xa7\\x60\\x5e\\x6f\\x94\\x65\\xc3\\x7f\\x12\\xb0\"\n\"\\xf9\\x43\\xfc\\x58\\x9a\\x79\\xea\\x0b\\xb0\\xfd\\x05\\xd7\\xf4\\xd5\\x87\\x7b\"\n\"\\x39\\x03\\xe4\\x2d\\x80\\xb1\\xc3\\x00\\xdc\\x6d\\x3a\\x0b\\x2d\\xc0\\xf7\\xc2\"\n\"\\x65\\x4e\\xeb\\x7f\\x3a\\xa1\\xe5\\x7a\\x64\\x56\\x3e\\xe9\\xc7\\x90\\xf2\\x6e\"\n\"\\x2c\\x8d\\xd5\\xd3\\xe8\\x6e\\x9c\\x7c\\x6e\\xda\\x52\\x29\\xe4\\xfa\\xfe\\x7c\"\n\"\\x98\\xcb\\xc2\\xb1\\x26\\x9c\\xd6\\xd9\\x8a\\x81\\x0a\\xf9\\x1e\\x79\\xae\\x18\"\n\"\\x25\\x72\\x81\\xcf\\xef\\x42\\xe1\\x6e\\x7f\\xdf\\x0c\\xf0\\xa6\\x1d\\x5f\\xcd\"\n\"\\x99\\xed\\x3e\\x6f\\x85\\xb9\\xb7\\xa2\\x1f\\x43\\x22\\x2a\\x4f\\x10\\x1e\\x7c\"\n\"\\xe3\\x6c\\x56\\x3c\\x7b\\x1a\\xc5\\xfc\\x3a\\xe6\\x1d\\xac\\x4b\\xe7\\x55\\x27\"\n\"\\x3e\\x6c\\x95\\xda\\xc4\\x6f\\xa3\\x1f\\xf9\\xec\\xe2\\xdc\\xd2\\x02\\x7d\\x5d\"\n\"\\xe8\\xa8\\x9d\\x17\\xc8\\x0b\\xaf\\xd8\\x45\\xf2\\x36\\xe2\\xd4\\x05\\x87\\x90\"\n\"\\x4a\\x70\\xe9\\xf9\\xc6\\x7d\\xf3\\x80\\xc7\\x83\\x27\\xc2\\xdb\\xc1\\x35\\xec\"\n\"\\xb9\\xa9\\x1a\\x1b\\xb4\\x41\\xe9\\xb7\\xd5\\xb9\\x17\\x9b\\x50\\xd7\\x98\\xbc\"\n\"\\x38\\xcb\\xd1\\x4c\\x42\\x5a\\x2a\\x61\\xfd\\xb3\\x8b\\xab\\xd0\\x39\\xe1\\x41\"\n\"\\x7d\\xec\\x8a\\xbf\\x0b\\x89\\x24\\xa7\\x2e\\xc7\\x26\\x04\\xa6\\x6c\\xcb\\xa2\"\n\"\\x53\\xed\\x8d\\x5a\\x96\\xf9\\x90\\x0e\\xda\\xbd\\xb3\\x65\\x6e\\xde\\x9e\\xdc\"\n\"\\x4c\\x53\\xed\\x9f\\x3f\\x57\\x5b\\x1a\\x1b\\x9a\\x01\\x4c\\xaa\\x07\\xe0\\x57\"\n\"\\x3c\\xb3\\x96\\xfd\\xf7\\x36\\xfd\\x15\\x71\\xaf\\xc2\\xff\\x2d\\x9b\\x27\\x9e\"\n\"\\xfc\\x70\\xf9\\xb6\\x79\\xf9\\xcb\\x10\\x14\\x41\\xc4\\xe1\\x62\\x97\\x90\\xac\"\n\"\\x47\\x9b\\x41\\x34\\x7a\\x07\\x63\\xd2\\xb0\\xa7\\xaa\\xc4\\x2b\\xba\\x74\\x1e\"\n\"\\x42\\x6d\\x29\\x57\\xe1\\x90\\xab\\x23\\x82\\x6c\\x82\\xcd\\x3b\\xbb\\x1e\\xce\"\n\"\\x7b\\x98\\x4e\\x86\\xb9\\xf6\\x61\\x9c\\x7f\\xf6\\x7d\\x4f\\xf2\\xb5\\x87\\xaa\"\n\"\\x1b\\x96\\x79\\x5b\\x71\\x47\\x11\\x9f\\x33\\x06\\x2e\\x76\\xb9\\x88\\x99\\xc6\"\n\"\\x2a\\x43\\xc2\\x5d\\x19\\xe6\\x31\\x29\\xac\\x32\\x21\\x96\\x13\\x10\\xb1\\xb1\"\n\"\\x94\\xc5\\x0a\\xcd\\x36\\xac\\x7b\\x93\\xdd\\x93\\x45\\x18\\x5e\\x7d\\x20\\xca\"\n\"\\x14\\xfe\\x68\\x5e\\xf4\\x14\\xa6\\xe9\\xfa\\x5a\\x3d\\xda\\x61\\x46\\x34\\x79\"\n\"\\x6b\\x05\\xf3\\x5a\\x19\\x17\\x33\\x61\\x55\\x87\\xb0\\x25\\x71\\x20\\x51\\x91\"\n\"\\x81\\x1d\\x40\\x54\\x88\\xe1\\x7a\\x28\\x66\\xbf\\x29\\x1a\\x63\\xe3\\xd6\\x1a\"\n\"\\x7e\\xed\\x84\\xa0\\x7a\\xda\\xb5\\xc6\\x0b\\x9c\\x65\\xf5\\xd8\\x61\\x8f\\x79\"\n\"\\xe3\\x65\\x41\\x9b\\xa0\\x50\\x1f\\x3f\\x93\\xa2\\x17\\x17\\x9d\\xa0\\x53\\xd9\"\n\"\\x16\\xaf\\x03\\x51\\x19\\xd9\\x60\\x79\\xeb\\x52\\x52\\x26\\x2e\\x72\\xb8\\x25\"\n\"\\x98\\x58\\xbe\\xcf\\xe2\\xf3\\x41\\xe0\\xcc\\x2c\\xa2\\x17\\x8d\\x73\\xb2\\x56\"\n\"\\x42\\x9a\\x3b\\x4e\\x99\\xa8\\xeb\\xe6\\x27\\x99\\x5d\\x07\\x5d\\x24\\xfe\\xbb\"\n\"\\x48\\x10\\xea\\xd7\\xcd\\xa1\\xda\\x7a\\xf2\\x2c\\xed\\x69\\xea\\x54\\x62\\x79\"\n\"\\xb1\\x33\\x4f\\x60\\x5e\\x24\\x2b\\x3b\\x46\\xee\\xf8\\x01\\xbe\\x32\\x9f\\x1f\"\n\"\\x89\\xf3\\x20\\xd9\\xdf\\x7c\\x28\\x8c\\x63\\x8b\\x5a\\x39\\x53\\x1b\\x36\\xf1\"\n\"\\xff\\xa1\\xf6\\xed\\x88\\x81\\x9a\\x96\\xf0\\x48\\xfc\\x6d\\x66\\x6d\\xaa\\xce\"\n\"\\x80\\x35\\xb2\\xf0\\xb0\\x7e\\xaf\\x59\\xb0\\x9a\\x47\\x0d\\x99\\xf9\\xc0\\xce\"\n\"\\x52\\xa9\\x3d\\xdc\\x4d\\xac\\xcb\\xbb\\x05\\xbb\\x8d\\x01\\x90\\x07\\x2b\\x7b\"\n\"\\x68\\x62\\xd7\\xe4\\x5b\\x2f\\x5d\\x11\\x22\\x6d\\x4b\\x81\\xbf\\x48\\xe0\\x1d\"\n\"\\x04\\x03\\x0b\\xad\\x77\\x0e\\x62\\xa1\\xbe\\x1d\\x30\\x9a\\xff\\x40\\x82\\xd7\"\n\"\\xc3\\x10\\xba\\x5f\\x89\\x57\\x75\\x84\\x19\\xcf\\xa5\\x25\\x50\\x96\\x49\\xd7\"\n\"\\x4f\\xad\\xfe\\x5a\\xf2\\xe5\\x55\\xb1\\x54\\x21\\x9e\\xb4\\x15\\x17\\x8f\\x67\"\n\"\\x9d\\x69\\xda\\x9b\\x27\\x0a\\xba\\xff\\xda\\x38\\x82\\xf2\\x3a\\x62\\x6f\\x79\"\n\"\\x15\\x37\\x4c\\xea\\x05\\x2b\\x33\\xd2\\x6d\\x58\\x96\\x8b\\xa9\\x2f\\x7b\\x08\"\n\"\\x08\\x7a\\x0d\\x1f\\x59\\xc9\\x32\\xa2\\xf7\\x40\\xe1\\x3d\\xb1\\xaa\\x8b\\x8a\"\n\"\\xdb\\x7c\\x87\\xfe\\xd2\\xa1\\x19\\xf7\\x65\\x0a\\xd2\\xe5\\xfa\\xcf\\x44\\xde\"\n\"\\xbb\\x42\\x7b\\x36\\xc3\\x8e\\xbc\\x60\\xf3\\xc8\\x44\\xbb\\x75\\xab\\x78\\x1f\"\n\"\\xa5\\x5e\\x01\\x2c\\x5d\\x9c\\xb6\\xf8\\xcc\\x52\\xcf\\x63\\x0c\\xfe\\xe3\\x8a\"\n\"\\x36\\x84\\x07\\x64\\x4d\\x9a\\x4f\\xea\\x70\\xa9\\x7d\\x7a\\xaa\\x65\\x6f\\x34\"\n\"\\xe8\\x7e\\x89\\x00\\x41\\x06\\x47\\xd6\\x7f\\x57\\x3f\\x60\\x6d\\x09\\x5a\\x5f\"\n\"\\x7d\\x87\\x14\\xce\\x79\\x88\\xab\\x74\\x6c\\x98\\x92\\xfd\\x20\\x46\\xd3\\x44\"\n\"\\xfc\\xe6\\x44\\xb0\\x03\\xda\\x57\\x61\\x3f\\x7e\\xa9\\x91\\x60\\x9e\\x11\\x55\"\n\"\\xff\\x76\\x0b\\x14\\x29\\x72\\x96\\xd9\\x00\\xff\\xe9\\x53\\x19\\x5f\\x68\\xec\"\n\"\\x86\\x01\\xdc\\x15\\x4c\\x59\\x7e\\x8a\\xb1\\x73\\x66\\x32\\x9e\\xf8\\x46\\xbc\"\n\"\\xa1\\x5b\\xf5\\x29\\x44\\x29\\xd4\\xd1\\x15\\x32\\x82\\xe9\\x84\\xee\\x70\\xa5\"\n\"\\xc9\\xcd\\xe9\\xea\\x5c\\x56\\x91\\xca\\x73\\xf8\\x4a\\x0f\\x5c\\x0b\\x9c\\x6d\"\n\"\\x3b\\x17\\x03\\x03\\x05\\x4b\\xb1\\x6b\\x56\\xf7\\x0a\\x4a\\xf4\\x4a\\x40\\x46\"\n\"\\x30\\xb6\\xaf\\x59\\xa7\\x9f\\xe3\\x36\\x17\\x9c\\xd5\\xd7\\xa8\\x10\\x20\\xb2\"\n\"\\x71\\x50\\xc3\\x6b\\xe4\\x70\\xc7\\x2e\\x27\\xd6\\x3b\\x8e\\xca\\x24\\x28\\x01\"\n\"\\x97\\x9b\\x70\\x02\\xae\\x87\\x29\\x75\\xe8\\x6b\\xa2\\xb1\\xf1\\x73\\x3d\\x3f\"\n\"\\x24\\x04\\x60\\x2d\\xe2\\xfb\\x95\\x5b\\x93\\x22\\xb3\\x67\\x93\\xdd\\x4c\\xc8\"\n\"\\x29\\xdf\\x60\\xde\\xe4\\x9b\\x6c\\x46\\x38\\xd3\\x82\\x59\\x75\\xbb\\x23\\x37\"\n\"\\xd7\\xcf\\xf1\\xc1\\x77\\xe8\\xd1\\x8b\\xe5\\xe0\\xe5\\x26\\x63\\x2d\\xce\\x06\"\n\"\\x0d\\xe9\\x0b\\x52\\xf6\\xfd\\x2e\\x67\\x7f\\xc1\\x41\\x8f\\x51\\x73\\x39\\xda\"\n\"\\x4c\\x65\\xd2\\x14\\xab\\x7d\\x18\\x03\\xd2\\x94\\x80\\x11\\x6f\\x66\\x8a\\x4b\"\n\"\\x6b\\xe5\\xac\\x6d\\x17\\xbb\\x79\\x8a\\x8b\\xd2\\x7d\\xf5\\xc2\\x41\\x01\\x32\"\n\"\\x2d\\x9f\\xde\\x41\\x26\\x28\\xc0\\x0b\\xa9\\x07\\x92\\x42\\x12\\x07\\x90\\x77\"\n\"\\x9f\\xa5\\x99\\x1e\\xe6\\x7c\\x39\\xef\\x6f\\xf8\\x9a\\x18\\xb8\\x23\\x6e\\xdd\"\n\"\\x8b\\x81\\xf0\\x07\\xb3\\x70\\xea\\x32\\x19\\xb0\\xd4\\x7c\\x78\\xc1\\xd2\\x52\"\n\"\\xb1\\xa4\\x41\\xf1\\x79\\xf2\\x97\\x29\\x0d\\xa6\\x07\\xc2\\xee\\x63\\xc0\\x55\"\n\"\\xcd\\x14\\x5c\\x34\\x14\\xb2\\xac\\x90\\x49\\x78\\xe6\\x3d\\x7c\\xc2\\x79\\x16\"\n\"\\x16\\x3a\\xd6\\x16\\x1c\\xf5\\x6b\\xe8\\x8b\\xfa\\xb9\\xde\\x6f\\xa6\\x63\\x27\"\n\"\\xc6\\xf8\\x08\\xb2\\xcb\\xf2\\xbf\\xa0\\x29\\x7b\\xaa\\xba\\x03\\x9c\\x3c\\x83\"\n\"\\x51\\xb5\\xef\\x66\\x97\\x5e\\x95\\x90\\xd8\\x80\\x20\\xc3\\xa0\\x23\\xa9\\x04\"\n\"\\x5d\\x15\\x03\\x3e\\x4f\\xef\\x3f\\x09\\xec\\x9f\\xe4\\xdf\\x5c\\x3d\\x5c\\x9e\"\n\"\\x35\\x69\\xe2\\xc9\\x2d\\xc8\\xcb\\xfe\\xa7\\x54\\x36\\x6d\\xe3\\x44\\xe3\\xb0\"\n\"\\xff\\x74\\x55\\xb3\\x41\\x27\\xc3\\x5c\\xe6\\x7f\\xcb\\xfd\\xc3\\x2b\\x9b\\xdb\"\n\"\\xe6\\xcc\\x87\\x6b\\xf0\\x9e\\x2d\\xbe\\xb6\\x8f\\xd4\\x7c\\x7a\\x72\\x74\\x3d\"\n\"\\x9b\\xb0\\x74\\x33\\x22\\x71\\x2b\\x92\\x63\\x55\\x1f\\x0f\\x5f\\xf2\\x65\\x7c\"\n\"\\xa3\\x9e\\xe9\\x42\\xf4\\x05\\x16\\xca\\x5e\\xa8\\x61\\xbc\\x1e\\xbd\\xca\\xdf\"\n\"\\x3c\\x7d\\x10\\x87\\xe4\\xbb\\x41\\xf0\\x34\\x4e\\xc6\\x00\\xf6\\xdf\\xe7\\xf1\"\n\"\\xeb\\xda\\x86\\x0a\\x8c\\x9c\\xb1\\x97\\xc4\\xa7\\x2c\\x4b\\x96\\xa6\\xbf\\xc0\"\n\"\\x85\\xaf\\x69\\x2d\\x28\\x63\\xbd\\x5f\\x85\\x1c\\x00\\x8a\\x8a\\xd6\\x9f\\x60\"\n\"\\xd6\\xd7\\x8f\\x75\\x62\\x74\\xb7\\x32\\x5d\\x0b\\x4f\\x29\\xb8\\x72\\xfa\\xf3\"\n\"\\x80\\x47\\x3a\\xbb\\x08\\x27\\x79\\xa7\\x2c\\x6a\\x63\\x66\\xaa\\xe2\\xc5\\x17\"\n\"\\x8d\\x1b\\xe5\\x6b\\xb7\\xd1\\xed\\x18\\x9b\\xde\\xfc\\x92\\xc8\\x3d\\x30\\xff\"\n\"\\xf3\\x33\\xba\\x01\\x0c\\x6a\\x19\\xc2\\x93\\xed\\x5c\\x19\\xc7\\xb7\\x45\\x99\"\n\"\\xf4\\x46\\x42\\x6a\\xe0\\xd9\\x5e\\x99\\x64\\x24\\xa2\\xd2\\x34\\xb6\\x46\\x88\"\n\"\\x2c\\xdd\\xc0\\xbc\\x7e\\xd1\\x57\\x72\\x2c\\xb5\\xa2\\x72\\xbd\\x8c\\xe0\\x2a\"\n\"\\x03\\xe7\\xe9\\x84\\xe4\\x90\\x1c\\x3a\\xa8\\x79\\x48\\xe1\\xc1\\x72\\x6a\\x83\"\n\"\\xf8\\x1f\\x39\\xb2\\x08\\x70\\xba\\x96\\xdd\\x9e\\xd0\\x4d\\x9f\\x2d\\x9a\\xdc\"\n\"\\x11\\xe2\\x4d\\x27\\x41\\xce\\xec\\x6e\\x4f\\xff\\x9a\\xd5\\x09\\xcd\\x38\\x9b\"\n\"\\xe6\\x4f\\xc5\\xfc\\xac\\xeb\\xb8\\x76\\xaa\\x42\\xc4\\xeb\\x9a\\xff\\xf8\\xd0\"\n\"\\x07\\x25\\xe8\\x08\\xa5\\xd1\\xa0\\x59\\x8c\\xca\\x85\\x5f\\x33\\xde\\x97\\x3b\"\n\"\\xa5\\xe9\\x81\\xd5\\x90\\x7c\\xeb\\xd9\\x50\\x84\\x0f\\x51\\xc2\\xdc\\x2a\\x21\"\n\"\\xe9\\x2e\\xb0\\xcd\\xc8\\x26\\x6e\\x81\\xbc\\x5a\\x63\\x9f\\x0b\\x4c\\x67\\x97\"\n\"\\x0e\\xfd\\xb8\\x03\\xd4\\xd5\\x1a\\x53\\x2c\\x59\\x7b\\xcd\\x14\\xd7\\x8b\\x09\"\n\"\\xee\\xbb\\xad\\xd4\\x02\\x47\\x4a\\xb0\\x23\\x4a\\xd2\\xdb\\x40\\x7d\\x03\\xf7\"\n\"\\x46\\xb8\\xf2\\x18\\x34\\x42\\x52\\xf4\\x77\\xc2\\xc8\\x91\\xb0\\x6b\\xb9\\xb6\"\n\"\\x87\\xda\\xbb\\xb8\\x1b\\x4c\\xf0\\x2b\\x1d\\x4e\\xff\\x87\\xd7\\xb8\\x10\\xa7\"\n\"\\xaf\\x08\\x20\\xa5\\x14\\xb6\\xe7\\xe8\\xc9\\x26\\xa6\\x29\\x6e\\x5f\\xbf\\x1f\"\n\"\\x4e\\xcd\\xd7\\x6f\\x7a\\x89\\x28\\x5a\\x1c\\x9c\\x82\\x88\\x05\\x50\\x75\\x8e\"\n\"\\xa3\\xec\\x50\\xe7\\xa8\\x69\\x4a\\x17\\xd4\\xab\\x92\\xca\\x35\\x42\\x5f\\xa4\"\n\"\\x40\\x07\\xe6\\xbb\\xf6\\x7b\\x57\\xe9\\xa8\\x29\\xae\\x98\\xf3\\x0a\\x8e\\x78\"\n\"\\x69\\xaf\\xc7\\x63\\xe7\\x15\\xd5\\xfc\\x4f\\x51\\x2f\\x5f\\xee\\x6d\\xec\\xe8\"\n\"\\x58\\xc3\\x7c\\x6c\\xbf\\x9d\\xb8\\xc0\\x40\\xb4\\xe5\\x17\\xc5\\x6e\\x63\\x32\"\n\"\\x78\\x34\\x94\\xfe\\x0c\\x6c\\xc3\\x1d\\x38\\x3e\\xe7\\x8b\\xd9\\x48\\x7e\\x39\"\n\"\\x39\\x25\\xcd\\x06\\xa2\\x94\\x37\\xb9\\x49\\xf9\\x51\\x84\\x95\\x1f\\x80\\xcd\"\n\"\\x6c\\x9e\\x4f\\xc0\\xc1\\x2a\\xbe\\xbd\\x6e\\xc0\\xb0\\xb8\\x1c\\x5e\\xbb\\xf5\"\n\"\\xdb\\xe1\\x74\\xe0\\x86\\x15\\xa9\\x77\\x5c\\x85\\x50\\xe1\\xa2\\x6b\\xe4\\xdf\"\n\"\\x5f\\x81\\xe6\\xd6\\xdb\\xae\\x3b\\xed\\x51\\xed\\xd9\\x3b\\xa3\\xf4\\x1c\\x79\"\n\"\\x1d\\x90\\x0d\\x14\\x3d\\x6b\\x94\\xc2\\xf3\\xdc\\xe0\\x5a\\xb7\\x9b\\x2d\\xdb\"\n\"\\xa2\\xea\\x66\\x53\\x13\\x3f\\xc7\\x3d\\xeb\\xb7\\x85\\x00\\xf3\\x85\\xc6\\xa2\"\n\"\\x5d\\x0d\\x5f\\x79\\xab\\x78\\x88\\x7c\\x5b\\x43\\xf1\\x4f\\xaf\\xdd\\xfd\\x80\"\n\"\\x89\\x15\\x00\\x71\\xc1\\xaf\\x86\\xf7\\x8a\\x9c\\xd0\\x71\\x32\\x8d\\x82\\x43\"\n\"\\xfe\\xa9\\x66\\xaf\\xed\\x17\\x31\\xf7\\x07\\xd1\\x55\\x60\\xbb\\xd5\\x31\\x7e\"\n\"\\x1c\\x3a\\x37\\x2d\\xb1\\x59\\x85\\x50\\xe9\\xac\\x0f\\xef\\xcf\\xbd\\x0a\\xee\"\n\"\\x7b\\xee\\xd3\\xe9\\x27\\xd1\\xbb\\xfc\\x76\\xe0\\x7d\\xc2\\xf5\\xc8\\xf0\\xc6\"\n\"\\x15\\x2c\\x06\\x0a\\xdd\\x86\\x59\\x69\\xd0\\x9e\\x00\\x68\\x7a\\x7e\\xdf\\x57\"\n\"\\xb6\\x49\\xc2\\xba\\xcc\\xf1\\x1f\\x69\\x89\\x44\\xdf\\x35\\xce\\x98\\xf1\\xbe\"\n\"\\x85\\x11\\x28\\x8a\\xdb\\x6c\\x38\\xf7\\x6a\\x27\\x72\\x78\\xfc\\x4f\\x7c\\x8b\"\n\"\\x41\\x23\\x2c\\x90\\x7d\\x37\\x70\\x48\\x4f\\xb0\\x4c\\x33\\xcd\\x73\\x6b\\x85\"\n\"\\xfd\\x61\\xe4\\x62\\xdd\\x63\\x72\\x20\\x73\\x53\\x01\\x0f\\x4f\\xe4\\xb4\\x8b\"\n\"\\x33\\x5f\\x64\\x03\\x03\\xe7\\x15\\xc9\\x50\\x71\\xd6\\x9e\\x37\\x49\\xc4\\x3e\"\n\"\\xf1\\xef\\x57\\x68\\xbd\\x9a\\xd5\\xe8\\x3d\\xaf\\xe5\\xc8\\x42\\xc6\\xed\\xf0\"\n\"\\x6a\\xd8\\x4e\\x90\\xa1\\xe2\\xb7\\x81\\xbf\\xa5\\x39\\x46\\xee\\x45\\x9f\\xd4\"\n\"\\x91\\xcb\\x74\\x10\\x81\\x88\\x9c\\xe8\\x94\\x17\\x05\\x33\\x39\\x96\\x4f\\x21\"\n\"\\x9f\\xd2\\x84\\x62\\x9b\\x1e\\x29\\x04\\x85\\xdd\\xbe\\x47\\xdd\\xc0\\x6c\\xfa\"\n\"\\x1e\\x00\\x41\\xf7\\x76\\xdc\\x10\\xc9\\xbb\\x1c\\xbd\\xc5\\x7b\\x59\\x0c\\x5b\"\n\"\\xc9\\x7e\\xca\\x9e\\xf8\\xcf\\x00\\xc1\\xf6\\x73\\x44\\x38\\x44\\x65\\xaa\\x57\"\n\"\\x72\\x6c\\x3a\\x22\\x70\\xbe\\xe7\\xc4\\x23\\xca\\xbb\\x14\\xcc\\x5a\\x3e\\xc3\"\n\"\\xf4\\xf7\\x11\\x92\\x05\\x77\\x5f\\x64\\x7b\\x5c\\x41\\x92\\xa2\\xd2\\x42\\x96\"\n\"\\x85\\x17\\x26\\xd0\\x49\\x93\\xa6\\x16\\x80\\x0d\\x44\\x75\\x52\\xd8\\xa3\\xf0\"\n\"\\x7f\\xbb\\x8d\\x96\\x60\\x61\\xf9\\xe3\\x11\\xfd\\x32\\xf9\\x8e\\xc5\\x6f\\x60\"\n\"\\x17\\x98\\x14\\xcf\\x8e\\x0e\\xd6\\x40\\xbd\\x05\\x67\\x1a\\x3a\\x6c\\x5d\\x29\"\n\"\\x00\\x72\\xc8\\x79\\xde\\x06\\xe1\\x61\\x8d\\x54\\x0b\\x0a\\xe8\\x07\\x52\\x97\"\n\"\\xaf\\x3e\\x7d\\xf7\\x08\\x86\\x3a\\x6b\\x10\\xde\\xc3\\x9c\\xad\\xe4\\x9b\\x12\"\n\"\\x8a\\x63\\x85\\x8a\\x38\\x59\\x12\\xd0\\x8b\\x1a\\x98\\xe1\\x65\\x14\\x5c\\x1d\"\n\"\\x8e\\xdf\\x77\\x84\\xde\\x66\\x37\\x4e\\x0a\\x25\\xea\\xd0\\x74\\x17\\xe0\\x34\"\n\"\\x17\\xeb\\xe2\\x4d\\x3d\\x21\\xe4\\xe1\\x75\\x40\\x36\\xe1\\x6c\\x32\\x8b\\x29\"\n\"\\xb6\\x87\\xd5\\x49\\xc6\\x6a\\xfe\\xa3\\x58\\x85\\x7e\\x67\\xae\\x74\\xe3\\xc2\"\n\"\\x3d\\x17\\x03\\x03\\x05\\x4b\\x7a\\xa0\\xc3\\x74\\x01\\x15\\xc9\\xa6\\xee\\xb1\"\n\"\\x6e\\x6a\\xa8\\xbf\\x2b\\x35\\x00\\xa9\\xf9\\x2c\\xaf\\x29\\x4d\\xad\\x6a\\xc7\"\n\"\\xba\\xda\\x74\\xaf\\x29\\x24\\x49\\x15\\xb2\\x9b\\x25\\x3c\\xae\\xa4\\x64\\xe2\"\n\"\\x27\\x32\\x8b\\xf7\\x79\\x05\\x47\\x69\\x5a\\xae\\xaf\\xdb\\x77\\x93\\x07\\xd3\"\n\"\\x9e\\x8e\\x66\\x97\\x39\\x0e\\x9a\\x33\\x12\\x4e\\xed\\x26\\xe3\\x29\\x12\\xb6\"\n\"\\xe3\\x67\\xf4\\x82\\x6b\\x4c\\xc9\\xcb\\x90\\xf1\\xac\\xd3\\xff\\x33\\x07\\xa7\"\n\"\\xe2\\x21\\xe4\\x0d\\x40\\x5a\\x73\\x3a\\x3c\\x34\\x16\\xf0\\xbd\\xfe\\xe9\\x4a\"\n\"\\x69\\xa0\\xb8\\xc0\\x7c\\x94\\x5e\\x0d\\x76\\xb7\\xcf\\x6d\\xc6\\xca\\x56\\x07\"\n\"\\xf9\\xeb\\xe2\\x5a\\x83\\x0d\\x45\\xf8\\x02\\x21\\x2d\\xf1\\xf1\\x3f\\x34\\x16\"\n\"\\x3d\\xbf\\x2c\\xba\\x26\\xe8\\x31\\x9f\\xa2\\x58\\xfe\\x84\\x97\\x19\\x39\\xbc\"\n\"\\xca\\xf2\\x18\\x80\\x73\\xda\\xbe\\xb8\\x01\\xfd\\xce\\xdb\\x5d\\x40\\x48\\x62\"\n\"\\x3c\\xa8\\xfa\\x2a\\xdf\\xc9\\x9c\\xa4\\x50\\x02\\x9a\\xa0\\x0d\\x7c\\xba\\x6b\"\n\"\\xa3\\xb7\\x4a\\x9e\\xd7\\x71\\x90\\x5c\\xfd\\xc1\\x98\\x1a\\xaa\\xcb\\x47\\x6a\"\n\"\\x5a\\x8b\\xa3\\x65\\xfc\\x68\\x8b\\x46\\x9e\\x9a\\x51\\x5f\\x74\\xcd\\x24\\x9b\"\n\"\\xb5\\x22\\x44\\x5b\\x8b\\x9f\\xc3\\x8b\\x44\\x25\\x86\\xc1\\x1e\\xee\\xa4\\x47\"\n\"\\x1d\\x71\\x5c\\x4a\\xa5\\xd9\\x1c\\x4c\\xa9\\x22\\xfb\\xb0\\x84\\xc1\\xf9\\xd3\"\n\"\\x1b\\xf4\\xfc\\xcd\\x1c\\xaf\\x5e\\xa5\\xa7\\x93\\xcb\\x2b\\x2f\\x6d\\xd1\\x4d\"\n\"\\xdb\\x7b\\x1c\\x70\\xba\\x42\\x32\\xfe\\x55\\x0f\\xa5\\xab\\xbc\\x27\\x88\\x5f\"\n\"\\x63\\x1a\\x46\\x99\\x64\\xc7\\x7b\\xc4\\x64\\x9c\\x10\\x72\\x1c\\x48\\x2c\\xf2\"\n\"\\x0f\\xba\\xa9\\xc0\\xcd\\x5a\\xea\\x18\\x74\\x7a\\x41\\x49\\x5a\\xc9\\x99\\x39\"\n\"\\x55\\x07\\xb9\\xc6\\x22\\xe6\\xed\\x04\\x70\\xdc\\xe0\\x56\\x57\\x38\\x86\\xf4\"\n\"\\x27\\x1d\\x01\\x06\\xf5\\xc8\\x73\\x50\\x1d\\xeb\\x67\\xbd\\x47\\x67\\x9e\\x1f\"\n\"\\xa8\\x86\\x5c\\xdf\\x0a\\xf9\\xd5\\x39\\x93\\x02\\x3e\\x39\\xde\\x73\\xd9\\xbc\"\n\"\\x6f\\x55\\xce\\x61\\x08\\x9c\\xd8\\x01\\x7f\\x48\\x89\\x9a\\x8e\\x94\\xe3\\xce\"\n\"\\x12\\xf8\\xe4\\x69\\xa3\\x5a\\xb9\\xa4\\x5d\\xcf\\x4e\\x5a\\x6a\\x7e\\x97\\x6c\"\n\"\\xd6\\x3d\\xf4\\x15\\xf0\\x37\\xe0\\x6a\\x16\\x7e\\xec\\x90\\xe1\\xea\\xdd\\x6d\"\n\"\\x29\\x27\\x06\\x4e\\x08\\x02\\xb8\\x87\\x7b\\x0b\\x18\\x71\\x7c\\xe9\\xf6\\x65\"\n\"\\x98\\x4d\\xbe\\x1f\\x1d\\x9e\\x5e\\xc5\\xb3\\xdd\\xa8\\xfa\\x10\\x5e\\x6b\\x89\"\n\"\\xba\\xf0\\xd3\\xfb\\x7c\\xb6\\x5a\\x74\\xbd\\x80\\xa4\\x2d\\x87\\x62\\x08\\xee\"\n\"\\x86\\xb3\\xdf\\x5e\\x7d\\xeb\\xe4\\xc4\\x1f\\x3a\\x4c\\x03\\x21\\xbc\\x1c\\x99\"\n\"\\x96\\xca\\x7d\\xed\\x46\\x4f\\x58\\x8f\\x3b\\xf0\\xfb\\x43\\xc1\\x14\\xfa\\x89\"\n\"\\x97\\x8c\\x8a\\xa6\\x77\\xdc\\x3b\\xe2\\xe1\\x3f\\x01\\xda\\xbf\\xfa\\x54\\xcd\"\n\"\\x45\\xbc\\xf5\\x6d\\x75\\x9f\\x17\\x05\\x64\\xad\\xb4\\x25\\x3b\\x79\\xcd\\xb2\"\n\"\\x61\\x9e\\xb8\\xd1\\x21\\xda\\x83\\x96\\xfa\\xe9\\x3b\\xa4\\xa9\\x24\\x80\\x91\"\n\"\\x8b\\x2d\\x6d\\xd6\\x94\\x4e\\x18\\x99\\x88\\xaf\\x09\\xe0\\x50\\x4a\\x83\\x7c\"\n\"\\xdb\\xc0\\x2b\\x86\\x02\\xf0\\xf7\\x22\\xd3\\x6b\\x2d\\x07\\x43\\xf2\\xd7\\x78\"\n\"\\x0a\\x0c\\x88\\x7a\\x05\\x2d\\x55\\xf3\\x0e\\x63\\x94\\x14\\x40\\x72\\xee\\xa4\"\n\"\\x9d\\x68\\x1e\\x75\\x1c\\x14\\x7e\\x07\\x4c\\x7c\\x36\\x0f\\x0b\\x8c\\xcc\\x26\"\n\"\\xa5\\xfc\\xe2\\x86\\xbf\\x0f\\x93\\x77\\xab\\xf7\\x2f\\x26\\x6e\\x5e\\x39\\x90\"\n\"\\xe2\\x10\\x1c\\xaf\\x27\\x8e\\x76\\x3d\\x63\\xff\\x4c\\xbe\\x39\\x10\\xfa\\x97\"\n\"\\x55\\xe0\\xe3\\x6e\\x76\\xcc\\x06\\xbd\\xb4\\x05\\x18\\xdb\\x0b\\x97\\x47\\x19\"\n\"\\x88\\x1d\\x0f\\x57\\xe0\\x46\\x07\\x87\\x4c\\x09\\x2d\\x46\\x2a\\xb5\\xda\\x22\"\n\"\\xd0\\x11\\xae\\xa1\\x9e\\xad\\x03\\xba\\xaa\\x8c\\x98\\x5f\\x80\\xd9\\x11\\xff\"\n\"\\x49\\xbb\\x87\\xe2\\x46\\x9d\\xe1\\xe6\\xab\\xf1\\xbc\\x14\\x82\\x9b\\xc4\\x77\"\n\"\\xcd\\xf8\\x07\\x14\\xf9\\xaa\\xc4\\xa0\\x7b\\x0a\\x46\\xe0\\xb5\\xf2\\x6b\\x7c\"\n\"\\xcf\\xb8\\x3a\\x84\\x1a\\xa3\\x28\\x36\\x7e\\xdd\\xe7\\xea\\xd1\\x5d\\xaf\\x38\"\n\"\\x8e\\xa0\\x4c\\x72\\xb4\\xbb\\x05\\x91\\x19\\x81\\x86\\x97\\x22\\xe4\\xc4\\xeb\"\n\"\\x8a\\xe3\\x20\\x62\\x45\\x24\\xf0\\x1f\\xc3\\x41\\xc2\\xe7\\x5e\\xbc\\xdb\\x98\"\n\"\\xb4\\x6b\\xec\\x0b\\x9c\\xcf\\xa1\\xe3\\x37\\x96\\xc7\\x92\\xfe\\x74\\x0e\\x38\"\n\"\\xbd\\xcb\\xdd\\x73\\x93\\x3c\\x4b\\x8f\\xe6\\xcc\\x86\\x17\\x45\\xbf\\x48\\x09\"\n\"\\xcf\\x33\\x5f\\xc1\\x81\\xe1\\xa8\\xb5\\x79\\xef\\x3c\\x9d\\x1d\\xf6\\xbf\\xec\"\n\"\\xc1\\xbb\\x42\\x82\\xea\\x4d\\x7d\\x9d\\x2a\\x52\\x45\\xaf\\x04\\xfa\\x3b\\x46\"\n\"\\x5d\\x23\\xbd\\x62\\x07\\xf9\\xbe\\x67\\x8e\\xb0\\xb3\\xe7\\x60\\x62\\xb6\\x1c\"\n\"\\xd8\\x99\\x2b\\x2a\\xff\\x36\\xb4\\xd2\\xa8\\xdc\\x8b\\xb8\\xd4\\x08\\xdb\\x81\"\n\"\\xd2\\x4d\\xda\\xc1\\x33\\xa6\\xe5\\xc8\\xfe\\x55\\xb7\\x20\\x07\\x73\\xcd\\x41\"\n\"\\x79\\x81\\xff\\x19\\xbf\\x84\\xa4\\x69\\x5c\\x65\\xe2\\xc9\\xae\\x3d\\x0f\\x68\"\n\"\\xab\\x65\\x74\\xdb\\xee\\xed\\x75\\x1e\\xc3\\xaa\\x6c\\xc5\\xef\\x25\\x26\\x9b\"\n\"\\xd8\\x36\\xd0\\x82\\xc7\\xd8\\x05\\xc9\\x47\\x0f\\xf1\\xf9\\x18\\xb6\\x64\\xfb\"\n\"\\xd2\\xcc\\x83\\xe0\\x2e\\x01\\x2d\\x58\\x59\\x8b\\xba\\x91\\xc1\\x99\\x42\\x99\"\n\"\\x93\\xc1\\x26\\xd5\\x52\\x03\\x7e\\x49\\x39\\xd9\\x13\\xf2\\x2c\\x18\\xec\\x89\"\n\"\\x2f\\x0a\\xe1\\x3f\\xb6\\x79\\x73\\xa6\\x82\\x2a\\x21\\x9f\\xf4\\x33\\x49\\x13\"\n\"\\xb6\\x09\\x58\\xca\\x93\\x39\\xa6\\x3a\\x62\\xd6\\x90\\xd7\\x06\\x2c\\x1e\\xf5\"\n\"\\xcc\\xc1\\xac\\x6e\\x27\\x78\\xc2\\x11\\x1a\\xf4\\xbf\\xd7\\x5a\\xd6\\x88\\xbc\"\n\"\\xfb\\x81\\xb1\\xa8\\xc1\\x61\\xbf\\x9d\\x02\\x89\\xce\\xf3\\x85\\x62\\x04\\x2e\"\n\"\\x90\\x9d\\x92\\x11\\x98\\xe6\\x05\\x21\\x7a\\x83\\x94\\x22\\x0c\\x95\\xcd\\xe2\"\n\"\\xa7\\xc3\\x66\\x0a\\x1c\\x28\\xcc\\x05\\xd2\\xde\\x96\\x9f\\xfb\\xd3\\x32\\xec\"\n\"\\x51\\x3e\\x67\\x96\\x2d\\x24\\xad\\x9c\\xe4\\xee\\xa7\\xc1\\x55\\xf0\\x86\\x1b\"\n\"\\x5d\\x5d\\xef\\x95\\x5a\\xab\\x39\\xbf\\xb1\\xe9\\x8e\\x82\\xef\\xb2\\xb0\\x8b\"\n\"\\x2e\\x88\\xdf\\x45\\xe9\\x09\\xe0\\x4c\\x50\\xec\\xb5\\xa1\\xa8\\x68\\x48\\xa9\"\n\"\\xf3\\x77\\xf5\\xaa\\xd0\\x8f\\xba\\xbf\\x89\\x97\\x9f\\xd2\\xff\\x0a\\x73\\x95\"\n\"\\xe3\\xde\\x2a\\x47\\x76\\x2f\\x56\\x37\\xef\\x44\\x7d\\xc4\\x61\\x23\\xac\\xd6\"\n\"\\x50\\x5e\\xd6\\x82\\x71\\x90\\xfe\\xd8\\x85\\xd2\\xf6\\xaf\\x8d\\x5e\\xfc\\x09\"\n\"\\xee\\x61\\x34\\xa2\\x8c\\xe6\\xad\\x49\\x8e\\x49\\xc1\\xe6\\xad\\xf0\\x93\\x28\"\n\"\\xb7\\xa9\\xe6\\x4e\\x4d\\xd9\\xb2\\x20\\xce\\x94\\x78\\x8b\\x72\\x8e\\x39\\x17\"\n\"\\xa5\\x6a\\x6e\\x85\\x83\\x4e\\x72\\x0f\\x9e\\x55\\xaa\\x25\\x6e\\x38\\xf6\\x9f\"\n\"\\xc4\\x2b\\xdf\\xe4\\x5d\\x06\\xdb\\x12\\x33\\xbd\\x3e\\xf3\\x49\\xbb\\x1c\\x0c\"\n\"\\xe1\\x58\\x49\\x07\\xe7\\xcb\\xdb\\x68\\xd5\\x03\\xe7\\xcb\\xfc\\xe6\\x21\\xaf\"\n\"\\xeb\\xb9\\x7c\\x80\\x81\\x8a\\xe9\\x92\\x4b\\x19\\x84\\x02\\x59\\xdf\\x47\\x47\"\n\"\\xc2\\x63\\xb8\\xfa\\x31\\xc3\\x56\\xf3\\x6f\\x4d\\x88\\x97\\x77\\x9d\\xfb\\x3a\"\n\"\\xdd\\x30\\xdd\\xd9\\x13\\x11\\xdf\\xa6\\xe8\\xe9\\x6a\\x75\\xde\\xdd\\xd8\\x1e\"\n\"\\xf1\\xc1\\x02\\xce\\x0e\\x89\\x68\\xc6\\xd5\\x66\\x29\\xee\\x58\\xe3\\x19\\xa0\"\n\"\\xc3\\xe1\\xfc\\x0f\\xaa\\xb3\\x68\\x43\\xd8\\x06\\x20\\x5f\\x0e\\x13\\xe6\\xd3\"\n\"\\x7e\\xcc\\x0d\\x84\\x68\\x16\\x9e\\x22\\xf9\\xc6\\xae\\x2b\\xe1\\xfd\\xe5\\xa7\"\n\"\\xba\\x65\\x12\\xf2\\x64\\xbc\\x78\\x02\\x4a\\x9d\\x76\\x7e\\xaa\\x83\\xcf\\x0f\"\n\"\\xa5\\xb6\\x1a\\x47\\x7a\\x16\\x50\\xd7\\x40\\x41\\x86\\x98\\x75\\xca\\x7b\\x79\"\n\"\\xc2\\x17\\x03\\x03\\x00\\x58\\x01\\x13\\xe8\\x5c\\xca\\xef\\xcf\\x13\\xe7\\x31\"\n\"\\x1a\\x59\\x81\\x57\\x8d\\x8f\\x15\\x2a\\xaf\\x2f\\xe3\\x37\\xf8\\x1e\\xf5\\xe6\"\n\"\\x91\\x5d\\x6a\\xde\\x22\\xd3\\x57\\x7e\\x90\\x5f\\x17\\x63\\xc2\\x98\\x0e\\x50\"\n\"\\x46\\xf7\\x04\\x7d\\x34\\xc5\\xd7\\xb8\\x6c\\xcf\\xda\\x59\\x43\\x66\\x6a\\x49\"\n\"\\x07\\xe4\\x30\\x1d\\xb9\\x18\\xb7\\xf0\\xe0\\xbb\\xca\\xc4\\xd9\\x3d\\xa6\\x87\"\n\"\\xd8\\xd2\\x0e\\x11\\xf6\\xe4\\x23\\x55\\xf0\\x54\\xd1\\xeb\\x93\\xaa\\x17\\x03\"\n\"\\x03\\x00\\x3e\\xa6\\xec\\xb5\\x00\\x2d\\xca\\x7a\\x32\\xbf\\xf0\\x82\\x38\\xe7\"\n\"\\xd1\\x97\\x8d\\x71\\x61\\x5b\\x01\\x4b\\xa6\\x03\\xc1\\xf5\\xcb\\xa4\\x3d\\x6a\"\n\"\\xd9\\xa4\\x77\\x75\\xe0\\x36\\xd1\\x49\\x2a\\xae\\x29\\x5a\\x54\\xa1\\x1b\\x00\"\n\"\\x43\\xfd\\x8e\\x60\\xd1\\xe7\\xe4\\xf7\\x94\\xb3\\x5a\\x1f\\x62\\x78\\x5a\\xe9\"\n\"\\x0b\\x17\\x03\\x03\\x02\\xfa\\xf8\\xa2\\x71\\x92\\xf6\\x0b\\x21\\x4d\\x79\\xa1\"\n\"\\xb8\\x27\\x14\\xe7\\xd3\\x21\\xc4\\x09\\xcd\\x7e\\x2e\\x65\\xf1\\xaf\\x09\\x93\"\n\"\\x1a\\xfb\\x0c\\x97\\xd7\\x87\\x7a\\x88\\xfe\\xd4\\xfc\\xd5\\xa0\\x81\\xd4\\x11\"\n\"\\x40\\x83\\x17\\x42\\x58\\x07\\x0f\\xf1\\xa8\\x6e\\xdb\\xa4\\x8c\\x51\\x50\\xc3\"\n\"\\x74\\xa6\\xf0\\xb1\\x87\\x89\\x75\\xad\\xa8\\xf2\\x9d\\x0f\\x4e\\x16\\x54\\xc7\"\n\"\\xaa\\xa9\\xb7\\x02\\x1c\\xa7\\xe7\\xe7\\x1e\\x70\\x88\\x1b\\xb0\\x79\\x3e\\xe2\"\n\"\\xde\\x7d\\x42\\xd3\\xc6\\x4e\\x92\\x1d\\x3a\\xe3\\xc2\\x8e\\x0c\\x50\\xbd\\xfd\"\n\"\\xbe\\xe6\\xdc\\x63\\x93\\x77\\x79\\x7d\\x51\\x63\\x59\\xad\\x5c\\xc8\\x0d\\xd0\"\n\"\\x0f\\x83\\x57\\xbe\\xd8\\x80\\x95\\xbb\\xde\\x40\\xb1\\x11\\xc9\\x54\\x7e\\x73\"\n\"\\x23\\xfc\\xd3\\x74\\x97\\x0f\\xdd\\xd1\\xaa\\x95\\xc6\\xf5\\x29\\xa3\\x85\\xd4\"\n\"\\x92\\x94\\xc3\\xf1\\x0c\\x92\\x9c\\x9a\\x3e\\x1c\\x9e\\x4f\\x1e\\x5a\\x05\\x5c\"\n\"\\xe2\\xed\\x03\\xb0\\x1b\\xb2\\xbe\\x26\\x25\\xd1\\x18\\x63\\x3f\\x89\\xf2\\x0e\"\n\"\\xed\\x63\\x01\\xdf\\x7f\\x78\\xe2\\x65\\xd1\\xa5\\xa0\\xe5\\x1d\\xf1\\x16\\x50\"\n\"\\xe5\\x48\\x9e\\x55\\xeb\\xb4\\x9a\\xa9\\xb2\\xa4\\xdf\\x72\\x77\\x04\\xfa\\x28\"\n\"\\x58\\x98\\xcf\\x17\\xae\\x47\\xef\\xdb\\x1f\\x36\\x28\\xd3\\x58\\x69\\x58\\x7e\"\n\"\\x51\\xb8\\xc2\\xd1\\xc8\\x6d\\x99\\x56\\x39\\x39\\x45\\xac\\xfd\\xde\\xf0\\x97\"\n\"\\x96\\x68\\x12\\x37\\xe0\\x3b\\xa0\\x70\\x41\\x96\\xe5\\xbd\\x28\\x7c\\x9b\\x7a\"\n\"\\x7d\\xe4\\xfe\\x5e\\x36\\x1a\\x2f\\x85\\xc5\\x65\\xa2\\xb8\\xb6\\x20\\xad\\xff\"\n\"\\x19\\x55\\xfe\\xa7\\x73\\x0e\\x6f\\x90\\x25\\x4c\\x85\\xda\\xbf\\x45\\x73\\x21\"\n\"\\x29\\xc7\\x7a\\x6f\\xa7\\xa9\\x71\\x13\\xc5\\x12\\x5d\\xe9\\xf6\\xec\\x38\\x86\"\n\"\\x0c\\xba\\x33\\x39\\x92\\x1b\\x32\\x46\\xd9\\xd8\\xe5\\x37\\xa2\\x27\\x64\\x9b\"\n\"\\x06\\x3d\\x38\\xff\\xd5\\x41\\x84\\x63\\x6a\\x0f\\xfd\\xec\\x2b\\x16\\x85\\x7f\"\n\"\\xa5\\xa5\\x0b\\xd9\\xc1\\x96\\x00\\xb9\\x30\\x91\\xb1\\xba\\x00\\xb1\\x07\\xa0\"\n\"\\x03\\xe9\\xc5\\x60\\x07\\x71\\x53\\x88\\xcf\\xd5\\x4f\\xdd\\x92\\xe8\\xd1\\xb3\"\n\"\\xac\\xb8\\xaa\\x7a\\xd5\\x1f\\x49\\x69\\xd8\\x8b\\x39\\x48\\xc9\\x82\\x05\\x5c\"\n\"\\x25\\x1a\\x84\\xc8\\x43\\xf3\\x7a\\x03\\xfa\\xf3\\x6e\\xff\\x56\\xc2\\x14\\xca\"\n\"\\x31\\x4b\\xb7\\xf6\\x19\\x3f\\x59\\x5a\\x96\\xb0\\xb2\\xdf\\x3f\\xfe\\x10\\x1a\"\n\"\\x01\\xcb\\xe9\\x6c\\xea\\xa4\\x92\\x02\\xfe\\xed\\x0e\\xed\\x3d\\x7a\\xa1\\xba\"\n\"\\xf5\\x53\\xe5\\x49\\x73\\xa1\\x25\\x8d\\x47\\x83\\x44\\xfe\\x22\\x06\\x7b\\x0c\"\n\"\\x47\\xba\\x79\\x4a\\x2e\\x6d\\x61\\x3c\\x8e\\xff\\x6f\\x5a\\xc7\\x5a\\x55\\x9f\"\n\"\\x48\\xf3\\xa4\\x5b\\x4f\\x39\\xad\\x8f\\x07\\x53\\xea\\x4c\\x0d\\x16\\xf4\\x62\"\n\"\\xcb\\xd0\\x87\\xc2\\xc2\\x18\\x92\\x27\\xfa\\xe4\\xed\\x76\\xe2\\x31\\xce\\xab\"\n\"\\x08\\xcc\\x15\\xb3\\xc3\\x57\\xe5\\xcf\\xcc\\xa4\\x6d\\x4b\\x73\\xb6\\xea\\x82\"\n\"\\x56\\x79\\x31\\x6f\\xdf\\x6c\\xa4\\x0b\\x43\\x21\\xbe\\x27\\x72\\x06\\x1b\\x31\"\n\"\\xbc\\x95\\xb6\\xb7\\x6a\\xdf\\xee\\x87\\x05\\x28\\x88\\x31\\x6a\\x6f\\x5e\\xdd\"\n\"\\xdb\\xe2\\x34\\x7d\\xdb\\x35\\x5b\\x75\\xf7\\x12\\x20\\x8e\\x9b\\xc2\\x8a\\x0a\"\n\"\\xad\\x12\\x27\\x5d\\x20\\x2d\\x1b\\x31\\x3f\\x53\\x81\\x39\\xd2\\x40\\x16\\x29\"\n\"\\x1a\\x39\\x6a\\x46\\x87\\x5e\\xbf\\xd0\\x22\\xa3\\x22\\x7e\\xf6\\xbe\\xc7\\xfb\"\n\"\\x28\\xd5\\x20\\x72\\xe5\\x05\\x49\\xef\\x59\\xdc\\x7b\\x5f\\x5d\\x5c\\x2e\\x63\"\n\"\\x08\\x7a\\xe0\\x48\\x13\\xe1\\x77\\xbc\\xbe\\x7a\\xea\\xd7\\x53\\xc6\\xd6\\xae\"\n\"\\x3a\\x03\\x3d\\x19\\xae\\x09\\x8b\\xed\\xb0\\xbf\\x04\\xa0\\x99\\xd9\\x7d\\xe2\"\n\"\\x87\\xcd\\xb7\\x13\\xe3\\x0f\\x51\\x5a\\x27\\x29\\xfe\\x40\\x58\\x0e\\x64\\x2d\"\n\"\\xe6\\x57\\xc8\\xc5\\x6e\\x56\\xaa\\x06\\x8b\\xf5\\xf5\\xb4\\x41\\xb7\\x6a\\x10\"\n\"\\x8b\\x02\\x44\\xfa\\x66\\x77\\xeb\\xc2\\x0c\\xc9\\xe3\\x72\\x16\\x0c\\x98\\x3f\"\n\"\\xb3\\xd1\\x0a\\x94\\x2e\\xc9\\xd5\\x8c\\xff\\x08\\x31\\x4f\\xd7\\x10\\x20\\x9c\"\n\"\\xa1\\xcf\\x52\\x74\\xf3\\xa5\\x04\\x29\\x31\\xe3\\xf3\\xce\\x36\\xf5\\x0f\\x9e\"\n\"\\x8c\\xb8\\x88\\x71\\x61\\x84\\xb8\\xec\\xd9\\xa1\\x45\\x9e\\x20\\xa6\\xd5\\x94\"\n\"\\x3c\\x06\\x0c\\xd1\\x5b\\x95\\x0d\\x38\\x2f\\xcc\\x25\\x45\\x4f\\x78\\x41\\xa2\"\n\"\\x17\\x03\\x03\\x00\\x3f\\x98\\x62\\x5c\\x36\\x38\\xab\\xdd\\x46\\xb1\\x5c\\xbc\"\n\"\\x34\\xcc\\xa1\\x29\\xb3\\x58\\xf0\\x40\\xf6\\x1d\\x6e\\x8f\\x6f\\xee\\xb6\\xb8\"\n\"\\x34\\x8f\\x89\\xe7\\x4e\\x63\\x52\\x3c\\x03\\x63\\xd9\\x93\\x78\\xb7\\x5b\\x74\"\n\"\\xb0\\xa1\\xd4\\x15\\xf7\\xeb\\x77\\xbc\\xec\\x3c\\x8f\\x01\\x18\\x71\\x18\\x42\"\n\"\\x21\\xf6\\x0c\\x40\\x17\\x03\\x03\\x05\\x4b\\xf5\\xe2\\xcb\\x37\\x60\\xc4\\x70\"\n\"\\x30\\x62\\xf6\\x9b\\x22\\x1a\\x6a\\xc6\\x31\\xb1\\xd4\\xc7\\x6f\\x41\\x99\\x67\"\n\"\\x2b\\x08\\xcf\\xe3\\xe8\\x77\\x1c\\x5c\\x37\\x37\\x4c\\xd1\\x00\\x20\\xa5\\xc1\"\n\"\\x60\\xc2\\x34\\xb0\\xdd\\x9d\\x16\\xef\\x03\\x60\\x4b\\x24\\xce\\xbf\\x71\\x99\"\n\"\\x42\\x02\\xb1\\x14\\x38\\xe6\\x04\\xa1\\xa6\\x74\\x11\\x27\\x18\\xe0\\xe5\\x36\"\n\"\\xeb\\x94\\x1d\\xe0\\x5a\\x50\\x2b\\x53\\x85\\xc6\\x56\\xe2\\xf7\\x7d\\x44\\xa5\"\n\"\\xc6\\x88\\xb7\\x4d\\xad\\x79\\xdb\\x57\\xb5\\x02\\x78\\x79\\x9e\\x43\\x6d\\xc7\"\n\"\\xcd\\x25\\x8c\\x11\\x50\\x9d\\x46\\xa7\\x23\\x76\\xc9\\x5d\\x02\\x47\\xad\\x15\"\n\"\\x94\\x18\\xa2\\x82\\x82\\x06\\x70\\xe2\\x57\\xc3\\x08\\xf3\\x4f\\xc3\\xe2\\x17\"\n\"\\x26\\x8f\\x6b\\x88\\x95\\x89\\xe8\\x6b\\x97\\x7f\\x10\\xf7\\x4f\\xe3\\xeb\\xbb\"\n\"\\x68\\x1a\\x83\\x40\\x12\\x5e\\x14\\xa9\\x28\\x25\\x56\\xc3\\x14\\x78\\x93\\xe1\"\n\"\\xae\\x09\\xf0\\xf7\\x38\\x03\\x2a\\x63\\x50\\x1f\\x5e\\x5b\\x53\\x85\\x59\\x43\"\n\"\\x69\\xa2\\x6f\\xaf\\x55\\x5a\\xf5\\xd6\\x82\\x3d\\x78\\xd8\\x55\\x22\\x53\\xd2\"\n\"\\x3c\\x90\\xe3\\x68\\xd7\\x31\\xb3\\xcc\\x3d\\x18\\x2e\\x70\\x49\\x82\\x86\\x58\"\n\"\\x89\\x0c\\x50\\xf8\\xec\\x28\\x48\\x62\\x0d\\xde\\x9a\\x2a\\x94\\x25\\x41\\x11\"\n\"\\xa8\\xc6\\x34\\xfa\\x65\\x38\\x97\\x24\\x5d\\x61\\x6d\\x37\\x01\\x2b\\x89\\xb9\"\n\"\\xd9\\x8c\\x34\\xbf\\x3c\\x59\\xbc\\x75\\xc4\\x31\\x6f\\xa0\\xf6\\x5e\\x23\\x22\"\n\"\\xfc\\x74\\xc5\\x56\\x60\\x0a\\xef\\x39\\x68\\x20\\xeb\\x8d\\x3f\\xef\\x12\\xb2\"\n\"\\x4c\\x0d\\xfb\\xbb\\x16\\xda\\xb1\\xd8\\xe9\\x5b\\x1b\\xb4\\x92\\x8a\\x8f\\xc7\"\n\"\\x7c\\x39\\x57\\x75\\x95\\x12\\x78\\xdc\\xec\\xc6\\x2f\\x2b\\x7a\\x46\\x5d\\x9c\"\n\"\\x9b\\xd7\\x9e\\xdf\\xfc\\xdc\\xc0\\x01\\x26\\x8e\\xbf\\x46\\x9b\\x4c\\x3c\\x0b\"\n\"\\xd6\\x4e\\xdf\\xf7\\x08\\xe0\\x45\\x27\\xcd\\x06\\xda\\xe6\\xae\\x1a\\x09\\xc4\"\n\"\\x78\\x83\\x3e\\xee\\x06\\x75\\x11\\x96\\xd9\\x8a\\xc7\\x3b\\xbb\\x3a\\x7e\\xb6\"\n\"\\x84\\xbe\\xaf\\x9e\\xf6\\x50\\x8f\\x6e\\x6d\\xa5\\x45\\xe7\\x99\\x0f\\xba\\x78\"\n\"\\x0b\\x1e\\xe9\\xf7\\x84\\x1a\\x45\\xbe\\xdc\\x9e\\x7e\\xa8\\xd2\\x95\\x45\\x8c\"\n\"\\x00\\x59\\xe4\\x14\\xef\\x78\\xd2\\x04\\x83\\x99\\xc5\\x8f\\x75\\x67\\xd0\\x5c\"\n\"\\x89\\xd9\\x6b\\x89\\x07\\xe1\\x27\\x2e\\x4c\\x6d\\x52\\xa0\\xc1\\xb7\\xa9\\xd9\"\n\"\\x42\\xb6\\xf0\\xbd\\x04\\x90\\xea\\x4c\\x2b\\x1c\\x38\\x17\\xaf\\x58\\xb3\\x8f\"\n\"\\x5f\\x01\\xad\\x15\\xb8\\x4f\\x01\\xc2\\x7d\\xa3\\x2c\\x5f\\x8c\\x4f\\xd8\\x81\"\n\"\\xba\\x1c\\x7e\\xd7\\xd4\\xcd\\xc6\\x33\\x0d\\x1d\\x22\\xd3\\xe5\\x31\\x2d\\x44\"\n\"\\x43\\xfb\\xca\\x57\\x46\\xbd\\x11\\x45\\xa0\\x4b\\xc4\\x25\\x3d\\x69\\x26\\x75\"\n\"\\x3c\\xc1\\xac\\xdf\\x17\\xa7\\xcc\\x2a\\x23\\xeb\\x83\\xae\\x40\\x90\\x27\\x0d\"\n\"\\xbb\\x96\\x44\\xe1\\x07\\xc8\\xd4\\x50\\x61\\x9c\\xd3\\xd4\\xe0\\xbd\\x40\\xc5\"\n\"\\x2e\\xe4\\x5b\\xff\\xe3\\x52\\xa4\\xae\\x0c\\xad\\x6a\\xdd\\xf7\\xaf\\x82\\x0d\"\n\"\\x7a\\x0d\\x36\\x7d\\x52\\x5b\\x80\\x55\\x13\\x6e\\x4f\\x96\\x41\\x0f\\xdb\\x70\"\n\"\\x62\\x1b\\xfa\\x81\\xc4\\x42\\x8e\\x17\\xe4\\x2e\\xb2\\x65\\x94\\x09\\x49\\xb2\"\n\"\\xe5\\x53\\x59\\xcb\\x6f\\x02\\xe7\\xee\\x44\\x71\\x09\\x85\\x83\\xf8\\xb0\\xd0\"\n\"\\x77\\xc6\\xc0\\x84\\xc0\\x6d\\x1a\\xfc\\x82\\x07\\xcc\\x3e\\x1e\\x76\\x93\\x9a\"\n\"\\xbd\\xdc\\xb4\\xc4\\xaf\\x75\\xac\\x25\\x0b\\x1e\\xfb\\xf3\\x17\\xf1\\x9c\\x56\"\n\"\\xeb\\x24\\x6d\\xf9\\xab\\xd8\\xf1\\xf4\\x88\\x14\\x9a\\xd0\\xc4\\x14\\x89\\x4f\"\n\"\\xe2\\xe9\\x0d\\x15\\xb8\\x76\\x84\\x90\\x87\\xa8\\xa4\\x3a\\x8f\\xed\\xb3\\x0f\"\n\"\\x46\\x5b\\x9f\\x6d\\xe1\\x21\\xd1\\x11\\x09\\x94\\x7a\\xdd\\xf7\\x0b\\xf0\\x11\"\n\"\\xe7\\xf2\\x4b\\x8e\\xdb\\x98\\x47\\xe7\\xec\\x84\\x6c\\xee\\x67\\x4b\\xb9\\x53\"\n\"\\x5a\\xa3\\x08\\x84\\xcc\\xcb\\xfe\\x11\\xcc\\x5a\\x71\\x1f\\xad\\x8d\\x9c\\x92\"\n\"\\x9a\\x93\\x08\\xd3\\x3d\\x32\\x1a\\xb9\\x62\\xd5\\x0d\\xab\\x4e\\xa3\\xa8\\xd7\"\n\"\\xa8\\x48\\x9c\\x8c\\xe0\\xf0\\x3e\\x92\\x21\\xf5\\x91\\xc8\\x0e\\xbe\\x19\\xbf\"\n\"\\x30\\x07\\xf7\\x78\\xb1\\xbd\\x09\\xd7\\xdc\\x82\\xcb\\x10\\xa3\\xee\\x0d\\x77\"\n\"\\xba\\x21\\x73\\x27\\x89\\x60\\x2f\\xd9\\x27\\xdd\\x81\\xde\\x00\\x95\\xbe\\xcd\"\n\"\\x4d\\x00\\xbc\\xfd\\x89\\x19\\x99\\xde\\xd1\\x16\\x91\\xcd\\x47\\xb2\\x55\\xf0\"\n\"\\x98\\xf7\\xdb\\x72\\xdb\\x05\\x21\\x2b\\xd3\\xc4\\x5d\\x43\\x6b\\x5b\\xf8\\x13\"\n\"\\x76\\x9e\\x42\\x2f\\x50\\xbc\\x39\\x1a\\xcf\\xff\\x9f\\x21\\xb1\\xdd\\x32\\x01\"\n\"\\xe1\\xc3\\x61\\xb5\\x76\\xee\\xcb\\xb8\\x16\\x3f\\xe6\\x7c\\xbf\\xff\\x0b\\xf3\"\n\"\\xb7\\x96\\x20\\x23\\xa9\\xbe\\x28\\x79\\x55\\x3d\\x04\\x54\\x0b\\xd4\\xbb\\x16\"\n\"\\xef\\x75\\xbf\\xc8\\xdf\\x87\\x7b\\xde\\x74\\xb9\\x88\\x92\\xf1\\x3c\\x99\\xbf\"\n\"\\x56\\xa7\\xe1\\xa6\\x14\\x46\\x9a\\xe9\\x55\\x4e\\x8f\\xbd\\xfe\\xa7\\x27\\xd4\"\n\"\\x4a\\x2f\\x5d\\xcd\\x84\\x71\\x20\\x8b\\x90\\xa5\\x93\\x1e\\xaf\\x40\\x4a\\xbd\"\n\"\\xe9\\xd9\\x40\\xb2\\x6e\\x8e\\x1b\\x84\\x02\\x79\\x0e\\xd7\\xaa\\x8e\\xc7\\x92\"\n\"\\x54\\x8a\\x6e\\xc9\\x44\\x9f\\x2d\\x39\\x35\\x0d\\x6d\\x6b\\x93\\x51\\x8a\\x02\"\n\"\\xba\\x80\\x7f\\x39\\xc8\\xb7\\x3a\\x82\\xcc\\x90\\x49\\xf7\\x77\\xa7\\x11\\xe6\"\n\"\\x01\\x75\\x2b\\xd5\\x6e\\x5a\\x2f\\xb0\\x0a\\x17\\x74\\xd0\\xbd\\x89\\xb7\\x1f\"\n\"\\x43\\xcd\\xbe\\xef\\xc8\\xc9\\x20\\x3e\\xf8\\xe0\\xb9\\xb7\\x94\\x09\\x43\\xcd\"\n\"\\x9c\\x7a\\xe0\\x8f\\xe6\\xf2\\x59\\x1f\\xed\\x88\\xb4\\xb8\\x90\\xe8\\x0a\\xe6\"\n\"\\x16\\x8c\\xb5\\xdc\\x13\\x0b\\xcb\\x36\\xa5\\xe5\\x97\\x24\\x71\\x2b\\x2b\\xee\"\n\"\\x81\\xd3\\xa6\\x83\\x98\\x70\\xca\\x99\\x02\\xe4\\x05\\x7c\\x89\\xb2\\x99\\xd1\"\n\"\\x35\\xf1\\x8e\\x77\\xa9\\x30\\x7f\\xb6\\x7b\\x81\\x90\\x7c\\xb2\\x5d\\xaf\\x17\"\n\"\\x97\\x74\\xc6\\x0a\\x21\\x45\\x47\\x03\\x94\\xf4\\x2e\\x7a\\x15\\x7d\\xfd\\xe3\"\n\"\\xf3\\xbc\\xae\\x7c\\xce\\x23\\xfc\\xe7\\xe7\\x0d\\x81\\x74\\x1f\\x8f\\xef\\x20\"\n\"\\x70\\x25\\x4c\\x01\\x30\\x55\\xe1\\xd2\\xb9\\xc3\\x26\\x5d\\x69\\x45\\x6e\\x8e\"\n\"\\x74\\x53\\xc0\\x4d\\x07\\xa3\\x9f\\xf3\\x46\\xbe\\xb2\\x0b\\x15\\x1a\\x17\\xae\"\n\"\\x3f\\x26\\x23\\xe1\\x03\\x20\\xee\\xfb\\xfe\\x50\\x34\\x70\\x57\\xd9\\xeb\\xa6\"\n\"\\xb0\\xd3\\x6d\\xc1\\x1d\\x89\\xd7\\x94\\xa6\\x4a\\x1e\\x47\\xf7\\xcb\\x97\\x20\"\n\"\\x20\\xe2\\x3f\\xea\\x74\\xc6\\x37\\x7c\\x16\\xda\\xa9\\x83\\x65\\xbf\\x64\\x20\"\n\"\\x1c\\xc4\\x3f\\xc7\\x83\\x07\\x1e\\x96\\xbd\\x77\\xd7\\x2c\\xf6\\x10\\x64\\x0c\"\n\"\\xef\\x61\\xd5\\xb0\\xa1\\x31\\xb6\\x8a\\x45\\xc9\\x85\\xcf\\xaa\\xf4\\x77\\xc6\"\n\"\\x2f\\xac\\xa5\\xde\\x69\\x62\\xf8\\x08\\x1c\\x74\\x80\\x4f\\x9e\\x08\\xc4\\xf4\"\n\"\\x8e\\x71\\x5b\\xa5\\x53\\x46\\xd6\\x9e\\x47\\x40\\xef\\x86\\x9f\\xa6\\x00\\xa1\"\n\"\\xc0\\xf1\\x36\\xa0\\xc3\\xda\\x92\\xf2\\x06\\x08\\x93\\x3d\\x04\\xc3\\x20\\x24\"\n\"\\xd9\\x7b\\x7a\\x80\\xdd\\xac\\xd4\\x01\\x7d\\xb8\\x5d\\xa8\\xce\\xbd\\x70\\x28\"\n\"\\x87\\x07\\x53\\x0c\\x0a\\x5a\\x6a\\xa3\\x6c\\x41\\x0c\\x05\\xf0\\xd1\\xaa\\x12\"\n\"\\x60\\xbc\\xd1\\xfa\\xb5\\xb9\\xec\\x52\\xa4\\x7b\\x32\\x28\\xd0\\xf9\\x5f\\xf0\"\n\"\\x14\\x39\\xdc\\xc9\\xff\\x53\\xc7\\x51\\xe7\\x60\\x9f\\x7e\\x6a\\x49\\x25\\xc1\"\n\"\\xf4\\x57\\x4a\\x95\\x93\\xf3\\x6d\\x7c\\xa1\\x67\\x1f\\xfd\\x2c\\xf2\\x36\\x12\"\n\"\\x02\\x29\\x2f\\x97\\x90\\xb7\\x5b\\xb8\\x80\\xb5\\x99\\xbe\\xaa\\xf1\\xd5\\xa1\"\n\"\\x4a\\x60\\x8f\\x5c\\xf8\\x0b\\x6e\\xa6\\x50\\x64\\x45\\xf4\\x3d\\x16\\x11\\x50\"\n\"\\x5c\\x7e\\x52\\x92\\x1c\\xd7\\x80\\x6a\\x56\\xc0\\xd8\\x81\\x7c\\x44\\x8b\\x75\"\n\"\\x97\\x67\\xcf\\xe6\\x17\\x03\\x03\\x05\\x4b\\xe6\\x0e\\xb7\\x81\\x02\\x6d\\x40\"\n\"\\xef\\x8e\\xb3\\xba\\xd0\\x06\\xf5\\xa0\\xc9\\x67\\xe1\\x47\\x93\\xab\\x8e\\xc6\"\n\"\\xd6\\x43\\xd8\\x78\\x03\\x6f\\xca\\xbf\\xb8\\x37\\xe9\\x99\\x16\\x57\\xb0\\x92\"\n\"\\x4c\\x53\\x30\\x49\\xb4\\xad\\x38\\x1f\\x3d\\x27\\x81\\x6e\\xf3\\x25\\x2e\\xa1\"\n\"\\xd6\\xbc\\xe5\\x1b\\xbc\\x20\\x2f\\x8c\\x48\\x87\\x9d\\xc3\\x16\\x6b\\x17\\x88\"\n\"\\x81\\x82\\x89\\x54\\x76\\x78\\xf2\\xfd\\x77\\x5c\\x76\\xb4\\x4a\\x23\\x57\\xb8\"\n\"\\xbe\\xc4\\x25\\xf3\\xc4\\x9a\\x6a\\xd1\\x44\\xd7\\xe6\\xe3\\x22\\x44\\x3a\\x24\"\n\"\\x07\\x78\\x36\\xcb\\x68\\xd6\\xe0\\x8f\\x88\\x0d\\x4c\\xd6\\x92\\x6b\\x67\\xd2\"\n\"\\x78\\xe1\\x07\\x9c\\x0d\\x62\\x18\\xbd\\x87\\x72\\xb5\\x05\\xf9\\x6f\\xfb\\x2f\"\n\"\\xb7\\x2a\\xe3\\x28\\x90\\x53\\xd9\\xd5\\xc3\\xc2\\xca\\xc8\\x5b\\x4d\\x99\\x2b\"\n\"\\xb7\\x94\\xec\\x26\\x40\\x2a\\x51\\xa0\\x2a\\xaa\\xf5\\x49\\x4c\\xce\\x3c\\x5d\"\n\"\\xcf\\x1f\\xd4\\x11\\xa6\\x03\\x56\\xe8\\x7f\\x6b\\xc8\\xd9\\xb6\\x9f\\x8e\\xce\"\n\"\\x95\\xe4\\x12\\xcc\\xda\\x02\\x8d\\xd2\\x5f\\x73\\x04\\x69\\xf5\\x5e\\x39\\xf1\"\n\"\\xbd\\x32\\x6f\\x53\\x91\\xd5\\x8f\\xe3\\x88\\x1d\\xb8\\x1e\\x33\\xf2\\xc2\\x17\"\n\"\\x0c\\x65\\xfe\\x5a\\x7c\\x3f\\x44\\x43\\x25\\x01\\xe5\\xb0\\xcd\\xd0\\xcd\\x57\"\n\"\\x68\\x2e\\x0d\\xcb\\xab\\xb2\\xca\\x1f\\x5e\\x29\\x37\\xce\\x8e\\x77\\xa9\\x28\"\n\"\\xa9\\xaf\\x36\\x63\\xab\\x66\\x31\\xa7\\x23\\x2b\\xb6\\xa1\\x3e\\x53\\xee\\x88\"\n\"\\x4d\\xa7\\x6f\\xda\\xa0\\x74\\xf2\\xeb\\x63\\x35\\x8f\\x24\\xa7\\x89\\xf5\\x0c\"\n\"\\x17\\xf0\\x91\\x67\\x3c\\x04\\xfb\\xcf\\xc2\\xd5\\x48\\x32\\xb4\\x2d\\xd6\\xb8\"\n\"\\x33\\x4c\\x72\\xf9\\x8d\\x29\\xc1\\xb5\\xde\\x3f\\x0a\\x06\\xb0\\x3b\\x60\\x4d\"\n\"\\x4e\\x14\\x4e\\x35\\x52\\x8b\\x5c\\x24\\xdd\\xfc\\x21\\xf5\\xac\\xf7\\x01\\x9e\"\n\"\\x72\\x71\\x0c\\x8e\\xaf\\x1a\\x9a\\xe5\\x27\\xbc\\xe0\\x57\\xf4\\xca\\xe3\\xe4\"\n\"\\x96\\xc1\\xf0\\xe0\\x2c\\xbf\\xe8\\x07\\xd2\\x75\\x95\\x93\\x75\\x97\\x97\\x91\"\n\"\\x20\\x34\\xe0\\xf4\\xf7\\x65\\xc2\\x55\\xe4\\x77\\x75\\x4b\\x23\\x70\\x7b\\x5b\"\n\"\\x51\\xe4\\x5a\\xab\\x87\\x05\\xbb\\x64\\x14\\xba\\x4a\\x4e\\x32\\x9f\\x38\\x67\"\n\"\\xbf\\x0c\\x11\\x0d\\x12\\xb6\\x5f\\xfe\\xf4\\xcc\\x71\\x12\\x01\\x11\\x57\\x5f\"\n\"\\x6f\\xe5\\x3d\\xbd\\xb3\\x62\\x9f\\x3e\\x7d\\x62\\xff\\x10\\xcb\\x8d\\x85\\x59\"\n\"\\xc5\\x8c\\xca\\x73\\x54\\x56\\xef\\x66\\x46\\x3c\\x92\\x54\\x69\\x35\\x4b\\x8e\"\n\"\\x37\\x77\\x60\\x57\\xc2\\x0b\\xfc\\x19\\xa3\\xba\\x2e\\x20\\xde\\x06\\x0b\\xc0\"\n\"\\xd0\\xf7\\x64\\xe7\\x3a\\x80\\xa7\\xb5\\x81\\x98\\x15\\xd6\\x47\\xe7\\x92\\x01\"\n\"\\x79\\xff\\xae\\x7a\\x3c\\x84\\x75\\x08\\x04\\x6e\\xc6\\xf6\\xdf\\x7b\\x19\\x8b\"\n\"\\x8c\\xa5\\x42\\x44\\xa3\\xf2\\x93\\x07\\xf7\\x3f\\x0a\\x60\\x69\\xa5\\x50\\xaf\"\n\"\\xc3\\xed\\xaf\\x11\\x21\\x0c\\xde\\xc9\\x76\\x51\\x3d\\x9d\\xc9\\x0b\\x14\\x2f\"\n\"\\xef\\x05\\x25\\x25\\x11\\xcf\\xff\\x00\\xf8\\xdd\\x5b\\x20\\x10\\xc1\\xe8\\x84\"\n\"\\xce\\xb6\\xd9\\xb8\\x13\\x6d\\x49\\xac\\xdf\\x2a\\xf4\\xc5\\x60\\x3d\\xa1\\xd2\"\n\"\\x7c\\x5d\\x5e\\x4e\\x9f\\xa0\\xc6\\xfa\\xf6\\xcc\\x6b\\x16\\x12\\xf1\\x42\\x06\"\n\"\\x6a\\x42\\x8e\\xf4\\xde\\x18\\x81\\x2f\\xcf\\xc2\\x59\\xe6\\x9c\\x1c\\x5a\\x8b\"\n\"\\x31\\x25\\x40\\x72\\x57\\xb4\\xde\\xb2\\x19\\xeb\\xe6\\x79\\x99\\x14\\x8f\\xa9\"\n\"\\xf3\\x35\\x8b\\x45\\x64\\x7b\\x8d\\x8c\\xbe\\x3b\\x06\\x5a\\x7a\\xc8\\x5e\\x0a\"\n\"\\x69\\x24\\x88\\x9f\\xd0\\x8a\\x56\\x0d\\xf2\\xad\\x25\\x37\\x9b\\x67\\x7a\\x4d\"\n\"\\xea\\x89\\xf6\\xa6\\x05\\x04\\xab\\xeb\\x49\\xff\\x03\\xfd\\x9d\\xf7\\xc4\\xcd\"\n\"\\x1a\\xd4\\x0c\\x68\\x8b\\x04\\x35\\xfc\\x9b\\xdf\\x48\\x6d\\x4c\\xe8\\x09\\xd5\"\n\"\\x43\\xcf\\xd7\\x1b\\x0e\\xd9\\x0c\\xd5\\x4a\\x6f\\x68\\x4a\\x3c\\xf1\\x70\\x93\"\n\"\\xb5\\x22\\xa7\\x9b\\x3d\\x21\\x3b\\x77\\x75\\x43\\x25\\x03\\xcb\\x34\\xff\\x73\"\n\"\\x27\\x1c\\x36\\x95\\xac\\xde\\x43\\xb2\\x89\\x2d\\x87\\x16\\x78\\xba\\xf7\\xb0\"\n\"\\xcf\\x2b\\xb2\\x1e\\x84\\x69\\x29\\x57\\x9e\\xb6\\xcc\\x67\\xef\\x52\\x9b\\x02\"\n\"\\x0d\\xbe\\xee\\xc7\\x52\\x00\\x74\\xec\\x14\\x2e\\xda\\x8d\\x1f\\xee\\xe9\\x55\"\n\"\\x5d\\x58\\x88\\xe8\\x0f\\x00\\x97\\xe2\\x2e\\xfe\\xa8\\x4a\\x24\\x24\\xec\\x49\"\n\"\\x45\\x0e\\x61\\xea\\xb2\\x1b\\xc7\\x70\\x09\\x46\\xfa\\x74\\xa1\\xd6\\x1c\\xe1\"\n\"\\x19\\x3d\\x94\\x16\\x74\\xb7\\xb0\\xaa\\x0f\\x0f\\x4b\\x9a\\x13\\xfa\\x21\\x80\"\n\"\\xb5\\x61\\xc7\\x45\\xc7\\x5f\\xd2\\x97\\x8a\\xd8\\x0f\\x6d\\xac\\xab\\xe7\\x35\"\n\"\\x63\\xd5\\x6d\\x2e\\x07\\x3c\\x9e\\x5d\\x99\\x46\\x8d\\x23\\xa7\\xaa\\xdb\\xdc\"\n\"\\xad\\xca\\xed\\x6f\\x77\\x85\\x59\\xf3\\x28\\xdf\\x19\\x5f\\x46\\x62\\x08\\x1e\"\n\"\\x5e\\x41\\xdd\\x3b\\xc2\\xf7\\xad\\xf6\\xbb\\xa8\\x0f\\xa8\\x5d\\xbc\\x18\\x37\"\n\"\\xbc\\x69\\xfd\\xb8\\x51\\x03\\x13\\x3d\\x6c\\x5c\\xce\\x01\\xa8\\xd8\\x81\\xbc\"\n\"\\xcf\\xc7\\x31\\xb5\\x36\\x46\\x14\\x5d\\x99\\x79\\x60\\x46\\xaf\\xe9\\xf7\\xa2\"\n\"\\x5b\\xb1\\x78\\xb2\\x69\\x9d\\x4e\\x81\\x19\\x13\\x67\\x6b\\x7a\\x89\\xa4\\x22\"\n\"\\x01\\xe8\\x76\\x1b\\xe0\\xbb\\xc1\\xe6\\x87\\x8d\\x67\\x7b\\x0d\\x35\\x35\\x71\"\n\"\\x5c\\xb9\\x81\\xc1\\x4c\\x93\\xfa\\xff\\xb2\\xa9\\xf3\\x62\\x64\\x3a\\x0a\\x3c\"\n\"\\x47\\x10\\x35\\xd8\\x2b\\xc5\\xb5\\xf0\\xa4\\xcd\\xe9\\xc6\\x4b\\x30\\x60\\x0d\"\n\"\\x3f\\xcd\\x8e\\x63\\xf3\\x04\\x00\\xa7\\xd4\\xb5\\x3f\\x0a\\x22\\x3d\\x05\\x7e\"\n\"\\x14\\x4e\\xf6\\xc4\\xbf\\x0a\\x87\\x32\\x45\\x7d\\x9e\\xd8\\x2e\\x07\\xdc\\x5b\"\n\"\\x3f\\xd5\\x6c\\x38\\x4b\\x8c\\xe0\\xa0\\x35\\xb0\\xb6\\x08\\x1b\\x76\\xaa\\x13\"\n\"\\x71\\xdc\\x15\\x27\\x64\\x55\\xb5\\x2a\\xb4\\xe9\\xf6\\xde\\x99\\x37\\x31\\x81\"\n\"\\xbe\\x38\\xe2\\xf1\\x70\\xab\\xbe\\xf8\\xae\\xe0\\x96\\x92\\xaf\\x33\\x68\\xe5\"\n\"\\x67\\xeb\\x01\\x7e\\x21\\xab\\x1e\\x29\\x06\\x1d\\x4a\\x8c\\x9d\\xea\\x0d\\x77\"\n\"\\xc1\\x78\\x9c\\x3f\\x34\\xd0\\xc7\\x35\\x6f\\x9f\\x17\\x5b\\x61\\x98\\xff\\x4e\"\n\"\\x16\\xc5\\x13\\x9b\\x62\\x24\\x26\\x47\\x40\\x8a\\xae\\xd7\\xa6\\x1a\\x78\\xbd\"\n\"\\x86\\x52\\xa1\\xc8\\x68\\x91\\x26\\x98\\x3c\\xe2\\xaa\\x21\\x0c\\x9a\\xc9\\x35\"\n\"\\x5f\\xbc\\x93\\x36\\xbc\\x46\\x0e\\x64\\x1f\\xae\\x64\\x4b\\x7a\\x3f\\x60\\x2e\"\n\"\\x5f\\x87\\x94\\x19\\x1b\\x73\\x8e\\x33\\xed\\x27\\xf7\\xcd\\x36\\xec\\x22\\xb7\"\n\"\\x28\\x3c\\x11\\x39\\x45\\xe3\\xf6\\x0b\\x25\\xe0\\x44\\xa4\\xc0\\xf5\\xca\\x64\"\n\"\\xed\\xe0\\x47\\x04\\xd1\\xe1\\x8b\\x1f\\x87\\xc6\\x61\\x38\\xfa\\x20\\xfe\\xb0\"\n\"\\x16\\x34\\xad\\xe7\\x3b\\xb9\\x59\\x48\\xd5\\x8d\\x54\\xa3\\x79\\x89\\xeb\\xaa\"\n\"\\x69\\xf2\\xb1\\x19\\x3f\\x38\\xe1\\x2d\\xab\\xeb\\xe7\\x3b\\xf4\\xd1\\x1e\\x13\"\n\"\\x1b\\x13\\xa2\\xfe\\xff\\xe1\\x15\\x3b\\xaa\\x56\\x37\\x94\\x6f\\x45\\xda\\x8f\"\n\"\\x89\\x35\\x05\\x5e\\x7e\\x60\\x9d\\x3a\\xdf\\x72\\xdc\\xf0\\x59\\x83\\x8b\\xb5\"\n\"\\xe4\\x58\\xa4\\xea\\x5a\\x81\\xbf\\xfd\\xc3\\xf6\\x97\\x20\\xb0\\xf4\\xdf\\xf1\"\n\"\\x21\\x65\\x61\\xc2\\x98\\x32\\x52\\xb6\\x3a\\x4b\\xd8\\x5b\\x48\\xb3\\xf7\\xd6\"\n\"\\x1a\\x3a\\x98\\x91\\x73\\x51\\xff\\xcb\\x50\\x09\\xf4\\x0d\\x64\\x57\\x87\\x3b\"\n\"\\xb7\\xaf\\x9f\\x81\\x37\\xf3\\x94\\x9b\\x97\\xde\\x10\\x50\\x7c\\xec\\x47\\x84\"\n\"\\x8b\\x53\\x56\\xac\\x46\\x6f\\xab\\xf1\\x0b\\x9f\\xc3\\xd9\\x5b\\x45\\x5b\\x7a\"\n\"\\x28\\xcc\\xec\\xb5\\x92\\x04\\x66\\xae\\x75\\x48\\xc7\\x56\\x36\\xa8\\x34\\x73\"\n\"\\xcd\\x23\\xa7\\x5e\\x8b\\x0a\\x92\\xbf\\x70\\x24\\x90\\x1b\\x75\\x27\\x88\\x80\"\n\"\\x82\\x10\\xfc\\x5b\\x50\\xc4\\xa3\\x7e\\x13\\x4f\\x76\\x24\\xd0\\x84\\x9c\\x85\"\n\"\\x06\\xb5\\x09\\xf0\\x17\\x03\\x03\\x05\\x4b\\xdb\\x98\\xcb\\xf1\\x36\\xa5\\xc5\"\n\"\\x48\\x6a\\x6f\\x5f\\xaf\\x36\\x17\\x90\\xd2\\xc3\\x67\\x69\\x98\\x50\\x0e\\x19\"\n\"\\x80\\x81\\xe7\\x61\\x09\\x1a\\x27\\x15\\x44\\xdc\\x08\\x59\\xaa\\xc1\\xb6\\xf7\"\n\"\\x22\\xa5\\xe2\\x83\\x25\\x9b\\x7d\\x02\\xd0\\xc2\\x85\\xfe\\x76\\xc5\\x47\\xfa\"\n\"\\x79\\xc1\\x92\\xfa\\xe0\\xbe\\xab\\x21\\xc2\\x8f\\x5a\\xce\\x42\\x3c\\xbf\\xb4\"\n\"\\xf2\\xcf\\x74\\x1b\\x1e\\x40\\x62\\x4d\\xa4\\xb4\\x25\\x5d\\xfb\\x1d\\x9f\\xed\"\n\"\\x4f\\x41\\xbb\\x24\\xa9\\xd0\\x24\\x0c\\x3a\\x30\\x99\\xb6\\xf9\\x84\\x20\\x31\"\n\"\\xec\\xc5\\xac\\x27\\x36\\x0d\\xbb\\x8f\\x0f\\x64\\xb4\\x28\\x61\\x20\\x79\\x46\"\n\"\\x49\\xc3\\xdb\\x26\\xf1\\x1d\\x25\\xf6\\x5b\\xaf\\x89\\xf0\\x71\\xc5\\x68\\x18\"\n\"\\xb1\\xdd\\xf5\\x94\\xf5\\x6a\\x10\\x5f\\x40\\x1e\\x45\\xaa\\x90\\x91\\xce\\x96\"\n\"\\xd6\\xe3\\xff\\x17\\x16\\xce\\xa6\\xb6\\xce\\x60\\x0d\\xe4\\x2d\\xc0\\x91\\xa0\"\n\"\\x06\\x59\\x34\\x03\\x43\\x0f\\x39\\x52\\x63\\x1f\\x7a\\xa3\\x25\\x06\\xed\\xf5\"\n\"\\x23\\xaf\\x13\\x26\\xd1\\xaa\\xea\\x33\\x7e\\xf1\\x9a\\x5b\\x9b\\x87\\xbf\\xd8\"\n\"\\x14\\xe5\\x00\\x4c\\x55\\x90\\x8c\\x24\\x5b\\x1d\\x66\\xdd\\x49\\x36\\x49\\xc0\"\n\"\\x1a\\xd7\\x18\\xed\\x97\\x4a\\x34\\xca\\x57\\xbd\\xf7\\x7d\\xa8\\xee\\x01\\x28\"\n\"\\xf2\\x10\\xa6\\x77\\x3b\\x6e\\xa6\\x62\\x37\\x9f\\x1e\\x6c\\xa6\\x9c\\xbc\\xd8\"\n\"\\xa7\\xf4\\xb7\\xf9\\x72\\xc2\\x59\\xff\\x76\\x5a\\x60\\xf4\\x6d\\xfb\\x4e\\xb1\"\n\"\\xe0\\x5c\\x0b\\xf7\\xec\\x8e\\x8e\\xf3\\x59\\x6a\\x0f\\x26\\x2a\\xc9\\x86\\x8b\"\n\"\\x55\\xf4\\x7f\\x98\\xc8\\x2a\\x2d\\x63\\x78\\x58\\x95\\xe9\\x9e\\xb1\\x22\\xa0\"\n\"\\x2a\\x43\\x56\\xf7\\xbe\\xef\\x80\\xb7\\x64\\x9d\\x43\\x5c\\x84\\x3b\\x54\\x56\"\n\"\\x23\\x49\\x5b\\x64\\xa3\\x2e\\xdd\\x48\\xb7\\x45\\x6f\\x8f\\xf6\\xcb\\x53\\xd0\"\n\"\\x9e\\x6f\\x8e\\xa0\\x1d\\x21\\x11\\xe8\\x86\\x8d\\x1d\\x89\\xe2\\x76\\x33\\x9e\"\n\"\\x39\\x67\\x7e\\xfb\\x37\\x89\\xce\\x43\\x66\\xa1\\x33\\xc3\\xb9\\x77\\xe9\\x11\"\n\"\\x2f\\xb5\\x4a\\xd4\\xb3\\x97\\x8f\\xfe\\x77\\x29\\xd1\\xcd\\x5e\\xb4\\x91\\x10\"\n\"\\xd2\\xaa\\xcc\\xa3\\xd6\\x95\\xa1\\x1b\\x1e\\xe0\\xa8\\x18\\x63\\x48\\xc0\\xe2\"\n\"\\x11\\xb0\\x00\\x1d\\x38\\x8c\\xdd\\xb6\\x0b\\xd5\\x4a\\xa5\\x8e\\x2a\\x6a\\x3a\"\n\"\\x37\\x02\\x68\\x4d\\xf6\\x89\\x6d\\x35\\xab\\x03\\x20\\x36\\x55\\xbb\\x78\\xca\"\n\"\\xf9\\x75\\x17\\x7e\\x25\\x42\\x07\\x37\\xdd\\x23\\x7d\\xb1\\x60\\xec\\x2f\\x9d\"\n\"\\xf3\\xc6\\x93\\xa3\\x52\\xdb\\xe6\\x74\\xed\\xfa\\xed\\x5e\\x5b\\xf7\\xc6\\xba\"\n\"\\xad\\x02\\x05\\xe6\\x66\\x81\\x68\\x7b\\x12\\x6f\\x3a\\x64\\xca\\x51\\x3d\\xd9\"\n\"\\x74\\x13\\xca\\x89\\x32\\xa5\\xcf\\xd9\\xf0\\x09\\xbe\\x1a\\xd1\\xc1\\x3d\\x60\"\n\"\\x5c\\x21\\x8f\\xed\\x73\\xc9\\x03\\x85\\x69\\x28\\xe9\\x26\\x5b\\x75\\xe3\\xc3\"\n\"\\xa2\\xee\\xa1\\xab\\x94\\x02\\x9c\\x52\\xf2\\x14\\x2d\\x43\\xfb\\xed\\xdf\\x79\"\n\"\\x97\\x88\\x6e\\x5f\\xff\\x08\\xb6\\x02\\xb6\\x1a\\x09\\xb0\\x0e\\xf3\\xf4\\xe9\"\n\"\\x3f\\x7c\\x23\\x05\\x63\\xba\\x3e\\x9c\\xe5\\x63\\xe6\\xb8\\xd3\\xef\\x8a\\x1f\"\n\"\\x76\\x3f\\xd1\\xdc\\x7e\\x80\\x3a\\x21\\xe5\\xb4\\x8c\\x94\\x90\\x46\\x65\\x08\"\n\"\\xcb\\x02\\x8d\\xad\\x80\\xb6\\x86\\x8d\\x3c\\xdc\\x6e\\xfa\\x07\\x78\\xb2\\x1e\"\n\"\\x6d\\xe8\\xf4\\xc4\\x48\\x82\\x77\\x72\\x03\\x6f\\x88\\xf8\\x64\\xc7\\x60\\x70\"\n\"\\x9c\\xe2\\x11\\xcf\\x79\\x8a\\x70\\xc9\\x9f\\x1a\\x7b\\x46\\x29\\x4f\\x2a\\x48\"\n\"\\xe0\\x54\\x51\\x19\\xe6\\x57\\x96\\x7b\\x40\\x92\\xb6\\x4f\\xa8\\x90\\x73\\x62\"\n\"\\x9f\\x4f\\xc6\\x55\\x2f\\xc9\\xc7\\xcc\\xe9\\xb7\\x74\\x0a\\xdb\\x51\\x3f\\x90\"\n\"\\xae\\x55\\x58\\xcd\\xd6\\xc1\\x6a\\x3e\\x7b\\xdf\\xd8\\xec\\xef\\x19\\xae\\xbe\"\n\"\\x9f\\x82\\x4d\\x44\\x29\\x4f\\xe9\\xa1\\xc0\\xba\\xcb\\x03\\x06\\xab\\xf4\\xf6\"\n\"\\x6e\\x0d\\xdd\\xaa\\xa9\\x35\\xcd\\x98\\xee\\xe1\\x94\\x97\\xd4\\x9c\\x2c\\xbc\"\n\"\\x5e\\xfb\\xce\\x42\\x13\\x6c\\xc3\\x61\\x52\\x43\\xc2\\x09\\x1b\\x58\\x06\\xba\"\n\"\\xa3\\xa4\\x38\\xb0\\xf3\\x16\\x02\\xdc\\xf5\\x24\\x02\\xe6\\xab\\xaf\\xc7\\x48\"\n\"\\x95\\xbc\\xa1\\xde\\x08\\xca\\x83\\xdd\\x83\\x5b\\xbc\\xfd\\x73\\x95\\x82\\x94\"\n\"\\xfc\\x11\\xc3\\xd5\\x29\\x92\\xd8\\xe2\\x16\\xbd\\xff\\x82\\x77\\xc6\\x1f\\xc7\"\n\"\\xd6\\xf2\\x1a\\x65\\xe9\\x74\\x76\\x9b\\x08\\x67\\x98\\x4f\\x7c\\xb9\\x32\\xda\"\n\"\\xed\\xa1\\x9b\\x1b\\x45\\x95\\x5f\\xa5\\x94\\xfc\\x1c\\x15\\x44\\xa9\\x46\\x0b\"\n\"\\x0f\\x20\\x4a\\xd4\\x4e\\x03\\x75\\x01\\x60\\x51\\x1c\\x92\\x22\\xaf\\x6a\\x2b\"\n\"\\x0e\\x55\\x3b\\xc4\\x12\\x3a\\xc4\\x5d\\x9f\\x3b\\xa0\\x2f\\x7f\\x66\\x6f\\x46\"\n\"\\xff\\xb1\\x4a\\x9d\\x2f\\x62\\x81\\x95\\x88\\xad\\xa5\\x25\\x21\\xb3\\x67\\x41\"\n\"\\xc5\\xf9\\x33\\xe8\\xbe\\x41\\xf3\\xf3\\xd7\\x2f\\x45\\x22\\xa9\\x97\\xb0\\xa1\"\n\"\\x9b\\xb1\\xe3\\x9e\\xa7\\x1b\\x64\\x0a\\x30\\xc8\\xfb\\x4f\\x3b\\x2d\\xc0\\x63\"\n\"\\xfa\\x54\\x05\\x24\\xb6\\xca\\x5f\\x0f\\x84\\x46\\xd8\\x4f\\x1a\\xcd\\xda\\x9e\"\n\"\\xaa\\xc0\\x68\\x92\\x64\\x4b\\x7f\\x50\\x14\\xc6\\xc6\\xec\\x19\\xf6\\xdb\\xe6\"\n\"\\xf1\\x44\\xf8\\x07\\x99\\xac\\xa7\\x73\\x0f\\x1d\\x70\\xdc\\x9c\\x62\\xc1\\x44\"\n\"\\xbf\\x79\\xa9\\xc5\\xee\\x4a\\x22\\xa2\\x24\\xb1\\xcd\\xaa\\x21\\x54\\xc7\\xbc\"\n\"\\x4e\\xf8\\xf7\\xfe\\x61\\x18\\xe1\\x44\\x14\\x53\\xc9\\x59\\x6c\\xa8\\xe6\\x14\"\n\"\\x74\\x12\\x64\\x50\\xa2\\x86\\x74\\x13\\x1b\\xfb\\xd0\\x11\\xc0\\xe4\\x95\\x8e\"\n\"\\x10\\xf6\\x01\\x27\\xb7\\x2a\\xc3\\x9c\\x69\\x80\\x01\\x5d\\x50\\x60\\x56\\xfa\"\n\"\\x6a\\x1d\\xdf\\xa4\\x8d\\xf6\\x81\\xb4\\x5d\\xaf\\x99\\x8b\\x4c\\xa4\\x51\\x34\"\n\"\\x18\\xc5\\x10\\x26\\xb1\\xbc\\x91\\x3f\\x75\\x0e\\x4d\\x8d\\x00\\xda\\xf4\\xd8\"\n\"\\x6f\\xe3\\x65\\x94\\x47\\x96\\x3a\\x68\\xab\\x31\\x25\\x8a\\xef\\x63\\xda\\x96\"\n\"\\xc3\\x4c\\x61\\x60\\xf9\\x6f\\xf7\\xa9\\x0d\\x29\\x40\\x56\\x34\\x3f\\x98\\x08\"\n\"\\xc7\\x82\\x27\\xfd\\xe5\\xb1\\x13\\xaa\\x3b\\x5f\\x38\\xc8\\x12\\x4f\\x8e\\xda\"\n\"\\x03\\x90\\x63\\x7b\\xc0\\xc5\\xc3\\x3c\\x59\\x78\\x9a\\x75\\xee\\x4b\\x57\\xf3\"\n\"\\xbe\\x4e\\x73\\x28\\x3c\\x24\\x5a\\x99\\xa7\\xfa\\x4e\\x16\\xe6\\x26\\xe7\\x86\"\n\"\\xf8\\x38\\x0d\\xc1\\xd8\\x44\\xc9\\xd4\\xb1\\x2c\\x6d\\x0d\\xbb\\x7c\\x46\\xcb\"\n\"\\xb9\\x6a\\x95\\xc6\\x71\\xe0\\xaf\\x98\\x47\\x9f\\xb9\\xc8\\x47\\x65\\x96\\xc3\"\n\"\\x8e\\xc6\\xa4\\xce\\x09\\x20\\x47\\x15\\xc1\\x3b\\x28\\xb4\\x2c\\xa3\\xc6\\x7b\"\n\"\\x7a\\xa0\\x32\\xfd\\x19\\xba\\x05\\x1b\\xd6\\xd7\\x91\\xf2\\x7f\\x91\\xef\\xc8\"\n\"\\x95\\x5c\\xf8\\xfe\\xaf\\xa0\\xa6\\x9a\\xf9\\x4a\\xe1\\x4e\\x5e\\xa7\\xcb\\x3f\"\n\"\\x18\\xfc\\x13\\x4d\\xa1\\xb5\\xea\\x43\\x10\\x5a\\x1c\\x84\\x52\\x5d\\x4c\\x93\"\n\"\\xf3\\xa4\\xda\\xf6\\xf6\\x4f\\x77\\xda\\x51\\x62\\x1d\\x4a\\xe2\\xe3\\x4b\\x1e\"\n\"\\x41\\x6a\\x84\\x79\\xc8\\x9f\\xb7\\x5d\\x6e\\x64\\x3e\\xe0\\x9a\\x25\\x51\\x89\"\n\"\\x3d\\x88\\x4f\\xc9\\x4d\\x0b\\x95\\x48\\x4d\\xb7\\x5a\\xea\\x9e\\x9b\\x0d\\x35\"\n\"\\xa6\\x86\\x0d\\x98\\xc9\\x41\\x7b\\xfc\\xf7\\x90\\x60\\x29\\x7c\\x0c\\xd1\\x82\"\n\"\\x82\\xdf\\xaf\\xb9\\xaa\\xf8\\x60\\x1d\\xeb\\xdd\\x9b\\xa6\\x0f\\x1f\\x55\\xe0\"\n\"\\x6a\\x50\\x73\\x6a\\xf5\\x47\\x81\\xfa\\xfe\\x60\\xab\\x27\\xf4\\x59\\xbf\\xda\"\n\"\\xf8\\xed\\x1a\\x64\\x53\\xba\\xcb\\x93\\xdb\\x01\\x11\\xb2\\x57\\x36\\x11\\x35\"\n\"\\x57\\xe4\\x84\\x19\\xab\\xba\\xf1\\xa6\\x5a\\x6b\\x68\\x95\\x7f\\xf4\\x8a\\x8c\"\n\"\\x08\\x64\\x2a\\x03\\xc0\\x8d\\xfd\\x7b\\x90\\x4d\\xf0\\xb2\\x55\\x9d\\x69\\x20\"\n\"\\x74\\x0d\\x8f\\x3a\\x20\\xb4\\x51\\x66\\x42\\x26\\x86\\xb5\\x63\\x4d\\x5e\\x86\"\n\"\\x58\\x89\\x9a\\xbd\\x17\\x03\\x03\\x05\\x4b\\xd4\\xb0\\xda\\x60\\xf7\\x7f\\x04\"\n\"\\xca\\x95\\x77\\xf1\\x5f\\xfd\\xd4\\x5d\\x09\\x7d\\x1d\\x16\\xa3\\x88\\x96\\xf8\"\n\"\\x8b\\x18\\xfd\\x4e\\x1c\\xe7\\xf1\\xa2\\x4f\\x84\\x84\\x11\\x64\\x63\\x65\\x5a\"\n\"\\xe1\\xc1\\x84\\x89\\xa5\\xd6\\x51\\xbd\\xc7\\x5c\\xc7\\xb0\\x71\\x37\\x84\\x22\"\n\"\\x46\\xea\\x61\\xeb\\xf5\\x32\\xfb\\x66\\xec\\x7b\\xe5\\x82\\xf2\\x76\\x71\\x2d\"\n\"\\x63\\xb1\\xdf\\x2a\\xe1\\x4d\\x67\\x84\\x9f\\xc4\\x68\\xa3\\x58\\x18\\x8c\\x57\"\n\"\\x2a\\xfb\\xe3\\x6d\\xf8\\x2e\\x25\\x19\\xc4\\x73\\x19\\x96\\x23\\x27\\xd7\\x6a\"\n\"\\xa2\\xd8\\xe6\\x2e\\x9e\\x01\\x83\\x53\\x28\\x17\\x73\\x54\\x96\\x6f\\x74\\xc5\"\n\"\\x36\\xff\\x27\\xa1\\x32\\xb4\\x33\\x10\\x73\\x5a\\x2d\\x90\\xe3\\xc9\\xb1\\x67\"\n\"\\x54\\x5d\\xc1\\x68\\x49\\xff\\xec\\x06\\x52\\x61\\x5f\\xe2\\x01\\x9f\\x74\\x25\"\n\"\\xb3\\xd5\\xb1\\xdc\\xc8\\x23\\xfa\\x55\\xab\\x46\\x88\\x76\\x13\\x2f\\x4f\\x06\"\n\"\\xea\\x39\\x2c\\xb1\\xd2\\xd1\\xd9\\xcd\\x05\\xde\\x2d\\x38\\x1d\\xf7\\xe6\\x62\"\n\"\\x05\\x5b\\x93\\x72\\xe9\\xc9\\x01\\x8a\\x31\\xe1\\x73\\x12\\x42\\x32\\x8e\\x9e\"\n\"\\x98\\xe3\\x45\\x0b\\x7f\\x7a\\xb5\\x21\\xd4\\xef\\x5e\\xbd\\xf5\\x9f\\x60\\xd9\"\n\"\\xe9\\x5e\\x14\\xb1\\x5a\\xf5\\x33\\x5f\\x37\\xe1\\x63\\xd7\\xd1\\x11\\x62\\xb7\"\n\"\\x10\\xc6\\x62\\x38\\x23\\xa7\\x60\\xd3\\x34\\x09\\xa0\\x55\\x70\\xce\\xf3\\xf4\"\n\"\\x4e\\x76\\xbf\\x5f\\x91\\x48\\xe5\\x73\\xd5\\x74\\x77\\x69\\x59\\x11\\x1f\\x33\"\n\"\\xa2\\xbc\\x28\\xa0\\xc7\\x5e\\x2c\\xee\\xb1\\x8e\\x0b\\xc8\\x2d\\xab\\x1c\\x86\"\n\"\\x93\\xa3\\x51\\x8f\\xcb\\x8c\\x98\\x68\\xa8\\x4a\\xa2\\xd0\\xae\\xe3\\x3c\\xb9\"\n\"\\x07\\x0f\\x0d\\xf6\\x5d\\x2a\\x32\\xe3\\x7e\\x41\\x87\\x7f\\xbb\\xab\\x2a\\x41\"\n\"\\x20\\x74\\x6f\\x32\\x56\\x03\\xd8\\x62\\x52\\x9d\\x41\\xb9\\xf4\\xc9\\xbd\\x2b\"\n\"\\x67\\x8d\\xeb\\xdd\\xc0\\x31\\x80\\xb5\\x06\\x4f\\x34\\xfa\\xad\\xd9\\x46\\x34\"\n\"\\x47\\xb7\\x10\\x7d\\x89\\xed\\xf7\\xd6\\x13\\x72\\x13\\x05\\x62\\x25\\x50\\x5f\"\n\"\\xb1\\x60\\x3c\\xc8\\x8f\\xe7\\x2c\\xfe\\x03\\xc1\\x1b\\xb2\\x72\\x46\\xd6\\x5d\"\n\"\\x90\\x05\\x1e\\x25\\x1f\\xdc\\x3a\\x8f\\x11\\x1e\\x53\\xc4\\xab\\x55\\x63\\x79\"\n\"\\x31\\xc3\\x0c\\x1b\\x09\\xab\\xba\\x6c\\xa9\\xc3\\xd3\\xf7\\x21\\x57\\x98\\xfb\"\n\"\\x7c\\xe6\\x0f\\xe1\\x85\\xe1\\xa7\\x7a\\x1c\\x4f\\xc5\\xac\\xb4\\x63\\x18\\x0a\"\n\"\\x20\\x86\\xa1\\xa3\\x68\\x59\\xce\\x29\\xa8\\x17\\x48\\x87\\x49\\x71\\x9d\\x6b\"\n\"\\x47\\xb3\\xb2\\x47\\xa4\\xa4\\x4f\\xe4\\x39\\x28\\x85\\x4d\\x74\\xe4\\x1b\\xc9\"\n\"\\x8c\\x9a\\xe6\\xe9\\x88\\xb2\\x3b\\xfe\\x1e\\x6e\\x0e\\x79\\xd1\\x22\\x8c\\x72\"\n\"\\x92\\x59\\x0b\\x2b\\x12\\x94\\xda\\xad\\xac\\xc3\\xcd\\x28\\xfd\\x4b\\x16\\xf0\"\n\"\\x59\\xf7\\x8c\\xb8\\x6d\\x8d\\xc1\\x44\\x6b\\xdd\\x16\\x2f\\x5d\\xe3\\x78\\xa8\"\n\"\\x28\\x39\\x20\\x07\\x97\\xbb\\xf5\\xe8\\xa5\\xd0\\x13\\x81\\x7d\\x7d\\x6e\\x9c\"\n\"\\xfb\\x48\\xb9\\xbc\\x86\\x43\\x3c\\x79\\xd7\\x09\\x17\\xa3\\x08\\x2e\\xe1\\x07\"\n\"\\x5c\\x10\\x30\\x61\\x85\\xa6\\x73\\x46\\x09\\x25\\x16\\xad\\xa7\\x37\\x5d\\x24\"\n\"\\x61\\x05\\x56\\x7e\\x71\\x38\\x0e\\x1a\\x6b\\xb8\\xfc\\xa0\\x29\\x9c\\x4f\\xae\"\n\"\\x07\\xe3\\x97\\xc5\\x1b\\xfb\\x36\\xef\\x80\\x36\\x72\\x69\\x99\\x2d\\x1b\\x8c\"\n\"\\xf6\\xff\\x60\\x3a\\xd3\\x80\\x03\\x7a\\x03\\x4d\\xeb\\x94\\xd9\\x87\\xf7\\xd1\"\n\"\\xc8\\x7a\\xb9\\x3a\\xc9\\x64\\x20\\xb1\\x19\\x14\\x5e\\x4c\\x5a\\x28\\x4a\\x38\"\n\"\\x06\\xd5\\x9b\\x70\\xdb\\x2c\\x8c\\x00\\xa7\\xa7\\x0e\\x3b\\x26\\xa9\\x88\\xe5\"\n\"\\xfc\\x3c\\x0a\\xf3\\xbc\\xfc\\x84\\xa1\\x0f\\x3e\\x27\\x59\\xcd\\xb3\\xcc\\x23\"\n\"\\xb5\\x80\\x59\\x07\\x9d\\xb4\\x76\\x7d\\x0a\\x54\\xa9\\xc5\\x76\\x7d\\x1c\\x89\"\n\"\\x2d\\xcd\\x2f\\xee\\x8c\\xf1\\x97\\x4d\\xa2\\x7c\\xb9\\xa8\\x54\\xff\\x8e\\xbd\"\n\"\\x8f\\x01\\xdc\\x77\\xcf\\x8a\\x1a\\xd2\\xe3\\xdb\\xc4\\x90\\x63\\x4a\\x5c\\x07\"\n\"\\x4d\\xd0\\xa0\\x61\\xec\\xd8\\x79\\x17\\x1a\\xbd\\x0f\\xa4\\x8b\\xfe\\x01\\x88\"\n\"\\x4d\\xa6\\x94\\x7e\\xd7\\x1c\\x5f\\xfc\\x89\\x9b\\x8a\\x74\\xe2\\x09\\x58\\x7f\"\n\"\\x1a\\x0a\\x58\\xbd\\x86\\xa8\\xda\\x68\\x69\\xea\\x1d\\x41\\x5e\\xe5\\x03\\x8d\"\n\"\\xe2\\x4f\\x0c\\x3c\\x72\\xc5\\xd9\\x11\\x96\\x65\\x65\\x28\\x20\\x3a\\xbe\\xbd\"\n\"\\x9f\\x92\\xca\\x1d\\xde\\xcb\\x09\\xb4\\x2c\\x5b\\x86\\x7c\\x41\\x7c\\xc8\\x75\"\n\"\\xc9\\x45\\x44\\x28\\x2d\\x66\\xe0\\x17\\x3e\\x7a\\x2d\\xb7\\xe5\\x2e\\x9a\\x84\"\n\"\\x68\\x99\\x15\\x21\\x0a\\x42\\x30\\xc3\\xe6\\x18\\x36\\x98\\x0a\\x0f\\xc4\\x5d\"\n\"\\xa1\\x36\\x55\\x71\\x52\\xad\\xc9\\x3e\\xf3\\xb9\\xa7\\x22\\x25\\xa3\\xb6\\x81\"\n\"\\x4c\\x47\\xd8\\x45\\x57\\x43\\x1a\\xa2\\x58\\x6e\\x51\\xd3\\xee\\xac\\x0c\\x87\"\n\"\\x8c\\xa8\\x3a\\xa7\\xca\\x9f\\x04\\xab\\x21\\x56\\x12\\xba\\xc5\\xe1\\x8d\\x42\"\n\"\\x18\\x06\\x9f\\x08\\x0f\\xa1\\xf2\\x89\\x58\\x33\\x2c\\xe5\\xf4\\x7e\\x78\\x9a\"\n\"\\xa7\\x34\\xdd\\x28\\xae\\x65\\xe8\\xf1\\xcc\\xe7\\xc4\\xdf\\x94\\x60\\x85\\xa7\"\n\"\\x6e\\x6f\\x47\\x7b\\xab\\x7d\\x7b\\x45\\xe6\\xe7\\x66\\xe0\\x02\\xfa\\x87\\xfe\"\n\"\\x26\\xb9\\x83\\x5f\\xea\\x4b\\xe6\\x12\\x1b\\xb1\\x66\\x9a\\x23\\x17\\xb7\\xf0\"\n\"\\xc7\\xe6\\x23\\xd3\\xfc\\x71\\xe0\\x62\\x35\\xbe\\xc6\\xc3\\xcd\\xf8\\xfd\\xfe\"\n\"\\x97\\x85\\xcc\\xb6\\x13\\xc2\\x1f\\x7e\\x4f\\x4d\\x32\\x5c\\x4c\\xa6\\xba\\xb8\"\n\"\\x2a\\xab\\x63\\x5c\\xd6\\x5c\\x4f\\xef\\xb2\\x42\\xad\\x61\\xa0\\xaf\\xa9\\xd5\"\n\"\\x7a\\xb1\\x8a\\x49\\x62\\x9a\\x4f\\x7e\\x6e\\x7e\\x07\\x5f\\x86\\x1e\\x8e\\xd9\"\n\"\\x1e\\x0d\\x85\\xe1\\x00\\x14\\x0a\\xb3\\x61\\xd3\\xeb\\xda\\xc2\\x9d\\xe7\\xbf\"\n\"\\x4f\\xed\\x5f\\x79\\x43\\xd0\\x6d\\x48\\x70\\xc4\\xc4\\x32\\x77\\x1c\\xf7\\x77\"\n\"\\xae\\xde\\xb3\\x68\\x98\\xe7\\x31\\x6c\\xf2\\x0e\\xf8\\xf9\\xab\\x45\\xe8\\x49\"\n\"\\xe0\\x6d\\x73\\xee\\xa6\\x50\\x25\\x7f\\x56\\xb2\\x60\\x3d\\xcf\\x89\\x2f\\xc0\"\n\"\\x11\\xc3\\xc4\\xd1\\x1d\\x0c\\xbc\\x1b\\x9e\\xb9\\xc6\\x4c\\x70\\xe4\\xd7\\x0a\"\n\"\\x30\\xb7\\x71\\x77\\x07\\x15\\x18\\xd0\\x2e\\x0e\\xb1\\x1b\\xe0\\x9a\\x94\\xd8\"\n\"\\xb6\\x17\\x14\\xba\\xba\\x6b\\x3e\\xc2\\xe2\\xc5\\xb8\\x7c\\x2c\\x16\\x99\\xec\"\n\"\\xf3\\xfe\\x68\\x6b\\xc7\\x49\\xbc\\x68\\x17\\x74\\xca\\xd3\\x18\\x21\\xdd\\x4e\"\n\"\\xa1\\x8c\\x1a\\x87\\x48\\xbe\\xfd\\x86\\x86\\x9a\\xcf\\xb5\\x4d\\xb9\\x2f\\x8a\"\n\"\\xef\\x4d\\x2a\\xec\\x89\\x9f\\x04\\x0f\\xb6\\x7f\\x43\\x81\\x94\\x13\\x05\\xda\"\n\"\\x46\\x0a\\x07\\x7a\\x56\\x83\\x02\\x8a\\xd0\\xcd\\x53\\x82\\xc5\\xc6\\x2c\\x67\"\n\"\\x49\\xcf\\x4f\\xff\\x34\\x49\\x82\\x48\\xab\\xe3\\xfe\\x7c\\x86\\xbd\\xc5\\x8c\"\n\"\\xa3\\x2e\\x9c\\x34\\x97\\xe8\\x57\\xde\\x4f\\x74\\x65\\x43\\x8a\\x5f\\x27\\x4d\"\n\"\\xc9\\x8e\\x51\\x99\\x22\\xc6\\x51\\x41\\xf5\\xb5\\x43\\x73\\x5a\\x98\\xe6\\xf6\"\n\"\\x2a\\xac\\xf3\\x59\\x9b\\xeb\\xce\\xe1\\x85\\xee\\xe5\\x7b\\x73\\x25\\xc4\\xde\"\n\"\\x2b\\x7b\\x05\\x31\\x48\\x6e\\x02\\xf7\\xbf\\x09\\xd6\\x27\\xe8\\xe6\\x2e\\xad\"\n\"\\x85\\x90\\x6f\\xc6\\x1f\\xa8\\x40\\x67\\x6e\\x45\\xf1\\x77\\x9d\\x5d\\x12\\x68\"\n\"\\x11\\x13\\x6e\\xc4\\x5c\\xfe\\xfe\\xdd\\xaf\\x54\\xc4\\x63\\xfe\\x42\\x02\\xd6\"\n\"\\x2d\\xa6\\x7b\\x83\\x3c\\x3d\\x9a\\x74\\xe0\\x3a\\xa2\\x37\\xe1\\xbe\\xc3\\xc2\"\n\"\\x7a\\x42\\xfd\\x33\\xa3\\x5f\\x5e\\xba\\xcb\\xd3\\x1a\\x6b\\x01\\x95\\x98\\x5a\"\n\"\\xf2\\x8d\\x78\\x23\\xca\\x2c\\x7e\\x40\\xd5\\xde\\x23\\x7f\\xac\\x7c\\x41\\xb6\"\n\"\\x38\\x1b\\x1d\\xbe\\x10\\x67\\xcd\\x48\\x98\\x76\\xf1\\x81\\x50\\x80\\x49\\x11\"\n\"\\xb9\\x73\\x55\\x2e\\x57\\xab\\x2e\\x87\\xed\\xc1\\x71\\xd2\\xe5\\x23\\xdf\\x62\"\n\"\\x2c\\xdc\\xd7\\xd6\\x17\\x03\\x03\\x05\\x4b\\x90\\xae\\x72\\xb7\\x18\\xf8\\x53\"\n\"\\x3a\\xb3\\x11\\x1d\\x3c\\x5b\\x70\\x31\\x04\\xa8\\x36\\x0b\\xb3\\xdb\\x5e\\x73\"\n\"\\x72\\x43\\x96\\x21\\x52\\x90\\xb2\\x70\\x99\\x59\\xe5\\x42\\x36\\x0b\\x22\\x0e\"\n\"\\xb8\\x48\\x4b\\x04\\xdd\\x99\\x41\\xdf\\x0d\\x84\\x76\\x25\\x7f\\xf7\\xd6\\x30\"\n\"\\x15\\x9c\\x1b\\xd8\\x25\\x37\\x86\\x04\\xe5\\x1b\\xdb\\xec\\x28\\x70\\xb9\\x9f\"\n\"\\x4f\\x74\\xd0\\x3f\\x78\\x1b\\x8f\\xb5\\xf8\\xe7\\x1c\\xcc\\xbf\\xc0\\x5a\\xee\"\n\"\\x3e\\x99\\xbd\\x54\\x91\\x29\\x63\\x79\\xc4\\x5b\\x35\\xa9\\xd1\\x25\\x2f\\xea\"\n\"\\x34\\x69\\x94\\x22\\x6f\\x02\\xeb\\xc0\\x91\\xdc\\x07\\x18\\xef\\x96\\x7e\\xc4\"\n\"\\x97\\xaf\\x74\\xd3\\x05\\xed\\x41\\xfb\\xb8\\x54\\xf4\\x14\\xed\\x60\\x44\\xc3\"\n\"\\xb0\\x54\\xb2\\x2f\\x60\\xd3\\x6d\\x8b\\x1b\\xdb\\x3c\\x84\\xe9\\xa1\\xb4\\x9d\"\n\"\\x29\\x52\\xea\\x1a\\x75\\x5c\\x9a\\xf3\\x26\\xf5\\xea\\x4e\\x53\\x83\\x16\\x48\"\n\"\\x35\\x94\\x68\\x8c\\xbb\\x9a\\x92\\x09\\xb6\\x11\\xa0\\x24\\xc8\\x34\\x2d\\x84\"\n\"\\xc5\\xee\\xad\\xb7\\xdb\\x6f\\xb7\\x60\\x28\\x30\\x84\\xa4\\x6e\\x5e\\xf9\\x9c\"\n\"\\x72\\xa3\\x27\\xde\\x2b\\xfe\\xf0\\x0a\\x52\\xc5\\xa0\\x4b\\x98\\x27\\x69\\xa8\"\n\"\\xb1\\x4f\\x17\\x4d\\x05\\x10\\x74\\xf1\\x38\\x60\\xf8\\xa4\\xff\\x7d\\xf8\\x78\"\n\"\\x16\\x84\\x41\\xc8\\xa1\\x48\\xc1\\x4b\\x3a\\xbb\\xff\\x04\\xdc\\x3c\\x0c\\xe2\"\n\"\\x43\\x1e\\x91\\x0e\\xbd\\x14\\xab\\xf2\\xdb\\x72\\x60\\x73\\x5c\\xaf\\x5f\\xab\"\n\"\\x66\\x27\\x4f\\xf6\\x34\\xf5\\x54\\x89\\xb9\\xf2\\xf7\\x69\\x02\\x87\\x8d\\x25\"\n\"\\xac\\x1e\\xda\\x03\\xa4\\xcd\\x07\\x58\\x53\\x98\\xd6\\x8d\\x0a\\x74\\x06\\xe5\"\n\"\\x1c\\x1c\\x91\\x22\\x9a\\xbb\\x10\\xfc\\xbe\\x86\\xcb\\x85\\x0d\\xe5\\x6b\\x17\"\n\"\\x54\\xa0\\x1a\\x4d\\x4a\\xc2\\xcc\\x24\\xe8\\x03\\xef\\x4b\\x9d\\x7b\\x21\\x50\"\n\"\\xe2\\xf4\\xe5\\x4f\\x73\\x8c\\xef\\x95\\xe1\\x88\\x6d\\x2e\\x1e\\x88\\x1d\\xa4\"\n\"\\x29\\x4d\\x35\\xf0\\x6d\\x7d\\xff\\x43\\xfd\\x1b\\x0e\\x8a\\xe3\\xf2\\xdd\\xfc\"\n\"\\x09\\xf1\\xd9\\x34\\x13\\xc2\\x23\\xc8\\x89\\xb5\\xee\\xca\\x53\\xe2\\x91\\x7e\"\n\"\\x1f\\x94\\xf0\\xe0\\xd8\\x24\\xdc\\x33\\x95\\xd5\\xbb\\x29\\x1a\\x5b\\xfe\\xe6\"\n\"\\x24\\xf9\\xe9\\xcd\\xe6\\xfc\\x94\\x49\\x8f\\xb7\\x06\\x6c\\x71\\x81\\xae\\xad\"\n\"\\x66\\x67\\x51\\x2a\\xc5\\xc0\\x39\\x41\\x5b\\x41\\xf5\\x66\\xff\\x8c\\xcc\\x47\"\n\"\\xbe\\x3e\\x02\\x06\\x02\\x6c\\xa4\\x1c\\x2a\\x94\\xca\\x0f\\x35\\xe0\\x23\\x81\"\n\"\\x68\\x37\\x9d\\x96\\xf5\\x7b\\xa3\\x2d\\xcc\\x9e\\xf4\\xbd\\x06\\x4a\\xcb\\x07\"\n\"\\xbf\\x22\\xf0\\xbc\\x01\\x3e\\xca\\x76\\x9f\\x1f\\xf0\\x63\\xc0\\xba\\x68\\x4f\"\n\"\\x62\\x14\\x93\\x94\\x47\\xa0\\x2a\\x31\\x65\\x03\\xdb\\xe5\\xa1\\x84\\xc6\\x82\"\n\"\\xe6\\x05\\xb7\\xa3\\x5c\\x00\\xcd\\xdc\\x82\\x27\\xde\\xfe\\x39\\xcf\\x4d\\xe0\"\n\"\\xb5\\xfe\\x83\\x83\\x80\\xb2\\x23\\x81\\xde\\xe1\\x6b\\x37\\xd7\\x61\\x5a\\xb0\"\n\"\\x64\\xb0\\xaa\\x95\\x9b\\x94\\xd6\\xcc\\x7d\\x5c\\x11\\xaa\\x5b\\x4d\\x49\\x0c\"\n\"\\x1c\\x55\\x2a\\xd5\\x7c\\x44\\x0c\\x2f\\x57\\xc0\\xf6\\x3a\\xcb\\xf7\\xc2\\x1b\"\n\"\\xe8\\x5c\\x2c\\xe9\\x91\\x3e\\x97\\x82\\x4a\\xe1\\xc0\\xa4\\xd7\\xe2\\x14\\xd8\"\n\"\\x9c\\xf3\\xf3\\x8c\\x35\\xfd\\xb1\\x2a\\xed\\x52\\x7c\\x8e\\xa9\\xfe\\x81\\x56\"\n\"\\x96\\xa4\\xb9\\x87\\x70\\xef\\x93\\x5a\\xdb\\xd1\\xca\\xc6\\x51\\x9a\\x94\\x30\"\n\"\\xb7\\x8b\\x64\\x0c\\x94\\x82\\x24\\x63\\x76\\x95\\x1a\\x62\\x11\\x1f\\x64\\xc2\"\n\"\\xda\\xda\\xbc\\x1f\\x2b\\x84\\x5b\\xda\\x97\\xf1\\x74\\x9c\\x83\\x83\\xb1\\xfb\"\n\"\\x34\\x05\\xce\\xb6\\x2e\\x88\\x5d\\x70\\x90\\xb5\\x1b\\x63\\x2d\\x0e\\x8c\\x2e\"\n\"\\x8b\\x88\\x9b\\xfc\\x98\\x16\\xe6\\x7d\\x72\\x05\\xd3\\x21\\x93\\xdd\\xdf\\xed\"\n\"\\xb0\\x4e\\xe9\\xb1\\x99\\xd2\\x24\\x00\\x0f\\x46\\xed\\x7b\\xf6\\xbb\\x2d\\x37\"\n\"\\xce\\xc5\\xad\\xf5\\x36\\xff\\x63\\x58\\x90\\x71\\x80\\x1f\\xb6\\xe5\\x15\\x58\"\n\"\\x27\\xf4\\x4b\\x33\\xa9\\xc9\\xde\\x92\\xea\\x1d\\x06\\x9b\\xb5\\x83\\x85\\xf4\"\n\"\\x8c\\xe1\\x0d\\x51\\x42\\xd8\\x93\\x1b\\xdd\\x9a\\x61\\xa9\\xe7\\xf3\\xa9\\x5f\"\n\"\\x77\\xdd\\x0d\\x10\\xff\\xe0\\x8d\\xb7\\x89\\x6b\\xb7\\x6f\\xb7\\x5c\\x62\\xd3\"\n\"\\xc2\\x8f\\xe0\\x63\\xe8\\xcf\\x21\\x47\\x74\\xd0\\xaa\\xd5\\xb3\\xe9\\x17\\xb2\"\n\"\\xc2\\xad\\xab\\x32\\x92\\xd3\\xa0\\x76\\xb5\\x77\\x1b\\x9d\\xb8\\x85\\x15\\x66\"\n\"\\x1e\\x59\\x4d\\xb0\\x5a\\xfb\\x7d\\x6d\\x29\\x46\\x5d\\xe4\\x86\\x0e\\x37\\x75\"\n\"\\x19\\xde\\xc8\\xd5\\xfd\\x11\\x38\\x8c\\xcb\\x37\\x16\\xc5\\x54\\x57\\x17\\xb5\"\n\"\\x5f\\x29\\x39\\x9c\\x0a\\xfc\\x6e\\xe0\\x36\\x5b\\xd7\\x32\\xf4\\xcb\\x80\\xae\"\n\"\\x10\\xb9\\x36\\x58\\xad\\x33\\x1b\\x79\\x0c\\xdd\\x86\\x79\\xef\\xd8\\xd3\\xff\"\n\"\\x20\\x4f\\x24\\x50\\xf1\\xc8\\x66\\x90\\xa2\\x9c\\xf3\\x61\\x88\\x61\\x77\\xa9\"\n\"\\xdf\\x8d\\x93\\x9a\\x15\\xd1\\x38\\x05\\xa4\\x9d\\xc3\\x02\\x62\\x22\\x78\\xe8\"\n\"\\x2a\\x02\\x5f\\xb9\\xa2\\xd7\\x0a\\xe5\\x15\\xe6\\x72\\x04\\xb6\\x11\\xd5\\xd6\"\n\"\\x1e\\x45\\x3f\\x80\\xb3\\x5a\\x94\\x99\\x22\\x4a\\x67\\xbe\\x33\\x49\\xe0\\x5e\"\n\"\\x27\\xa7\\x31\\xe1\\x8b\\x88\\x47\\x58\\xb8\\x9e\\xbf\\x6d\\x04\\x7b\\xe0\\x0f\"\n\"\\x02\\xbe\\x34\\xe0\\x14\\x80\\xbe\\x17\\x17\\xa6\\x21\\x02\\xa2\\x6b\\xa8\\xa6\"\n\"\\xd0\\x18\\xa9\\x47\\xb9\\x71\\xd1\\x7e\\x17\\xfd\\xd0\\xa7\\xc4\\x2f\\x51\\x0f\"\n\"\\x1d\\x4a\\x97\\xda\\x80\\xea\\x64\\x0c\\xef\\x38\\x7e\\x7f\\x5d\\x09\\xd4\\x4e\"\n\"\\xcd\\xcb\\x9c\\x64\\xe1\\x63\\x09\\x80\\xc7\\x6a\\x20\\x26\\x98\\x95\\xec\\x2b\"\n\"\\xd2\\xff\\x19\\x24\\x25\\xd9\\xd1\\x0d\\x0c\\x18\\x3d\\x55\\x56\\x15\\x4b\\xe3\"\n\"\\xf1\\x13\\x71\\x39\\x99\\xb4\\x3c\\xdc\\x90\\xef\\x44\\x50\\x6d\\xeb\\xb8\\x4d\"\n\"\\x37\\xab\\x66\\xf2\\x4c\\x8a\\x86\\x4d\\x45\\x35\\x73\\x5f\\xc5\\x64\\x2c\\xa5\"\n\"\\x44\\xcf\\xc3\\x5f\\x91\\xa7\\xbb\\x1f\\xa6\\xfd\\x79\\x47\\xde\\x58\\x79\\x18\"\n\"\\x0c\\x31\\x1d\\x69\\x98\\xc0\\xef\\x94\\x54\\x2e\\xc1\\xc4\\x25\\xf9\\x8f\\x20\"\n\"\\xc0\\x66\\xe2\\x00\\x14\\xee\\x02\\x7c\\x50\\xc9\\x40\\xd0\\x57\\x28\\xdb\\x1f\"\n\"\\x61\\xb6\\x90\\x19\\x4d\\x12\\x0f\\x15\\xbe\\x41\\x51\\xe5\\x76\\xf6\\xf2\\xda\"\n\"\\x54\\xb4\\x1b\\xab\\x93\\xbc\\xdb\\x4c\\x4b\\x4b\\x46\\x88\\x09\\x23\\x79\\x80\"\n\"\\xb3\\xc4\\xf5\\x9f\\xab\\xb0\\x00\\xb4\\x46\\xe9\\x5e\\x11\\xa8\\x3d\\xed\\x92\"\n\"\\x41\\x03\\x3a\\xc4\\xa6\\x96\\xbd\\x00\\x1e\\x6f\\xf7\\xa4\\xdc\\x92\\x4f\\x6c\"\n\"\\x5c\\x16\\xfa\\x44\\x4a\\x8e\\x1a\\xb5\\x1f\\xd1\\x7e\\xb2\\x4a\\xcd\\x4a\\x5a\"\n\"\\xd5\\xd3\\xcf\\x14\\x71\\x0b\\x17\\x9f\\xee\\x6a\\xa4\\x90\\xc0\\xa2\\x8a\\x89\"\n\"\\x8a\\x62\\xd1\\x68\\x1c\\xa3\\xdd\\x68\\xed\\xe3\\xdd\\x99\\x2c\\x94\\xb6\\x45\"\n\"\\xce\\xd1\\x74\\x39\\x00\\xf4\\x35\\x96\\xe1\\x9a\\x90\\x35\\x9a\\x97\\x30\\x78\"\n\"\\xf1\\x16\\x21\\x94\\xce\\x9f\\x36\\x46\\x25\\xea\\x48\\x1a\\xf6\\x2d\\x77\\x5e\"\n\"\\xfb\\x63\\x37\\xe3\\xbe\\xdb\\x8d\\xb4\\x13\\xd7\\x68\\xfd\\x2e\\x56\\x96\\xf7\"\n\"\\xb8\\x9e\\x91\\xe0\\x7c\\xe3\\x44\\x6e\\xbd\\x52\\x46\\xdd\\xbc\\xec\\xe6\\x76\"\n\"\\x57\\x7a\\xb9\\x24\\x66\\xcd\\xd3\\x5d\\xee\\x33\\x69\\x8e\\xd9\\x68\\xbf\\xda\"\n\"\\x63\\xe9\\x5c\\x89\\x67\\xcd\\xa2\\x54\\xa0\\x26\\xdc\\xbc\\x88\\x55\\x33\\x3c\"\n\"\\xad\\x26\\xca\\x62\\x39\\x9b\\xfc\\xb8\\x5e\\xa8\\x4e\\xb2\\xff\\xfd\\xaf\\x54\"\n\"\\x13\\x32\\x4a\\x8b\\xba\\x6d\\x72\\x6f\\xf7\\xdb\\x73\\x43\\xef\\x1f\\x4f\\x02\"\n\"\\x30\\x17\\x04\\xfe\\x88\\x25\\x07\\x95\\x41\\x07\\x4b\\x85\\x74\\x74\\x88\\x03\"\n\"\\x52\\x2a\\x08\\x21\\xa0\\xfe\\xa1\\xe7\\x51\\x08\\x43\\x41\\x00\\x8e\\xfe\\x10\"\n\"\\x1c\\xb4\\xe9\\x02\\x17\\x03\\x03\\x05\\x4b\\x8f\\xd5\\xbb\\x32\\x19\\x69\\xdc\"\n\"\\xf4\\xbe\\x44\\xfd\\x99\\xca\\xe5\\x5c\\xbf\\xbe\\x05\\xb7\\x93\\x0f\\x62\\x1f\"\n\"\\x04\\xfc\\xe4\\xce\\x5a\\xa5\\x9b\\xdc\\x23\\xcc\\x69\\x47\\x5b\\xb5\\xaa\\x5e\"\n\"\\x98\\x5d\\x4b\\x37\\x28\\x3c\\xad\\x6d\\x63\\x23\\x90\\x91\\x83\\xc6\\x10\\x5e\"\n\"\\xf7\\xc8\\xbf\\x11\\xfc\\xf4\\x71\\x14\\xbb\\x25\\x8d\\x9b\\xcd\\x2e\\xfd\\x72\"\n\"\\xd7\\x47\\x6f\\x1e\\x73\\x3c\\x75\\x41\\x4c\\x7a\\x96\\x64\\xf0\\x18\\xea\\x58\"\n\"\\x54\\x5d\\x9f\\x3f\\x88\\x0d\\x2f\\xc0\\xe1\\x50\\xd5\\xbc\\x6a\\x09\\x44\\x8a\"\n\"\\xf4\\x45\\x0b\\x0e\\x8b\\x47\\x25\\x93\\x18\\x61\\x2d\\x75\\x96\\x2b\\xe7\\x5a\"\n\"\\x37\\xf1\\x1e\\xc1\\x71\\xcd\\x1b\\xee\\x83\\x13\\x90\\x03\\x29\\xbf\\x0b\\x5a\"\n\"\\x4f\\x38\\x0c\\x7c\\xca\\x17\\x13\\x2f\\xde\\x06\\x27\\x35\\x70\\xec\\xca\\xe2\"\n\"\\x5b\\x59\\xbb\\x16\\x41\\x12\\x6c\\x9c\\xb4\\xe0\\x93\\xc4\\x44\\x5a\\x5b\\xac\"\n\"\\x99\\xc9\\xa4\\x24\\x29\\xe4\\x8f\\x4f\\x79\\x60\\xce\\xee\\x0a\\xcf\\x99\\xda\"\n\"\\xa5\\x78\\x7e\\x6a\\xea\\x9f\\xd6\\x2a\\xed\\x41\\x44\\x78\\xe8\\x80\\x07\\xfc\"\n\"\\xd8\\x11\\x87\\x5e\\x36\\x0d\\x0d\\x44\\x79\\xf8\\x2d\\xb2\\x17\\xd9\\x2a\\xf5\"\n\"\\xb4\\x46\\xb7\\x17\\x34\\xe0\\x7e\\xd7\\xb3\\x5c\\x16\\x71\\x66\\xca\\xda\\x23\"\n\"\\x3c\\xcd\\x52\\x33\\x66\\x0e\\x07\\x54\\x3e\\x0f\\xc5\\x10\\xc4\\xb6\\xa0\\xae\"\n\"\\xae\\x1d\\x80\\x2a\\x63\\xf1\\x4f\\xb4\\x1f\\xad\\xb3\\x49\\x58\\x41\\x6a\\x2a\"\n\"\\xd1\\x7c\\x13\\x8d\\x06\\xaf\\x60\\xcf\\xa9\\xb4\\x50\\xc1\\x32\\x94\\x5a\\x15\"\n\"\\x90\\xc5\\x51\\x2f\\x90\\x68\\x40\\x7b\\x55\\x91\\x50\\x70\\x64\\x9d\\x8a\\x7f\"\n\"\\xcd\\x55\\xc9\\x60\\x24\\x47\\x0c\\xfc\\x7c\\x61\\xcd\\x8d\\x8b\\x2f\\x36\\x27\"\n\"\\xb2\\xf3\\x41\\x9d\\x92\\x14\\x9a\\xdd\\x9b\\x78\\x22\\x6c\\x78\\x82\\x37\\x15\"\n\"\\x66\\xdd\\x3b\\xbd\\x31\\xc4\\x80\\xa8\\x8c\\xd8\\x95\\x41\\xb3\\xcb\\xdf\\xb8\"\n\"\\xd7\\x70\\xe9\\xa4\\x01\\x68\\xa7\\x8c\\xcb\\x94\\xd7\\x10\\xce\\x0d\\x2c\\x9a\"\n\"\\x13\\x86\\x16\\xc6\\x93\\x8f\\x08\\x64\\xb8\\xe6\\x49\\x6e\\x1d\\xd3\\x90\\x44\"\n\"\\x13\\x76\\x5e\\x14\\x3b\\xbd\\x06\\xbf\\x9c\\x29\\xff\\x76\\x25\\x96\\x2a\\x56\"\n\"\\x88\\x2d\\xaf\\xfe\\x5f\\x4e\\xd2\\x67\\xb6\\x8b\\x36\\xa7\\xf6\\x8a\\x9f\\x7e\"\n\"\\x0a\\x58\\xed\\xaa\\xe3\\x68\\x9d\\x0a\\x65\\x7b\\xc8\\xb3\\x5e\\x2b\\x47\\xae\"\n\"\\x9a\\x4d\\x19\\xae\\x3d\\xdc\\xb6\\xf6\\x97\\xe3\\x89\\x3c\\x3d\\x91\\xa4\\xe8\"\n\"\\x42\\xb0\\x45\\xcb\\x89\\x3d\\xc2\\x8e\\xa1\\x04\\xac\\x44\\xf8\\x51\\xab\\xf4\"\n\"\\x60\\x54\\xfe\\x04\\xa4\\x42\\x85\\xd9\\x4b\\xdf\\x54\\xd0\\x05\\xce\\x00\\x15\"\n\"\\x4c\\xbb\\xa6\\x87\\x4c\\xe4\\xcf\\xfd\\xbc\\xd1\\x5d\\x9e\\xdc\\xb0\\x20\\x18\"\n\"\\xaa\\x2a\\x5c\\x7a\\xb5\\xf7\\x8a\\xe3\\xb9\\xdf\\x9f\\x9f\\x5b\\x74\\xad\\xc2\"\n\"\\x5f\\x60\\x83\\xf2\\x98\\x8b\\xa7\\xb7\\x90\\xc7\\xf3\\x9b\\xe3\\x98\\x1b\\x0d\"\n\"\\x4b\\x5e\\xcd\\x9f\\x22\\x82\\x9e\\xe8\\x48\\xad\\x00\\xe3\\xe7\\x80\\x40\\x01\"\n\"\\x5c\\xaa\\x55\\xa0\\xd4\\x56\\x6e\\x78\\xee\\xe2\\xa7\\x95\\x6b\\x27\\xc8\\xa8\"\n\"\\xf9\\xc6\\xa1\\x90\\x45\\x43\\xc6\\xcd\\xff\\x88\\xac\\xfa\\x69\\x08\\x23\\x69\"\n\"\\xc8\\x5d\\x17\\x5d\\x38\\xc7\\x87\\x60\\xc7\\xf7\\x24\\xfd\\x33\\x99\\x1a\\x3f\"\n\"\\x0f\\xff\\x52\\x50\\xc9\\x8c\\xc1\\x21\\x4c\\xd8\\xf5\\xd5\\xd1\\xd4\\x23\\x2e\"\n\"\\x6a\\xba\\xbb\\xed\\xb2\\xe5\\x51\\x99\\xdd\\x73\\xd5\\x39\\xec\\x80\\x7d\\x30\"\n\"\\x85\\x54\\xb8\\x57\\xb4\\x5b\\x5d\\x02\\x23\\x24\\xba\\x1c\\x6e\\x5d\\xc5\\xbe\"\n\"\\xed\\x8f\\x1b\\xf9\\xa1\\x6a\\x83\\x2c\\xbe\\xe8\\xd4\\x6a\\x09\\x7d\\x09\\x55\"\n\"\\x92\\x49\\xc0\\x9a\\xea\\x2e\\xd8\\x6b\\xb9\\xbe\\x6f\\x1b\\xc1\\x2d\\xbc\\xc4\"\n\"\\x79\\x27\\x24\\xa1\\xda\\x44\\x18\\x3e\\xd2\\xff\\x92\\x56\\xf2\\xef\\x45\\x0d\"\n\"\\xc6\\xb2\\x34\\x9b\\x3c\\xe1\\x40\\xb9\\xb1\\x14\\xc5\\xb6\\xe0\\x02\\xab\\x12\"\n\"\\xd5\\xb4\\x6f\\xdd\\x71\\xc1\\x20\\x92\\xd6\\x9a\\xef\\x30\\x60\\x36\\x00\\xaf\"\n\"\\x09\\x06\\xeb\\x0c\\xbe\\x29\\xd2\\xc3\\x25\\x46\\x48\\xc3\\xd4\\x8a\\xd9\\xdd\"\n\"\\xd6\\x44\\x97\\xed\\xa4\\xbf\\x5a\\x8d\\xfd\\x3d\\x2d\\x82\\xa3\\x3d\\x5c\\x0d\"\n\"\\xde\\xfe\\x11\\xd5\\x3f\\x7e\\xc3\\x69\\xc2\\xac\\x9f\\x7d\\x08\\x2e\\xef\\x8f\"\n\"\\x2d\\x30\\xac\\x7b\\x76\\xc1\\x43\\x29\\x20\\x50\\x4a\\xca\\x87\\x21\\xd8\\x61\"\n\"\\x7c\\x1c\\xfe\\x57\\xb0\\x66\\x82\\x91\\xe7\\x62\\xa7\\x95\\x35\\xdd\\xda\\x92\"\n\"\\xff\\xc5\\x6d\\x79\\x84\\x4b\\xac\\x9c\\xef\\x76\\x40\\x43\\xa6\\x86\\x10\\xa4\"\n\"\\x5a\\xa8\\x16\\x78\\x40\\xc3\\x4a\\x6f\\xc3\\xb8\\xbd\\x5f\\xa1\\x3a\\x4f\\x22\"\n\"\\xca\\xd0\\x81\\x0f\\x20\\xea\\xde\\xfc\\x8e\\x8d\\x52\\x9f\\x6d\\x3f\\x12\\x0f\"\n\"\\xf0\\xbb\\x10\\x17\\x39\\xa8\\x7a\\xec\\xf4\\xbc\\x31\\x95\\xb3\\xe4\\x3e\\x71\"\n\"\\xbd\\xc2\\xbb\\x2b\\x71\\x2f\\x96\\xc2\\x50\\xa0\\xe5\\xa9\\xaa\\x9a\\xc1\\x02\"\n\"\\x06\\x3b\\x26\\xc8\\x6f\\xf7\\x0c\\xea\\x39\\x2a\\x30\\x69\\x6a\\x43\\x46\\x94\"\n\"\\xc6\\x9e\\xf9\\x45\\xc6\\x15\\x57\\xc6\\x9d\\xc9\\xd2\\xdf\\xee\\xb1\\xa0\\xe1\"\n\"\\x7e\\x83\\xd7\\x5f\\x47\\xe0\\x33\\x3a\\x3e\\x54\\x60\\xd1\\x9a\\x9a\\x1f\\x9a\"\n\"\\x91\\xc4\\x33\\xd6\\x2d\\x39\\xa1\\x94\\x26\\x75\\x8e\\x1f\\x03\\x8f\\x62\\xb1\"\n\"\\x48\\x53\\xb0\\x3e\\xe4\\x83\\x07\\xd9\\xb8\\x02\\x87\\x5e\\x34\\x29\\x05\\xb9\"\n\"\\xfd\\x2a\\xff\\x57\\xae\\x68\\x88\\x7c\\x9a\\x5a\\xe6\\xa4\\x3e\\x4f\\x95\\x9c\"\n\"\\x21\\xe6\\x62\\x54\\x30\\xce\\x21\\x87\\x7e\\x64\\x91\\xf6\\x08\\x6f\\x11\\x66\"\n\"\\xad\\x62\\x82\\xe3\\x9d\\x15\\xd2\\xd0\\xbb\\xf1\\x59\\x38\\x4d\\xfa\\x78\\xa8\"\n\"\\xf9\\x40\\x37\\x2b\\x88\\xe2\\xd2\\xcf\\xb9\\x21\\x24\\xe5\\xeb\\xb2\\x09\\x0c\"\n\"\\x09\\xb8\\xd4\\x9c\\x19\\x05\\x4f\\x73\\x42\\x4a\\x5a\\x36\\xeb\\x75\\xac\\x96\"\n\"\\xf8\\xad\\xc6\\xdf\\xe4\\x88\\x8b\\xb4\\xca\\x59\\x5a\\x5e\\x80\\x56\\x70\\x7d\"\n\"\\x20\\x23\\xcf\\xf7\\x50\\x2d\\xc8\\x13\\xb1\\x2b\\xac\\x30\\xe9\\x18\\xe2\\xc8\"\n\"\\xbf\\x5d\\xe9\\x97\\xff\\x9a\\x1a\\x9f\\x94\\x31\\x68\\xb0\\x23\\xdc\\xf2\\x5c\"\n\"\\xe8\\xc7\\xbc\\xb2\\xea\\x40\\x95\\x1f\\xcb\\xc8\\xf3\\xc8\\x44\\x4a\\xdd\\x2e\"\n\"\\xbd\\x84\\x29\\x2d\\x77\\xef\\x28\\x78\\x54\\x68\\x8a\\x9d\\x00\\x2a\\xcf\\x1d\"\n\"\\xbe\\x04\\x95\\xf2\\x1b\\x35\\x8a\\x1f\\xae\\x62\\x28\\x6d\\x03\\xce\\x8a\\x26\"\n\"\\xe3\\xb9\\x2d\\xf7\\x50\\xb8\\xbb\\xd8\\x42\\x34\\x49\\x5a\\xb1\\x9c\\x6e\\xad\"\n\"\\x03\\xf9\\x23\\x60\\x75\\x8e\\xc4\\xbd\\x33\\x3c\\xdc\\x13\\x9b\\xfd\\xa7\\x1d\"\n\"\\x28\\x54\\x48\\x7a\\x30\\x08\\xa6\\xe6\\xb2\\xc6\\xa1\\x41\\x27\\xf5\\x07\\xf8\"\n\"\\x70\\xd6\\x6c\\x66\\x19\\xee\\xe3\\x5c\\x61\\xcc\\x37\\x82\\xab\\x36\\x72\\x4a\"\n\"\\xcc\\xe0\\xd7\\x93\\x62\\x94\\xf1\\x7e\\x46\\x5f\\x05\\xb7\\x9e\\x0e\\x4d\\xea\"\n\"\\xc0\\x55\\xb9\\x49\\xcc\\xc5\\x06\\xa5\\xb4\\x8d\\xf6\\x3f\\x5d\\x7c\\x07\\x8c\"\n\"\\x3b\\x90\\xa1\\x80\\xa3\\x2f\\x9a\\xe3\\xf1\\xc2\\xcb\\x1b\\x74\\x2b\\x92\\xae\"\n\"\\xce\\x19\\xa2\\xfc\\xb4\\x9f\\xf4\\xc7\\x92\\x88\\xb2\\x1e\\x37\\x2b\\x8d\\xc3\"\n\"\\x24\\x9e\\x68\\x44\\x9d\\xa0\\x76\\x8a\\x7f\\x3e\\x03\\xc1\\x4d\\x6a\\xfa\\xa1\"\n\"\\x01\\x4c\\xd7\\x09\\xbc\\x59\\xc9\\xa4\\x72\\x4b\\xb9\\x6d\\x96\\xde\\x75\\xb3\"\n\"\\xe0\\xde\\x8f\\x51\\xf2\\x9e\\xe9\\x19\\x56\\x4c\\x36\\x3f\\xbe\\x52\\xcf\\x9e\"\n\"\\x7c\\xab\\x6a\\xc7\\x27\\x2a\\x71\\x47\\xe3\\x9b\\x96\\x6b\\xf5\\xd9\\x21\\x06\"\n\"\\x09\\xbd\\x9e\\xbd\\x00\\xc5\\xb2\\x9d\\x42\\x81\\x05\\x48\\x97\\x0f\\x9d\\x46\"\n\"\\x20\\x82\\xd3\\x6c\\x9d\\xe7\\x23\\x82\\x7e\\x35\\x0c\\xe3\\x15\\xb2\\x35\\x88\"\n\"\\x07\\xbb\\x69\\x76\\x17\\x03\\x03\\x00\\xeb\\x91\\x48\\xe1\\xda\\x41\\x9c\\xbb\"\n\"\\x7a\\x0e\\xa0\\xed\\x32\\x03\\x2e\\xf2\\x1d\\x55\\x29\\xb3\\x29\\x09\\x27\\x30\"\n\"\\xe6\\x88\\xb9\\x3f\\x1e\\x21\\x5e\\xe6\\x4a\\xdb\\xb1\\xf8\\xec\\x18\\xe3\\x47\"\n\"\\xc2\\x95\\x42\\x39\\x31\\xb1\\x66\\x18\\xb9\\xaa\\x04\\x30\\xde\\x5a\\xb1\\xe3\"\n\"\\x9d\\xee\\xa4\\x7f\\x0e\\x0c\\x93\\x99\\x08\\x4d\\x6d\\x2e\\x17\\xd0\\xd6\\xa0\"\n\"\\x0c\\xf3\\xf9\\x49\\x8f\\x16\\xc5\\xd0\\x78\\x31\\x40\\xf3\\xf7\\xf9\\xe0\\x12\"\n\"\\x0a\\xff\\xff\\x4d\\x81\\x90\\x06\\xe5\\x6c\\x2d\\x00\\xaf\\xa5\\x70\\x09\\xf7\"\n\"\\xa7\\x9b\\x02\\xf2\\x33\\x67\\x72\\x10\\xd6\\x22\\xf6\\x87\\x66\\x03\\x17\\x73\"\n\"\\x8e\\x7d\\xfe\\x3d\\x0e\\x09\\xf5\\x32\\x2a\\x11\\x0e\\x1e\\x46\\x55\\xf2\\x6d\"\n\"\\x23\\xa0\\x02\\x56\\x69\\x4f\\x92\\x89\\x44\\xfd\\x7a\\x09\\x5c\\xdf\\xd3\\x58\"\n\"\\xfa\\x70\\xc2\\x86\\x1c\\x57\\x8f\\xfb\\x93\\x98\\x83\\xf4\\x34\\x43\\x44\\x3a\"\n\"\\x5c\\x89\\xf1\\x0c\\xd4\\x37\\x72\\x13\\xd5\\x53\\x89\\x6f\\xfb\\x30\\x7b\\x04\"\n\"\\xe3\\x3c\\x61\\xf6\\x99\\x01\\xb1\\x76\\x8a\\x3d\\xe7\\xf9\\xf7\\x1e\\xe9\\x37\"\n\"\\xf1\\xe0\\x85\\x5b\\xa0\\x9f\\x5b\\x56\\xa9\\x26\\xb2\\xff\\x9b\\xca\\x29\\x20\"\n\"\\x64\\x57\\x95\\x3f\\xf5\\x8b\\x16\\x86\\x9a\\x9f\\xca\\x1a\\xb3\\x43\\x25\\x1f\"\n\"\\xd2\\xf3\\x60\\x56\\x17\\x03\\x03\\x00\\x35\\x32\\xda\\xe9\\xf2\\x03\\xc0\\x8b\"\n\"\\x19\\x08\\xbc\\x02\\xe3\\x60\\x6f\\xee\\xf9\\x15\\x50\\xc1\\x46\\xeb\\x78\\x1f\"\n\"\\x97\\x96\\x87\\x7b\\x4f\\xc9\\x27\\x92\\xb2\\x5c\\x0d\\xbd\\xb5\\x0e\\x92\\x34\"\n\"\\x10\\xe2\\x80\\x98\\x46\\x34\\x28\\xd6\\x83\\xbd\\xe8\\xd8\\xf0\\x5d\\x17\\x03\"\n\"\\x03\\x00\\xec\\x8d\\x37\\x66\\xe8\\x26\\xd6\\x41\\x25\\xa7\\xb0\\x7f\\x29\\x7a\"\n\"\\x42\\x1a\\xef\\x99\\x67\\x0e\\x86\\x0f\\x8a\\xa1\\x66\\xb1\\x1d\\x78\\x4e\\xf0\"\n\"\\x75\\xd9\\x77\\xcb\\x70\\x64\\x93\\x1a\\x47\\x00\\xee\\x85\\xc5\\x65\\x44\\x8f\"\n\"\\x9a\\x74\\x5f\\xa1\\x5c\\x9d\\xea\\x72\\xfa\\x6a\\x0d\\x43\\x66\\xba\\x9d\\xee\"\n\"\\x5c\\x81\\xf4\\xbb\\xd0\\x69\\x36\\x1f\\xf4\\xee\\x70\\xb4\\x74\\xbd\\x55\\x08\"\n\"\\xc0\\x9a\\x3c\\x45\\x05\\x80\\xf8\\xa8\\xf4\\x13\\x90\\x54\\x45\\xf0\\x61\\x4a\"\n\"\\x70\\x00\\x2d\\xc3\\xf2\\x2e\\x2c\\x03\\xc6\\xb7\\xe3\\xc8\\x1f\\x6f\\x8d\\xb0\"\n\"\\x97\\xa3\\xfa\\xf6\\x6a\\xe3\\x96\\x9a\\xba\\x51\\x21\\x0a\\xe0\\xc6\\x3a\\xd0\"\n\"\\x4b\\x15\\x81\\xad\\xed\\xdf\\x23\\xf2\\x01\\x2b\\xac\\xe6\\xff\\x32\\x43\\x69\"\n\"\\x15\\x06\\xc4\\x32\\xdc\\x68\\x2c\\x60\\x37\\x8b\\xa4\\x94\\x76\\x12\\x21\\x69\"\n\"\\xa0\\x1f\\x0d\\x2e\\x89\\x1b\\xe2\\x4d\\x32\\x3f\\x35\\x3e\\x97\\x3e\\x85\\x1e\"\n\"\\x59\\xf4\\x89\\x3b\\x96\\x60\\x81\\x4d\\x69\\x8a\\x32\\x14\\x4d\\xcf\\x76\\x06\"\n\"\\x40\\x7e\\xa0\\x96\\x2d\\x1c\\x34\\x25\\x27\\x6e\\x01\\x04\\x72\\xb0\\x0a\\xb7\"\n\"\\x18\\x64\\xd3\\x5e\\x20\\x6b\\xb9\\x03\\x54\\x1d\\x2f\\x4c\\x08\\x72\\x1d\\xa1\"\n\"\\xe0\\xc5\\xa2\\xd9\\x43\\xf4\\xdd\\x27\\x95\\xab\\xcf\\xe5\\x49\\x45\\x5c\";\n\nsize_t ssl_test_case_1_size = sizeof(ssl_test_case_1);\n\nunsigned char ssl_test_case_2[] = {\n0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00,\n0x46, 0x03, 0x01, 0x52, 0x8c, 0x30, 0x62, 0x00,\n0x61, 0x09, 0xc1, 0xaf, 0xb1, 0x9e, 0x62, 0x99,\n0x65, 0x39, 0x82, 0x77, 0x21, 0x59, 0x65, 0x26,\n0x2a, 0xeb, 0x64, 0xd9, 0xe3, 0x5d, 0xe6, 0xf7,\n0x55, 0x3b, 0xf1, 0x20, 0xb0, 0x14, 0x78, 0x6c,\n0xb9, 0x39, 0x8e, 0x23, 0xf0, 0xe4, 0xdc, 0x43,\n0xc2, 0x98, 0x51, 0x58, 0xe5, 0x24, 0x43, 0x28,\n0xbc, 0xd8, 0xb9, 0x5e, 0xcb, 0x3a, 0x11, 0x04,\n0x8f, 0xd7, 0xa9, 0xc7, 0x00, 0x39, 0x00, 0x16,\n0x03, 0x01, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xec,\n0x00, 0x02, 0xe9, 0x00, 0x02, 0xe6, 0x30, 0x82,\n0x02, 0xe2, 0x30, 0x82, 0x01, 0xca, 0xa0, 0x03,\n0x02, 0x01, 0x02, 0x02, 0x04, 0x83, 0x7c, 0x42,\n0x54, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,\n0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,\n0x30, 0x33, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03,\n0x55, 0x04, 0x03, 0x13, 0x10, 0x46, 0x47, 0x54,\n0x38, 0x30, 0x43, 0x33, 0x39, 0x31, 0x31, 0x36,\n0x30, 0x32, 0x31, 0x31, 0x32, 0x31, 0x16, 0x30,\n0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,\n0x46, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x65, 0x74,\n0x20, 0x4c, 0x74, 0x64, 0x2e, 0x30, 0x1e, 0x17,\n0x0d, 0x31, 0x31, 0x30, 0x34, 0x30, 0x35, 0x31,\n0x39, 0x32, 0x34, 0x35, 0x33, 0x5a, 0x17, 0x0d,\n0x32, 0x31, 0x30, 0x34, 0x30, 0x35, 0x31, 0x39,\n0x32, 0x34, 0x35, 0x33, 0x5a, 0x30, 0x33, 0x31,\n0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,\n0x13, 0x10, 0x46, 0x47, 0x54, 0x38, 0x30, 0x43,\n0x33, 0x39, 0x31, 0x31, 0x36, 0x30, 0x32, 0x31,\n0x31, 0x32, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,\n0x55, 0x04, 0x0a, 0x13, 0x0d, 0x46, 0x6f, 0x72,\n0x74, 0x69, 0x6e, 0x65, 0x74, 0x20, 0x4c, 0x74,\n0x64, 0x2e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,\n0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,\n0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,\n0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,\n0x01, 0x01, 0x00, 0x9f, 0xdb, 0xe1, 0x8d, 0x6e,\n0x0b, 0xe1, 0xad, 0xbc, 0x3e, 0x76, 0xa9, 0x14,\n0x3f, 0xb1, 0xfd, 0x1e, 0x95, 0xc5, 0xc8, 0x87,\n0x2b, 0x72, 0xf5, 0x48, 0x32, 0xf0, 0x6b, 0x81,\n0x9b, 0x56, 0x41, 0x92, 0x6e, 0x78, 0x1d, 0x26,\n0x10, 0x1e, 0xcc, 0xc8, 0x2a, 0x1d, 0x74, 0x18,\n0xad, 0x38, 0x1f, 0xb5, 0x36, 0xf3, 0xe2, 0x64,\n0x45, 0x6b, 0x10, 0xde, 0x23, 0x4a, 0xfa, 0xfa,\n0x44, 0x5c, 0xc6, 0xf7, 0x4f, 0xe2, 0xd2, 0x41,\n0x76, 0xbc, 0x59, 0xbc, 0x8b, 0x13, 0x1b, 0xc5,\n0x66, 0x0f, 0xbf, 0x96, 0x11, 0xe5, 0xc4, 0x35,\n0x14, 0x7f, 0x16, 0x2f, 0x40, 0x9d, 0xe2, 0x88,\n0xe6, 0xef, 0x29, 0xa1, 0x34, 0x10, 0xc7, 0x56,\n0xe2, 0xec, 0xfd, 0x5b, 0x52, 0x88, 0x7c, 0x5b,\n0xb1, 0x27, 0x9c, 0x85, 0xaa, 0x4b, 0x62, 0x34,\n0xb8, 0xf5, 0xa2, 0x32, 0x1f, 0x4d, 0xfc, 0xe0,\n0x81, 0xab, 0x08, 0xc3, 0xf7, 0x37, 0xf9, 0x44,\n0x13, 0x9e, 0xfb, 0x48, 0x1c, 0xf5, 0xce, 0xcf,\n0xbc, 0xbf, 0x56, 0xaf, 0xbf, 0x05, 0x1b, 0xf8,\n0x60, 0x27, 0xdf, 0x22, 0x33, 0xea, 0xf3, 0xcf,\n0x29, 0x19, 0x4b, 0x9b, 0xb9, 0xe6, 0x94, 0x60,\n0xea, 0xc0, 0x8b, 0xfd, 0x12, 0xcc, 0xfc, 0x5e,\n0x45, 0xd5, 0x6e, 0x1b, 0x47, 0x25, 0x36, 0x54,\n0x2a, 0x97, 0x25, 0x53, 0x0e, 0xff, 0xa6, 0x0b,\n0x0f, 0xfd, 0x47, 0xf8, 0xa7, 0x43, 0xfc, 0x2e,\n0x32, 0xcc, 0x2a, 0xd0, 0x3d, 0xab, 0x1d, 0x9d,\n0x12, 0x2e, 0x56, 0x82, 0x18, 0x08, 0xba, 0x03,\n0xf3, 0x87, 0xbc, 0x89, 0x0e, 0x44, 0x82, 0x9a,\n0xfd, 0x01, 0xfb, 0x19, 0xa6, 0xa0, 0x1e, 0x9c,\n0xb4, 0x30, 0x6c, 0x20, 0xb3, 0xa8, 0x5a, 0x39,\n0x9a, 0xa6, 0xee, 0x13, 0xb0, 0xed, 0xd0, 0x87,\n0x00, 0x7d, 0xfd, 0xa8, 0x92, 0xc6, 0x06, 0xa2,\n0x38, 0x31, 0x91, 0x02, 0x03, 0x01, 0x00, 0x01,\n0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,\n0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,\n0x82, 0x01, 0x01, 0x00, 0x2a, 0xaf, 0x06, 0x84,\n0x68, 0xe4, 0x06, 0xe7, 0x2a, 0x5c, 0x37, 0x1f,\n0x42, 0xbf, 0xfe, 0x76, 0x80, 0x89, 0xee, 0xf0,\n0x04, 0xb9, 0x66, 0xec, 0x4e, 0x5e, 0x0f, 0xf4,\n0x7f, 0x2c, 0x2a, 0x3b, 0xd6, 0x9c, 0x78, 0xc0,\n0xb6, 0x52, 0x55, 0xb6, 0x8f, 0xf7, 0xca, 0x1a,\n0xe7, 0x5f, 0xb6, 0xd5, 0xf4, 0x2d, 0x2b, 0xad,\n0x28, 0x9e, 0x02, 0x6f, 0xf9, 0x48, 0xef, 0x99,\n0x9a, 0xee, 0x9d, 0x94, 0x99, 0x2f, 0x8b, 0xa4,\n0x18, 0xf0, 0xdf, 0x21, 0x32, 0x0f, 0x7a, 0x80,\n0x5f, 0x63, 0x19, 0xd8, 0x84, 0x0f, 0x73, 0x9d,\n0xa3, 0x95, 0x2b, 0xe8, 0x13, 0x45, 0xd3, 0x11,\n0xb2, 0x2a, 0xcf, 0xb3, 0x06, 0x10, 0x01, 0x02,\n0x58, 0x53, 0xb2, 0x75, 0x95, 0x6f, 0x79, 0xc7,\n0x55, 0x9e, 0xe2, 0xb6, 0x1b, 0x79, 0xf1, 0x76,\n0x27, 0x48, 0xb2, 0xc9, 0xea, 0x05, 0xad, 0x69,\n0x5b, 0x06, 0xdb, 0x16, 0x5d, 0x9c, 0x00, 0x52,\n0x09, 0xe0, 0x82, 0xe7, 0x07, 0x58, 0xc0, 0x01,\n0x67, 0x94, 0xe1, 0x3e, 0xfc, 0xe1, 0x7d, 0x6e,\n0xd3, 0x93, 0xf2, 0xfe, 0x53, 0xe8, 0x71, 0x89,\n0x09, 0x1b, 0x13, 0x31, 0x47, 0xad, 0x26, 0xc3,\n0xbe, 0x72, 0xb0, 0x58, 0x08, 0x66, 0x51, 0x4d,\n0x5a, 0x9e, 0xf5, 0x8c, 0x29, 0x9b, 0xef, 0x97,\n0xf5, 0xc1, 0xb4, 0x1e, 0xc0, 0x37, 0xe7, 0x79,\n0x7d, 0x54, 0x5d, 0x36, 0xb3, 0xb6, 0xf9, 0x03,\n0xb5, 0xb9, 0xa4, 0xf0, 0xc9, 0x93, 0x7d, 0x34,\n0x63, 0x95, 0xc7, 0xe0, 0x77, 0xec, 0x18, 0x5f,\n0xcb, 0x87, 0x2e, 0x7b, 0x87, 0xee, 0x6b, 0xbf,\n0x38, 0xaa, 0x0b, 0xcf, 0xb0, 0x14, 0x84, 0x47,\n0xd2, 0xd3, 0x25, 0x4b, 0x72, 0x86, 0xb5, 0xef,\n0x60, 0x39, 0x94, 0x75, 0xe4, 0xc5, 0x58, 0xf3,\n0x29, 0x9e, 0xe6, 0xe7, 0xbd, 0xeb, 0x36, 0x8b,\n0x21, 0x63, 0xd1, 0xb3, 0x16, 0x03, 0x01, 0x02,\n0x0d, 0x0c, 0x00, 0x02, 0x09, 0x00, 0x80, 0xff,\n0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9,\n0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4,\n0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29,\n0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02,\n0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51,\n0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef,\n0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30,\n0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f,\n0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4,\n0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4,\n0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b,\n0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee,\n0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae,\n0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49,\n0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, 0xff,\n0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,\n0x01, 0x02, 0x00, 0x80, 0xbb, 0x86, 0xf1, 0x2c,\n0xf4, 0x05, 0x26, 0xcb, 0x05, 0x6e, 0x35, 0x04,\n0x34, 0xd5, 0x44, 0x00, 0xf4, 0xc5, 0x63, 0x89,\n0xa8, 0x4e, 0x42, 0xd8, 0x12, 0x18, 0xfc, 0xfc,\n0x15, 0x35, 0xe2, 0x9e, 0x30, 0xc5, 0x18, 0xc5,\n0x2a, 0x96, 0x67, 0x0a, 0x63, 0xd1, 0xd5, 0x8b,\n/* };\nchar peer1_1[] = {*/\n0xe1, 0x32, 0x51, 0x78, 0xdf, 0x9e, 0xc8, 0xa0,\n0x30, 0xa5, 0x42, 0x66, 0xac, 0x11, 0xc9, 0x86,\n0xc1, 0xba, 0x93, 0xe3, 0x76, 0xab, 0x2b, 0x68,\n0xd6, 0x78, 0xf0, 0xd5, 0xee, 0x0e, 0x61, 0x04,\n0xb8, 0x60, 0x5b, 0x91, 0x30, 0x8f, 0x4e, 0x79,\n0xf8, 0xa2, 0x51, 0xe9, 0xcb, 0x28, 0x29, 0xf1,\n0x21, 0xef, 0xa3, 0x00, 0x35, 0x0d, 0xec, 0xb1,\n0x6d, 0xf4, 0xef, 0xe9, 0xea, 0x5a, 0xce, 0x2c,\n0x9a, 0xcb, 0x41, 0x14, 0xde, 0xfe, 0x3a, 0x2a,\n0x6f, 0x7d, 0x0b, 0x69, 0x0a, 0x52, 0x61, 0x20,\n0x2e, 0x9f, 0xa3, 0x2a, 0x01, 0x00, 0x5a, 0x65,\n0x10, 0xde, 0x4a, 0x73, 0x2a, 0x04, 0x93, 0x73,\n0x39, 0x33, 0xd3, 0x2d, 0x27, 0x48, 0xe9, 0x4a,\n0x3e, 0xd4, 0x0c, 0x98, 0xbb, 0xd3, 0x20, 0x24,\n0x3c, 0x31, 0x44, 0xae, 0xa4, 0xb8, 0xd1, 0x62,\n0xb1, 0xd8, 0x52, 0xe8, 0x06, 0xc2, 0x95, 0xf0,\n0x3f, 0x44, 0xd7, 0x76, 0x35, 0x24, 0xa9, 0x35,\n0x35, 0x11, 0xda, 0x95, 0x10, 0x9b, 0xb9, 0xb6,\n0xd2, 0xb8, 0x9d, 0x13, 0x35, 0xbc, 0x43, 0xd9,\n0x5d, 0x44, 0xda, 0x88, 0x3a, 0xa4, 0xef, 0x23,\n0xc6, 0x9e, 0x30, 0x00, 0xfc, 0x27, 0xf4, 0xb3,\n0xb9, 0x0b, 0x00, 0x4d, 0x72, 0x56, 0xc5, 0xa7,\n0xa5, 0x3c, 0x5b, 0x74, 0x55, 0x07, 0x8f, 0x12,\n0x08, 0xf2, 0x74, 0x5d, 0x86, 0x38, 0xb3, 0xc9,\n0x1c, 0xe9, 0xd2, 0xdb, 0xd3, 0x74, 0xe0, 0xe4,\n0x70, 0x5a, 0x36, 0xc5, 0xa2, 0x2a, 0x79, 0xac,\n0x59, 0xd9, 0x2b, 0xb1, 0xf0, 0xb3, 0xa4, 0xfd,\n0x22, 0x8e, 0x43, 0x91, 0x60, 0x3d, 0x91, 0xd7,\n0x02, 0xdf, 0x18, 0xb9, 0x8a, 0xc2, 0xf8, 0x3d,\n0x8c, 0x4e, 0x4b, 0xec, 0x5f, 0x4d, 0x76, 0x3b,\n0x9c, 0xda, 0x77, 0xa9, 0x86, 0x5a, 0x58, 0x4c,\n0xb7, 0x3b, 0x15, 0x65, 0xf9, 0xfb, 0x46, 0xda,\n0xa5, 0x71, 0x06, 0x92, 0xf0, 0x4f, 0x7f, 0x16,\n0xb4, 0xe4, 0x7f, 0x28, 0x61, 0x7a, 0x04, 0x6a,\n0xef, 0xf1, 0x95, 0x14, 0x8d, 0xe9, 0xd0, 0x11,\n0xc9, 0x63, 0xa1, 0x6c, 0xc6, 0x86, 0xc5, 0x95,\n0x03, 0x66, 0xf9, 0xd0, 0x8f, 0x88, 0xc9, 0x9c,\n0xbb, 0x98, 0x7e, 0xa5, 0x42, 0x43, 0x48, 0xae,\n0x8f, 0xab, 0x01, 0x45, 0x1d, 0x83, 0x10, 0x1f,\n0x45, 0x46, 0x01, 0xe5, 0x92, 0x27, 0x62, 0xb4,\n0x0e, 0xc5, 0xdb, 0xf9, 0xf6, 0xf1, 0x9b, 0xb4,\n0xdc, 0x81, 0xa2, 0x6b, 0xa6, 0xff, 0xce, 0x7f,\n0x71, 0x5c, 0x51, 0x93, 0x10, 0x6a, 0x16, 0x03,\n0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,\n/* };\nchar peer1_2[] = {*/\n0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,\n0x01, 0x00, 0x30, 0xa7, 0xa2, 0xb7, 0xa1, 0x1c,\n0x86, 0x9c, 0x8a, 0x52, 0x0c, 0x66, 0x80, 0xc5,\n0x22, 0xf9, 0x1e, 0x24, 0xa4, 0xb3, 0x0a, 0x8b,\n0xcb, 0x8b, 0x72, 0x8d, 0x76, 0xb0, 0x16, 0xd6,\n0x1d, 0x56, 0x96, 0x0f, 0xda, 0xc0, 0x44, 0xde,\n0xa2, 0x81, 0xc6, 0x83, 0x5c, 0xd4, 0x41, 0xea,\n0x31, 0xa3, 0x62,\n/* };\nchar peer1_3[] = {*/\n0x15, 0x03, 0x01, 0x00, 0x20, 0xf0, 0xf1, 0xdb,\n0x2b, 0x08, 0xae, 0xc4, 0x76, 0xdf, 0x0c, 0x1c,\n0xc1, 0xdd, 0x70, 0x42, 0xd2, 0x6f, 0x91, 0x8a,\n0xb5, 0xd2, 0x9f, 0x26, 0x75, 0xa3, 0x45, 0xd0,\n0x6e, 0x17, 0xb1, 0xb2, 0x7b };\n\nsize_t ssl_test_case_2_size = sizeof(ssl_test_case_2);\n\n\nunsigned char ssl_test_case_3[] = {\n0x16, 0x03, 0x01, 0x00, 0x35, 0x02, 0x00, 0x00,\n0x31, 0x03, 0x01, 0x52, 0x8c, 0x2f, 0xb6, 0x9d,\n0x0c, 0x4c, 0x3e, 0xc2, 0xa5, 0x55, 0x2f, 0x0a,\n0xa3, 0x03, 0x2d, 0x64, 0x64, 0x7b, 0xed, 0x92,\n0x87, 0xa7, 0x94, 0x62, 0x41, 0x5b, 0x23, 0xef,\n0x0d, 0x8f, 0xe0, 0x00, 0x00, 0x88, 0x00, 0x00,\n0x09, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x23,\n0x00, 0x00, 0x16, 0x03, 0x01, 0x0a, 0xf2, 0x0b,\n0x00, 0x0a, 0xee, 0x00, 0x0a, 0xeb, 0x00, 0x05,\n0x9b, 0x30, 0x82, 0x05, 0x97, 0x30, 0x82, 0x03,\n0x7f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01,\n0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,\n0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,\n0x30, 0x28, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,\n0x55, 0x04, 0x03, 0x0c, 0x1d, 0x50, 0x75, 0x70,\n0x70, 0x65, 0x74, 0x20, 0x43, 0x41, 0x3a, 0x20,\n0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x2e, 0x6c,\n0x6f, 0x63, 0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61,\n0x69, 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,\n0x31, 0x31, 0x31, 0x39, 0x30, 0x33, 0x33, 0x34,\n0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x31,\n0x31, 0x31, 0x39, 0x30, 0x33, 0x33, 0x34, 0x30,\n0x30, 0x5a, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19,\n0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x75,\n0x62, 0x75, 0x6e, 0x74, 0x75, 0x2e, 0x6c, 0x6f,\n0x63, 0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69,\n0x6e, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06,\n0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f,\n0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02,\n0x01, 0x00, 0xc7, 0xf7, 0xa6, 0xaf, 0x45, 0xe4,\n0x20, 0xff, 0x02, 0x4d, 0xe2, 0xb2, 0xd6, 0x67,\n0x97, 0x37, 0x4e, 0x7a, 0x58, 0x56, 0x81, 0xba,\n0x07, 0x64, 0x1c, 0xf5, 0xa0, 0xb2, 0x86, 0xbd,\n0xc4, 0x3d, 0x66, 0x93, 0x72, 0xd1, 0x3d, 0xf7,\n0xa4, 0x43, 0xfb, 0x9e, 0xbe, 0x22, 0xd9, 0x27,\n0x35, 0x6a, 0xc9, 0xe9, 0x17, 0x34, 0x69, 0x92,\n0x60, 0xd9, 0x4b, 0xe0, 0xaa, 0x53, 0x46, 0xb3,\n0x4b, 0x40, 0x12, 0xa4, 0xfa, 0xcc, 0xff, 0xfa,\n0x5d, 0x72, 0x0e, 0xb9, 0xec, 0x32, 0xb8, 0xf7,\n0x74, 0x4c, 0xda, 0xc2, 0xc4, 0x35, 0xae, 0xd1,\n0xb8, 0x9f, 0x2e, 0xa4, 0x19, 0xe2, 0xa1, 0x94,\n0xe2, 0xc4, 0x12, 0x49, 0x82, 0x97, 0x5b, 0xb6,\n0x08, 0x79, 0xcf, 0xf8, 0x9c, 0x8a, 0x8d, 0x04,\n0xfa, 0xb7, 0xe1, 0xec, 0xf1, 0x9e, 0xc3, 0x2d,\n0x6c, 0x83, 0xfe, 0x4a, 0x9d, 0x72, 0x98, 0x99,\n0xaa, 0xc0, 0xd7, 0x13, 0xb9, 0xb9, 0x34, 0x65,\n0x47, 0x36, 0x44, 0xdd, 0x8d, 0x30, 0x49, 0x10,\n0x04, 0x19, 0x64, 0x01, 0x79, 0x6d, 0xb4, 0xb0,\n0x2a, 0x98, 0x95, 0xc6, 0xfb, 0x97, 0xa9, 0x4e,\n0xd3, 0x30, 0x24, 0x37, 0x92, 0x87, 0x91, 0x6c,\n0x0d, 0x04, 0x34, 0x40, 0x03, 0x20, 0x25, 0xd1,\n0xde, 0x00, 0x0f, 0xad, 0xc1, 0xc9, 0xc3, 0xd4,\n0x50, 0x0c, 0x90, 0xbd, 0x07, 0xd7, 0x9d, 0xd1,\n0xf1, 0x88, 0xe0, 0xa1, 0x75, 0x5a, 0xe0, 0xdb,\n0x36, 0x3c, 0x88, 0xa4, 0x9a, 0x84, 0x8b, 0x27,\n0xfd, 0xe3, 0xd3, 0x92, 0x4b, 0xa4, 0x29, 0x81,\n0xa7, 0x4a, 0x61, 0x64, 0xe3, 0xa8, 0x92, 0x97,\n0xa1, 0xa2, 0xa9, 0xde, 0xdd, 0x27, 0x42, 0x77,\n0xe9, 0x87, 0xb1, 0x17, 0x21, 0x70, 0xbb, 0x22,\n0xab, 0xf4, 0x4c, 0x23, 0xc4, 0x8d, 0x0c, 0x7c,\n0x3a, 0x9a, 0x44, 0x8d, 0xd3, 0x97, 0xf5, 0x30,\n0x70, 0xd5, 0x05, 0x04, 0x0c, 0xaa, 0xb3, 0x19,\n0x73, 0x90, 0x12, 0x9b, 0xf9, 0x9d, 0x0f, 0x37,\n0x76, 0xe0, 0xfc, 0xa0, 0x1a, 0x32, 0xca, 0x2a,\n0x14, 0x23, 0x2f, 0xaf, 0xed, 0x7c, 0x42, 0x36,\n0xc0, 0xbb, 0x98, 0x27, 0xe3, 0xed, 0xaa, 0x80,\n0xff, 0x4d, 0xea, 0x1d, 0x9f, 0x01, 0xc1, 0xb0,\n0x51, 0x61, 0x96, 0x2b, 0x1c, 0x15, 0xcb, 0x38,\n0x10, 0x8f, 0xbf, 0xd9, 0xa2, 0xf1, 0x01, 0x36,\n0x8d, 0xec, 0x10, 0xb0, 0xea, 0x07, 0x43, 0xf5,\n0xce, 0xb3, 0x80, 0xba, 0x6c, 0xb5, 0xdd, 0xc4,\n0xaf, 0x17, 0x69, 0x18, 0x72, 0xd9, 0x34, 0x22,\n0x00, 0xcc, 0x4f, 0x16, 0xb2, 0x75, 0x8c, 0x31,\n0x7c, 0xeb, 0xd0, 0x90, 0x45, 0xba, 0x78, 0x02,\n0xc1, 0xbb, 0x2c, 0xbe, 0x7c, 0x8a, 0xc4, 0xa2,\n0x7b, 0x07, 0x8f, 0x54, 0x69, 0xc7, 0x54, 0x7a,\n0x4a, 0xea, 0x5d, 0xc7, 0x02, 0x88, 0xeb, 0x8d,\n0xdd, 0x59, 0xf5, 0x0d, 0xd8, 0xd5, 0x58, 0x45,\n0xa9, 0xaf, 0xaa, 0xec, 0x38, 0x55, 0x40, 0xe0,\n0x1a, 0xcf, 0x72, 0x1b, 0x67, 0x7c, 0xf7, 0x0c,\n0x72, 0x5b, 0x55, 0xfd, 0xc0, 0x0d, 0x2e, 0xf3,\n0x24, 0xb4, 0x63, 0xb1, 0x3d, 0xdd, 0xca, 0xeb,\n0xac, 0x0c, 0x8a, 0xcb, 0x09, 0xb7, 0xaf, 0x05,\n0xb5, 0x7d, 0x79, 0xb7, 0xa2, 0x75, 0xbc, 0xa7,\n0x2d, 0x5a, 0x1e, 0x30, 0x68, 0x69, 0x98, 0x62,\n0x7d, 0xaa, 0x42, 0xcd, 0x7f, 0xb9, 0x00, 0xda,\n0xef, 0xac, 0xcc, 0x41, 0xe4, 0x61, 0x3e, 0x90,\n0x9b, 0xeb, 0xdb, 0xe0, 0x01, 0x24, 0xf5, 0x3c,\n0xc6, 0x9c, 0x46, 0x17, 0xa1, 0x9f, 0xfc, 0xc2,\n0x47, 0x6f, 0xa6, 0xf5, 0x1b, 0x21, 0xd7, 0x00,\n0x5d, 0x26, 0x1b, 0x67, 0x54, 0x36, 0x76, 0x71,\n0x3e, 0xfa, 0xbf, 0x1d, 0x7d, 0xaf, 0x88, 0x8b,\n0xe3, 0xe7, 0x2b, 0x8d, 0x53, 0x75, 0x73, 0x8c,\n0xbb, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,\n0x81, 0xd6, 0x30, 0x81, 0xd3, 0x30, 0x39, 0x06,\n0x03, 0x55, 0x1d, 0x11, 0x04, 0x32, 0x30, 0x30,\n0x82, 0x06, 0x70, 0x75, 0x70, 0x70, 0x65, 0x74,\n0x82, 0x12, 0x70, 0x75, 0x70, 0x70, 0x65, 0x74,\n0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x64, 0x6f,\n0x6d, 0x61, 0x69, 0x6e, 0x82, 0x12, 0x75, 0x62,\n0x75, 0x6e, 0x74, 0x75, 0x2e, 0x6c, 0x6f, 0x63,\n0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,\n0x30, 0x20, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01,\n0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08,\n0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,\n0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,\n0x03, 0x02, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,\n0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,\n0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,\n0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,\n0x30, 0x37, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,\n0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x2a, 0x16,\n0x28, 0x50, 0x75, 0x70, 0x70, 0x65, 0x74, 0x20,\n0x52, 0x75, 0x62, 0x79, 0x2f, 0x4f, 0x70, 0x65,\n0x6e, 0x53, 0x53, 0x4c, 0x20, 0x49, 0x6e, 0x74,\n0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x65,\n0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,\n0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,\n0x04, 0x16, 0x04, 0x14, 0xde, 0x9c, 0x3e, 0x14,\n0x35, 0x6f, 0x93, 0xe3, 0xbc, 0x84, 0x8b, 0x0c,\n0xfb, 0x64, 0x30, 0x22, 0xf2, 0x9d, 0x31, 0x1a,\n0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,\n0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,\n0x82, 0x02, 0x01, 0x00, 0xb7, 0x22, 0x97, 0x64,\n0x5c, 0xde, 0x12, 0x6c, 0x37, 0x9d, 0x56, 0x41,\n0x92, 0x12, 0xf0, 0x9f, 0xc4, 0xcd, 0x99, 0x38,\n0x8e, 0x06, 0x78, 0x0b, 0x76, 0xdd, 0x87, 0x31, /* };\nchar peer1_1[] = {*/\n0x62, 0xb2, 0x92, 0xb5, 0xd6, 0x1c, 0xd0, 0xb2,\n0x92, 0xb5, 0xd6, 0x63, 0x47, 0x58, 0xe3, 0x99,\n0x55, 0x0b, 0xee, 0xa1, 0xe7, 0x9a, 0x0d, 0xac,\n0x57, 0x97, 0xbc, 0x13, 0xb7, 0x24, 0xb2, 0x5a,\n0x9a, 0x49, 0x28, 0xfa, 0xf6, 0x68, 0xdb, 0xe1,\n0x1a, 0xe8, 0x58, 0x7a, 0x00, 0x35, 0xa7, 0x4b,\n0xe2, 0xcd, 0x28, 0x89, 0x50, 0xe3, 0x20, 0xb0,\n0x93, 0xbb, 0x1c, 0xae, 0x04, 0x3e, 0x80, 0xbd,\n0x54, 0xeb, 0xeb, 0x41, 0x7b, 0xd5, 0x92, 0x5b,\n0xc3, 0x89, 0xed, 0x5f, 0xdd, 0xed, 0x10, 0xb9,\n0x41, 0xef, 0xeb, 0x30, 0x7a, 0x18, 0xba, 0x88,\n0x4a, 0x49, 0x25, 0x06, 0xab, 0x1d, 0xfa, 0xe9,\n0xc2, 0x0e, 0x31, 0x26, 0x52, 0xfd, 0x09, 0xac,\n0xff, 0x1d, 0xb7, 0xfa, 0x2e, 0xb5, 0x6f, 0x3e,\n0x04, 0x30, 0xa9, 0xf8, 0x66, 0x3c, 0xc0, 0xaf,\n0x16, 0x7b, 0xaf, 0x88, 0xdb, 0xd4, 0x1a, 0xbf,\n0x1f, 0xef, 0x4f, 0xbb, 0xc2, 0xf4, 0x6f, 0x98,\n0x84, 0x77, 0x64, 0xd6, 0xd2, 0x28, 0x8f, 0xa4,\n0xf7, 0x21, 0x64, 0xae, 0x9d, 0xc2, 0x50, 0xd3,\n0xd9, 0xd2, 0xe0, 0x19, 0x31, 0xbf, 0xcd, 0xf8,\n0x5a, 0x7e, 0x51, 0x07, 0x85, 0x6b, 0x67, 0x31,\n0x87, 0xcc, 0x28, 0x6e, 0xa5, 0xc5, 0x11, 0x86,\n0x62, 0xb8, 0x4f, 0xe4, 0x4b, 0x19, 0xdc, 0x79,\n0xd2, 0xd3, 0x6e, 0x25, 0x8c, 0x88, 0x14, 0x0d,\n0xf4, 0x04, 0xcf, 0x52, 0xc6, 0xff, 0x2a, 0xdb,\n0x04, 0xbf, 0xc1, 0x1b, 0x4e, 0x10, 0x7a, 0x37,\n0x56, 0x89, 0xb3, 0x83, 0xb4, 0x4a, 0x07, 0xb3,\n0x23, 0x5f, 0xbe, 0x41, 0xc4, 0x3c, 0xc7, 0xc0,\n0xec, 0xe0, 0xe8, 0x5c, 0x1a, 0xde, 0xff, 0x1f,\n0xf4, 0x20, 0x8e, 0x57, 0x0e, 0x6c, 0x57, 0xa3,\n0xdf, 0xab, 0x63, 0x13, 0x15, 0xd8, 0x63, 0xcb,\n0x44, 0x89, 0x58, 0xb7, 0xfd, 0x81, 0x4c, 0x2c,\n0xdb, 0x98, 0x6a, 0xe0, 0xe8, 0x6f, 0x20, 0xe8,\n0xd3, 0xaf, 0x1c, 0x5d, 0x7a, 0x5f, 0x2c, 0xb5,\n0xd9, 0x2f, 0xf9, 0x3b, 0xf8, 0x86, 0xda, 0xbf,\n0x1d, 0xd1, 0x3e, 0xaa, 0xf1, 0xa2, 0x7d, 0x9c,\n0xa3, 0xbf, 0xfb, 0x79, 0x54, 0xed, 0x4d, 0xd5,\n0xc9, 0x22, 0xe8, 0x48, 0x95, 0x05, 0xf0, 0xe2,\n0x8c, 0xc5, 0x3e, 0xea, 0x8e, 0xeb, 0x50, 0xaf,\n0x9d, 0xe1, 0x8a, 0x0b, 0x63, 0x12, 0x89, 0x7b,\n0x2f, 0x1f, 0x0e, 0x78, 0x1a, 0x86, 0xde, 0x0d,\n0xd4, 0x70, 0x15, 0xa5, 0xa2, 0xd2, 0xb3, 0x98,\n0x19, 0xd8, 0x7f, 0xef, 0x43, 0x11, 0x12, 0x76,\n0x36, 0xdb, 0xde, 0x06, 0x1e, 0xe1, 0x56, 0x9a,\n0x44, 0xce, 0xc8, 0xcc, 0x3b, 0x52, 0x3c, 0x3c,\n0x74, 0xe5, 0x99, 0x40, 0xe1, 0xc5, 0xdf, 0xc0,\n0x17, 0xc0, 0x96, 0xcf, 0xcb, 0x93, 0x60, 0xc3,\n0xf6, 0x36, 0x25, 0x1e, 0x27, 0x09, 0x11, 0xae,\n0x63, 0xf2, 0x88, 0x04, 0xbe, 0x0f, 0xda, 0x3f,\n0x61, 0xe4, 0x5a, 0xa5, 0x89, 0xde, 0x3e, 0x3c,\n0x93, 0x1f, 0xad, 0xf9, 0x67, 0x25, 0xf3, 0x35,\n0x3d, 0x61, 0x4e, 0x67, 0x25, 0x4b, 0x27, 0xad,\n0x6f, 0xcf, 0x78, 0xeb, 0x8e, 0x77, 0xf0, 0xe4,\n0x2c, 0xc2, 0xc4, 0xcd, 0xbd, 0xaa, 0x72, 0x66,\n0x4b, 0x46, 0x14, 0x45, 0xe2, 0xa8, 0x66, 0xce,\n0xa2, 0xb3, 0xac, 0x24, 0x2d, 0x97, 0x9b, 0x5e,\n0x18, 0xe2, 0xf7, 0x97, 0x3b, 0xce, 0x9d, 0xe4,\n0x1a, 0xa0, 0x89, 0x49, 0xb2, 0xa2, 0xdf, 0x0d,\n0x1d, 0xc2, 0x3d, 0x6d, 0xc4, 0x04, 0xec, 0xb2,\n0x5e, 0x91, 0xc2, 0x8c, 0xcf, 0x40, 0xeb, 0x52,\n0x7a, 0x1b, 0x46, 0x0c, 0x00, 0x05, 0x4a, 0x30,\n0x82, 0x05, 0x46, 0x30, 0x82, 0x03, 0x2e, 0xa0,\n0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30,\n0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,\n0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x28,\n0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,\n0x03, 0x0c, 0x1d, 0x50, 0x75, 0x70, 0x70, 0x65,\n0x74, 0x20, 0x43, 0x41, 0x3a, 0x20, 0x75, 0x62,\n0x75, 0x6e, 0x74, 0x75, 0x2e, 0x6c, 0x6f, 0x63,\n0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,\n0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x31,\n0x31, 0x39, 0x30, 0x33, 0x33, 0x33, 0x35, 0x39,\n0x5a, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x31, 0x31,\n0x39, 0x30, 0x33, 0x33, 0x33, 0x35, 0x39, 0x5a,\n0x30, 0x28, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,\n0x55, 0x04, 0x03, 0x0c, 0x1d, 0x50, 0x75, 0x70,\n0x70, 0x65, 0x74, 0x20, 0x43, 0x41, 0x3a, 0x20,\n0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x2e, 0x6c,\n0x6f, 0x63, 0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61,\n0x69, 0x6e, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,\n0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,\n0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02,\n0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82,\n0x02, 0x01, 0x00, 0xbf, 0x81, 0x70, 0x18, 0x7b,\n0x07, 0x5f, 0x6d, 0x33, 0x27, 0x2c, 0x32, 0x4d,\n0x20, 0x0d, 0x2e, 0xed, 0x05, 0xaa, 0xd0, 0xfa,\n0x2f, 0xcb, 0x97, 0x00, 0x17, 0xe8, 0xcf, 0xcb,\n0x68, 0x4b, 0x93, 0x9a, 0x0d, 0x64, 0x71, 0x15,\n0x2c, 0x5b, 0x43, 0x98, 0x87, 0xa4, 0x2b, 0xa9,\n0x45, 0xcb, 0x55, 0x3d, 0x17, 0xe4, 0xed, 0x43,\n0xae, 0x2b, 0x08, 0x56, 0xae, 0xd4, 0xcd, 0x4b,\n0x12, 0xd9, 0x54, 0xbe, 0x1f, 0x45, 0xf5, 0x53,\n0x92, 0x0b, 0x58, 0xc9, 0x4b, 0xec, 0x15, 0x14,\n0xb9, 0xb9, 0x92, 0xf4, 0x0d, 0xbd, 0xf7, 0xee,\n0xb5, 0x36, 0xab, 0xc7, 0x54, 0xc3, 0x78, 0x32,\n0xed, 0xec, 0x91, 0x1c, 0x8c, 0x6b, 0x72, 0xfc,\n0x69, 0xfb, 0x2a, 0xbe, 0xd7, 0x18, 0x6a, 0xa1,\n0xc5, 0xa9, 0x28, 0x91, 0xbf, 0xc1, 0x12, 0x0e,\n0xff, 0x75, 0xa2, 0x61, 0x9b, 0xc1, 0x01, 0x49,\n0x69, 0xee, 0xde, 0x00, 0x18, 0x89, 0x7b, 0xfc,\n0x9c, 0x4f, 0x10, 0xe5, 0x40, 0x21, 0x3b, 0x0e,\n0x15, 0x37, 0x64, 0x25, 0x0b, 0x27, 0xa4, 0xd1,\n0x8b, 0xd0, 0x60, 0x54, 0xb4, 0xe2, 0x8b, 0x1a,\n0xe2, 0x97, 0x63, 0x51, 0x71, 0xdc, 0xb1, 0x6f,\n0xe2, 0x74, 0xc9, 0x37, 0xd5, 0x51, 0x26, 0x1a,\n0xdc, 0x4a, 0x2d, 0x69, 0xd6, 0xa3, 0x16, 0x5d,\n0x25, 0x21, 0x58, 0xbf, 0x30, 0xb9, 0xc1, 0x25,\n0x70, 0x5b, 0xf5, 0x77, 0x9d, 0x01, 0x4a, 0x26,\n0x7e, 0xca, 0x84, 0x60, 0xa5, 0x1d, 0x64, 0xfa,\n0x27, 0x22, 0x89, 0x27, 0xa6, 0xb9, 0xf5, 0x76,\n0xc1, 0x2e, 0xba, 0x91, 0xb6, 0xd3, 0x83, 0x59,\n0x07, 0xeb, 0xa4, 0x30, 0x49, 0xb1, 0x35, 0x33,\n0x46, 0xab, 0x0d, 0xf9, 0xf9, 0xb7, 0xb8, 0x13,\n0x6a, 0xc3, 0xa7, 0x66, 0x19, 0x2f, 0x26, 0x87,\n0xdd, 0x91, 0x9d, 0xc5, 0xf1, 0xc1, 0xc7, 0x82,\n0xaf, 0x9e, 0x73, 0x28, 0x52, 0xbd, 0xb2, 0xa5,\n0xa4, 0xae, 0xba, 0xdb, 0xbe, 0x29, 0xd4, 0x00,\n0x65, 0x69, 0xe6, 0xc0, 0x01, 0x38, 0xe8, 0xb1,\n0x74, 0xf7, 0xa4, 0x84, 0x61, 0x83, 0x12, 0xec,\n0x16, 0x8d, 0x1a, 0xb7, 0xaa, 0x9f, 0x36, 0xae,\n0x8e, 0x50, 0x06, 0x9c, 0x0f, 0xe9, 0x74, 0xff,\n0xa2, 0x9b, 0x55, 0x5b, 0xc4, 0xb1, 0x25, 0xd0,\n0x49, 0x03, 0xdb, 0xe4, 0xd5, 0x11, 0x03, 0xa0,\n0x10, 0x82, 0x0c, 0x35, 0xae, 0xcb, 0x62, 0x6b,\n0x3e, 0x93, 0xc9, 0x69, 0xa9, 0xfd, 0x66, 0x74,\n0x51, 0x44, 0x46, 0xe9, 0xd7, 0x1a, 0xa3, 0x9e,\n0x4d, 0xbe, 0xca, 0x84, 0xf7, 0x57, 0x18, 0x8f,\n0x8f, 0xce, 0x78, 0xf5, 0xe7, 0xb6, 0x7b, 0xed, /* };\nchar peer1_2[] = {*/\n0x60, 0x7b, 0xae, 0x43, 0x62, 0x0f, 0x83, 0x0d,\n0x0c, 0xce, 0xaf, 0xf3, 0x1f, 0xc7, 0x69, 0xc4,\n0x55, 0x4a, 0xe1, 0x35, 0xe8, 0xc1, 0x9b, 0x66,\n0xfa, 0x04, 0xe4, 0x99, 0x31, 0x4e, 0x4d, 0x97,\n0xca, 0x2d, 0xe6, 0xf4, 0x0a, 0x31, 0x7e, 0x51,\n0x47, 0xdf, 0x2f, 0xce, 0x3f, 0xdd, 0x50, 0x3d,\n0xd5, 0xe6, 0x81, 0x0e, 0xb5, 0x8c, 0x40, 0x8d,\n0x58, 0xd2, 0x4d, 0x1b, 0x8f, 0xd0, 0xd5, 0x16,\n0xcd, 0x2e, 0x29, 0x8f, 0x40, 0xa4, 0x23, 0x3b,\n0xc3, 0x1f, 0x56, 0x5e, 0x42, 0x03, 0x12, 0x79,\n0x9a, 0x66, 0x25, 0xec, 0x55, 0x4b, 0xd7, 0x2d,\n0xb5, 0xe8, 0x62, 0xb1, 0xf4, 0x7e, 0x93, 0x0b,\n0xfc, 0x9a, 0x71, 0x52, 0x09, 0x2d, 0x61, 0xfb,\n0x65, 0x22, 0x07, 0x68, 0x7e, 0x9c, 0xc7, 0x74,\n0xf9, 0xe7, 0xbe, 0x16, 0x99, 0x92, 0x14, 0x71,\n0x2e, 0x91, 0xc2, 0x36, 0xf9, 0x2d, 0xb9, 0x95,\n0x9d, 0x3b, 0x3a, 0x3e, 0x16, 0xfb, 0x09, 0x8c,\n0x84, 0x52, 0x50, 0x2f, 0x78, 0x62, 0x37, 0x54,\n0xef, 0x69, 0xdf, 0xd4, 0x3f, 0xa5, 0xc1, 0x4e,\n0x67, 0xd5, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01,\n0xa3, 0x7b, 0x30, 0x79, 0x30, 0x0f, 0x06, 0x03,\n0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,\n0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,\n0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,\n0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x37, 0x06,\n0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,\n0x01, 0x0d, 0x04, 0x2a, 0x16, 0x28, 0x50, 0x75,\n0x70, 0x70, 0x65, 0x74, 0x20, 0x52, 0x75, 0x62,\n0x79, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53,\n0x4c, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,\n0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,\n0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d,\n0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,\n0x14, 0xde, 0x9c, 0x3e, 0x14, 0x35, 0x6f, 0x93,\n0xe3, 0xbc, 0x84, 0x8b, 0x0c, 0xfb, 0x64, 0x30,\n0x22, 0xf2, 0x9d, 0x31, 0x1a, 0x30, 0x0d, 0x06,\n0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01,\n0x00, 0xa9, 0x16, 0x08, 0xe6, 0xb8, 0x3c, 0x04,\n0x33, 0xcd, 0xcc, 0x87, 0x9a, 0x7b, 0x41, 0xdd,\n0xe7, 0x6b, 0xe0, 0xa9, 0xfd, 0x2a, 0x35, 0x3a,\n0xd8, 0xb1, 0xf1, 0xf8, 0x5c, 0x85, 0xd4, 0x3b,\n0xab, 0x61, 0xc1, 0xd2, 0x2e, 0x21, 0x00, 0xfe,\n0x1b, 0xd6, 0xeb, 0x0c, 0x75, 0xfb, 0x80, 0x66,\n0x3d, 0x01, 0xc9, 0xb1, 0x3e, 0x87, 0xd7, 0x11,\n0x8c, 0x93, 0x2f, 0x91, 0x44, 0x35, 0xf8, 0xe0,\n0x7d, 0xaf, 0xe5, 0xd9, 0x24, 0xd8, 0xc1, 0x0d,\n0xc4, 0x48, 0x72, 0x45, 0xdc, 0x3b, 0x4f, 0x23,\n0xed, 0x1a, 0x57, 0xe0, 0xeb, 0x2c, 0x91, 0x09,\n0x1c, 0xa0, 0x9f, 0x10, 0x77, 0xb6, 0x71, 0x81,\n0x0a, 0x21, 0xca, 0x09, 0x3c, 0xea, 0xa0, 0x5d,\n0x03, 0x88, 0xdb, 0x00, 0x48, 0xf0, 0x2b, 0x49,\n0xee, 0x49, 0xc8, 0x83, 0xd1, 0x14, 0xe7, 0xcd,\n0x92, 0x98, 0x23, 0xc3, 0xbd, 0xdb, 0x19, 0x30,\n0x7b, 0xe8, 0xb2, 0xc0, 0x7f, 0xff, 0x0c, 0xa2,\n0x52, 0x45, 0x16, 0xc3, 0x74, 0x3a, 0x9b, 0xfa,\n0xc2, 0x71, 0xad, 0x6e, 0xc5, 0x80, 0xe6, 0x9a,\n0x55, 0x09, 0x2b, 0xc4, 0xf0, 0xe8, 0xdb, 0x75,\n0x15, 0xdc, 0x58, 0xdb, 0x7d, 0xa6, 0xf7, 0x48,\n0xfd, 0x68, 0x86, 0x10, 0xdc, 0xaf, 0x49, 0x5d,\n0xe7, 0x05, 0x7f, 0xd0, 0x4d, 0xf6, 0xfe, 0xf8,\n0xf6, 0x2f, 0x88, 0x2c, 0xed, 0xeb, 0xee, 0x89,\n0x55, 0xcf, 0x69, 0xb2, 0x3c, 0x39, 0x61, 0xb8,\n0x4b, 0xba, 0xbb, 0x2b, 0x6d, 0x83, 0xc9, 0x04,\n0xe7, 0x03, 0xe7, 0xd8, 0xd7, 0xb5, 0x43, 0x4b,\n0x9b, 0x3f, 0xd9, 0xf8, 0xa4, 0xb2, 0xdb, 0x83,\n0x54, 0x45, 0xe0, 0x18, 0xde, 0x56, 0x0f, 0x72,\n0x21, 0x26, 0xda, 0xcd, 0xc8, 0x80, 0x3b, 0x88,\n0x0f, 0xff, 0xf3, 0xe0, 0x3d, 0x8c, 0xba, 0x87,\n0x83, 0x78, 0x55, 0x10, 0xed, 0x0b, 0x6d, 0x73,\n0x69, 0x2d, 0x47, 0xa4, 0xc6, 0xf4, 0xef, 0xb2,\n0xb6, 0xbf, 0xb7, 0xda, 0x33, 0x76, 0xa4, 0x06,\n0x1b, 0x39, 0x1a, 0x98, 0xa5, 0x5a, 0xde, 0x81,\n0x73, 0xfd, 0xe2, 0x0e, 0xb7, 0xe0, 0x3d, 0x80,\n0x91, 0x78, 0xa2, 0x67, 0x0a, 0x8b, 0x8b, 0x90,\n0xe0, 0x8e, 0x6b, 0xda, 0x58, 0x3b, 0xfc, 0x77,\n0x74, 0xdb, 0x77, 0xcf, 0xf2, 0xf1, 0xed, 0x37,\n0x16, 0xae, 0x87, 0xd9, 0x39, 0x39, 0x82, 0x4e,\n0x3b, 0x0f, 0xf7, 0xed, 0x8d, 0x19, 0x86, 0xfd,\n0x7d, 0x6c, 0x21, 0x03, 0x2d, 0x89, 0x66, 0xaa,\n0x3e, 0x2f, 0xf9, 0x07, 0x60, 0xd7, 0x89, 0x33,\n0xb3, 0x77, 0xe8, 0x72, 0x77, 0x63, 0xf0, 0x5f,\n0xe7, 0x2a, 0xae, 0xf1, 0xe1, 0xe2, 0xa1, 0x85,\n0x3b, 0x8c, 0x85, 0x8f, 0x30, 0x37, 0x0e, 0x66,\n0x83, 0x48, 0x0a, 0xd9, 0x35, 0xc1, 0xcf, 0x1e,\n0x72, 0x62, 0x99, 0x7a, 0xa1, 0xf0, 0x8b, 0xc4,\n0xf0, 0x0d, 0x89, 0x58, 0x3f, 0x20, 0x72, 0x9e,\n0x96, 0x80, 0x70, 0x5f, 0x71, 0x25, 0x92, 0x22,\n0xf5, 0x27, 0x38, 0x2a, 0x4e, 0x03, 0x3e, 0xdc,\n0x4a, 0x2a, 0x1a, 0xe2, 0x4a, 0x20, 0x1a, 0x3e,\n0xb1, 0x8e, 0x59, 0x7b, 0xe8, 0x15, 0x2e, 0xf9,\n0x37, 0x2b, 0x96, 0xeb, 0x34, 0xef, 0x73, 0x47,\n0x62, 0xc8, 0x5e, 0x58, 0x96, 0x8d, 0xb0, 0xfb,\n0xe9, 0xbf, 0xd8, 0xe6, 0x6a, 0x8e, 0x22, 0x71,\n0x07, 0x63, 0xe5, 0xbe, 0xf0, 0x62, 0x93, 0xba,\n0x8c, 0x8d, 0x4b, 0x3d, 0x88, 0x36, 0x8f, 0x01,\n0x29, 0xc8, 0xb4, 0x35, 0x28, 0xc7, 0x73, 0x78,\n0xd9, 0x1e, 0xcd, 0x35, 0xa9, 0xca, 0xec, 0xea,\n0xd0, 0x3d, 0x87, 0x1d, 0xf8, 0x4c, 0x06, 0x6d,\n0xd4, 0x9e, 0x30, 0xcb, 0x45, 0x79, 0xff, 0x68,\n0x7e, 0x2d, 0x29, 0x14, 0x1e, 0x69, 0x53, 0xb5,\n0x83, 0x54, 0x80, 0xa6, 0xa5, 0x33, 0x93, 0xd0,\n0xc8, 0x16, 0x03, 0x01, 0x03, 0x0d, 0x0c, 0x00,\n0x03, 0x09, 0x00, 0x80, 0x9d, 0x25, 0x39, 0x5c,\n0xb4, 0x54, 0x8a, 0xff, 0x25, 0xe6, 0xd6, 0x9f,\n0x4c, 0xc3, 0xc1, 0x8d, 0xa1, 0xfa, 0xba, 0x88, /* };\nchar peer1_3[] = {*/\n0x4c, 0x53, 0xa9, 0x74, 0xda, 0xfa, 0xba, 0x0b,\n0x20, 0xbe, 0x40, 0xd7, 0xba, 0xe7, 0x1d, 0x70,\n0x28, 0x61, 0x60, 0x4c, 0x49, 0x01, 0x5f, 0xd9,\n0x0f, 0x60, 0x16, 0x3d, 0xba, 0xd3, 0xa9, 0x5e,\n0xfa, 0x98, 0x64, 0x60, 0x26, 0x0e, 0x04, 0x75,\n0xd8, 0x13, 0xd7, 0x31, 0xb4, 0x8e, 0xad, 0xeb,\n0x9c, 0x57, 0x4c, 0x8f, 0x65, 0xf3, 0x90, 0x16,\n0x31, 0xdc, 0x15, 0x6f, 0x7d, 0x1d, 0x00, 0xae,\n0x76, 0xf2, 0xd1, 0x11, 0xd1, 0x4f, 0x88, 0x7b,\n0x29, 0x9f, 0xf6, 0xce, 0x68, 0xef, 0x57, 0xe7,\n0x85, 0xf2, 0x40, 0x54, 0x1c, 0x12, 0x40, 0xa2,\n0x35, 0x25, 0xcf, 0x12, 0xa3, 0xe1, 0x07, 0x8e,\n0xdb, 0x1d, 0xb4, 0x14, 0xff, 0x57, 0xe7, 0x19,\n0x8d, 0x51, 0x77, 0x83, 0x00, 0x01, 0x02, 0x00,\n0x80, 0x96, 0x22, 0x80, 0xe9, 0x86, 0xcc, 0xfc,\n0x63, 0x58, 0x45, 0x78, 0xe0, 0x9b, 0xbb, 0x2e,\n0x89, 0x1e, 0x5a, 0x7a, 0x11, 0xbf, 0xb8, 0xed,\n0x6d, 0x69, 0x49, 0xf5, 0xdb, 0xa8, 0x58, 0x6d,\n0x39, 0x03, 0x66, 0x8b, 0x1a, 0x54, 0xab, 0xe3,\n0x31, 0xc8, 0xc9, 0x07, 0x10, 0x0d, 0x28, 0x0b,\n0x81, 0x15, 0xf1, 0x28, 0xb7, 0xed, 0xc2, 0x80,\n0x0a, 0xef, 0xef, 0xa3, 0x23, 0x2d, 0x0c, 0x20,\n0x76, 0xd1, 0x5b, 0x33, 0x07, 0x6b, 0x99, 0xc2,\n0xb1, 0xcb, 0x90, 0x87, 0x5e, 0xf3, 0xef, 0x1d,\n0xa6, 0x57, 0x3b, 0x0d, 0x32, 0xad, 0xd0, 0x96,\n0xc6, 0xe2, 0xd1, 0x38, 0x65, 0x7e, 0x7c, 0xe1,\n0xe4, 0xb1, 0x2e, 0x53, 0xfd, 0xf6, 0x01, 0xc6,\n0x0d, 0x5b, 0x0d, 0xe3, 0x12, 0x21, 0x78, 0xc4,\n0x2b, 0x4f, 0xa9, 0x47, 0x71, 0x1b, 0x05, 0x68,\n0x9b, 0x52, 0x90, 0xc8, 0x35, 0xd8, 0x1b, 0x98,\n0x00, 0x02, 0x00, 0x9b, 0x91, 0x80, 0xfb, 0xa2,\n0x15, 0xb4, 0xab, 0xf7, 0xee, 0x57, 0xb0, 0xe4,\n0xe8, 0xb7, 0x46, 0x3a, 0x90, 0x3b, 0x83, 0x18,\n0xfb, 0x41, 0x2c, 0x58, 0xb4, 0xa5, 0x19, 0x01,\n0xb5, 0x4c, 0x44, 0x79, 0x11, 0x4b, 0x41, 0x00,\n0xf6, 0x9e, 0x2b, 0x71, 0x43, 0xea, 0xb6, 0xb4,\n0xc5, 0xc7, 0x8f, 0x39, 0xf8, 0x32, 0xeb, 0x69,\n0xf5, 0xde, 0xbc, 0xc9, 0x45, 0x70, 0x38, 0x03,\n0xcf, 0x72, 0xf9, 0x14, 0x75, 0x00, 0xf0, 0xfd,\n0x2e, 0x96, 0xd9, 0x3a, 0xad, 0xae, 0x8f, 0x96,\n0x50, 0xc1, 0x5d, 0xe4, 0xd9, 0x13, 0x60, 0x44,\n0x25, 0x90, 0xaa, 0xd1, 0x50, 0x5f, 0x01, 0xd4,\n0x5d, 0x51, 0x2d, 0x6b, 0xaf, 0x6a, 0xb9, 0x13,\n0x27, 0xdc, 0x5a, 0x79, 0xde, 0xb5, 0x66, 0xe7,\n0xc9, 0x52, 0x57, 0x8f, 0x6f, 0x72, 0x39, 0x00,\n0x5b, 0x8f, 0xdb, 0x8e, 0x19, 0x98, 0x9b, 0x12,\n0x3b, 0xb4, 0xb3, 0x32, 0x74, 0x4c, 0x8d, 0x8b,\n0xd3, 0xfe, 0xb9, 0x7d, 0xb0, 0xad, 0x9d, 0x81,\n0x47, 0x69, 0x8b, 0x7b, 0xeb, 0x79, 0x39, 0x6c,\n0xf6, 0x40, 0xe5, 0xb0, 0x95, 0x56, 0x7f, 0xbc,\n0x8f, 0x4e, 0xed, 0x5d, 0xff, 0x32, 0x53, 0x5d,\n0x72, 0x65, 0x5e, 0xdf, 0xe3, 0xa6, 0xfe, 0xce,\n0x6b, 0x1d, 0xbf, 0x54, 0xe0, 0xc7, 0x93, 0xca,\n0xb0, 0xd2, 0x7a, 0x03, 0x2d, 0xe4, 0x0d, 0x94,\n0x3a, 0xbf, 0xe5, 0x3a, 0xbe, 0xa9, 0x6a, 0xa9,\n0x1b, 0xe9, 0x6b, 0x51, 0x87, 0x18, 0x3f, 0xe7,\n0xd6, 0x8e, 0x46, 0xb4, 0x91, 0xda, 0x66, 0xd7,\n0xd3, 0x5f, 0xdd, 0x9b, 0xd9, 0xb3, 0xd0, 0xc8,\n0x0d, 0xbd, 0xba, 0xb3, 0x20, 0xeb, 0x27, 0xd0,\n0x4b, 0xa9, 0xa6, 0x42, 0x09, 0xef, 0x33, 0xb9,\n0x25, 0xc7, 0xa6, 0xa4, 0x09, 0xce, 0xef, 0xe4,\n0xe1, 0xb3, 0x6c, 0x4c, 0x98, 0xc9, 0x7a, 0xb1,\n0x32, 0xb3, 0x0f, 0x31, 0xa0, 0x56, 0xc8, 0xc9,\n0x8c, 0x1e, 0xc8, 0xed, 0x55, 0xd1, 0xdf, 0xd4,\n0x13, 0xe8, 0x95, 0x4f, 0x6e, 0x4f, 0xb2, 0xd9,\n0x1c, 0x19, 0xb5, 0x1a, 0x43, 0x6f, 0x69, 0x8f,\n0x9c, 0x1c, 0xaa, 0xff, 0xbf, 0xe9, 0xc1, 0x5d,\n0x6e, 0x85, 0x9f, 0x65, 0x7d, 0xc5, 0xdb, 0x76,\n0x59, 0x58, 0xfb, 0xe3, 0xd6, 0x24, 0xd8, 0xae,\n0xc4, 0xc7, 0x84, 0x74, 0xab, 0x40, 0xa0, 0xc4,\n0xeb, 0xd9, 0x13, 0x05, 0x0c, 0xd6, 0x5a, 0x9d,\n0x98, 0xb7, 0x88, 0x39, 0x1d, 0xb7, 0x33, 0xff,\n0x1d, 0xc6, 0xd4, 0x49, 0xec, 0x5d, 0x93, 0x2f,\n0x5c, 0xf1, 0xc9, 0x0e, 0x1f, 0x89, 0xf0, 0x93,\n0x20, 0x53, 0x5e, 0xde, 0x85, 0x78, 0x49, 0x69,\n0x51, 0x32, 0x6c, 0x53, 0x1b, 0x50, 0xfb, 0xef,\n0x34, 0x57, 0xec, 0xb0, 0x33, 0x95, 0x54, 0xf3,\n0x39, 0x1d, 0x89, 0x92, 0x02, 0x46, 0x26, 0x4e,\n0xce, 0x8e, 0x95, 0xa3, 0x9a, 0x51, 0xec, 0xcb,\n0xb3, 0x91, 0x5e, 0x00, 0x03, 0x64, 0x38, 0xbf,\n0x41, 0xb8, 0x0d, 0x61, 0xb8, 0x99, 0x10, 0xfd,\n0xb6, 0xf4, 0x98, 0x01, 0xca, 0x7a, 0x1b, 0x8c,\n0xd6, 0x62, 0x28, 0xf1, 0x67, 0x87, 0x4f, 0x02,\n0xe4, 0x59, 0x73, 0x39, 0x5b, 0xe2, 0xa6, 0x39,\n0xb0, 0xb2, 0x0a, 0xc0, 0x86, 0xe4, 0xec, 0x77,\n0x86, 0x8b, 0x72, 0xb5, 0x1a, 0x6e, 0xaa, 0x52,\n0xf3, 0x6a, 0x13, 0x69, 0xb9, 0x27, 0x75, 0x5d,\n0xf5, 0x85, 0xe5, 0xbf, 0x81, 0x50, 0x1a, 0xcc,\n0x43, 0x7a, 0x76, 0x68, 0x81, 0x95, 0x9b, 0x02,\n0x3b, 0x1a, 0x5d, 0x76, 0x2b, 0xd0, 0xc1, 0x89,\n0x9b, 0xe1, 0xb3, 0xea, 0x5c, 0x08, 0x4f, 0x7a,\n0x0c, 0x77, 0xf4, 0xd8, 0xcc, 0x78, 0xd2, 0x96,\n0x07, 0xe1, 0x61, 0x3c, 0x9e, 0x0f, 0x80, 0x22,\n0x51, 0x22, 0x65, 0xfc, 0x6e, 0xa4, 0x67, 0x0c,\n0x85, 0xbc, 0xb9, 0x16, 0x03, 0x01, 0x00, 0x10,\n0x0d, 0x00, 0x00, 0x08, 0x05, 0x03, 0x04, 0x01,\n0x02, 0x40, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00 };\n\nsize_t ssl_test_case_3_size = sizeof(ssl_test_case_3);\n\n\nconst char google_cert[] = \n\"\\x30\\x82\\x04\\x76\\x30\\x82\\x03\\x5e\\xa0\\x03\\x02\\x01\\x02\\x02\\x08\\x6b\"\n\"\\xa4\\xae\\xf1\\xc9\\xe3\\x08\\x5e\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\"\n\"\\x0d\\x01\\x01\\x05\\x05\\x00\\x30\\x49\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\"\n\"\\x06\\x13\\x02\\x55\\x53\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x0a\\x13\\x0a\"\n\"\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\\x49\\x6e\\x63\\x31\\x25\\x30\\x23\\x06\\x03\"\n\"\\x55\\x04\\x03\\x13\\x1c\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\\x49\\x6e\\x74\\x65\"\n\"\\x72\\x6e\\x65\\x74\\x20\\x41\\x75\\x74\\x68\\x6f\\x72\\x69\\x74\\x79\\x20\\x47\"\n\"\\x32\\x30\\x1e\\x17\\x0d\\x31\\x34\\x30\\x34\\x30\\x39\\x31\\x31\\x34\\x30\\x31\"\n\"\\x31\\x5a\\x17\\x0d\\x31\\x34\\x30\\x37\\x30\\x38\\x30\\x30\\x30\\x30\\x30\\x30\"\n\"\\x5a\\x30\\x68\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\"\n\"\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x08\\x0c\\x0a\\x43\\x61\\x6c\\x69\\x66\"\n\"\\x6f\\x72\\x6e\\x69\\x61\\x31\\x16\\x30\\x14\\x06\\x03\\x55\\x04\\x07\\x0c\\x0d\"\n\"\\x4d\\x6f\\x75\\x6e\\x74\\x61\\x69\\x6e\\x20\\x56\\x69\\x65\\x77\\x31\\x13\\x30\"\n\"\\x11\\x06\\x03\\x55\\x04\\x0a\\x0c\\x0a\\x47\\x6f\\x6f\\x67\\x6c\\x65\\x20\\x49\"\n\"\\x6e\\x63\\x31\\x17\\x30\\x15\\x06\\x03\\x55\\x04\\x03\\x0c\\x0e\\x77\\x77\\x77\"\n\"\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x30\\x82\\x01\\x22\\x30\"\n\"\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x01\\x05\\x00\\x03\\x82\"\n\"\\x01\\x0f\\x00\\x30\\x82\\x01\\x0a\\x02\\x82\\x01\\x01\\x00\\x9f\\x3c\\x67\\x60\"\n\"\\x62\\xa7\\x30\\xbb\\xb7\\x63\\xd0\\x00\\xe0\\x98\\xab\\x24\\x3e\\x15\\xdf\\x1a\"\n\"\\x85\\x54\\x8f\\xf0\\xd9\\x0d\\xc6\\x77\\x32\\x79\\xe0\\x48\\x1c\\x76\\x46\\x22\"\n\"\\x61\\x64\\x93\\xa3\\x12\\xcf\\xd8\\xd1\\x86\\x5d\\x23\\x9f\\xca\\xc7\\x3b\\xd9\"\n\"\\x4b\\xad\\xf0\\xf0\\xe4\\x83\\x3d\\x64\\x93\\xb3\\x21\\x3f\\xef\\x03\\x9f\\xde\"\n\"\\x5f\\x01\\x9e\\xbc\\x73\\xf2\\xf4\\xeb\\xc3\\x71\\x39\\x4c\\x42\\x6b\\x97\\x23\"\n\"\\x3c\\x0a\\x4b\\x55\\x46\\x07\\x6f\\x55\\x17\\x90\\xfa\\x57\\xb0\\xbe\\x54\\x77\"\n\"\\x3d\\x77\\x2e\\x20\\x74\\x53\\xad\\xd3\\x59\\x28\\x4d\\xd3\\x8d\\x38\\x93\\xf3\"\n\"\\x04\\xa0\\x0d\\xec\\xa6\\x3e\\x62\\x2e\\x90\\x9f\\x18\\x3e\\x22\\x71\\xcc\\xd9\"\n\"\\x81\\xf6\\x49\\xab\\x50\\x86\\xfd\\xde\\xed\\x5a\\x7c\\xc8\\x00\\xa6\\x9d\\x87\"\n\"\\xa1\\xee\\x4b\\x91\\xe8\\xd0\\x91\\x8e\\xdc\\x4b\\xbc\\x5b\\xf4\\xd2\\xae\\xa5\"\n\"\\x62\\x37\\x7e\\x7a\\xd2\\x5d\\x37\\x6b\\x5d\\x18\\xee\\xde\\x6d\\x8a\\xb3\\x8e\"\n\"\\xc0\\x52\\x28\\xbe\\x52\\x5a\\xdd\\xd8\\x95\\x5d\\xd3\\xdf\\xb4\\x71\\x64\\x6a\"\n\"\\x8a\\x03\\x25\\xe4\\xc1\\xd2\\xbf\\xfe\\x9d\\xa3\\xb0\\xaf\\xd0\\x01\\x4a\\x90\"\n\"\\x60\\x8e\\x89\\xfa\\x0a\\x0e\\xbf\\x08\\x66\\x89\\x42\\x0a\\x88\\x5d\\x86\\xd5\"\n\"\\xc5\\x2f\\xa8\\xcd\\x8f\\x8a\\xfc\\xab\\xef\\xbd\\xc4\\x9a\\x44\\x01\\xd4\\x0a\"\n\"\\x89\\x9b\\x7b\\xa6\\x0b\\xe6\\xee\\x6f\\xc1\\x5d\\x55\\x9f\\x02\\x03\\x01\\x00\"\n\"\\x01\\xa3\\x82\\x01\\x41\\x30\\x82\\x01\\x3d\\x30\\x1d\\x06\\x03\\x55\\x1d\\x25\"\n\"\\x04\\x16\\x30\\x14\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x03\\x01\\x06\\x08\"\n\"\\x2b\\x06\\x01\\x05\\x05\\x07\\x03\\x02\\x30\\x19\\x06\\x03\\x55\\x1d\\x11\\x04\"\n\"\\x12\\x30\\x10\\x82\\x0e\\x77\\x77\\x77\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\"\n\"\\x63\\x6f\\x6d\\x30\\x68\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x01\\x01\\x04\"\n\"\\x5c\\x30\\x5a\\x30\\x2b\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x30\\x02\\x86\"\n\"\\x1f\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x70\\x6b\\x69\\x2e\\x67\\x6f\\x6f\\x67\"\n\"\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x47\\x49\\x41\\x47\\x32\\x2e\\x63\\x72\\x74\"\n\"\\x30\\x2b\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x30\\x01\\x86\\x1f\\x68\\x74\"\n\"\\x74\\x70\\x3a\\x2f\\x2f\\x63\\x6c\\x69\\x65\\x6e\\x74\\x73\\x31\\x2e\\x67\\x6f\"\n\"\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x6f\\x63\\x73\\x70\\x30\\x1d\\x06\"\n\"\\x03\\x55\\x1d\\x0e\\x04\\x16\\x04\\x14\\x15\\xc9\\xbc\\x55\\xa7\\x7d\\x75\\x7c\"\n\"\\xa5\\x0c\\x5e\\xdc\\x92\\xee\\xdf\\x42\\x59\\x0c\\xe5\\x3c\\x30\\x0c\\x06\\x03\"\n\"\\x55\\x1d\\x13\\x01\\x01\\xff\\x04\\x02\\x30\\x00\\x30\\x1f\\x06\\x03\\x55\\x1d\"\n\"\\x23\\x04\\x18\\x30\\x16\\x80\\x14\\x4a\\xdd\\x06\\x16\\x1b\\xbc\\xf6\\x68\\xb5\"\n\"\\x76\\xf5\\x81\\xb6\\xbb\\x62\\x1a\\xba\\x5a\\x81\\x2f\\x30\\x17\\x06\\x03\\x55\"\n\"\\x1d\\x20\\x04\\x10\\x30\\x0e\\x30\\x0c\\x06\\x0a\\x2b\\x06\\x01\\x04\\x01\\xd6\"\n\"\\x79\\x02\\x05\\x01\\x30\\x30\\x06\\x03\\x55\\x1d\\x1f\\x04\\x29\\x30\\x27\\x30\"\n\"\\x25\\xa0\\x23\\xa0\\x21\\x86\\x1f\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x70\\x6b\"\n\"\\x69\\x2e\\x67\\x6f\\x6f\\x67\\x6c\\x65\\x2e\\x63\\x6f\\x6d\\x2f\\x47\\x49\\x41\"\n\"\\x47\\x32\\x2e\\x63\\x72\\x6c\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\"\n\"\\x01\\x01\\x05\\x05\\x00\\x03\\x82\\x01\\x01\\x00\\x2c\\xfa\\x64\\xeb\\xb3\\x14\"\n\"\\xe9\\x84\\x08\\x0f\\xf9\\x30\\x94\\x19\\x65\\xff\\x8f\\xf5\\x6e\\x2c\\x1f\\xcd\"\n\"\\x15\\x94\\x11\\x48\\xaf\\x8d\\x37\\x8b\\x7c\\xa7\\x02\\x70\\xde\\x71\\x57\\x56\"\n\"\\x0e\\x46\\xbc\\xdd\\x03\\xb3\\x34\\x5e\\x66\\xf2\\x85\\xe8\\x3b\\xf6\\xfe\\x32\"\n\"\\x48\\xa0\\xa8\\x91\\xc8\\x80\\xb9\\xf1\\xd2\\x16\\x5b\\x7d\\x2c\\x93\\xb3\\x7c\"\n\"\\x66\\x82\\x15\\xb2\\x84\\x96\\x47\\xfa\\xbe\\x55\\xb6\\x4e\\xa6\\x56\\x12\\x69\"\n\"\\x60\\xa0\\x90\\x9f\\xe2\\xc2\\x8e\\x60\\x5e\\x62\\x61\\x56\\x66\\x77\\x7d\\x95\"\n\"\\x37\\xa8\\x78\\xd6\\x94\\xf2\\x06\\x50\\x2f\\x9c\\xf8\\x61\\xc9\\x57\\x9c\\x26\"\n\"\\x60\\x28\\xcd\\x7a\\xe9\\x77\\xfe\\xc9\\x61\\x38\\x6c\\x05\\x5b\\x38\\x97\\xf1\"\n\"\\xff\\x1e\\xad\\x78\\xef\\xad\\x00\\x64\\x6b\\x51\\x90\\xd3\\x49\\xce\\xa1\\x58\"\n\"\\x63\\xce\\x66\\x36\\xe6\\xde\\x48\\xf8\\xe0\\x6a\\xe6\\x27\\xd4\\xba\\x62\\x62\"\n\"\\x9d\\xdc\\x7a\\x29\\x98\\x2f\\x9b\\x11\\x4c\\x9a\\x9a\\x82\\xcb\\x31\\x3c\\x69\"\n\"\\xff\\xd2\\xae\\x56\\x33\\x45\\x20\\xdd\\xc4\\x66\\x29\\xc7\\xd4\\xff\\x06\\xf4\"\n\"\\x26\\x59\\x43\\x16\\x2b\\x3e\\x7d\\x73\\x1e\\x45\\xfd\\x8a\\x5f\\xd4\\x77\\x02\"\n\"\\xfc\\xe2\\x49\\xbd\\x5e\\x9d\\xc3\\xd9\\x8c\\x70\\x97\\x42\\x3d\\x7b\\x63\\x1c\"\n\"\\xfc\\xbc\\x2e\\x8d\\x19\\xc0\\x5f\\xaa\\x2c\\xa2\\x15\\x40\\x61\\x4d\\xae\\x9b\"\n\"\\x2c\\x17\\x2d\\xc3\\xee\\x38\\x3e\\x18\\xd6\\x32\";\nsize_t google_cert_size = sizeof(google_cert) - 1;\n\nconst char yahoo_cert[] = \n\"\\x30\\x82\\x07\\xb9\\x30\\x82\\x06\\xa1\\xa0\\x03\\x02\\x01\\x02\\x02\\x10\\x1d\"\n\"\\xc0\\x12\\x4a\\x02\\x4a\\x2c\\xd6\\xce\\x88\\xc9\\x4c\\x0f\\x24\\xf1\\xcf\\x30\"\n\"\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\\x30\\x81\"\n\"\\xb5\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x17\"\n\"\\x30\\x15\\x06\\x03\\x55\\x04\\x0a\\x13\\x0e\\x56\\x65\\x72\\x69\\x53\\x69\\x67\"\n\"\\x6e\\x2c\\x20\\x49\\x6e\\x63\\x2e\\x31\\x1f\\x30\\x1d\\x06\\x03\\x55\\x04\\x0b\"\n\"\\x13\\x16\\x56\\x65\\x72\\x69\\x53\\x69\\x67\\x6e\\x20\\x54\\x72\\x75\\x73\\x74\"\n\"\\x20\\x4e\\x65\\x74\\x77\\x6f\\x72\\x6b\\x31\\x3b\\x30\\x39\\x06\\x03\\x55\\x04\"\n\"\\x0b\\x13\\x32\\x54\\x65\\x72\\x6d\\x73\\x20\\x6f\\x66\\x20\\x75\\x73\\x65\\x20\"\n\"\\x61\\x74\\x20\\x68\\x74\\x74\\x70\\x73\\x3a\\x2f\\x2f\\x77\\x77\\x77\\x2e\\x76\"\n\"\\x65\\x72\\x69\\x73\\x69\\x67\\x6e\\x2e\\x63\\x6f\\x6d\\x2f\\x72\\x70\\x61\\x20\"\n\"\\x28\\x63\\x29\\x31\\x30\\x31\\x2f\\x30\\x2d\\x06\\x03\\x55\\x04\\x03\\x13\\x26\"\n\"\\x56\\x65\\x72\\x69\\x53\\x69\\x67\\x6e\\x20\\x43\\x6c\\x61\\x73\\x73\\x20\\x33\"\n\"\\x20\\x53\\x65\\x63\\x75\\x72\\x65\\x20\\x53\\x65\\x72\\x76\\x65\\x72\\x20\\x43\"\n\"\\x41\\x20\\x2d\\x20\\x47\\x33\\x30\\x1e\\x17\\x0d\\x31\\x34\\x30\\x34\\x30\\x39\"\n\"\\x30\\x30\\x30\\x30\\x30\\x30\\x5a\\x17\\x0d\\x31\\x35\\x30\\x34\\x30\\x39\\x32\"\n\"\\x33\\x35\\x39\\x35\\x39\\x5a\\x30\\x81\\x84\\x31\\x0b\\x30\\x09\\x06\\x03\\x55\"\n\"\\x04\\x06\\x13\\x02\\x55\\x53\\x31\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x08\\x13\"\n\"\\x0a\\x43\\x61\\x6c\\x69\\x66\\x6f\\x72\\x6e\\x69\\x61\\x31\\x12\\x30\\x10\\x06\"\n\"\\x03\\x55\\x04\\x07\\x14\\x09\\x53\\x75\\x6e\\x6e\\x79\\x76\\x61\\x6c\\x65\\x31\"\n\"\\x13\\x30\\x11\\x06\\x03\\x55\\x04\\x0a\\x14\\x0a\\x59\\x61\\x68\\x6f\\x6f\\x20\"\n\"\\x49\\x6e\\x63\\x2e\\x31\\x1f\\x30\\x1d\\x06\\x03\\x55\\x04\\x0b\\x14\\x16\\x49\"\n\"\\x6e\\x66\\x6f\\x72\\x6d\\x61\\x74\\x69\\x6f\\x6e\\x20\\x54\\x65\\x63\\x68\\x6e\"\n\"\\x6f\\x6c\\x6f\\x67\\x79\\x31\\x16\\x30\\x14\\x06\\x03\\x55\\x04\\x03\\x14\\x0d\"\n\"\\x77\\x77\\x77\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x30\\x82\\x01\"\n\"\\x22\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\\x86\\xf7\\x0d\\x01\\x01\\x01\\x05\\x00\"\n\"\\x03\\x82\\x01\\x0f\\x00\\x30\\x82\\x01\\x0a\\x02\\x82\\x01\\x01\\x00\\xbe\\xac\"\n\"\\xb9\\x4f\\xc4\\xb7\\xea\\x0a\\xa1\\x6d\\x56\\xab\\xee\\x6a\\x27\\x06\\x21\\x8c\"\n\"\\x82\\x4f\\x60\\xfc\\xbe\\xab\\x92\\x80\\xa1\\x11\\x6e\\x36\\x01\\xa6\\x1a\\x3b\"\n\"\\xdb\\xf0\\xb9\\xda\\x55\\xed\\x91\\xa6\\x1d\\x1a\\x5a\\x30\\xb7\\x5c\\xc9\\x1b\"\n\"\\xdb\\x03\\x8f\\x7c\\xeb\\x74\\x3a\\x58\\xaf\\x0f\\x6d\\x08\\xf5\\x70\\xd3\\x42\"\n\"\\xed\\x1c\\xd1\\xce\\xac\\xea\\xd7\\xb8\\x40\\x10\\xb5\\x20\\xf3\\x04\\x0a\\x7d\"\n\"\\x8c\\x34\\xac\\x05\\xba\\xec\\x84\\x31\\x30\\x07\\x00\\x4d\\xb9\\xc5\\x64\\xb9\"\n\"\\x61\\x91\\xae\\x37\\xe7\\x4e\\x91\\x64\\xbc\\x51\\x60\\xd2\\x61\\xbb\\x5a\\x58\"\n\"\\x4a\\x05\\x10\\xae\\xc8\\x84\\x80\\x30\\xaa\\xd1\\x37\\x21\\x4d\\x46\\x63\\xaa\"\n\"\\x5b\\xaa\\x31\\x2e\\x82\\x3e\\x58\\x76\\xb3\\xaa\\xb9\\xb7\\x91\\xe2\\x2a\\xbf\"\n\"\\x8e\\x3c\\x8b\\xe5\\x40\\x16\\xba\\xcf\\x6f\\xbe\\x90\\x40\\x2a\\xe2\\xe7\\x6d\"\n\"\\x6e\\x0d\\x2c\\xb0\\x39\\xfa\\x46\\x83\\x4c\\x88\\xea\\xdb\\x10\\xb5\\x25\\x80\"\n\"\\x3a\\x29\\x60\\x40\\x55\\x25\\x1a\\xfa\\xc4\\x7f\\x5d\\xe9\\x2e\\x18\\xac\\x4e\"\n\"\\x69\\x3a\\xcb\\x3b\\x30\\xe9\\xb2\\xe0\\xba\\x91\\x71\\x6d\\xb4\\xcb\\x1b\\x0c\"\n\"\\x13\\x00\\x51\\x19\\x1f\\x36\\x66\\xfb\\xf0\\x22\\x11\\xef\\xde\\xd9\\x24\\xbf\"\n\"\\x53\\xdd\\xa0\\x6c\\x94\\x0c\\x13\\x51\\xa1\\x07\\x26\\xcf\\xb7\\x9e\\xf4\\x26\"\n\"\\xe3\\x88\\x9f\\x9f\\x4e\\x99\\xf4\\xe7\\x8f\\x90\\x4c\\xca\\x7f\\x39\\x02\\x03\"\n\"\\x01\\x00\\x01\\xa3\\x82\\x03\\xf2\\x30\\x82\\x03\\xee\\x30\\x82\\x02\\x8b\\x06\"\n\"\\x03\\x55\\x1d\\x11\\x04\\x82\\x02\\x82\\x30\\x82\\x02\\x7e\\x82\\x0d\\x77\\x77\"\n\"\\x77\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x09\\x79\\x61\\x68\"\n\"\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0e\\x68\\x73\\x72\\x64\\x2e\\x79\\x61\\x68\"\n\"\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x75\\x73\\x2e\\x79\\x61\\x68\\x6f\\x6f\"\n\"\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x66\\x72\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\"\n\"\\x6f\\x6d\\x82\\x0c\\x75\\x6b\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x0c\\x7a\\x61\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\"\n\"\\x69\\x65\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x69\\x74\"\n\"\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x65\\x73\\x2e\\x79\"\n\"\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x64\\x65\\x2e\\x79\\x61\\x68\"\n\"\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x63\\x61\\x2e\\x79\\x61\\x68\\x6f\\x6f\"\n\"\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x71\\x63\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\"\n\"\\x6f\\x6d\\x82\\x0c\\x62\\x72\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x0c\\x72\\x6f\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\"\n\"\\x73\\x65\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x62\\x65\"\n\"\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0f\\x66\\x72\\x2d\\x62\"\n\"\\x65\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x61\\x72\\x2e\"\n\"\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x6d\\x78\\x2e\\x79\\x61\"\n\"\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x63\\x6c\\x2e\\x79\\x61\\x68\\x6f\"\n\"\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x63\\x6f\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\"\n\"\\x63\\x6f\\x6d\\x82\\x0c\\x76\\x65\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\"\n\"\\x6d\\x82\\x11\\x65\\x73\\x70\\x61\\x6e\\x6f\\x6c\\x2e\\x79\\x61\\x68\\x6f\\x6f\"\n\"\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x70\\x65\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\"\n\"\\x6f\\x6d\\x82\\x0c\\x69\\x6e\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x0c\\x73\\x67\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\"\n\"\\x69\\x64\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x12\\x6d\\x61\"\n\"\\x6c\\x61\\x79\\x73\\x69\\x61\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\"\n\"\\x82\\x0c\\x70\\x68\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\"\n\"\\x76\\x6e\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x11\\x6d\\x61\"\n\"\\x6b\\x74\\x6f\\x6f\\x62\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\"\n\"\\x14\\x65\\x6e\\x2d\\x6d\\x61\\x6b\\x74\\x6f\\x6f\\x62\\x2e\\x79\\x61\\x68\\x6f\"\n\"\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0f\\x63\\x61\\x2e\\x6d\\x79\\x2e\\x79\\x61\\x68\"\n\"\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x67\\x72\\x2e\\x79\\x61\\x68\\x6f\\x6f\"\n\"\\x2e\\x63\\x6f\\x6d\\x82\\x0d\\x61\\x74\\x74\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\"\n\"\\x63\\x6f\\x6d\\x82\\x0c\\x61\\x75\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\"\n\"\\x6d\\x82\\x0c\\x6e\\x7a\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\"\n\"\\x0c\\x74\\x77\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x68\"\n\"\\x6b\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0d\\x62\\x72\\x62\"\n\"\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x0c\\x6d\\x79\\x2e\\x79\"\n\"\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x82\\x10\\x61\\x64\\x64\\x2e\\x6d\\x79\"\n\"\\x2e\\x79\\x61\\x68\\x6f\\x6f\\x2e\\x63\\x6f\\x6d\\x30\\x09\\x06\\x03\\x55\\x1d\"\n\"\\x13\\x04\\x02\\x30\\x00\\x30\\x0e\\x06\\x03\\x55\\x1d\\x0f\\x01\\x01\\xff\\x04\"\n\"\\x04\\x03\\x02\\x05\\xa0\\x30\\x1d\\x06\\x03\\x55\\x1d\\x25\\x04\\x16\\x30\\x14\"\n\"\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x03\\x01\\x06\\x08\\x2b\\x06\\x01\\x05\"\n\"\\x05\\x07\\x03\\x02\\x30\\x43\\x06\\x03\\x55\\x1d\\x20\\x04\\x3c\\x30\\x3a\\x30\"\n\"\\x38\\x06\\x0a\\x60\\x86\\x48\\x01\\x86\\xf8\\x45\\x01\\x07\\x36\\x30\\x2a\\x30\"\n\"\\x28\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x02\\x01\\x16\\x1c\\x68\\x74\\x74\"\n\"\\x70\\x73\\x3a\\x2f\\x2f\\x77\\x77\\x77\\x2e\\x76\\x65\\x72\\x69\\x73\\x69\\x67\"\n\"\\x6e\\x2e\\x63\\x6f\\x6d\\x2f\\x63\\x70\\x73\\x30\\x1f\\x06\\x03\\x55\\x1d\\x23\"\n\"\\x04\\x18\\x30\\x16\\x80\\x14\\x0d\\x44\\x5c\\x16\\x53\\x44\\xc1\\x82\\x7e\\x1d\"\n\"\\x20\\xab\\x25\\xf4\\x01\\x63\\xd8\\xbe\\x79\\xa5\\x30\\x45\\x06\\x03\\x55\\x1d\"\n\"\\x1f\\x04\\x3e\\x30\\x3c\\x30\\x3a\\xa0\\x38\\xa0\\x36\\x86\\x34\\x68\\x74\\x74\"\n\"\\x70\\x3a\\x2f\\x2f\\x53\\x56\\x52\\x53\\x65\\x63\\x75\\x72\\x65\\x2d\\x47\\x33\"\n\"\\x2d\\x63\\x72\\x6c\\x2e\\x76\\x65\\x72\\x69\\x73\\x69\\x67\\x6e\\x2e\\x63\\x6f\"\n\"\\x6d\\x2f\\x53\\x56\\x52\\x53\\x65\\x63\\x75\\x72\\x65\\x47\\x33\\x2e\\x63\\x72\"\n\"\\x6c\\x30\\x76\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x01\\x01\\x04\\x6a\\x30\"\n\"\\x68\\x30\\x24\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\\x07\\x30\\x01\\x86\\x18\\x68\"\n\"\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x6f\\x63\\x73\\x70\\x2e\\x76\\x65\\x72\\x69\\x73\"\n\"\\x69\\x67\\x6e\\x2e\\x63\\x6f\\x6d\\x30\\x40\\x06\\x08\\x2b\\x06\\x01\\x05\\x05\"\n\"\\x07\\x30\\x02\\x86\\x34\\x68\\x74\\x74\\x70\\x3a\\x2f\\x2f\\x53\\x56\\x52\\x53\"\n\"\\x65\\x63\\x75\\x72\\x65\\x2d\\x47\\x33\\x2d\\x61\\x69\\x61\\x2e\\x76\\x65\\x72\"\n\"\\x69\\x73\\x69\\x67\\x6e\\x2e\\x63\\x6f\\x6d\\x2f\\x53\\x56\\x52\\x53\\x65\\x63\"\n\"\\x75\\x72\\x65\\x47\\x33\\x2e\\x63\\x65\\x72\\x30\\x0d\\x06\\x09\\x2a\\x86\\x48\"\n\"\\x86\\xf7\\x0d\\x01\\x01\\x05\\x05\\x00\\x03\\x82\\x01\\x01\\x00\\x1f\\x3c\\xb5\"\n\"\\x6f\\x4d\\xd3\\x15\\x6a\\x7b\\x02\\x63\\x7a\\xe0\\x10\\xba\\x45\\xf4\\xa6\\x47\"\n\"\\xca\\x8c\\x47\\xc0\\x1d\\x13\\x88\\xed\\xe7\\xbe\\x11\\x34\\x72\\x89\\x91\\xd2\"\n\"\\x53\\x54\\xaa\\xd2\\xc5\\x3c\\x00\\xb7\\x70\\xcd\\xe5\\x30\\xb8\\xa1\\x79\\x47\"\n\"\\xae\\xbc\\xeb\\x5c\\x48\\x37\\x57\\xbe\\xe6\\x1b\\x9e\\x55\\x30\\x21\\x7f\\x17\"\n\"\\x00\\xad\\xd6\\x1b\\x5c\\xb9\\x3b\\x94\\xd2\\xe9\\xfe\\xb5\\x04\\xa9\\x0d\\x43\"\n\"\\x6c\\x20\\x3b\\x2d\\xd2\\xa7\\xe5\\x37\\xb4\\x68\\x9f\\xf9\\x86\\xd1\\x73\\x53\"\n\"\\x4b\\x15\\x6a\\x21\\x84\\xd3\\xf1\\x36\\x82\\xcc\\xe3\\x07\\xab\\x61\\x58\\x55\"\n\"\\x12\\x40\\x23\\x00\\xf2\\xef\\xb6\\xab\\xa8\\x2c\\xc0\\x5e\\x23\\x0c\\x5c\\x23\"\n\"\\x42\\xc4\\xee\\xe3\\x2e\\xe5\\xf8\\xf7\\x8b\\x0e\\xec\\xe3\\xf5\\x8f\\x0b\\x72\"\n\"\\xde\\x30\\x15\\x21\\x7f\\x85\\x47\\x7a\\x4f\\xab\\x3a\\x3a\\x99\\x38\\x27\\x11\"\n\"\\x24\\x94\\x90\\x96\\x56\\xab\\xc6\\x07\\x4d\\xd3\\x5f\\xec\\x2d\\x3c\\x60\\x03\"\n\"\\xb3\\x64\\x78\\x26\\xa8\\x22\\xf7\\x8f\\x3c\\x4c\\x43\\x31\\x7b\\x46\\x6a\\x38\"\n\"\\x21\\xb4\\xc6\\x69\\xca\\x14\\x13\\x88\\x9c\\x02\\xeb\\x7f\\x3c\\x91\\x18\\xe6\"\n\"\\x27\\x6a\\x36\\xba\\x6b\\x0a\\xd5\\x4f\\xbc\\x6a\\x2b\\xd3\\x30\\xf9\\x30\\x7d\"\n\"\\xf0\\xa1\\x63\\x2e\\x68\\x40\\xd8\\x3d\\xc3\\x25\\x52\\xd8\\xda\\xbb\\xdf\\x14\"\n\"\\xbe\\xbd\\x25\\x4f\\x24\\x9b\\x26\\x98\\x2c\\x04\\x1c\\x51\\x2b\";\nsize_t yahoo_cert_size = sizeof(yahoo_cert) - 1;\n\n"
  },
  {
    "path": "src/proto-ssl.c",
    "content": "/*\n    SSL parser\n \n    This parses SSL packets from the server. It is built in multiple levels:\n \n    RECORDS - ssl_parse_record()\n      |\n      +---> heartbeat\n      |        |\n      |        +---> banner grab\n      |\n      +---> handshake\n               |\n               +---> server hello\n               |        |\n               |        +---> banner grab\n               |\n               +---> certificate\n                        |\n                        +---> X.509 parser\n                                 |\n                                 +---> subject name (banner)\n                                 |\n                                 +---> certificate (banner)\n \n\n    For \"heartbeat\", we grab the so-called \"heartbleed\" exploit info.\n    For \"server hello\", we grab which cipher is used\n    For \"certificate\", we grab the subjectName of the server\n \n \n    !!!!!!!!!!!!  BIZARRE CODE ALERT !!!!!!!!!!!!!!!\n    \n    This module uses a \"streaming state-machine\" to parse the SSL protocol.\n    In other words, this does not \"reasemble\" fragments. Instead, it allows\n    state to cross packet-boundaries. Thus, it supports both fragmentation\n    at the TCP layer and the SSL record layer, but without reassembling\n    things. Only in the output, in the gathered \"banners\", does reassembly\n    happen -- in other words, reassembly happens after OSI Layer 7 rather\n    than OSI Layer 4.\n \n    As many are unfamiliar with this technique, they'll find it a little\n    weird.\n \n    The upshot of doing things this way is that we can support 10 million\n    open TCP connections with minimal memory usage.\n */\n#include \"proto-ssl.h\"\n#include \"stack-tcp-api.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"crypto-siphash24.h\"\n#include \"util-safefunc.h\"\n#include \"util-malloc.h\"\n#include <string.h>\n#include <ctype.h>\n#include <assert.h>\n\n\n\n/**\n * Fugly macro for doing state-machine parsing. I know it's bad, but\n * it makes stepping through the code in a debugger so much easier.\n */\n#define DROPDOWN(i,length,state) (state)++;if (++(i)>=(length)) break\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nBANNER_CIPHER(struct BannerOutput *banout, unsigned cipher_suite)\n{\n    //const char *notes = \"\";\n    char foo[64];\n    snprintf(foo, sizeof(foo), \"cipher:0x%x\", cipher_suite);\n    banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);\n    \n    /*switch (cipher_suite) {\n     case 0x0005: notes = \"(_/RSA/RC4/SHA)\"; break;\n     case 0x0035: notes = \"(_/RSA/AES-CBC/SHA)\"; break;\n     case 0x002f: notes = \"(_/RSA/AES-CBC/SHA)\"; break;\n     case 0xc013: notes = \"(ECDHE/RSA/AES-CBC/SHA)\"; break;\n     }\n     banout_append(banout, PROTO_SSL3, notes, AUTO_LEN);*/\n    \n}\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nBANNER_VERSION(struct BannerOutput *banout, unsigned version_major,\n               unsigned version_minor)\n{\n    char foo[64];\n\n    switch (version_major<<8 | version_minor) {\n        case 0x0300:\n            banout_append(banout, PROTO_SSL3, \"SSLv3 \", AUTO_LEN);\n            banout_append(  banout, PROTO_VULN, \"SSL[v3] \", AUTO_LEN);\n            break;\n        case 0x0301:\n            banout_append(banout, PROTO_SSL3, \"TLS/1.0 \", AUTO_LEN);\n            break;\n        case 0x0302:\n            banout_append(banout, PROTO_SSL3, \"TLS/1.1 \", AUTO_LEN);\n            break;\n        case 0x0303:\n            banout_append(banout, PROTO_SSL3, \"TLS/1.2 \", AUTO_LEN);\n            break;\n        case 0x0304:\n            banout_append(banout, PROTO_SSL3, \"TLS/1.3 \", AUTO_LEN);\n            break;\n        default:\n            snprintf(foo, sizeof(foo), \"SSLver[%u,%u] \", \n                      version_major,\n                      version_minor);\n            banout_append(banout, PROTO_SSL3, foo, strlen(foo));\n    }\n}\n\n\n/*****************************************************************************\n * This parses the \"Server Hello\" packet, the response to our \"ClientHello\"\n * that we sent. We are looking for the following bits of information:\n *  - cipher chosen by the server\n *  - whether heartbeats are enabled\n *****************************************************************************/\nstatic void\nparse_server_hello(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    struct SSL_SERVER_HELLO *hello = &pstate->sub.ssl.x.server_hello;\n    unsigned state = hello->state;\n    unsigned remaining = hello->remaining;\n    unsigned i;\n    enum {\n        VERSION_MAJOR, VERSION_MINOR,\n        TIME0, TIME1, TIME2, TIME3,\n        RANDOM,\n        SESSION_LENGTH, SESSION_ID,\n        CIPHER0, CIPHER1,\n        COMPRESSION,\n        LENGTH0, LENGTH1,\n        EXT_TAG0, EXT_TAG1,\n        EXT_LEN0, EXT_LEN1,\n        EXT_DATA,\n        EXT_DATA_HEARTBEAT,\n        UNKNOWN,\n    };\n\n    UNUSEDPARM(banout);\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n\n    /* What this structure looks like in ASN.1 format\n       struct {\n           ProtocolVersion server_version;\n           Random random;\n           SessionID session_id;\n           CipherSuite cipher_suite;\n           CompressionMethod compression_method;\n       } ServerHello;\n    */\n\n    /* 'for all bytes in the packet...' */\n    for (i=0; i<length; i++)\n    switch (state) {\n    case VERSION_MAJOR:\n        hello->version_major = px[i];\n        DROPDOWN(i,length,state);\n\n    case VERSION_MINOR:\n        hello->version_minor = px[i];\n        BANNER_VERSION(banout, hello->version_major, hello->version_minor);\n        if (banner1->is_poodle_sslv3) {\n            banout_append(banout, PROTO_VULN, \" POODLE \", AUTO_LEN);\n        }\n        if (hello->version_major > 3 || hello->version_minor > 4) {\n            state = UNKNOWN;\n            break;\n        }\n        hello->timestamp = 0;\n        DROPDOWN(i,length,state);\n\n    case TIME0:\n        hello->timestamp <<= 8;\n        hello->timestamp |= px[i];\n        DROPDOWN(i,length,state);\n    case TIME1:\n        hello->timestamp <<= 8;\n        hello->timestamp |= px[i];\n        DROPDOWN(i,length,state);\n    case TIME2:\n        hello->timestamp <<= 8;\n        hello->timestamp |= px[i];\n        DROPDOWN(i,length,state);\n    case TIME3:\n        hello->timestamp <<= 8;\n        hello->timestamp |= px[i];\n        remaining = 28;\n        DROPDOWN(i,length,state);\n    case RANDOM:\n        {\n            /* do our typical \"skip\" logic to skip this\n             * 32 byte field */\n            unsigned len = (unsigned)length-i;\n            if (len > remaining)\n                len = remaining;\n\n            remaining -= len;\n            i += len-1;\n\n            if (remaining != 0) {\n                break;\n            }\n        }\n        DROPDOWN(i,length,state);\n\n    case SESSION_LENGTH:\n        remaining = px[i];\n\t\tif (banner1->is_ticketbleed && remaining > 16) {\n\t\t\tbanout_append(  banout, PROTO_VULN, \"SSL[ticketbleed] \", 17);\n\t\t}\n        DROPDOWN(i,length,state);\n\n    case SESSION_ID:\n        {\n            unsigned len = (unsigned)length-i;\n            if (len > remaining)\n                len = remaining;\n\n            remaining -= len;\n            i += len-1;\n\n            if (remaining != 0) {\n                break;\n            }\n        }\n        hello->cipher_suite = 0;\n        DROPDOWN(i,length,state);\n\n    case CIPHER0:\n        hello->cipher_suite <<= 8;\n        hello->cipher_suite |= px[i];\n        DROPDOWN(i,length,state);\n\n    case CIPHER1:\n        hello->cipher_suite <<= 8;\n        hello->cipher_suite |= px[i]; /* cipher-suite recorded here */\n        BANNER_CIPHER(banout, hello->cipher_suite);\n        DROPDOWN(i,length,state);\n\n    case COMPRESSION:\n        hello->compression_method = px[i];\n        DROPDOWN(i,length,state);\n\n    case LENGTH0:\n        remaining = px[i];\n        DROPDOWN(i,length,state);\n\n    case LENGTH1:\n        remaining <<= 8;\n        remaining |= px[i];\n        DROPDOWN(i,length,state);\n  \n    case EXT_TAG0:\n    ext_tag:\n        if (remaining < 4) {\n            state = UNKNOWN;\n            continue;\n        }\n        hello->ext_tag = px[i]<<8;\n        remaining--;\n        DROPDOWN(i,length,state);\n            \n    case EXT_TAG1:\n        hello->ext_tag |= px[i];\n        remaining--;\n        DROPDOWN(i,length,state);\n\n    case EXT_LEN0:\n        hello->ext_remaining = px[i]<<8;\n        remaining--;\n        DROPDOWN(i,length,state);\n    case EXT_LEN1:\n        hello->ext_remaining |= px[i];\n        remaining--;\n        switch (hello->ext_tag) {\n            case 0x000f: /* heartbeat */\n                state = EXT_DATA_HEARTBEAT;\n                continue;\n        }\n        DROPDOWN(i,length,state);\n        \n    case EXT_DATA:\n        if (hello->ext_remaining == 0) {\n            state = EXT_TAG0;\n            goto ext_tag;\n        }\n        if (remaining == 0) {\n            state = UNKNOWN;\n            continue;\n        }\n        remaining--;\n        hello->ext_remaining--;\n        continue;\n\n    case EXT_DATA_HEARTBEAT:\n        if (hello->ext_remaining == 0) {\n            state = EXT_TAG0;\n            goto ext_tag;\n        }\n        if (remaining == 0) {\n            state = UNKNOWN;\n            continue;\n        }\n        remaining--;\n        hello->ext_remaining--;\n        if (px[i]) {\n            banout_append(  banout, PROTO_VULN, \"SSL[heartbeat] \", 15);\n        }\n        state = EXT_DATA;\n        continue;\n\n    \n\n    case UNKNOWN:\n    default:\n        i = (unsigned)length;\n    }\n\n    hello->state = state;\n    hello->remaining = remaining;\n}\n\n\n/*****************************************************************************\n * This parses the certificates from the server. This contains an outer\n * length field for all certificates, and then uses a length field for\n * each certificate. The length fields are 3 bytes long.\n *\n * +--------+--------+--------+\n * |  length of all certs     |\n * +--------+--------+--------+\n *    +--------+--------+--------+\n *    |        cert length       |\n *    +--------+--------+--------+\n *    .                          .\n *    . . .    certificate   . . .\n *    .                          .\n *    +--------+--------+--------+\n *    |        cert length       |\n *    +--------+--------+--------+\n *    .                          .\n *    . . .    certificate   . . .\n *    .                          .\n *\n * This parser doesn't parse the certificates themselves, but initializes\n * and passes fragments to the X.509 parser.\n *\n * Called by ssl_parser_record()->parse_handshake()\n * Calls x509_decode() to parse the certificate\n * Calls banout_append_base64() to capture the certificate\n *****************************************************************************/\nstatic void\nparse_server_cert(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    struct SSL_SERVER_CERT *data = &pstate->sub.ssl.x.server_cert;\n    unsigned state = data->state;\n    unsigned remaining = data->remaining;\n    unsigned cert_remaining = data->sub.remaining;\n    unsigned i;\n    enum {\n        LEN0, LEN1, LEN2,\n        CLEN0, CLEN1, CLEN2,\n        CERT,\n        CALEN0, CALEN1, CALEN2,\n        CACERT,\n        UNKNOWN,\n    };\n\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(socket);\n\n    for (i=0; i<length; i++)\n    switch (state) {\n    case LEN0:\n        remaining = px[i];\n        DROPDOWN(i,length,state);\n    case LEN1:\n        remaining = remaining * 256 + px[i];\n        DROPDOWN(i,length,state);\n    case LEN2:\n        remaining = remaining * 256 + px[i];\n        DROPDOWN(i,length,state);\n\n    case CLEN0:\n    case CALEN0:\n        if (remaining < 3) {\n            state = UNKNOWN;\n            continue;\n        }\n        cert_remaining = px[i];\n        remaining--;\n        DROPDOWN(i,length,state);\n    case CLEN1:\n    case CALEN1:\n        cert_remaining = cert_remaining * 256 + px[i];\n        remaining--;\n        DROPDOWN(i,length,state);\n    case CLEN2:\n    case CALEN2:\n        cert_remaining = cert_remaining * 256 + px[i];\n        remaining--;\n        if (banner1->is_capture_cert) {\n            banout_init_base64(&pstate->base64);\n            //banout_append(  banout, PROTO_X509_CERT, \"cert:\", 5);\n        }\n\n        {\n            unsigned count = data->x509.count;\n            memset(&data->x509, 0, sizeof(data->x509));\n            x509_decode_init(&data->x509, cert_remaining);\n            data->x509.count = (unsigned char)count + 1;\n        }\n        DROPDOWN(i,length,state);\n\n    case CERT:\n    case CACERT:\n        {\n            unsigned len = (unsigned)length-i;\n\t    unsigned proto = (state == CERT ? PROTO_X509_CERT : PROTO_X509_CACERT);\n            if (len > remaining)\n                len = remaining;\n            if (len > cert_remaining)\n                len = cert_remaining;\n\n            /* parse the certificate */\n            if (banner1->is_capture_cert) {\n                banout_append_base64(banout, \n                             proto,\n                             px+i, len,\n                             &pstate->base64);\n            }\n\n            x509_decode(&data->x509, px+i, len, banout);\n\n\n            remaining -= len;\n            cert_remaining -= len;\n            i += len-1;\n\n            if (cert_remaining == 0) {\n                /* We've reached the end of the certificate, so make\n                 * a record of it */\n                if (banner1->is_capture_cert) {\n                    banout_finalize_base64(banout, \n                                           proto,\n                                           &pstate->base64);        \n                    banout_end(banout, proto);\n                }\n                state = CALEN0;\n                if (remaining == 0) {\n                    /* FIXME: reduce this logic, it should only flush the\n                     * FIXME: ertificate, not close the connection*/\n                    if (!banner1->is_heartbleed) {\n                        ; //tcpapi_close(socket);\n                    }\n                }\n            }\n        }\n        break;\n\n\n    case UNKNOWN:\n    default:\n        i = (unsigned)length;\n    }\n\n    data->state = state;\n    data->remaining = remaining;\n    data->sub.remaining = cert_remaining;\n}\n\n/*****************************************************************************\n * Called from the SSL Record parser to parse the contents of\n * a handshake record. The way SSL handshaking works is that after we\n * have sent the \"hello\", the server then sends us a bunch of records,\n * including its certificate, then is done on their side with the handshake.\n * Then, the client sends a bunch of stuff, to complete their end of the\n * handshake (which we won't do). At that point, they then do a \"change\n * cipher spec\" to negotiate the encryption keys, which isn't technically\n * part of the handshaking.\n *\n * This is a four byte protocol:\n * +--------+\n * |  type  |\n * +--------+--------+--------+\n * |          length          |\n * +--------+--------+--------+\n * |  content ...\n * .\n * .\n *\n * Note that the \"length\" field is 3 bytes, supporting in theory 16-megs\n * of content, but the outer record that calls this uses only 2-byte length\n * fields. That's because records support fragmentation. This parser supports\n * this fragmentation -- the 'state' variable crosses fragment boundaries.\n *****************************************************************************/\nstatic void\nparse_handshake(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    struct SSLRECORD *ssl = &pstate->sub.ssl;\n    unsigned state = ssl->handshake.state;\n    unsigned remaining = ssl->handshake.remaining;\n    unsigned i;\n    enum {\n        START,\n        LENGTH0, LENGTH1, LENGTH2,\n        CONTENTS,\n        UNKNOWN,\n    };\n\n    /*\n     * `for all bytes in the segment`\n     *   `do a state transition for that byte `\n     */\n    for (i=0; i<length; i++)\n    switch (state) {\n            \n    /* There are 20 or so handshaking sub-messages, indicates by it's own\n     * 'type' field, which we parse out here */\n    case START:\n        if (px[i] & 0x80) {\n            state = UNKNOWN;\n            break;\n        }\n        /* remember the 'type' field for use later in the CONTENT state */\n        ssl->handshake.type = px[i];\n        \n        /* initialize the state variable that will be used by the inner\n         * parsers */\n        ssl->x.all.state = 0;\n        DROPDOWN(i,length,state);\n\n    /* This grabs the 'length' field. Note that unlike other length fields,\n     * this one is 3 bytes long. That's because a single certificate \n     * packet can contain so many certificates in a chain that it exceeds\n     * 64k kilobytes in size. */\n    case LENGTH0:\n        remaining = px[i];\n        DROPDOWN(i,length,state);\n    case LENGTH1:\n        remaining <<= 8;\n        remaining |= px[i];\n        DROPDOWN(i,length,state);\n    case LENGTH2:\n        remaining <<= 8;\n        remaining |= px[i];\n\n        /* If we get a \"server done\" response, then it's a good time to\n         * send the heartbleed request. Note that these are usually zero\n         * length, so we can't process this below in the CONTENT state\n         * but have to do it here at the end of the LENGTH2 state */\n        if (ssl->handshake.type == 2 && banner1->is_heartbleed) {\n            static const char heartbleed_request[] = \n                \"\\x15\\x03\\x02\\x00\\x02\\x01\\x80\"\n                \"\\x18\\x03\\x02\\x00\\x03\\x01\" \"\\x40\\x00\";\n            tcpapi_send(socket, heartbleed_request, sizeof(heartbleed_request)-1, 0);\n        }\n        DROPDOWN(i,length,state);\n\n    /* This parses the contents of the handshake. This parser just skips\n     * the data, in the same way as explained in the \"ssl_parse_record()\"\n     * function at its CONTENT state. We may pass the fragment to an inner\n     * parser, but whatever the inner parser does is independent from this\n     * parser, and has no effect on this parser\n     */\n    case CONTENTS:\n        {\n            unsigned len = (unsigned)length-i;\n            if (len > remaining)\n                len = remaining;\n\n            switch (ssl->handshake.type) {\n                case 0: /* hello request*/\n                case 1: /* client hello */\n                case 3: /* DTLS hello verify request */\n                case 4: /* new session ticket */\n                case 12: /* server key exchange */\n                case 13: /* certificate request */\n                case 14: /* server done */\n                case 15: /* certificate verify */\n                case 16: /* client key exchange */\n                case 20: /* finished */\n                case 22: /* certificate status */\n                default:\n                    /* don't parse these types, just skip them */\n                    break;\n                    \n                case 2: /* server hello */\n                    parse_server_hello( banner1,\n                                       banner1_private,\n                                       pstate,\n                                       px+i, len,\n                                       banout,\n                                       socket);\n                    break;\n                case 11: /* server certificate */\n                    parse_server_cert(  banner1,\n                                      banner1_private,\n                                      pstate,\n                                      px+i, len,\n                                      banout,\n                                      socket);\n                    break;\n            }\n\n            remaining -= len;\n            i += len-1;\n\n            if (remaining == 0)\n                state = START;\n        }\n\n        break;\n    case UNKNOWN:\n    default:\n        i = (unsigned)length;\n    }\n\n    ssl->handshake.state = state;\n    ssl->handshake.remaining = remaining;\n}\n\n\n/*****************************************************************************\n * Called to parse the \"hearbeat\" data. This consists of the following \n * structure:\n *\n * +--------+\n * |  type  | 1=request, 2=response\n * +--------+--------+\n * |      length     |\n * +--------+--------+\n *\n * This is followed by the echoed bytes, followed by some padding.\n *\n *****************************************************************************/\nstatic void\nparse_heartbeat(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    struct SSLRECORD *ssl = &pstate->sub.ssl;\n    unsigned state = ssl->handshake.state;\n    unsigned remaining = ssl->handshake.remaining;\n    unsigned i;\n    enum {\n        START,\n        LENGTH0, LENGTH1,\n        CONTENTS,\n        UNKNOWN,\n    };\n\n    UNUSEDPARM(socket);\n    UNUSEDPARM(banner1_private);\n\n    /*\n     * `for all bytes in the segment`\n     *   `do a state transition for that byte `\n     */\n    for (i=0; i<length; i++)\n    switch (state) {\n            \n    /* this is the 'type' field for the heartbeat. There are only two\n     * values, '1' for request and '2' for response. Anything else indicates\n     * that either the data was corrupted, or else it is encrypted.\n     */\n    case START:\n        if (px[i] < 1 || 2 < px[i]) {\n            state = UNKNOWN;\n            break;\n        }\n        ssl->handshake.type = px[i];\n        DROPDOWN(i,length,state);\n\n    /* Grab the two byte length field */\n    case LENGTH0:\n        remaining = px[i];\n        DROPDOWN(i,length,state);\n    case LENGTH1:\n        remaining <<= 8;\n        remaining |= px[i];\n        \n        /* `if heartbeat response ` */\n        if (ssl->handshake.type == 2) {\n            \n            /* if we have a non-trivial amount of data in the response, then\n             * it means the \"bleed\" attempt succeeded. */\n            if (remaining >= 16)\n                banout_append(  banout, PROTO_VULN, \"SSL[HEARTBLEED] \", 16);\n            \n            /* if we've been configured to \"capture\" the heartbleed contents,\n             * then initialize the BASE64 encoder */\n            if (banner1->is_capture_heartbleed) {\n                banout_init_base64(&pstate->base64);\n                banout_append(banout, PROTO_HEARTBLEED, \"\", 0);\n            }\n        }\n        DROPDOWN(i,length,state);\n\n    /* Here is where we parse the contents of the heartbeat. This is the same\n     * skipping logic as the CONTENTS state within the ssl_parse_record()\n     * function.*/\n    case CONTENTS:\n        {\n            unsigned len = (unsigned)length-i;\n            if (len > remaining)\n                len = remaining;\n\n            /* If this is a RESPONSE, and we've been configured to CAPTURE\n             * hearbleed responses, then we write the bleeding bytes in \n             * BASE64 into the banner system. The user will be able to \n             * then do research on those bleeding bytes */\n            if (ssl->handshake.type == 2 && banner1->is_capture_heartbleed) {\n                banout_append_base64(banout, \n                                     PROTO_HEARTBLEED, \n                                     px+i, len,\n                                     &pstate->base64);\n            }\n\n            remaining -= len;\n            i += len-1;\n\n            if (remaining == 0)\n                state = UNKNOWN; /* padding */\n        }\n\n        break;\n    \n    /* We reach this state either because the heartbeat data is corrupted or\n     * encrypted, or because we've reached the padding area after the \n     * heartbeat */\n    case UNKNOWN:\n    default:\n        i = (unsigned)length;\n    }\n\n    /* not the handshake protocol, but we re-use their variables */\n    ssl->handshake.state = state;\n    ssl->handshake.remaining = remaining;\n}\n\n/*****************************************************************************\n * Called to parse the \"hearbeat\" data. This consists of the following \n * structure:\n *\n * +--------+\n * | level  | 1=warning, 2=fatal\n * +--------+\n * | descr  |\n * +--------+\n *\n *****************************************************************************/\nstatic void\nparse_alert(\n                const struct Banner1 *banner1,\n                void *banner1_private,\n                struct StreamState *pstate,\n                const unsigned char *px, size_t length,\n                struct BannerOutput *banout,\n                struct stack_handle_t *socket)\n{\n    struct SSLRECORD *ssl = &pstate->sub.ssl;\n    unsigned state = ssl->handshake.state;\n    unsigned remaining = ssl->handshake.remaining;\n    unsigned i;\n    enum {\n        START,\n        DESCRIPTION,\n        UNKNOWN,\n    };\n    \n    UNUSEDPARM(socket);\n    UNUSEDPARM(banner1_private);\n    \n    /*\n     * `for all bytes in the segment`\n     *   `do a state transition for that byte `\n     */\n    for (i=0; i<length; i++)\n        switch (state) {\n            case START:\n                ssl->x.server_alert.level = px[i];\n                DROPDOWN(i,length,state);\n                \n            case DESCRIPTION:\n                ssl->x.server_alert.description = px[i];\n                if (banner1->is_poodle_sslv3 && ssl->x.server_alert.level == 2) {\n                    char foo[64];\n\n                    /* fatal error */\n                    switch (ssl->x.server_alert.description) {\n                        case 86:\n                            if (!banout_is_contains(banout, PROTO_SAFE, \"TLS_FALLBACK_SCSV\"))\n                                banout_append(banout, PROTO_SAFE, \n                                      \"poodle[TLS_FALLBACK_SCSV] \", AUTO_LEN);\n                            break;\n                        case 40:\n                            if (!banout_is_contains(banout, PROTO_SAFE, \"TLS_FALLBACK_SCSV\"))\n                                banout_append(banout, PROTO_SAFE, \n                                          \"poodle[no-SSLv3] \", AUTO_LEN);\n                            break;\n                        default:\n                            banout_append(banout, PROTO_SAFE, \n                                          \"poodle[no-SSLv3] \", AUTO_LEN);\n                            snprintf(foo, sizeof(foo), \" ALERT(0x%02x%02x) \",\n                                      ssl->x.server_alert.level,\n                                      ssl->x.server_alert.description\n                                      );\n                            \n                            banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);\n                            break;\n                    }\n                } else {\n                    char foo[64];\n                    snprintf(foo, sizeof(foo), \" ALERT(0x%02x%02x) \",\n                              ssl->x.server_alert.level,\n                              ssl->x.server_alert.description\n                              );\n                \n                    banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);\n                }\n                DROPDOWN(i,length,state);\n                \n            case UNKNOWN:\n            default:\n                i = (unsigned)length;\n        }\n    \n    /* not the handshake protocol, but we re-use their variables */\n    ssl->handshake.state = state;\n    ssl->handshake.remaining = remaining;\n}\n\n\n/*****************************************************************************\n * This is the main SSL parsing function.\n *\n * SSL is a multi-layered protocol, consisting of \"Records\" as the outer\n * protocol, with records containing data inside. The inner data is\n * unencrypted during the session handshake, but then encrypted from then on.\n *\n * The SSL Records are a simple 5 byte protocol:\n *\n * +--------+\n * |  type  |\n * +--------+--------+\n * |ver-mjr |ver-mnr |\n * +--------+--------+\n * |      length     |\n * +--------+--------+\n *\n * This allows simple state-machine parsing. We need only 6 states, one for\n * each byte, and then a \"content\" state tracking the contents of the record\n * until we've parsed \"length\" bytes, then back to the initial state.\n *\n *****************************************************************************/\nstatic void\nssl_parse_record(\n        const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned remaining = pstate->remaining;\n    struct SSLRECORD *ssl = &pstate->sub.ssl;\n    unsigned i;\n    enum {\n        START,\n        VERSION_MAJOR,\n        VERSION_MINOR,\n        LENGTH0, LENGTH1,\n        CONTENTS,\n        UNKNOWN,\n    };\n\n    /*\n     * `for all bytes in the segment`\n     *   `do a state transition for that byte `\n     */\n    for (i=0; i<length; i++)\n    switch (state) {\n            \n    /* \n     * The initial state parses the \"type\" byte. There are only a few types\n     * defined so far, the values 20-25, but socket can be defined in the\n     * future. The standard explicitly says that they must be lower than 128,\n     * so if the high-order bit is set, we know that the byte is invalid,\n     * and that something is wrong.\n     */\n    case START:\n        if (px[i] & 0x80) {\n            state = UNKNOWN;\n            break;\n        }\n        if (ssl->type != px[i]) {\n            ssl->type = px[i];\n            \n            /* this is for some minimal fragmentation/reassembly */\n            ssl->handshake.state = 0;\n        }\n        DROPDOWN(i,length,state);\n\n    /* This is the major version number, which must be the value '3',\n     * which means both SSLv3 and TLSv1. This parser doesn't support\n     * earlier versions of SSL. */\n    case VERSION_MAJOR:\n        if (px[i] != 3) {\n            state = UNKNOWN;\n            break;\n        }\n        ssl->version_major = px[i];\n        DROPDOWN(i,length,state);\n\n    /* This is the minor version number. It's a little weird:\n     * 0 = SSLv3.0\n     * 1 = TLSv1.0\n     * 2 = TLSv1.1\n     * 3 = TLSv1.2\n     * 4 = TLSv1.3\n     */\n    case VERSION_MINOR:\n        ssl->version_minor = px[i];\n        DROPDOWN(i,length,state);\n\n    /* This is the length field. In theory, it can be the full 64k bytes\n     * in length, but typical implements limit it to 16k */\n    case LENGTH0:\n        remaining = px[i]<<8;\n        DROPDOWN(i,length,state);\n    case LENGTH1:\n        remaining |= px[i];\n        DROPDOWN(i,length,state);\n        ssl->handshake.state = 0;\n        \n    /*\n     * This state parses the \"contents\" of a record. What we do here is at\n     * this level of the parser is that we calculate a sub-segment size,\n     * which is bounded by either the number of bytes in this records (when\n     * there are multiple records per packet), or the packet size (when the\n     * record exceeds the size of the packet).\n     * We then pass this sub-segment to the inner content parser. However, the\n     * inner parser has no effect on what happens in this parser. It's wholly\n     * independent, doing it's own thing.\n     */\n    case CONTENTS:\n        {\n            unsigned len;\n            \n            /* Size of this segment is either the bytes remaining in the \n             * current packet, or the bytes remaining in the record */\n            len = (unsigned)length - i;\n            if (len > remaining)\n                len = remaining;\n\n            /* Do an inner-parse of this segment. Note that the inner-parser\n             * has no effect on this outer record parser */\n            switch (ssl->type) {\n                case 20: /* change cipher spec */\n                    break;\n                case 21: /* alert */\n                    /* encrypted, usually, but if we get one here, it won't\n                     * be encrypted */\n                    parse_alert(banner1,\n                                    banner1_private,\n                                    pstate,\n                                    px+i, len,\n                                    banout,\n                                    socket);\n                    break;\n                case 22: /* handshake */\n                    parse_handshake(banner1,\n                                    banner1_private,\n                                    pstate,\n                                    px+i, len,\n                                    banout,\n                                    socket);\n                    break;\n                case 23: /* application data */\n                    /* encrypted, always*/\n                    break;\n                case 24: /* heartbeat */\n                    /* encrypted, in theory, but not practice */\n                    parse_heartbeat(banner1,\n                                    banner1_private,\n                                    pstate,\n                                    px+i, len,\n                                    banout,\n                                    socket);\n                    break;\n            }\n            \n            /* Skip ahead the number bytes in this segment. This makes the\n             * parser very fast, because we aren't actually doing a single\n             * byte at a time, but skipping forward large number of bytes\n             * at a time -- except for the 5 byte headers */\n            remaining -= len;\n            i += len-1; /* if 'len' is zero, this still works */\n            \n            /* Once we've exhausted the contents of record, go back to the\n             * start parsing the next record */\n            if (remaining == 0)\n                state = START;\n        }\n        break;\n            \n    /* We reach the state when the protocol has become corrupted, such as in\n     * those cases where it's not SSL */\n    case UNKNOWN:\n    default:\n        i = (unsigned)length;\n    }\n\n    pstate->state = state;\n    pstate->remaining = remaining;\n}\n\n\n/*****************************************************************************\n * This is called at program startup to initialize any structures we need\n * for parsing. The SSL parser doesn't need anything in particular, so\n * we just ignore it. We have to implement the callback, however, which\n * is why this empty function exists.\n *****************************************************************************/\nstatic void *\nssl_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n/*****************************************************************************\n * This is the template \"Client Hello\" packet that is sent to the server\n * to initiate the SSL connection. Right now, it's statically just transmitted\n * on to the wire.\n * TODO: we need to make this dynamically generated, so that users can\n * select various options.\n *****************************************************************************/\nstatic const char\nssl_hello_template[] =\n\"\\x16\\x03\\x01\\x00\\xc1\"          /* TLSv1.0 record layer */\n\"\\x01\" /* type = client-hello */\n\"\\x00\\x00\\xbd\" /* length = 193 */\n\"\\x03\\x03\"      /* version = 3.03 (TLS 1.2) */\n\n\"\\x97\\xe5\\x60\\x50\\xc4\\xa5\\x4a\\xe0\\xb9\\x01\\x75\\x15\\x31\\x23\\x27\\x68\" /* random */\n\"\\x87\\xdc\\x3d\\x66\\xec\\x07\\xdc\\xa0\\xe5\\x1f\\x1f\\xa1\\x3f\\x49\\xf8\\xfc\" /* TODO: re-randomize for each request, or at least on startup */\n\n\"\\x00\"/* session-id-length = 0 */\n\n\"\\x00\\x3c\" /* cipher suites length */\n\"\\xc0\\x2b\\xcc\\xa9\\xc0\\x2c\\xc0\\x09\\xc0\\x0a\\xc0\\x23\\xc0\\x24\\xc0\\x2f\"\n\"\\xcc\\xa8\\xc0\\x30\\xc0\\x13\\xc0\\x14\\xc0\\x27\\xc0\\x28\\x00\\x9e\\xcc\\xaa\"\n\"\\x00\\x9f\\x00\\x33\\x00\\x39\\x00\\x67\\x00\\x6b\\x00\\x9c\\x00\\x9d\\x00\\x3c\"\n\"\\x00\\x3d\\x00\\x2f\\x00\\x35\\x00\\x0a\\x00\\x05\\x00\\xff\"\n\n\"\\x01\" /* compression-methods-length = 1 */\n\"\\x00\"\n\n\"\\x00\\x58\" /* extensions length = 88 */\n/* extensions */\n\"\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\x0a\\x00\\x0c\\x00\\x0a\\x00\\x1d\"\n\"\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\\x00\\x23\\x00\\x00\\x00\\x16\\x00\\x00\"\n\"\\x00\\x17\\x00\\x00\\x00\\x0d\\x00\\x30\\x00\\x2e\\x04\\x03\\x05\\x03\\x06\\x03\"\n\"\\x08\\x07\\x08\\x08\\x08\\x09\\x08\\x0a\\x08\\x0b\\x08\\x04\\x08\\x05\\x08\\x06\"\n\"\\x04\\x01\\x05\\x01\\x06\\x01\\x03\\x03\\x02\\x03\\x03\\x01\\x02\\x01\\x03\\x02\"\n\"\\x02\\x02\\x04\\x02\\x05\\x02\\x06\\x02\"\n;\n\n/*****************************************************************************\n * This is the template \"Client Hello\" packet that is sent to the server\n * to initiate the SSL connection. Right now, it's statically just transmitted\n * on to the wire.\n * TODO: we need to make this dynamically generated, so that users can\n * select various options.\n *****************************************************************************/\nstatic const char\nssl_12_hello_template[] =\n\"\\x16\\x03\\x01\\x01\\x1a\"\n\"\\x01\"\n\"\\x00\\x01\\x16\"\n\"\\x03\\x03\\x02\\x58\\x33\\x79\\x5f\\x71\\x03\\xef\\x07\\xfe\\x36\\x61\\xb0\\x32\\x81\\xaa\\x99\\x10\\x87\\x6a\\x8e\\x5b\\xf9\\x03\\x93\\x44\\x58\\x4b\\x19\\xff\\x42\\x6a\\x20\\x64\\x84\\xcd\\x28\\x9c\\xe9\\xb1\\x9d\\xcd\\x8a\\x11\\x4c\\x3b\\x40\\x1c\\x90\\x02\\xf2\\xb5\\x1a\\xf1\\x7e\\x5d\\xb8\\x42\\xc2\\x1e\\x17\\x1e\\x59\\xa4\\xac\\x00\\x3e\\x13\\x02\\x13\\x03\\x13\\x01\\xc0\\x2c\\xc0\\x30\\x00\\x9f\\xcc\\xa9\\xcc\\xa8\\xcc\\xaa\\xc0\\x2b\\xc0\\x2f\\x00\\x9e\\xc0\\x24\\xc0\\x28\\x00\\x6b\\xc0\\x23\\xc0\\x27\\x00\\x67\\xc0\\x0a\\xc0\\x14\\x00\\x39\\xc0\\x09\\xc0\\x13\\x00\\x33\\x00\\x9d\\x00\\x9c\\x00\\x3d\\x00\\x3c\\x00\\x35\\x00\\x2f\\x00\\xff\\x01\\x00\\x00\\x8f\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\x0a\\x00\\x0c\\x00\\x0a\\x00\\x1d\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\\x00\\x23\\x00\\x00\\x00\\x16\\x00\\x00\\x00\\x17\\x00\\x00\\x00\\x0d\\x00\\x2a\\x00\\x28\\x04\\x03\\x05\\x03\\x06\\x03\\x08\\x07\\x08\\x08\\x08\\x09\\x08\\x0a\\x08\\x0b\\x08\\x04\\x08\\x05\\x08\\x06\\x04\\x01\\x05\\x01\\x06\\x01\\x03\\x03\\x03\\x01\\x03\\x02\\x04\\x02\\x05\\x02\\x06\\x02\\x00\\x2b\\x00\\x09\\x08\\x03\\x04\\x03\\x03\\x03\\x02\\x03\\x01\\x00\\x2d\\x00\\x02\\x01\\x01\\x00\\x33\\x00\\x26\\x00\\x24\\x00\\x1d\\x00\\x20\\xb6\\x87\\xb7\\x72\\xb9\\xcb\\x07\\xe0\\x14\\x0a\\x14\\x81\\x3f\\x3f\\x0a\\xcc\\xc4\\x7d\\x80\\xf7\\xe8\\xaa\\x1e\\x73\\xb0\\xa9\\xad\\xb8\\x3a\\xa7\\x3c\\x64\";\n;\n/*****************************************************************************\n *****************************************************************************/\nstatic char *\nssl_add_cipherspec_sslv3(void *templ, unsigned cipher_spec, unsigned is_append)\n{\n    unsigned char *px;\n    size_t len0 = ssl_hello_size(templ);\n    size_t len1;\n    size_t len1b;\n    size_t len2;\n    size_t offset;\n    size_t offset2;\n    \n    /* Increase space by 2 for additional cipherspec */\n    px = REALLOC(templ, ssl_hello_size(templ) + 2);\n    \n    /* parse the lengths */\n    len1 = px[3] << 8 | px[4];\n    len1b = px[6] << 16 | px[7] << 8 | px[8];\n    \n    \n    /* skip session id field */\n    offset = 43;\n    offset += px[offset] + 1;\n    \n    /* do cipherspecs */\n    len2 = px[offset] << 8 | px[offset+1];\n    offset2 = offset+2;\n    if (is_append) {\n        /* append to end of list */\n        memmove(px + offset2 + len2 + 2,\n                px + offset2 + len2,\n                len0 - (offset2 + len2));\n        px[offset2 + len2    ] = (unsigned char)(cipher_spec>>8);\n        px[offset2 + len2 + 1] = (unsigned char)(cipher_spec>>0);\n    } else {\n        /* prepend to start of list, making this the preferred cipherspec*/\n        memmove(px + offset2 + 2,\n                px + offset2,\n                len0 - offset2);\n        px[offset2    ] = (unsigned char)(cipher_spec>>8);\n        px[offset2 + 1] = (unsigned char)(cipher_spec>>0);\n    }\n    \n    /* fix length fields */\n    len2 += 2;\n    px[offset    ] = (unsigned char)(len2>>8);\n    px[offset + 1] = (unsigned char)(len2>>0);\n    len1b += 2;\n    px[6] = (unsigned char)(len1b>>16);\n    px[7] = (unsigned char)(len1b>> 8);\n    px[8] = (unsigned char)(len1b>> 0);\n    len1 += 2;\n    px[3] = (unsigned char)(len1>>8);\n    px[4] = (unsigned char)(len1>>0);\n    \n    return (char*)px;    \n}\n\n/*****************************************************************************\n *****************************************************************************/\nchar *\nssl_add_cipherspec(void *templ, unsigned cipher_spec, unsigned is_append)\n{\n    const unsigned char *px = (const unsigned char *)templ;\n    unsigned version;\n    \n    /* ignore things that aren't \"Hello\" messages */\n    if (px[0] != 0x16) {\n        fprintf(stderr, \"internal error\\n\");\n        return templ;\n    }\n\n    /* figure out the proper version */\n    version = px[1] << 8 | px[2];\n    \n    /* do different parsing depending on version */\n    switch (version) {\n        case 0x300:\n            return ssl_add_cipherspec_sslv3(templ, cipher_spec, is_append);\n        default:\n            /*TODO:*/\n            fprintf(stderr, \"internal error\\n\");\n            return templ;\n    }\n}\n\n/*****************************************************************************\n * Figure out the Hello message size by parsing the data\n *****************************************************************************/\nunsigned\nssl_hello_size(const void *templ)\n{\n    const unsigned char *px = (const unsigned char *)templ;\n    size_t template_size;\n    \n    template_size = (px[3]<<8 | px[4]) + 5;\n    \n    return (unsigned)template_size;\n}\n    \n/*****************************************************************************\n *****************************************************************************/\nchar *\nssl_hello(const void *templ)\n{\n    unsigned char *px = (unsigned char *)templ;\n    unsigned now = (unsigned)time(0);\n    unsigned i;\n    \n    /* parse existing template to figure out size */\n    size_t template_size = (px[3]<<8 | px[4]) + 5;\n    \n    /* allocate memory for that size and copy */\n    px = MALLOC(template_size);\n    memcpy(px, templ, template_size);\n    \n    /* set the new timestamp and randomize buffer */\n    px[11] = (unsigned char)(now>>24);\n    px[12] = (unsigned char)(now>>16);\n    px[13] = (unsigned char)(now>> 8);\n    px[14] = (unsigned char)(now>> 0);\n    \n    /* create a pattern to make this detectable as specifically masscan */\n    for (i=4; i<32; i++) {\n        static const uint64_t key[2] = {0,0};\n        unsigned val = i+now;\n        unsigned char c = (unsigned char)siphash24(&val, sizeof(val), key);\n        \n        px[11+i] = c;\n    }\n    \n    return (char*)px;\n}\n\n\nextern unsigned char ssl_test_case_1[];\nextern size_t ssl_test_case_1_size;\nextern unsigned char ssl_test_case_3[];\nextern size_t ssl_test_case_3_size;\nextern unsigned char google_cert[];\nextern size_t google_cert_size;\nextern unsigned char yahoo_cert[];\nextern size_t yahoo_cert_size;\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int\nssl_selftest(void)\n{\n    struct Banner1 *banner1;\n    struct StreamState state[1];\n    unsigned ii;\n    struct BannerOutput banout1[1];\n    struct BannerOutput banout2[1];\n\n    unsigned x;\n\n    /*\n     * Yahoo cert\n     */\n    {\n        struct CertDecode certstate[1];\n\n        memset(certstate, 0, sizeof(certstate));\n        x509_decode_init(certstate, yahoo_cert_size);\n\n        banner1 = banner1_create();\n        banner1->is_capture_cert = 1;\n        banout_init(banout1);\n        x509_decode(certstate, \n                    yahoo_cert,\n                    yahoo_cert_size,\n                    banout1);\n        x = banout_is_contains(banout1, PROTO_SSL3,\n                            \", fr.yahoo.com, \");\n        if (!x) {\n            printf(\"x.509 parser failure: google.com\\n\");\n            return 1;\n        }\n        \n        \n        banner1_destroy(banner1);\n        banout_release(banout1);\n    }\n\n\n    /*\n     * Google cert\n     */\n    {\n        struct CertDecode certstate[1];\n\n        memset(certstate, 0, sizeof(certstate));\n        x509_decode_init(certstate, google_cert_size);\n\n        banner1 = banner1_create();\n        banner1->is_capture_cert = 1;\n        banout_init(banout1);\n        x509_decode(certstate, \n                    google_cert,\n                    google_cert_size,\n                    banout1);\n        x = banout_is_equal(banout1, PROTO_SSL3,\n                            \", www.google.com, www.google.com\");\n        if (!x) {\n            printf(\"x.509 parser failure: google.com\\n\");\n            return 1;\n        }\n        banner1_destroy(banner1);\n        banout_release(banout1);\n    }\n\n\n    /*\n     * Do the normal parse\n     */\n    banner1 = banner1_create();\n    banner1->is_capture_cert = 1;\n    memset(state, 0, sizeof(state));\n    banout_init(banout1);\n    {\n        size_t i;\n        for (i=0; i<ssl_test_case_3_size; i++)\n        ssl_parse_record(  banner1,\n                         0,\n                         state,\n                         ssl_test_case_3+i,\n                         1,\n                         banout1,\n                         0\n                         );\n    }\n    /*if (0) {\n        const char *foo = (char*)banout_string(banout1, PROTO_X509_CERT);\n        printf(\"-----BEGIN CERTIFICATE-----\\n\");\n        for (;;) {\n            if (strlen(foo) > 72) {\n                printf(\"%.*s\\n\", 72, foo);\n                foo += 72;\n            } else {\n                printf(\"%s\\n\", foo);\n                break;\n            }\n\n        }\n        printf(\"-----END CERTIFICATE-----\\n\");\n    }*/\n    banner1_destroy(banner1);\n    banout_release(banout1);\n\n    /*\n     * Do the fragmented parse\n     */\n    banner1 = banner1_create();\n    banner1->is_capture_cert = 1;\n    memset(state, 0, sizeof(state));\n    banout_init(banout2);\n    for (ii=0; ii<ssl_test_case_3_size; ii++)\n    ssl_parse_record(  banner1,\n                0,\n                state,\n                (const unsigned char *)ssl_test_case_3+ii,\n                1,\n                banout2,\n                0\n                );\n    banner1_destroy(banner1);\n    banout_release(banout2);\n\n    /*\n     * Do checking\n     */\n#if 0\n    if (memcmp(banner, \"cert:MIIGYjCCBUqgAwIBAgIIWQmqMKKz/PYwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE\", 65) != 0) {\n        fprintf(stderr, \"FAIL: ssl test\\n\");\n        return 1;\n    }\n\n    if (banner_offset != bannerx_offset\n        || memcmp(banner, bannerx, banner_offset) != 0)\n        return 1;\n#endif\n#if 0\n    {\n        unsigned i = 0;\n\n        while (i < banner_offset) {\n            while (i < banner_offset && isspace(banner[i]))\n                i++;\n            if (memcmp(&banner[i], \"cert:\", 5) == 0)\n                i += 5;\n\n            printf(\"-----BEGIN CERTIFICATE-----\\n\");\n            while (i < banner_offset && !isspace(banner[i])) {\n                unsigned j;\n                for (j=0; i+j<banner_offset && !isspace(banner[i+j]) && j < 64; j++)\n                    ;\n                printf(\"%.*s\\n\", j, banner+i);\n                i += j;\n            }\n            printf(\"-----END CERTIFICATE-----\\n\");\n        }\n    }\n#endif\n\n    return 0;\n}\n\n/*****************************************************************************\n * This is the 'plugin' structure that registers callbacks for this parser in\n * the main system.\n *****************************************************************************/\nstruct ProtocolParserStream banner_ssl_12 = {\n    \"ssl\", 443, ssl_12_hello_template, sizeof(ssl_12_hello_template)-1, 0,\n    ssl_selftest,\n    ssl_init,\n    ssl_parse_record,\n};\n\nstruct ProtocolParserStream banner_ssl = {\n    \"ssl\", 443, ssl_hello_template, sizeof(ssl_hello_template)-1,\n    SF__close, /* send FIN after the hello */\n    ssl_selftest,\n    ssl_init,\n    ssl_parse_record,\n    0,\n    0,\n    &banner_ssl_12,\n};\n"
  },
  {
    "path": "src/proto-ssl.h",
    "content": "#ifndef PROTO_SSL_H\n#define PROTO_SSL_H\n#include \"proto-banner1.h\"\n\nextern struct ProtocolParserStream banner_ssl;\nextern struct ProtocolParserStream banner_ssl_12;\n\nextern const char *ssl_hello_heartbeat_template;\nextern const char *ssl_hello_ticketbleed_template;\nextern const char *ssl_hello_sslv3_template;\n\n/**\n * Parse the SSL Hello template to find its size\n */\nunsigned ssl_hello_size(const void *templ);\n\n/**\n * Allocate memory and make a copy of the template, so that we can \n * rewrite some fields, such as setting the correct timestamp\n */\nchar *ssl_hello(const void *templ);\n\n/**\n * Add a cipher-spec.\n * There are many possible uses for this, but for now it's used for the POODLE\n * bug, appending TLS_FALLBACK_SCSV to the list. It may need to reallocate\n * the template.\n */\nchar *ssl_add_cipherspec(void *templ, unsigned cipher_spec, unsigned is_append);\n\n\n#endif\n"
  },
  {
    "path": "src/proto-tcp-rdp.c",
    "content": "\n#include \"proto-tcp-rdp.h\"\n#include \"proto-banner1.h\"\n#include \"stack-tcp-api.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"util-malloc.h\"\n#include \"assert.h\"\n#include <ctype.h>\n#include <string.h>\n#include \"util-safefunc.h\"\n\n/***************************************************************************\n * @param length\n *      Number of bytes remaining in this header, or bytes remaining in\n *      the packet, whichever is fewer.\n * @return the number of bytes processed\n ***************************************************************************/\nstatic size_t\ncc_parse(struct BannerOutput *banout, struct RDPSTUFF *rdp, const unsigned char *px, size_t length)\n{\n    size_t offset;\n    unsigned state = rdp->cc.state;\n    enum {\n        TYPE, FLAGS, LENGTH, RESERVED, RESULT0, RESULT1, RESULT2, RESULT3, EXTRA, UNKNOWN_PROTOCOL\n    };\n    for (offset = 0; offset < length; offset++) {\n        unsigned char c = px[offset];\n        switch (state) {\n            case TYPE:\n                rdp->cc.type = c;\n                state++;\n                break;\n            case FLAGS:\n                rdp->cc.flags = c;\n                state++;\n                break;\n            case LENGTH:\n                rdp->cc.len = c;\n                if (rdp->cc.len < 4) {\n                    state = UNKNOWN_PROTOCOL;\n                } else {\n                    rdp->cc.len -= 4;\n                    state++;\n                }\n                break;\n            case RESERVED:\n                switch (rdp->cc.type) {\n                    case 2: /* negotiate success */\n                    case 3: /* negotiate failure */\n                        state = RESULT0;\n                        rdp->cc.result = 0;\n                        break;\n                    default:\n                        state = EXTRA;\n                        break;\n                }\n                break;\n            case RESULT0:\n            case RESULT1:\n            case RESULT2:\n            case RESULT3:\n                if (rdp->cc.len == 0)\n                    state = EXTRA;\n                else {\n                    rdp->cc.len--;\n                    rdp->cc.result = rdp->cc.result>>8 | (c << 24);\n                    state++;\n                    if (state == EXTRA) {\n                        switch (rdp->cc.type) {\n                            case 2:\n                                if (rdp->cc.result & 2)\n                                    banout_append(banout, PROTO_RDP, \" NLA-supported\", AUTO_LEN);\n                                else\n                                    banout_append(banout, PROTO_RDP, \" NLA-unused\", AUTO_LEN);\n                                break;\n                            case 3:\n                                if (rdp->cc.result == 5)\n                                    banout_append(banout, PROTO_RDP, \" NLA-unsupported\", AUTO_LEN);\n                                else\n                                    banout_append(banout, PROTO_RDP, \" failure\", AUTO_LEN);\n                                break;\n                            default:\n                                banout_append(banout, PROTO_RDP, \" unknown\", AUTO_LEN);\n                                break;\n                        }\n                    }\n                }\n                break;\n                \n            case EXTRA:\n                offset = length;\n                break;\n            case UNKNOWN_PROTOCOL:\n                banout_append(banout, PROTO_HEUR, px, length);\n                offset = length;\n                break;\n        }\n    }\n    \n    rdp->cc.state = state;\n    return offset;\n}\n\n/***************************************************************************\n * @param length\n *      The number of bytes left in those received, or the number of bytes\n *      left in the COTP contents, whichever is less.\n * @return the number of bytes processed\n ***************************************************************************/\nstatic size_t\ncotp_parse(struct BannerOutput *banout, struct RDPSTUFF *rdp, const unsigned char *px, size_t length)\n{\n    size_t offset;\n    unsigned state = rdp->cotp.state;\n    enum {\n        LENGTH, PDU_TYPE, DSTREF0, DSTREF1, SRCREF0, SRCREF1,\n        FLAGS, CONTENT, UNKNOWN_PROTOCOL,\n    };\n    for (offset = 0; offset < length; offset++) {\n        unsigned char c = px[offset];\n        switch (state) {\n            case LENGTH:\n                rdp->cotp.len = c;\n                if (rdp->cotp.len < 6) {\n                    state = UNKNOWN_PROTOCOL;\n                } else {\n                    rdp->cotp.len -= 6;\n                    state++;\n                }\n                break;\n            case PDU_TYPE:\n                rdp->cotp.type = c;\n                rdp->cotp.srcref = 0;\n                rdp->cotp.dstref = 0;\n                state++;\n                break;\n            case DSTREF0:\n            case DSTREF1:\n                rdp->cotp.dstref = rdp->cotp.dstref<<8 | c;\n                state++;\n                break;\n            case SRCREF0:\n            case SRCREF1:\n                rdp->cotp.dstref = rdp->cotp.dstref<<8 | c;\n                state++;\n                break;\n            case FLAGS:\n                rdp->cotp.flags = c;\n                rdp->cc.state = 0;\n                state++;\n                break;\n            case CONTENT:\n                switch (rdp->cotp.type) {\n                    case 0xd0: /* connect confirm */\n                    {\n                        size_t length2 = rdp->cotp.len;\n                        size_t bytes_parsed;\n                        \n                        /* In case the TPKT length is more bytes than are in this packet */\n                        if (length2 >= length - offset)\n                            length2 = length - offset;\n                        \n                        bytes_parsed = cc_parse(banout, rdp, px + offset, length2);\n                        \n                        /* Track how many bytes the sub-parsers parsed, remembering\n                         * that when the for-loop increments, it'll increment the offset\n                         * by 1. */\n                        assert(bytes_parsed != 0);\n                        offset += bytes_parsed - 1;\n                        rdp->cotp.len -= (unsigned char)bytes_parsed;\n                        \n                        /* If we have bytes left in the TPKT, then stay in this state,\n                         * otherwise transition to the next TPKT */\n                        if (rdp->cotp.len)\n                            state = CONTENT;\n                        else\n                            state = UNKNOWN_PROTOCOL;\n\n                    }\n                        break;\n                    default:\n                        banout_append(banout, PROTO_RDP, \" COTPPDU=unknown\", AUTO_LEN);\n                        offset = length;\n                        break;\n                }\n                break;\n            case UNKNOWN_PROTOCOL:\n                banout_append(banout, PROTO_HEUR, px, length);\n                offset = length;\n                break;\n        }\n    }\n    \n    rdp->cotp.state = state;\n    return offset;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nrdp_parse(  const struct Banner1 *banner1,\n             void *banner1_private,\n             struct StreamState *pstate,\n             const unsigned char *px, size_t length,\n             struct BannerOutput *banout,\n             struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state & 0xFFFFFF;\n    struct RDPSTUFF *rdp = &pstate->sub.rdp;\n    size_t offset;\n    enum {\n        TPKT_START,\n        TPKT_RESERVED,\n        TPKT_LENGTH0, TPKT_LENGTH1,\n        TPKT_CONTENT,\n        UNKNOWN_PROTOCOL,\n    };\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n    \n    for (offset=0; offset<length; offset++) {\n        unsigned char c = px[offset];\n        switch (state & 0xF) {\n            case TPKT_START:\n                if (c != 3) { /* TPKT version=3 */\n                    state = UNKNOWN_PROTOCOL;\n                    offset--;\n                } else {\n                    rdp->tpkt_length = 0;\n                    rdp->cotp.state = 0;\n                    state = TPKT_RESERVED;\n                }\n                break;\n            case TPKT_RESERVED:\n                state++;\n                break;\n            case TPKT_LENGTH0:\n                rdp->tpkt_length = rdp->tpkt_length;\n                state++;\n                break;\n            case TPKT_LENGTH1:\n                rdp->tpkt_length = rdp->tpkt_length<<8 | c;\n                if (rdp->tpkt_length < 4) {\n                    state = UNKNOWN_PROTOCOL;\n                } else if (rdp->tpkt_length == 4) {\n                    state = 0;\n                } else {\n                    rdp->tpkt_length -= 4;\n                    state++;\n                }\n                break;\n            case TPKT_CONTENT:\n            {\n                size_t length2 = rdp->tpkt_length;\n                size_t bytes_parsed;\n                \n                /* In case the TPKT length is more bytes than are in this packet */\n                if (length2 >= length - offset)\n                    length2 = length - offset;\n                \n                bytes_parsed = cotp_parse(banout, rdp, px + offset, length2);\n                \n                /* Track how many bytes the sub-parsers parsed, remembering\n                 * that when the for-loop increments, it'll increment the offset\n                 * by 1. */\n                assert(bytes_parsed != 0);\n                offset += bytes_parsed - 1;\n                rdp->tpkt_length -= (unsigned short)bytes_parsed;\n                \n                /* If we have bytes left in the TPKT, then stay in this state,\n                 * otherwise transition to the next TPKT */\n                if (rdp->tpkt_length)\n                    state = TPKT_CONTENT;\n                else\n                    state = TPKT_START;\n            }\n                break;\n            case UNKNOWN_PROTOCOL:\n                banout_append(banout, PROTO_HEUR, px, length);\n                offset = length;\n                break;\n            default:\n                break;\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nrdp_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nrdp_selftest_item(const char *input, size_t length, const char *expect)\n{\n    struct Banner1 *banner1;\n    struct StreamState pstate[1];\n    struct BannerOutput banout1[1];\n    struct stack_handle_t more = {0};\n    int x;\n    \n    /*\n     * Initiate a pseudo-environment for the parser\n     */\n    banner1 = banner1_create();\n    banout_init(banout1);\n    memset(&pstate[0], 0, sizeof(pstate[0]));\n    \n    /*\n     * Parse the input payload\n     */\n    rdp_parse(banner1,\n              0,\n              pstate,\n              (const unsigned char *)input,\n              length,\n              banout1,\n              &more\n              );\n    \n    /*\n     * Verify that somewhere in the output is the string\n     * we are looking for\n     */\n    x = banout_is_contains(banout1, PROTO_RDP, expect);\n    if (x == 0)\n        printf(\"RDP parser failure: %s\\n\", expect);\n    \n    banner1_destroy(banner1);\n    banout_release(banout1);\n    \n    return (x?0:1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nrdp_selftest(void)\n{\n    static const char test1[] =\n        \"\\x03\\x00\\x00\\x13\"\n        \"\\x0e\\xd0\\x00\\x00\\x12\\x34\\x00\\x02\\x0f\\x08\\x00\\x02\\x00\\x00\\x00\";\n    static const char test2[] = \"\\x03\\x00\\x00\\x13\"\n        \"\\x0e\\xd0\\x00\\x00\\x12\\x34\\x00\\x03\\x00\\x08\\x00\\x05\\x00\\x00\\x00\";\n\n    int result = 0;\n    \n    result += rdp_selftest_item(test1, sizeof(test1) - 1, \"NLA-sup\");\n    result += rdp_selftest_item(test2, sizeof(test2) - 1, \"NLA-unsup\");\n\n    return result;\n}\n\n    \n/***************************************************************************\n ***************************************************************************/\nstatic const char rdp_hello[] =\n\"\\x03\\x00\\x00\\x2d\"\n\"\\x28\\xe0\\x00\\x00\\x00\\x00\\x00\\x43\\x6f\\x6f\\x6b\\x69\\x65\\x3a\\x20\\x6d\" \\\n\"\\x73\\x74\\x73\\x68\\x61\\x73\\x68\\x3d\"  \"masscan\" \"\\x0d\\x0a\\x01\\x00\" \\\n\"\\x08\\x00\\x03\\x00\\x00\\x00\";\n\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_rdp = {\n    \"rdp\", 3389, rdp_hello, sizeof(rdp_hello)-1, 0,\n    rdp_selftest,\n    rdp_init,\n    rdp_parse,\n};\n"
  },
  {
    "path": "src/proto-tcp-rdp.h",
    "content": "\n#ifndef PROTO_TCP_RDP_H\n#define PROTO_TCP_RDP_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_rdp;\n\n#endif\n"
  },
  {
    "path": "src/proto-tcp-telnet.c",
    "content": "#include \"proto-tcp-telnet.h\"\n#include \"proto-banner1.h\"\n#include \"stack-tcp-api.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"util-malloc.h\"\n#include <ctype.h>\n#include <string.h>\n#include \"util-safefunc.h\"\n\nstruct TelnetOptions {\n    unsigned num;\n    const char *text;\n};\n\n/*\n This is a list of the options during negotiation that we might be interested\n in.\n*/\nstruct TelnetOptions options[] = {\n    { 0, \"binary\"},       /* 0x00     Binary */\n    { 1, \"echo\"},             /* 0x01     Echo */\n    //{ 2, \"recon\"},      /* 0x02     Reconnection  */\n    { 3, \"sga\"},             /* 0x03     Suppress go ahead */\n    //{ 4, \"msgsz\"},      /* 0x04     Approx Message Size Negotiation */\n    { 5, \"status\"},       /* 0x05     Status  */\n    { 6, \"timing-mark\"},  /* 0x06     Timing Mark */\n    /*\n    7     Remote Controlled Trans and Echo                   [107,JBP]\n    8     Output Line Width                                   [40,JBP]\n    9     Output Page Size                                    [41,JBP]\n    10     Output Carriage-Return Disposition                  [28,JBP]\n    11     Output Horizontal Tab Stops                         [32,JBP]\n    12     Output Horizontal Tab Disposition                   [31,JBP]\n    13     Output Formfeed Disposition                         [29,JBP]\n    14     Output Vertical Tabstops                            [34,JBP]\n    15     Output Vertical Tab Disposition                     [33,JBP]\n    16     Output Linefeed Disposition                         [30,JBP]\n    17     Extended ASCII                                     [136,JBP]\n    18     Logout                                              [25,MRC]\n    19     Byte Macro                                          [35,JBP]\n    20     Data Entry Terminal                             [145,38,JBP]*/\n    //{21, \"supdup\"},     /* 0x15    SUPDUP */\n    {22, \"supdupout\"},  /* 0x16    SUPDUP Output */\n    {23, \"sendloc\"},    /* 0x17    Send Location */\n    {24, \"term\"},       /* 0x18    Terminal type */\n/*  25     End of Record                                      [103,JBP]\n    26     TACACS User Identification                           [1,BA4]\n    27     Output Marking                                     [125,SXS]\n    28     Terminal Location Number                            [84,RN6]\n    29     Telnet 3270 Regime                                 [116,JXR]\n    30     X.3 PAD                                            [70,SL70]\n */\n    {31, \"naws\"},       /* 0x1f    Negotiate About Window Size */\n    {32, \"tspeed\"},     /* 0x20    Terminal Speed */\n    {33, \"rflow\"},      /* 0x21  ! Remote Flow Control */\n    {34, \"linemode\"},   /* 0x22  \" Linemode  */\n    {35, \"xloc\"},       /* 0x23  # X Display Location  */\n    {36, \"env\"},        /* 0x24  $ Environment Option                                    [DB14]*/\n    {37, \"auth\"},       /* 0x25  % Authentication Option  */\n    {38, \"encrypt\"},    /* 0x26  & Encryption Option */\n    {39, \"new-env\"},    /* 0x27  ' */\n    \n    {46, \"starttls\"},   /* 0x2e  . STARTTLS */\n/*\n    255     Extended-Options-List                              [109,JBP]\n*/\n    {0,0}\n};\n\n#if 0\nstatic const char *\noption_name_lookup(unsigned optnum)\n{\n    size_t i;\n    for (i=0; options[i].text; i++) {\n        if (options[i].num == optnum)\n            return options[i].text;\n    }\n    return 0;\n}\n#endif\n\nenum {\n    FLAG_WILL=1,\n    FLAG_WONT=2,\n    FLAG_DO=4,\n    FLAG_DONT=8,\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntelnet_parse(  const struct Banner1 *banner1,\n        void *banner1_private,\n        struct StreamState *pstate,\n        const unsigned char *px, size_t length,\n        struct BannerOutput *banout,\n        struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    size_t offset;\n    enum {\n        TELNET_DATA,\n        TELNET_IAC,\n        TELNET_DO,\n        TELNET_DONT,\n        TELNET_WILL,\n        TELNET_WONT,\n        TELNET_SB,\n        TELNET_SB_DATA,\n        TELNET_INVALID,\n    };\n    //static const char *foobar[4] = {\"DO\", \"DONT\", \"WILL\", \"WONT\"};\n    unsigned char nego[256] = {0};\n\n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n\n    for (offset=0; offset<length; offset++) {\n        int c = px[offset];\n        banout_append_char(banout, PROTO_TELNET, c);\n        switch (state) {\n            case 0:\n                if (c == 0xFF)\n                    /* Telnet option code negotiation */\n                    state = TELNET_IAC;\n                break;\n            case TELNET_IAC:\n                switch (c) {\n                    case 240: /* 0xF0 SE - End of subnegotiation parameters */\n                        state = 0;\n                        break;\n                    case 246: /* 0xF6 Are you there? - The function AYT. */\n                        state = 0;\n                        break;\n                    case 241: /* 0xF1 NOP - No operation. */\n                        state = 0;\n                        break;\n                    case 242: /* 0xF2 Data mark */\n                        state = 0;\n                        break;\n                    case 243: /* 0xF3 BRK - NVT character BRK. */\n                        state = 0;\n                        break;\n                    case 244: /* 0xF4 Interrupt process - The function IP. */\n                        state = 0;\n                        break;\n                    case 245: /* 0xF5 Abort - The function AO. */\n                        state = 0;\n                        break;\n                    case 247: /* 0xF7 Erase character -  The function EC. */\n                        state = 0;\n                        break;\n                    case 248: /* 0xF8 Erase line - The function EL. */\n                        state = 0;\n                        break;\n                    case 249: /* 0xF9 Go ahead -  The GA signal. */\n                        state = 0;\n                        break;\n                    case 250: /* 0xFA SB - Start of subnegotiation */\n                        state = TELNET_SB;\n                        break;\n                    case 251: /* 0xFB WILL */\n                        state = TELNET_WILL;\n                        break;\n                    case 252: /* 0xFC WONT */\n                        state = TELNET_WONT;\n                        break;\n                    case 253: /* 0xFD DO */\n                        state = TELNET_DO;\n                        break;\n                    case 254: /* 0xFE DONT */\n                        state = TELNET_DONT;\n                        break;\n                    default:\n                    case 255: /* 0xFF IAC */\n                        /* ??? */\n                        state = TELNET_INVALID;\n                        break;\n                }\n                break;\n            case TELNET_SB_DATA:\n                if (c == 0xFF)\n                    state = TELNET_IAC;\n                break;\n            case TELNET_SB:\n                state = TELNET_SB_DATA;\n                break;\n            case TELNET_DO:\n            case TELNET_DONT:\n            case TELNET_WILL:\n            case TELNET_WONT:\n                switch (state) {\n                    case TELNET_DO:\n                        nego[c] = FLAG_WONT;\n                        break;\n                    case TELNET_DONT:\n                        nego[c] = FLAG_WONT;\n                        break;\n                    case TELNET_WILL:\n                        nego[c] = FLAG_DONT;\n                        break;\n                    case TELNET_WONT:\n                        nego[c] = FLAG_DONT;\n                        break;\n                }\n                state = 0;\n                break;\n            default:\n                offset = (unsigned)length;\n                break;\n        }\n    }\n    \n    {\n#define r_length (256*3*4)\n        unsigned char reply[r_length];\n        size_t r_offset = 0;\n        size_t i;\n        \n        for (i=0; i<256 && r_offset + 3 < r_length; i++) {\n            if (nego[i] & FLAG_WILL) {\n                reply[r_offset++] = 0xFF; /* IAC */\n                reply[r_offset++] = 0xFB; /* WILL */\n                reply[r_offset++] = (unsigned char)i;\n            }\n            if (nego[i] & FLAG_WONT) {\n                reply[r_offset++] = 0xFF; /* IAC */\n                reply[r_offset++] = 0xFC; /* WONT */\n                reply[r_offset++] = (unsigned char)i;\n            }\n            if (nego[i] & FLAG_DO) {\n                reply[r_offset++] = 0xFF; /* IAC */\n                reply[r_offset++] = 0xFD; /* DO */\n                reply[r_offset++] = (unsigned char)i;\n            }\n            if (nego[i] & FLAG_DONT) {\n                reply[r_offset++] = 0xFF; /* IAC */\n                reply[r_offset++] = 0xFE; /* DONT */\n                reply[r_offset++] = (unsigned char)i;\n            }\n        }\n        if (r_offset) {\n            unsigned char *outbuf = MALLOC(r_offset);\n            memcpy(outbuf, reply, r_offset);\n            tcpapi_send(socket, outbuf, r_offset, TCP__copy);\n        }\n    }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\ntelnet_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\ntelnet_selftest_item(const char *input, const char *output)\n{\n    struct Banner1 *banner1;\n    struct StreamState pstate[1];\n    struct BannerOutput banout1[1];\n\n    int x;\n    \n    /*\n     * Initiate a pseudo-environment for the parser\n     */\n    banner1 = banner1_create();\n    banout_init(banout1);\n    memset(&pstate[0], 0, sizeof(pstate[0]));\n    \n    /*\n     * Parse the input payload\n     */\n    telnet_parse(banner1,\n                 0,\n                 pstate,\n                 (const unsigned char *)input,\n                 strlen(input),\n                 banout1,\n                 0\n                 );\n    //fprintf(stderr, \"%.*s\\n\", (int)banout_string_length(banout1, PROTO_TELNET), banout_string(banout1, PROTO_TELNET));\n    /*\n     * Verify that somewhere in the output is the string\n     * we are looking for\n     */\n    x = banout_is_contains(banout1, PROTO_TELNET, output);\n    if (x == 0)\n        printf(\"telnet parser failure: %s\\n\", output);\n    banner1_destroy(banner1);\n    banout_release(banout1);\n    \n    return (x==0)?1:0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\ntelnet_selftest(void)\n{\n    struct {\n        const char *input;\n        const char *output;\n    } tests[] = {\n        {\"\\xff\\xfd\\x1flogin:\", \"login:\"},\n        {\"\\xff\\xfd\\x27\\xff\\xfd\\x18 \", \" \"},\n        {\n            \"\\xff\\xfb\\x25\\xff\\xfd\\x03\\xff\\xfb\\x18\\xff\\xfb\\x1f\\xff\\xfb\\x20\\xff\" \\\n            \"\\xfb\\x21\\xff\\xfb\\x22\\xff\\xfb\\x27\\xff\\xfd\\x05\"\n            \"\\xff\\xfb\\x01\\xff\\xfb\\x03\\xff\\xfd\\x18\\xff\\xfd\\x1f\"\n            \"\\xff\\xfa\\x18\\x01\\xff\\xf0\"\n            \"\\x0d\\x0a\\x55\\x73\\x65\\x72\\x20\\x41\\x63\\x63\\x65\\x73\\x73\\x20\\x56\\x65\" \\\n            \"\\x72\\x69\\x66\\x69\\x63\\x61\\x74\\x69\\x6f\\x6e\\x0d\\x0a\\x0d\\x0a\"\n            ,\n            \"User Access\"\n            \n        },\n        {   \"\\xff\\xfd\\x01\\xff\\xfd\\x1f\\xff\\xfd\\x21\\xff\\xfb\\x01\\xff\\xfb\\x03\\x46\"\n            \"\\x36\\x37\\x30\\x0d\\x0a\\x0d\\x4c\\x6f\\x67\\x69\\x6e\\x3a\\x20\",\n            \"F670\\r\\n\\rLogin:\"\n        },\n        {0,0}\n    };\n    size_t i;\n    \n    for (i=0; tests[i].input; i++) {\n        int err;\n        \n        err = telnet_selftest_item(tests[i].input, tests[i].output);\n        if (err) {\n            fprintf(stderr, \"telnet: selftest fail, item %u\\n\", (unsigned)i);\n            return err;\n        }\n    }\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_telnet = {\n    \"telnet\", 23, \"\\xff\\xf6\", 2, 0,\n    telnet_selftest,\n    telnet_init,\n    telnet_parse,\n};\n"
  },
  {
    "path": "src/proto-tcp-telnet.h",
    "content": "#ifndef PROTO_TELNET_H\n#define PROTO_TELNET_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_telnet;\n\n#endif\n"
  },
  {
    "path": "src/proto-udp.c",
    "content": "#include \"proto-udp.h\"\n#include \"proto-coap.h\"\n#include \"proto-dns.h\"\n#include \"proto-isakmp.h\"\n#include \"proto-netbios.h\"\n#include \"proto-snmp.h\"\n#include \"proto-memcached.h\"\n#include \"proto-ntp.h\"\n#include \"proto-zeroaccess.h\"\n#include \"proto-preprocess.h\"\n#include \"syn-cookie.h\"\n#include \"util-logger.h\"\n#include \"output.h\"\n#include \"masscan-status.h\"\n#include \"unusedparm.h\"\n\n\n/****************************************************************************\n * When the \"--banner\" command-line option is selected, this will\n * will take up to 64 bytes of a response and display it. Other UDP\n * protocol parsers may also default to this function when they detect\n * a response is not the protocol they expect. For example, if a response\n * to port 161 obviously isn't ASN.1 formatted, the SNMP parser will\n * call this function instead. In such cases, the protocool identifier will\n * be [unknown] rather than [snmp].\n ****************************************************************************/\nunsigned\ndefault_udp_parse(struct Output *out, time_t timestamp,\n           const unsigned char *px, unsigned length,\n           struct PreprocessedInfo *parsed,\n           uint64_t entropy)\n{\n    ipaddress ip_them = parsed->src_ip;\n    unsigned port_them = parsed->port_src;\n    \n    UNUSEDPARM(entropy);\n\n\n    if (length > 64)\n        length = 64;\n    \n    output_report_banner(\n                         out, timestamp,\n                         ip_them, 17, port_them,\n                         PROTO_NONE,\n                         parsed->ip_ttl,\n                         px, length);\n\n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nvoid \nhandle_udp(struct Output *out, time_t timestamp,\n        const unsigned char *px, unsigned length, \n        struct PreprocessedInfo *parsed, uint64_t entropy)\n{\n    ipaddress ip_them = parsed->src_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned status = 0;\n\n    /* Report \"open\" status regardless  */\n    output_report_status(\n                             out,\n                             timestamp,\n                             PortStatus_Open,\n                             ip_them,\n                             17, /* ip proto = udp */\n                             port_them,\n                             0,\n                             parsed->ip_ttl,\n                             parsed->mac_src);\n\n\n    switch (port_them) {\n        case 53: /* DNS - Domain Name System (amplifier) */\n            status = handle_dns(out, timestamp, px, length, parsed, entropy);\n            break;\n        case 123: /* NTP - Network Time Protocol (amplifier) */\n            status = ntp_handle_response(out, timestamp, px, length, parsed, entropy);\n            break;\n        case 137: /* NetBIOS (amplifier) */\n            status = handle_nbtstat(out, timestamp, px, length, parsed, entropy);\n            break;\n        case 161: /* SNMP - Simple Network Managment Protocol (amplifier) */\n            status = handle_snmp(out, timestamp, px, length, parsed, entropy);\n            break;\n        case 500: /* ISAKMP - IPsec key negotiation */\n            status = isakmp_parse(out, timestamp,\n                                px + parsed->app_offset, parsed->app_length, parsed, entropy);\n            break;\n        case 5683:\n            status = coap_handle_response(out, timestamp, \n                                px + parsed->app_offset, parsed->app_length, parsed, entropy);\n            break;\n        case 11211: /* memcached (amplifier) */\n            px += parsed->app_offset;\n            length = parsed->app_length;\n            status = memcached_udp_parse(out, timestamp, px, length, parsed, entropy);\n            break;\n        case 16464:\n        case 16465:\n        case 16470:\n        case 16471:\n            status = handle_zeroaccess(out, timestamp, px, length, parsed, entropy);\n            break;\n        default:\n            px += parsed->app_offset;\n            length = parsed->app_length;\n            status = default_udp_parse(out, timestamp, px, length, parsed, entropy);\n            break;\n    }\n\n    \n    /* Report banner if some parser didn't already do so.\n     * Also report raw dump if `--rawudp` specified on the\n     * command-line, even if a protocol above already created a more detailed\n     * banner. */\n    if (status == 0 || out->is_banner_rawudp) {\n            output_report_banner(\n                    out,\n                    timestamp,\n                    ip_them,\n                    17, /* ip proto = udp */\n                    port_them,\n                    PROTO_NONE,\n                    parsed->ip_ttl,\n                    px + parsed->app_offset,\n                    parsed->app_length);\n    }\n}\n"
  },
  {
    "path": "src/proto-udp.h",
    "content": "#ifndef PROTO_UDP_H\n#define PROTO_UDP_H\n#include <time.h>\n#include <stdint.h>\nstruct PreprocessedInfo;\nstruct Output;\n\n/**\n * Parse an incoming UDP response. We parse the basics, then hand it off\n * to a protocol parser (SNMP, NetBIOS, NTP, etc.)\n * @param entropy\n *      The random seed, used in calculating syn-cookies.\n */\nvoid \nhandle_udp(struct Output *out, time_t timestamp,\n    const unsigned char *px, unsigned length,\n    struct PreprocessedInfo *parsed,\n    uint64_t entropy);\n\n/**\n * Default banner for UDP, consisting of the first 64 bytes, when it isn't\n * detected as the appropriate protocol\n */\nunsigned\ndefault_udp_parse(struct Output *out, time_t timestamp,\n                  const unsigned char *px, unsigned length,\n                  struct PreprocessedInfo *parsed,\n                  uint64_t entropy);\n\n\n#endif\n"
  },
  {
    "path": "src/proto-versioning.c",
    "content": "/*\n    SERVICE VERSIONING\n \n */\n#include \"proto-versioning.h\"\n#include \"proto-banner1.h\"\n#include \"smack.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"output.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-ssl.h\"\n#include \"proto-udp.h\"\n#include \"syn-cookie.h\"\n#include \"massip-port.h\"\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nversioning_tcp_parse(\n                    const struct Banner1 *banner1,\n                    void *banner1_private,\n                    struct StreamState *pstate,\n                    const unsigned char *px, size_t length,\n                    struct BannerOutput *banout,\n                    struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n   \n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n    UNUSEDPARM(banout);\n    \n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nversioning_init(struct Banner1 *b)\n{\n    //b->memcached_responses = smack_create(\"memcached-responses\", SMACK_CASE_INSENSITIVE);\n    \n    return b->http_fields;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\n#if 0\nstatic unsigned\nversioning_udp_parse(struct Output *out, time_t timestamp,\n                    const unsigned char *px, unsigned length,\n                    struct PreprocessedInfo *parsed,\n                    uint64_t entropy\n                    )\n{\n    \n    return default_udp_parse(out, timestamp, px, length, parsed, entropy);\n}\n#endif\n\n/****************************************************************************\n ****************************************************************************/\n#if 0\nstatic unsigned\nversioning_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    return 0;\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nversioning_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_versioning = {\n    \"versioning\", 11211, \"stats\\r\\n\", 7, 0,\n    versioning_selftest,\n    versioning_init,\n    versioning_tcp_parse,\n};\n\n"
  },
  {
    "path": "src/proto-versioning.h",
    "content": "#ifndef VERSIONING_H\n#define VERSIONING_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_versioning;\n\n\n#endif\n\n"
  },
  {
    "path": "src/proto-vnc.c",
    "content": "#include \"proto-vnc.h\"\n#include \"proto-banner1.h\"\n#include \"stack-tcp-api.h\"\n#include \"unusedparm.h\"\n#include \"masscan-app.h\"\n#include \"util-safefunc.h\"\n#include \"smack.h\"\n#include <ctype.h>\n\n\nstatic void\nvnc_append_sectype(struct BannerOutput *banout, unsigned sectype)\n{\n    char foo[16];\n\n    /*\n     http://www.iana.org/assignments/rfb/rfb.xml\n    Value \tName \tReference \n    0\tInvalid\t[RFC6143]\n    1\tNone\t[RFC6143]\n    2\tVNC Authentication\t[RFC6143]\n    3-15\tRealVNC\thistoric assignment\n    16\tTight\thistoric assignment\n    17\tUltra\thistoric assignment\n    18\tTLS\thistoric assignment\n    19\tVeNCrypt\thistoric assignment\n    20\tGTK-VNC SASL\thistoric assignment\n    21\tMD5 hash authentication\thistoric assignment\n    22\tColin Dean xvp\thistoric assignment\n    23-29\tUnassigned\t\n    30-35\tApple Inc.\t[Michael_Stein]\n    36-127\tUnassigned\t\n    128-255\tRealVNC\thistoric assignment\n    */\n    switch (sectype) {\n        case 0:\n            banout_append(banout, PROTO_VNC_INFO, \"  invalid\", AUTO_LEN);\n            break;\n        case 1:\n            banout_append(banout, PROTO_VNC_INFO, \"  none\", AUTO_LEN);\n            break;\n        case 2:\n            banout_append(banout, PROTO_VNC_INFO, \"  VNC-chap\", AUTO_LEN);\n            break;\n        case 5:\n            banout_append(banout, PROTO_VNC_INFO, \"  RA2\", AUTO_LEN);\n            break;\n        case 6:\n            banout_append(banout, PROTO_VNC_INFO, \"  RA2ne\", AUTO_LEN);\n            break;\n        case 7:\n            banout_append(banout, PROTO_VNC_INFO, \"  SSPI\", AUTO_LEN);\n            break;\n        case 8:\n            banout_append(banout, PROTO_VNC_INFO, \"  SSPIne\", AUTO_LEN);\n            break;\n        case 16:\n            banout_append(banout, PROTO_VNC_INFO, \"  Tight\", AUTO_LEN);\n            break;\n        case 17:\n            banout_append(banout, PROTO_VNC_INFO, \"  Ultra\", AUTO_LEN);\n            break;\n        case 18:\n            banout_append(banout, PROTO_VNC_INFO, \"  TLS\", AUTO_LEN);\n            break;\n        case 19:\n            banout_append(banout, PROTO_VNC_INFO, \"  VeNCrypt\", AUTO_LEN);\n            break;\n        case 20:\n            banout_append(banout, PROTO_VNC_INFO, \"  GTK-VNC-SASL\", AUTO_LEN);\n            break;\n        case 21:\n            banout_append(banout, PROTO_VNC_INFO, \"  MD5\", AUTO_LEN);\n            break;\n        case 22:\n            banout_append(banout, PROTO_VNC_INFO, \"  Colin-Dean-xvp\", AUTO_LEN);\n            break;\n        case 30:\n            banout_append(banout, PROTO_VNC_INFO, \"  Apple30\", AUTO_LEN);\n            break;\n        case 35:\n            banout_append(banout, PROTO_VNC_INFO, \"  Apple35\", AUTO_LEN);\n            break;\n        default:\n            snprintf(foo, sizeof(foo), \"  %u\", sectype);\n            banout_append(banout, PROTO_VNC_INFO, foo, AUTO_LEN);\n            break;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nvnc_parse(  const struct Banner1 *banner1,\n          void *banner1_private,\n          struct StreamState *pstate,\n          const unsigned char *px, size_t length,\n          struct BannerOutput *banout,\n          struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    unsigned i;\n    char foo[64];\n    \n    enum {\n        RFB3_3_SECURITYTYPES=50,\n        RFB_SECURITYERROR=60,\n        RFB3_7_SECURITYTYPES=100,\n        RFB_SERVERINIT=200,\n        RFB_SECURITYRESULT=300,\n        RFB_DONE=0x7fffffff,\n    };\n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    \n    for (i=0; i<length; i++)\n        switch (state) {\n            case 0: \n                \n            \n            case 1: case 2: case 3: case 4: case 5: case 6:\n            case 7: case 8: case 9:\n                state++;\n                banout_append_char(banout, PROTO_VNC_RFB, px[i]);\n                break;\n            case 10:\n                state++;\n                banout_append_char(banout, PROTO_VNC_RFB, px[i]);\n                break;\n            case 11:\n                banout_append_char(banout, PROTO_VNC_RFB, px[i]);\n                if ('\\n' == px[i]) {\n                    static const char *response[] = {\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.003\\n\",\n                        \"RFB 003.007\\n\",\n                        \"RFB 003.008\\n\",\n                        \"RFB 003.008\\n\",\n                    };\n                    unsigned version = pstate->sub.vnc.version % 10;\n                    \n                    tcpapi_send(socket, response[version], 12, 0);\n\n                    if (version < 7)\n                        /* Version 3.3: the server selects either \"none\" or\n                         * \"vnc challenge/response\" and informs us which one\n                         * to use */\n                        state = RFB3_3_SECURITYTYPES;\n                    else {\n                        /* Version 3.7 onwards: the server will send us a list\n                         * of security types it supports, from which the\n                         * client will select one */\n                        state = RFB3_7_SECURITYTYPES;\n                    }\n                } else {\n                    state = 0xFFFFFFFF;\n                    tcpapi_close(socket);\n                }\n                break;\n            case RFB3_3_SECURITYTYPES:\n            case RFB_SECURITYERROR:\n            case RFB_SECURITYRESULT:\n            case RFB_SERVERINIT+20:\n                pstate->sub.vnc.sectype = px[i];\n                state++;\n                break;\n            case RFB3_3_SECURITYTYPES+1:\n            case RFB3_3_SECURITYTYPES+2:\n            case RFB_SECURITYERROR+1:\n            case RFB_SECURITYERROR+2:\n            case RFB_SECURITYRESULT+1:\n            case RFB_SECURITYRESULT+2:\n            case RFB_SERVERINIT+21:\n            case RFB_SERVERINIT+22:\n                pstate->sub.vnc.sectype <<= 8;\n                pstate->sub.vnc.sectype |= px[i];\n                state++;\n                break;\n            case RFB3_3_SECURITYTYPES+3:\n                pstate->sub.vnc.sectype <<= 8;\n                pstate->sub.vnc.sectype |= px[i];\n                banout_append(banout, PROTO_VNC_INFO, \"Security types:\\n\", AUTO_LEN);\n                vnc_append_sectype(banout, pstate->sub.vnc.sectype);\n                if (pstate->sub.vnc.sectype == 0)\n                    state = RFB_SECURITYERROR;\n                else if (pstate->sub.vnc.sectype == 1) {\n                    /* v3.3 sectype=none\n                     * We move immediately to ClientInit stage */\n                    tcpapi_send(socket, \"\\x01\", 1, 0);\n                    state = RFB_SERVERINIT;\n                } else {\n                    state = RFB_DONE;\n                    tcpapi_close(socket);\n                }\n                break;\n            case RFB_SECURITYRESULT+3:\n                pstate->sub.vnc.sectype <<= 8;\n                pstate->sub.vnc.sectype |= px[i];\n                if (pstate->sub.vnc.sectype == 0) {\n                    /* security OK, move to client init */\n                    tcpapi_send(socket, \"\\x01\", 1, 0);\n                    state = RFB_SERVERINIT;\n                } else {\n                    /* error occurred, so grab error message */\n                    state = RFB_SECURITYERROR;\n                }\n                break;\n            case RFB_SECURITYERROR+3:\n                pstate->sub.vnc.sectype <<= 8;\n                pstate->sub.vnc.sectype = px[i];\n                banout_append(banout, PROTO_VNC_INFO, \"ERROR: \", AUTO_LEN);\n                state++;\n                break;\n            case RFB_SECURITYERROR+4:\n                if (pstate->sub.vnc.sectype == 0) {\n                    state = RFB_DONE;\n                    tcpapi_close(socket);\n                } else {\n                    pstate->sub.vnc.sectype--;\n                    banout_append_char(banout, PROTO_VNC_INFO, px[i]);\n                }\n                break;\n            case RFB3_7_SECURITYTYPES:\n                pstate->sub.vnc.len = px[i];\n                if (pstate->sub.vnc.len == 0)\n                    state = RFB_SECURITYERROR;\n                else {\n                    state++;\n                    banout_append(banout, PROTO_VNC_INFO, \"Security types:\\n\", AUTO_LEN);\n                }\n                break;\n            case RFB3_7_SECURITYTYPES+1:\n                if (pstate->sub.vnc.len != 0) {\n                    pstate->sub.vnc.len--;\n                    vnc_append_sectype(banout, px[i]);\n                }\n                if (pstate->sub.vnc.len == 0) {\n                    banout_append(banout, PROTO_VNC_INFO, \"\\n\", AUTO_LEN);\n                    if (pstate->sub.vnc.version < 7) {\n                        state = RFB_SERVERINIT;\n                        tcpapi_send(socket, \"\\x01\", 1, 0);\n                    } else if (pstate->sub.vnc.version == 7) {\n                        state = RFB_SERVERINIT;\n                        tcpapi_send(socket, \"\\x01\\x01\", 2, 0);\n                    } else {\n                        state = RFB_SECURITYRESULT;\n                        tcpapi_send(socket, \"\\x01\", 1, 0);\n                    }\n                } else {\n                    banout_append(banout, PROTO_VNC_INFO, \"\\n\", AUTO_LEN);\n                }\n                break;\n            \n            \n                \n            case RFB_SERVERINIT:\n                pstate->sub.vnc.width = px[i];\n                state++;\n                break;\n            case RFB_SERVERINIT+1:\n                pstate->sub.vnc.width <<= 8;\n                pstate->sub.vnc.width |= px[i];\n                snprintf(foo, sizeof(foo), \" width=%u\", pstate->sub.vnc.width);\n                banout_append(banout, PROTO_VNC_RFB, foo, AUTO_LEN);\n                state++;\n                break;\n            case RFB_SERVERINIT+2:\n                pstate->sub.vnc.height = px[i];\n                state++;\n                break;\n            case RFB_SERVERINIT+3:\n                pstate->sub.vnc.height <<= 8;\n                pstate->sub.vnc.height |= px[i];\n                snprintf(foo, sizeof(foo), \" height=%u\", pstate->sub.vnc.height);\n                banout_append(banout, PROTO_VNC_RFB, foo, AUTO_LEN);\n                state++;\n                break;\n            \n            case RFB_SERVERINIT+ 4:\n            case RFB_SERVERINIT+ 5:\n            case RFB_SERVERINIT+ 6:\n            case RFB_SERVERINIT+ 7:\n            case RFB_SERVERINIT+ 8:\n            case RFB_SERVERINIT+ 9:\n            case RFB_SERVERINIT+10:\n            case RFB_SERVERINIT+11:\n            case RFB_SERVERINIT+12:\n            case RFB_SERVERINIT+13:\n            case RFB_SERVERINIT+14:\n            case RFB_SERVERINIT+15:\n            case RFB_SERVERINIT+16:\n            case RFB_SERVERINIT+17:\n            case RFB_SERVERINIT+18:\n            case RFB_SERVERINIT+19:\n                state++;\n                break;\n                \n            case RFB_SERVERINIT+23:\n                pstate->sub.vnc.sectype <<= 8;\n                pstate->sub.vnc.sectype |= px[i];\n                state++;\n                if (pstate->sub.vnc.sectype) {\n                    banout_append(banout, PROTO_VNC_INFO, \"Name: \", AUTO_LEN);\n                } else {\n                    state = RFB_DONE;\n                    tcpapi_close(socket);\n                }\n                break;\n                \n            case RFB_SERVERINIT+24:\n                pstate->sub.vnc.sectype--;\n                banout_append_char(banout, PROTO_VNC_INFO, px[i]);\n                if (pstate->sub.vnc.sectype == 0) {\n                    banout_append(banout, PROTO_VNC_INFO, \"\\n\", AUTO_LEN);\n                    state = RFB_DONE;\n                    tcpapi_close(socket);\n                }\n                break;\n\n\n                \n            case RFB_DONE:\n                tcpapi_close(socket);\n                i = (unsigned)length;\n                break;\n            default:\n                i = (unsigned)length;\n                break;\n        }\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nvnc_init(struct Banner1 *banner1)\n{\n    UNUSEDPARM(banner1);\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nvnc_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_vnc = {\n    \"vnc\", 5900, 0, 0, 0,\n    vnc_selftest,\n    vnc_init,\n    vnc_parse,\n};\n"
  },
  {
    "path": "src/proto-vnc.h",
    "content": "#ifndef PROTO_VNC_H\n#define PROTO_VNC_H\n#include \"proto-banner1.h\"\n\nextern const struct ProtocolParserStream banner_vnc;\n\n\n#endif\n"
  },
  {
    "path": "src/proto-x509.c",
    "content": "/*\n    !!!!! BIZZARE CODE ALERT !!!!\n\n    This module decodes X.509 public-key certificates using a\n    \"state-machine parser\". If you are unfamiliar with such parsers,\n    this will look very strange to you.\n\n    The reason for such parsers is scalability. Certificates are so big\n    that they typically cross packet boundaries. This requires some sort\n    of \"reassembly\", which in term requires \"memory allocation\". This\n    is done on a per-connection basis, resulting in running out of memory\n    when dealing with millions of connections.\n \n    With a state-machine parser, we don't need to reassemble certificates, or\n    allocate memory. Instead, we maintain \"state\" between fragments. There\n    is about 60 bytes of state that we must keep.\n \n    If you are a code reviewer, you may care about looking into these common\n    ASN.1 parsing errors. I've marked them with a [NAME] here, you can search\n    these strings in the code to see how they are handled.\n \n    [ASN1-CHILD-OVERFLOW]\n        when the child length field causes it to exceed the length of\n        its parent\n    [ASN1-CHILD-UNDERFLOW]\n        when there is padding after all the child fields within a larger\n        parent field\n    [ASN1-DER-LENGTH]\n        when there are more bits used to encode a length field than necessary,\n        such as using 0x82 0x00 0x12 instead of simply 0x12 as a length\n    [ASN1-DER-NUMBER]\n        When there are more bits than necessary to encode an integer, such\n        as 0x00 0x00 0x00 0x20 rather than just 0x20.\n        Since we don't deal with numbers, we don't check this.\n    [ASN1-DER-SIGNED]\n        issues with signed vs. unsigned numbers, where unsined 4 byte integers\n        need an extra leading zero byte if their high-order bit is set\n        Since we don't deal with numbers, we don't check this.\n    [ASN1-DER-OID]\n        Issues with inserting zeroes into OIDs.\n        We explicitly deal with the opposite issue, allowing zeroes to be\n        inserted. We should probably chainge that, and detect it as a DER\n        error.\n\n    CERTIFICATE FORMAT\n\n    Certificate  ::=  SEQUENCE  {\n        tbsCertificate       TBSCertificate,\n        signatureAlgorithm   AlgorithmIdentifier,\n        signatureValue       BIT STRING  }\nTBSCertificate  ::=  SEQUENCE  {\n        version         [0]  EXPLICIT Version DEFAULT v1,\n        serialNumber         CertificateSerialNumber,\n        signature            AlgorithmIdentifier,\n        issuer               Name,\n        validity             Validity,\n        subject              Name,\n        subjectPublicKeyInfo SubjectPublicKeyInfo,\n        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,\n                             -- If present, version MUST be v2 or v3\n        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,\n                             -- If present, version MUST be v2 or v3\n        extensions      [3]  EXPLICIT Extensions OPTIONAL\n                             -- If present, version MUST be v3\n        }\n   Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }\n   CertificateSerialNumber  ::=  INTEGER\n   Validity ::= SEQUENCE {\n        notBefore      Time,\n        notAfter       Time }\n   Time ::= CHOICE {\n        utcTime        UTCTime,\n        generalTime    GeneralizedTime }\n   UniqueIdentifier  ::=  BIT STRING\n   SubjectPublicKeyInfo  ::=  SEQUENCE  {\n        algorithm            AlgorithmIdentifier,\n        subjectPublicKey     BIT STRING  }\n   Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension\n   Extension  ::=  SEQUENCE  {\n        extnID      OBJECT IDENTIFIER,\n        critical    BOOLEAN DEFAULT FALSE,\n        extnValue   OCTET STRING\n                    -- contains the DER encoding of an ASN.1 value\n                    -- corresponding to the extension type identified\n                    -- by extnID\n        }\n */\n#include \"proto-x509.h\"\n#include \"proto-spnego.h\"\n#include \"proto-banout.h\"\n#include \"masscan-app.h\"\n#include \"smack.h\"\n#include \"util-logger.h\"\n#include <assert.h>\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <time.h>\n\n/****************************************************************************\n * The X.509 certificates mark certain extensible fields with ASN.1\n * object-identifiers. Instead of copying these out of the certificate,\n * we match them using an Aho-Corasick DFA parser. These object-ids are\n * below. At program startup, the main() function must call x509_init()\n * to build the Aho-Corasick state-machine, which the main state-machine\n * will use to parse these object-ids.\n ****************************************************************************/\nstatic struct SMACK *global_mib;\n\n\n/****************************************************************************\n * Currently, the only field we extract is the \"Common Name\".\n ****************************************************************************/\nenum {\n    Subject_Unknown,\n    Subject_Common,\n};\n\n/****************************************************************************\n * See \"global_mib\" above.\n ****************************************************************************/\nstatic struct ObjectIdentifer {\n    const char *oid;\n    const char *name;\n    int id;\n} mib[] = {\n    {\"43.1006.51.341332\", \"selftest\"}, /* for regression test */\n    {\"43\", \"iso.org\"},\n    {\"43.6\", \"dod\"},\n    {\"43.6.1\", \"inet\"},\n    {\"43.6.1.2\", \"mgmt\"},\n    {\"43.6.1.2.1\", \"mib2\"},\n    {\"43.6.1.2.1.\", \"sys\"},\n    {\"43.6.1.2.1.1.1\", \"sysDescr\"},\n    {\"43.6.1.2.1.1.2\", \"sysObjectID\"},\n    {\"43.6.1.2.1.1.3\", \"sysUpTime\"},\n    {\"43.6.1.2.1.1.4\", \"sysContact\"},\n    {\"43.6.1.2.1.1.5\", \"sysName\"},\n    {\"43.6.1.2.1.1.6\", \"sysLocation\"},\n    {\"43.6.1.2.1.1.7\", \"sysServices\"},\n    {\"43.6.1.4\", \"priv\"},\n    {\"43.6.1.4.1\", \"enterprise\"},\n    {\"43.6.1.4.1.2001\", \"okidata\"},\n    {\"42\", \"1.2\"},\n    {\"42.840\", \"1.2.840\"},\n    {\"42.840.52\", \"0\"},\n    {\"42.840.113549\", \"1.2.840.113549\"},\n    {\"42.840.113549.1\", \"1.2.840.113549.1\"},\n    {\"42.840.113549.1.1\", \"1.2.840.113549.1.1\"},\n    {\"42.840.113549.1.1.4\", \"md5WithRSAEncryption\"},\n    {\"42.840.113549.1.1.5\", \"shaWithRSAEncryption\"},\n    {\"42.840.113549.1.1.11\", \"sha256WithRSAEncryption\"},\n    {\"42.840.113549.1.9\", \"1.2.840.113549.1.9\"},\n    {\"42.840.113549.1.9.1\", \"email\"},\n    {\"85\", \"2.5\"},\n    {\"85.4\", \"2.5.4\"},\n    {\"85.4.3\", \"common\", Subject_Common},\n    {\"85.4.5\", \"serial\"},\n    {\"85.4.6\", \"country\"},\n    {\"85.4.7\", \"locality\"},\n    {\"85.4.8\", \"state\"},\n    {\"85.4.10\", \"organization\"},\n    {\"85.4.11\", \"unit\"},\n    {\"85.4.13\", \"description\"},\n    {\"85.29\", \"2.5.29\"},\n    {\"85.29.17\", \"altname\", Subject_Common},\n    {0,0},\n};\n\n\n\n/****************************************************************************\n * Used in converting text object-ids into their binary form.\n * @see convert_oid()\n ****************************************************************************/\nstatic unsigned\nid_prefix_count(unsigned id)\n{\n#define TWO_BYTE       ((unsigned long long)(~0)<<7)\n#define THREE_BYTE     ((unsigned long long)(~0)<<14)\n#define FOUR_BYTE      ((unsigned long long)(~0)<<21)\n#define FIVE_BYTE      ((unsigned long long)(~0)<<28)\n    \n    if (id & FIVE_BYTE)\n        return 4;\n    if (id & FOUR_BYTE)\n        return 3;\n    if (id & THREE_BYTE)\n        return 2;\n    if (id & TWO_BYTE)\n        return 1;\n    return 0;\n}\n\n\n/****************************************************************************\n * Convert text OID to binary. This is used when building a Aho-Corasick\n * table for matching object-identifiers: we type the object-ids in the \n * source-code in human-readable format, but must compile them to binary\n * pattenrs to match within the X.509 certificates.\n * @see x509_init()\n ****************************************************************************/\nstatic unsigned\nconvert_oid(unsigned char *dst, size_t sizeof_dst, const char *src)\n{\n    size_t offset = 0;\n\n    /* 'for all text characters' */\n    while (*src) {\n        const char *next_src;\n        unsigned id;\n        unsigned count;\n        unsigned i;\n\n        /* skip to next number */\n        while (*src == '.')\n            src++;\n\n        /* parse integer */\n        id = (unsigned)strtoul(src, (char**)&next_src, 0);\n        if (src == next_src)\n            break; /* invalid integer, programming error */\n        else\n            src = next_src;\n\n        /* find length of the integer */\n        count = id_prefix_count(id);\n        \n        /* add binary integer to pattern */\n        for (i=count; i>0; i--) {\n            if (offset < sizeof_dst)\n                dst[offset++] = ((id>>(7*i)) & 0x7F) | 0x80;\n        }\n        if (offset < sizeof_dst)\n            dst[offset++] = (id & 0x7F);\n    }\n\n    return (unsigned)offset;\n}\n\n\n/****************************************************************************\n * We need to initialize the OID/MIB parser\n * This should be called on program startup.\n * This is so that we can show short names, like \"sysName\", rather than\n * the entire OID.\n ****************************************************************************/\nvoid\nx509_init(void)\n{\n    unsigned i;\n\n    /* We use an Aho-Corasick pattern matcher for this. Not necessarily\n     * the most efficient, but also not bad */\n    global_mib = smack_create(\"ssl-oids\", 0);\n\n    /* We just go through the table of OIDs and add them all one by\n     * one */\n    for (i=0; mib[i].name; i++) {\n        unsigned char pattern[256];\n        unsigned len;\n\n        len = convert_oid(pattern, sizeof(pattern), mib[i].oid);\n\n        smack_add_pattern(  global_mib,\n                            pattern,\n                            len,\n                            i,\n                            SMACK_ANCHOR_BEGIN | SMACK_SNMP_HACK\n                            );\n    }\n\n    /* Now that we've added all the OIDs, we need to compile this into\n     * an efficientdata structure. Later, when we get packets, we'll\n     * use this for searching */\n    smack_compile(global_mib);\n\n}\n\n\n\n/****************************************************************************\n * Since ASN.1 contains nested structures, each with their own length field,\n * we must maintain a small stack as we parse down the structure. Every time\n * we enter a field, this function \"pushes\" the ASN.1 \"length\" field onto\n * the stack. When we are done parsing the current field, we'll pop the\n * length back off the stack, and subtract from it the number of bytes\n * we've parsed.\n *\n * @param x\n *      The X.509 certificate parsing structure.\n * @param next_state\n *      Tells the parser the next field we'll be parsing after this field\n *      at the same level of the nested ASN.1 structure, or nothing if\n *      there are no more fields.\n * @param remaining\n *      The 'length' field. We call it 'remaining' instead of 'length'\n *      because as more bytes arrive, we decrement the length field until\n *      it reaches zero. Thus, at any point of time, it doesn't represent\n *      the length of the current ASN.1 field, but the remaining-length.\n ****************************************************************************/\nstatic void\nASN1_push(struct CertDecode *x, unsigned next_state, uint64_t remaining)\n{\n    static const size_t STACK_DEPTH \n                            = sizeof(x->stack.remainings)\n                                / sizeof(x->stack.remainings[0]);\n    \n    /* X.509 certificates can't be more than 64k in size. Therefore, to\n     * conserve space (as we must store the state for millions of TCP\n     * connections), we use the smallest number possible for the length,\n     * meaning a 16-bit 'unsigned short'. If the certificate has a larger\n     * length field, we need to reject it. */\n    if ((remaining >> 16) != 0) {\n        fprintf(stderr, \"ASN.1 length field too big\\n\");\n        x->state = 0xFFFFFFFF;\n        return;\n    }\n    \n    /* Make sure we don't recurse too deep, past the end of the stack. Note\n     * that this condition checks a PRGRAMMING error not an INPUT error,\n     * because we skip over fields we don't care about, and don't recurse\n     * into them even if they have many levels deep */\n    if (x->stack.depth >= STACK_DEPTH) {\n        fprintf(stderr, \"ASN.1 recursion too deep\\n\");\n        x->state = 0xFFFFFFFF;\n        return;\n    }\n    \n    /* Subtract this length from it's parent.\n     * \n     *[ASN1-CHILD-OVERFLOW]\n     * It is here that we deal with the classic ASN.1 parsing problem in\n     * which the child object claims a bigger length than its parent \n     * object. We could shrink the length field to fit, then continue\n     * parsing, but instead we choose to instead cease parsing the certificate.\n     * Note that this property is recursive: I don't need to redo the check\n     * all the way up the stack, because I know my parent's length does\n     * not exceed my grandparent's length.\n     * I know certificates exist that trigger this error -- I need to track\n     * them down and figure out why.\n     */\n    if (x->stack.depth) {\n        if (remaining > x->stack.remainings[0]) {\n            LOG(1, \"ASN.1 inner object bigger than container [%u, %u]\\n\",\n                next_state, x->stack.states[0]);\n            x->state = 0xFFFFFFFF;\n            return;\n        }\n        x->stack.remainings[0] = (unsigned short)\n                                        (x->stack.remainings[0] - remaining);\n    }\n    \n    /* Since 'remainings[0]' always represents the top of the stack, we\n     * move all the bytes down one during the push operation. I suppose this\n     * is more expensive than doing it the other way, where something\n     * like \"raminings[stack.depth]\" represents the top of the stack,\n     * meaning no moves are necessary, but I prefer the cleanliness of the\n     * code using [0] index instead */\n    memmove(    &x->stack.remainings[1], \n                &x->stack.remainings[0], \n                x->stack.depth * sizeof(x->stack.remainings[0]));\n    x->stack.remainings[0] = (unsigned short)remaining;\n    \n    memmove(    &x->stack.states[1], \n                &x->stack.states[0], \n                x->stack.depth * sizeof(x->stack.states[0]));\n    x->stack.states[0] = (unsigned char)next_state;\n    \n    /* increment the count by one and exit */\n    x->stack.depth++;\n}\n\n\n/****************************************************************************\n * This is the corresponding 'pop' operation to the ASN1_push() operation.\n * See that function for more details.\n * @see ASN1_push()\n ****************************************************************************/\nstatic unsigned\nASN1_pop(struct CertDecode *x)\n{\n    unsigned next_state;\n    next_state = x->stack.states[0];\n    x->stack.depth--;\n    memmove(    &x->stack.remainings[0], \n                &x->stack.remainings[1], \n                x->stack.depth * sizeof(x->stack.remainings[0]));\n    memmove(    &x->stack.states[0], \n                &x->stack.states[1], \n                x->stack.depth * sizeof(x->stack.states[0]));\n    return next_state;\n}\n\n\n/****************************************************************************\n * Called to skip the remainder of the ASN.1 field\n * @return\n *      1 if we've reached the end of the field\n *      0 otherwise\n ****************************************************************************/\nstatic unsigned\nASN1_skip(struct CertDecode *x, unsigned *i, size_t length)\n{\n    unsigned len;\n\n    if (x->stack.remainings[0] == 0)\n        return 1;\n    \n    /* bytes remaining in packet */\n    len = (unsigned)(length - (*i) - 1);\n\n    /* bytes remaining in field */\n    if (len > x->stack.remainings[0])\n        len = x->stack.remainings[0];\n\n    /* increment 'offset' by this length */\n    (*i) += len;\n\n    /* decrement 'remaining' by this length */\n    x->stack.remainings[0] = (unsigned short)(x->stack.remainings[0] - len);\n\n    return x->stack.remainings[0] == 0;\n    \n}\n\n\n/****************************************************************************\n * The X.509 ASN.1 parser is done with a state-machine, where each byte of\n * the certificate has a corresponding state value. This massive enum\n * is for all those states.\n * DANGER NOTE NOTE NOTE NOTE DANGER NOTE DANGER NOTE\n *  These states are in a specific order. We'll just do 'state++' sometimes\n *  to go the next state. Therefore, you can't change the order without\n *  changing the code.\n ****************************************************************************/\nenum X509state {\n    TAG0,           TAG0_LEN,       TAG0_LENLEN,\n    TAG1,           TAG1_LEN,       TAG1_LENLEN,\n    VERSION0_TAG,   VERSION0_LEN,   VERSION0_LENLEN,\n    VERSION1_TAG,   VERSION1_LEN,   VERSION1_LENLEN,    VERSION_CONTENTS,\n    SERIAL_TAG,     SERIAL_LEN,     SERIAL_LENLEN,      SERIAL_CONTENTS,\n    SIG0_TAG,       SIG0_LEN,       SIG0_LENLEN,\n    SIG1_TAG,       SIG1_LEN,       SIG1_LENLEN,        SIG1_CONTENTS0,SIG1_CONTENTS1,\n    ISSUER0_TAG,    ISSUER0_LEN,    ISSUER0_LENLEN,\n    ISSUER1_TAG,    ISSUER1_LEN,    ISSUER1_LENLEN,\n    ISSUER2_TAG,    ISSUER2_LEN,    ISSUER2_LENLEN,\n    ISSUERID_TAG,   ISSUERID_LEN,   ISSUERID_LENLEN,    ISSUERID_CONTENTS0, ISSUERID_CONTENTS1,\n    ISSUERNAME_TAG, ISSUERNAME_LEN, ISSUERNAME_LENLEN,  ISSUERNAME_CONTENTS,\n    VALIDITY_TAG,   VALIDITY_LEN,   VALIDITY_LENLEN,\n    VNBEFORE_TAG,   VNBEFORE_LEN,   VNBEFORE_LENLEN,    VNBEFORE_CONTENTS,\n    VNAFTER_TAG,    VNAFTER_LEN,    VNAFTER_LENLEN,     VNAFTER_CONTENTS,\n    SUBJECT0_TAG,   SUBJECT0_LEN,   SUBJECT0_LENLEN,\n    SUBJECT1_TAG,   SUBJECT1_LEN,   SUBJECT1_LENLEN,\n    SUBJECT2_TAG,   SUBJECT2_LEN,   SUBJECT2_LENLEN,\n    SUBJECTID_TAG,  SUBJECTID_LEN,  SUBJECTID_LENLEN,   SUBJECTID_CONTENTS0, SUBJECTID_CONTENTS1,\n    SUBJECTNAME_TAG,SUBJECTNAME_LEN,SUBJECTNAME_LENLEN, SUBJECTNAME_CONTENTS,\n    PUBKEY0_TAG,    PUBKEY0_LEN,    PUBKEY0_LENLEN,     PUBKEY0_CONTENTS,\n    EXTENSIONS_A_TAG, EXTENSIONS_A_LEN, EXTENSIONS_A_LENLEN,\n    EXTENSIONS_S_TAG, EXTENSIONS_S_LEN, EXTENSIONS_S_LENLEN,\n    EXTENSION_TAG,    EXTENSION_LEN,    EXTENSION_LENLEN,\n    EXTENSION_ID_TAG, EXTENSION_ID_LEN, EXTENSION_ID_LENLEN, EXTENSION_ID_CONTENTS0, EXTENSION_ID_CONTENTS1,\n    EXTVALUE_TAG,   EXTVALUE_LEN,   EXTVALUE_LENLEN, \n    EXTVALUE2_TAG,  EXTVALUE2_LEN,  EXTVALUE2_LENLEN, \n    EXTVALUE3_TAG,  EXTVALUE3_LEN,  EXTVALUE3_LENLEN, \n        EXT_DNSNAME_TAG, EXT_DNSNAME_LEN, EXT_DNSNAME_LENLEN, EXT_DNSNAME_CONTENTS,\n    ALGOID0_TAG,    ALGOID0_LEN,    ALGOID0_LENLEN,\n    ALGOID1_TAG,    ALGOID1_LEN,    ALGOID1_LENLEN,     ALGOID1_CONTENTS0, ALGOID1_CONTENTS1,\n    ENC_TAG,        ENC_LEN,        ENC_LENLEN,         ENC_CONTENTS,\n    \n    \n    PADDING=254,\n    ERROR=0xFFFFFFFF,\n};\n\n/****************************************************************************\n * My parser was kludged together in a couple of hours, and has this bug \n * where I really don't know the next state like I should. Therefore, this\n * function patches it, converting the next state I think I want to the\n * next state that I really do want.\n * TODO: fix the parser so that this function is no longer necessary.\n ****************************************************************************/\nstatic unsigned\nkludge_next(unsigned state)\n{\n    switch (state) {\n    case TAG1_LEN:\n        return ALGOID0_TAG;\n    case ALGOID0_LEN:\n        return ENC_TAG;\n    case SERIAL_LEN:\n        return SIG0_TAG;\n    case VERSION0_LEN:\n        return SERIAL_TAG;\n    case SIG0_LEN:\n        return ISSUER0_TAG;\n    case ISSUER0_LEN:\n        return VALIDITY_TAG;\n    case SUBJECT0_LEN:\n        return PUBKEY0_TAG;\n    case ISSUER1_LEN:\n        return ISSUER1_TAG;\n    case SUBJECT1_LEN:\n        return SUBJECT1_TAG;\n    case ISSUERID_LEN:\n        return ISSUERNAME_TAG;\n    case EXTENSION_LEN:\n        return EXTENSION_TAG;\n    case EXTENSION_ID_LEN:\n        return EXTVALUE_TAG;\n    case EXT_DNSNAME_LEN:\n        return EXTVALUE3_TAG;\n    case SUBJECTID_LEN:\n        return SUBJECTNAME_TAG;\n    case VALIDITY_LEN:\n        return SUBJECT0_TAG;\n    case VNBEFORE_LEN:\n        return VNAFTER_TAG;\n    case PUBKEY0_LEN:\n        return EXTENSIONS_A_TAG;\n    default:\n        return PADDING;\n    }\n}\n\n\n\n\n/****************************************************************************\n * This is a parser for X.509 certificates. It uses \"state-machine\"\n * technology, so that it accepts an in-order sequence of fragments. The\n * entire x.509 certificate does not need to be in memory -- you can start\n * calling this function when you have only the first fragment.\n *\n * It works by enumerating every possible state. In other words, every\n * byte of an X.509 certificate has an enumerated 'state' variable. As \n * each byte arrives from the stream, we parse it, and change to the next\n * state. When we run out of input, we exit the function, saving the\n * current state-variable. When the next fragment arrives, we resume\n * at the same state where we left off.\n ****************************************************************************/\nvoid\nx509_decode(struct CertDecode *x, \n            const unsigned char *px, size_t length, \n            struct BannerOutput *banout)\n{\n    unsigned i;\n    enum X509state state = x->state;\n\n\n#define GOTO_ERROR(state, i, length) (state)=0xFFFFFFFF;(i)=(length);continue\n\n    /* 'for all bytes in the current fragment ...'\n     *   'process that byte, causing a state-transition ' \n     */\n    for (i=0; i<length; i++) {\n        \n        \n        /*\n         * If we've reached the end of the current field, then we need to \n         * pop up the stack and resume parsing the parent field. Since we\n         * reach the end of several levels simultaneously, we may need to\n         * pop several levels at once\n         */\n        while (x->stack.remainings[0] == 0) {\n            if (x->stack.depth == 0)\n                return;\n            state = ASN1_pop(x);\n        }\n        \n        /*\n         * Decrement the current 'remaining' length field.\n         */\n        x->stack.remainings[0]--;\n\n        /*\n         * Jump to the current current state\n         */\n        switch (state) {\n        case ENC_TAG:\n            if (px[i] != 0x03) {\n                state = ERROR;\n                continue;\n            }\n            state++;\n            break;\n        case ISSUERNAME_TAG:\n            if (px[i] != 0x13 && px[i] != 0x0c) {\n                state++;\n                continue;\n            }\n            if (x->is_capture_issuer) {\n                banout_append(banout, PROTO_SSL3, \" issuer[\", AUTO_LEN);\n            }\n            state++;\n            break;\n        case SUBJECTNAME_TAG:\n            if (px[i] != 0x13 && px[i] != 0x0c) {\n                state++;\n                continue;\n            }\n            if (x->is_capture_subject) {\n                banout_append(banout, PROTO_SSL3, \" subject[\", AUTO_LEN);\n            }\n            state++;\n            break;\n        case ISSUER1_TAG:\n        case SUBJECT1_TAG:\n            x->subject.type = 0;\n            if (px[i] != 0x31) {\n                state++;\n                continue;\n            }\n            state++;\n            break;\n        case VNBEFORE_TAG:\n        case VNAFTER_TAG:\n            if (px[i] != 0x17) {\n                state++;\n                continue;\n            }\n            state++;\n            break;\n        case VERSION0_TAG:\n            if (px[i] != 0xa0) {\n                state = ERROR;\n                continue;\n            }\n            state++;\n            break;\n        case SIG1_TAG:\n        case ISSUERID_TAG:\n        case SUBJECTID_TAG:\n        case EXTENSION_ID_TAG:\n        case ALGOID1_TAG:\n            if (px[i] != 0x06) {\n                state = ERROR;\n                continue;\n            }\n            state++;\n            break;\n        case VERSION1_TAG:\n        case SERIAL_TAG:\n            if (px[i] != 0x02) {\n                state = ERROR;\n                continue;\n            }\n            x->u.num = 0;\n            state++;\n            break;\n        case ISSUERNAME_CONTENTS:\n            if (x->is_capture_issuer) {\n                banout_append(banout, PROTO_SSL3, px+i, 1);\n                if (x->stack.remainings[0] == 0)\n                    banout_append(banout, PROTO_SSL3, \"]\", 1);\n            }\n            break;\n        case SUBJECTNAME_CONTENTS:\n        case EXT_DNSNAME_CONTENTS:\n            if (x->is_capture_subject) {\n                banout_append(banout, PROTO_SSL3, px+i, 1);\n                if (x->stack.remainings[0] == 0)\n                    banout_append(banout, PROTO_SSL3, \"]\", 1);\n            } else if (x->subject.type == Subject_Common)\n                banout_append(banout, PROTO_SSL3, px+i, 1);\n            break;\n        case VERSION_CONTENTS:\n            x->u.num <<= 8;\n            x->u.num |= px[i];\n            if (x->stack.remainings[0] == 0)\n                state = PADDING;\n            break;\n        case ISSUERID_CONTENTS0:\n        case SUBJECTID_CONTENTS0:\n        case EXTENSION_ID_CONTENTS0:\n        case ALGOID1_CONTENTS0:\n        case SIG1_CONTENTS0:\n            memset(&x->u.oid, 0, sizeof(x->u.oid));\n            state++;\n        case ISSUERID_CONTENTS1:\n        case SUBJECTID_CONTENTS1:\n        case EXTENSION_ID_CONTENTS1:\n        case ALGOID1_CONTENTS1:\n        case SIG1_CONTENTS1:\n            {\n                size_t id;\n                unsigned offset = i;\n                unsigned oid_state = x->u.oid.state;\n                \n\n                /* First, look it up */\n                id = smack_search_next( global_mib,\n                                        &oid_state,\n                                        px,\n                                        &offset,\n                                        offset + 1);\n                x->u.oid.state = (unsigned short)oid_state;\n\n                /* Do the multibyte numbers */\n                x->u.oid.num <<= 7;\n                x->u.oid.num |= px[i] & 0x7F;\n\n                if (px[i] & 0x80) {\n                    /* This is a multibyte number, don't do anything at\n                     * this stage */\n                    ;\n                } else {\n                    if (id == SMACK_NOT_FOUND) {\n                        if (x->u.oid.last_id) {\n                            //printf(\"%s\", mib[x->u.oid.last_id].name);\n                            x->u.oid.last_id = 0;\n                        }\n                        //printf(\".%u\", (unsigned)x->u.oid.num);\n                    } else {\n                        //printf(\"%s [%u]\\n\", mib[x->u.oid.last_id].name, mib[x->u.oid.last_id].id);\n                        x->subject.type = mib[id].id;\n                        if (x->subject.type == Subject_Common \n                                            && state == SUBJECTID_CONTENTS1) {\n                            if (x->count <= 1) {\n                                /* only handle first certificate in the chain */\n                                banout_append(banout, PROTO_SSL3, \", \", 2);\n                            } else {\n                                x->subject.type = 0;\n                            }\n\n                            \n                        }\n                        //if (x->subject.type == Subject_Common \n                        //                    && state == EXTENSION_ID_CONTENTS1)\n                        //    ; //banout_append(banout, PROTO_SSL3, \", \", 2);\n                        x->u.oid.last_id = (unsigned char)id;\n                    }\n                    x->u.oid.num = 0;\n                }\n                if (x->stack.remainings[0] == 0) {\n                    if (x->u.oid.last_id) {\n                        //printf(\"%s\", mib[x->u.oid.last_id].name);\n                        x->u.oid.last_id = 0;\n                    }\n                    state = PADDING;\n                    //printf(\"\\n\");\n                }\n            }\n            break;\n        case SERIAL_CONTENTS:\n            x->stack.states[0] = (unsigned char)(state+1);\n            x->u.num <<= 8;\n            x->u.num |= px[i];\n            if (x->stack.remainings[0] == 0)\n                state = PADDING;\n            break;\n\n        case TAG0:\n        case TAG1:\n        case SIG0_TAG:\n        case ISSUER0_TAG:\n        case ISSUER2_TAG:\n        case SUBJECT0_TAG:\n        case SUBJECT2_TAG:\n        case VALIDITY_TAG:\n        case PUBKEY0_TAG:\n        case EXTENSIONS_S_TAG:\n        case EXTENSION_TAG:\n        case EXTVALUE2_TAG:\n        case ALGOID0_TAG:\n            if (px[i] != 0x30) {\n                state = ERROR;\n                continue;\n            }\n            state++;\n            break;\n        case EXTENSIONS_A_TAG:\n            if (px[i] != 0xa3) {\n                state = ERROR;\n                continue;\n            }\n            state++;\n            break;\n\n        /*\n        GeneralName ::= CHOICE {\n            otherName                       [0]     OtherName,\n            rfc822Name                      [1]     IA5String,\n            dNSName                         [2]     IA5String,\n            x400Address                     [3]     ORAddress,\n            directoryName                   [4]     Name,\n            ediPartyName                    [5]     EDIPartyName,\n            uniformResourceIdentifier       [6]     IA5String,\n            iPAddress                       [7]     OCTET STRING,\n            registeredID                    [8]     OBJECT IDENTIFIER }\n        */\n      \n        case EXTVALUE3_TAG:\n            if (x->subject.type == Subject_Common) {\n                switch (px[i]) {\n                case 0x82: /* dNSName */\n                    banout_append(banout, PROTO_SSL3, \", \", 2);\n                    state = EXT_DNSNAME_LEN;\n                    break;\n                default:\n                    state = PADDING;\n                    break;\n                }\n            } else {\n                state = PADDING;\n            }\n            break;\n\n        case EXTVALUE_TAG:\n            /* can be anything */\n            switch (px[i]) {\n            default:\n            case 2:\n                state = PADDING;\n                break;\n            case 4:\n                state++;\n                break;\n            }\n            break;\n\n\n        case TAG0_LEN:\n        case TAG1_LEN:\n        case VERSION0_LEN:\n        case VERSION1_LEN:\n        case SERIAL_LEN:\n        case SIG0_LEN:\n        case SIG1_LEN:\n        case ISSUER0_LEN:\n        case ISSUER1_LEN:\n        case ISSUER2_LEN:\n        case ISSUERID_LEN:\n        case ISSUERNAME_LEN:\n        case VALIDITY_LEN:\n        case VNBEFORE_LEN:\n        case VNAFTER_LEN:\n        case SUBJECT0_LEN:\n        case SUBJECT1_LEN:\n        case SUBJECT2_LEN:\n        case SUBJECTID_LEN:\n        case SUBJECTNAME_LEN:\n        case EXTENSIONS_A_LEN:\n        case EXTENSIONS_S_LEN:\n        case EXTENSION_LEN:\n        case EXTENSION_ID_LEN:\n        case EXTVALUE_LEN:\n        case EXTVALUE2_LEN:\n        case EXTVALUE3_LEN:\n        case EXT_DNSNAME_LEN:\n        case PUBKEY0_LEN:\n        case ALGOID0_LEN:\n        case ALGOID1_LEN:\n        case ENC_LEN:\n            /* We do the same processing for all the various length fields.\n             * There are three possible length fields:\n             * 0x7F - for lengths 127 and below\n             * 0x81 XX - for lengths 127 to 255\n             * 0x82 XX XX - for length 256 to 65535\n             * This state processes the first byte, and if it's an extended\n             * field, switches to the corresponding xxx_LENLEN state\n             */\n            if (px[i] & 0x80) {\n                x->u.tag.length_of_length = px[i]&0x7F;\n                x->u.tag.remaining = 0;\n                state++;\n                break;\n            } else {\n                x->u.tag.remaining = px[i];\n                ASN1_push(x, kludge_next(state), x->u.tag.remaining);\n                state += 2;\n                memset(&x->u, 0, sizeof(x->u));\n                break;\n            }\n\n        case TAG0_LENLEN:\n        case TAG1_LENLEN:\n        case VERSION0_LENLEN:\n        case VERSION1_LENLEN:\n        case SERIAL_LENLEN:\n        case SIG0_LENLEN:\n        case SIG1_LENLEN:\n        case ISSUER0_LENLEN:\n        case ISSUER1_LENLEN:\n        case ISSUER2_LENLEN:\n        case ISSUERID_LENLEN:\n        case ISSUERNAME_LENLEN:\n        case VALIDITY_LENLEN:\n        case VNBEFORE_LENLEN:\n        case VNAFTER_LENLEN:\n        case SUBJECT0_LENLEN:\n        case SUBJECT1_LENLEN:\n        case SUBJECT2_LENLEN:\n        case SUBJECTID_LENLEN:\n        case SUBJECTNAME_LENLEN:\n        case PUBKEY0_LENLEN:\n        case EXTENSIONS_A_LENLEN:\n        case EXTENSIONS_S_LENLEN:\n        case EXTENSION_LENLEN:\n        case EXTENSION_ID_LENLEN:\n        case EXTVALUE_LENLEN:\n        case EXTVALUE2_LENLEN:\n        case EXTVALUE3_LENLEN:\n        case EXT_DNSNAME_LENLEN:\n        case ALGOID0_LENLEN:\n        case ALGOID1_LENLEN:\n        case ENC_LENLEN:\n            /* We process all multibyte lengths the same way in this\n             * state.\n             */\n                \n            /* [ASN1-DER-LENGTH]\n             * Check for strict DER compliance, which says that there should\n             * be no leading zero bytes */\n            if (x->u.tag.remaining == 0 && px[i] == 0)\n                x->is_der_failure = 1;\n            \n            /* parse this byte */\n            x->u.tag.remaining = (x->u.tag.remaining)<<8 | px[i];\n            x->u.tag.length_of_length--;\n                \n            /* If we aren't finished yet, loop around and grab the next */\n            if (x->u.tag.length_of_length)\n                continue;\n                \n            /* [ASN1-DER-LENGTH]\n             * Check for strict DER compliance, which says that for lengths\n             * 127 and below, we need only 1 byte to encode it, not many */\n            if (x->u.tag.remaining < 128)\n                x->is_der_failure = 1;\n\n            /*\n             * We have finished parsing the tag-length fields, and are now\n             * ready to parse the 'value'. Push the current state on the \n             * stack, then descend into the child field.\n             */\n            ASN1_push(x, kludge_next(state-1), x->u.tag.remaining);\n            state++;\n            memset(&x->u, 0, sizeof(x->u));\n            break;\n\n        case VNBEFORE_CONTENTS:\n        case VNAFTER_CONTENTS:\n            switch (x->u.timestamp.state) {\n            case 0:\n                x->u.timestamp.year = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 1:\n                x->u.timestamp.year += (px[i] - '0');\n                x->u.timestamp.state++;\n                break;\n            case 2:\n                x->u.timestamp.month = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 3:\n                x->u.timestamp.month += (px[i] - '0');\n                x->u.timestamp.state++;\n                break;\n            case 4:\n                x->u.timestamp.day = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 5:\n                x->u.timestamp.day += (px[i] - '0');\n                x->u.timestamp.state++;\n                break;\n            case 6:\n                x->u.timestamp.hour = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 7:\n                x->u.timestamp.hour += (px[i] - '0');\n                x->u.timestamp.state++;\n                break;\n            case 8:\n                x->u.timestamp.minute = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 9:\n                x->u.timestamp.minute += (px[i] - '0');\n                x->u.timestamp.state++;\n                break;\n            case 10:\n                x->u.timestamp.second = (px[i] - '0') * 10;\n                x->u.timestamp.state++;\n                break;\n            case 11:\n                x->u.timestamp.second += (px[i] - '0');\n                x->u.timestamp.state++;\n                {\n                    struct tm tm;\n                    time_t now;\n\n                    tm.tm_hour = x->u.timestamp.hour;\n                    tm.tm_isdst = 0;\n                    tm.tm_mday = x->u.timestamp.day;\n                    tm.tm_min = x->u.timestamp.minute;\n                    tm.tm_mon = x->u.timestamp.month - 1;\n                    tm.tm_sec = x->u.timestamp.second;\n                    tm.tm_wday = 0;\n                    tm.tm_yday = 0;\n                    tm.tm_year = 100 + x->u.timestamp.year;\n\n\n                    now = mktime(&tm);\n\n                    //tm = *localtime(&now);\n                    if (state == VNBEFORE_CONTENTS)\n                        x->prev = now;\n                    else {\n                        ;//printf(\"validity:%u-days\\n\", (now-x->prev)/(24*60*60));\n                    }\n                }\n                break;\n            case 12:\n                break;\n            }\n            break;\n\n        case PADDING:\n            /* [ASN1-CHILD-UNDERFLOW]\n             * This state is reached when we've parsed everything inside an\n             * ASN.1 field, yet there are still bytes left to parse. There\n             * are TWO reasons why we reach this state.\n             *  #1  there is a strict DER encoding problem, and we ought\n             *      to flag the error\n             *  #2  are parser is incomplete; we simply haven't added code\n             *      for all fields yet, and therefore treat them as padding\n             * We should flag the DER failure, but we can't, because the\n             * existence of unparsed fields mean we'll falsely trigger DER\n             * errors all the time.\n             *\n             * Note that due to the state-machine style parsing, we don't do\n             * anything in this field. This problem naturally takes care of\n             * itself.\n             */\n            break;\n\n        case PUBKEY0_CONTENTS:\n        case ENC_CONTENTS:\n            ASN1_skip(x, &i, length);\n            break;\n\n        case ERROR:\n        default:\n            ASN1_skip(x, &i, length);\n            break;\n        }\n    }\n\n    /*\n     * Save the state variable and exit\n     */\n    if (x->state != 0xFFFFFFFF)\n        x->state = state;\n}\nvoid\nspnego_decode(struct SpnegoDecode *spnego,\n            const unsigned char *px, size_t length,\n            struct BannerOutput *banout)\n{\n    struct CertDecode *x = spnego->x509;\n    unsigned i;\n    unsigned state = x->state;\n    \n    enum {\n        /*NegotiationToken ::= CHOICE {\n            negTokenInit    [0] NegTokenInit,\n            negTokenResp    [1] NegTokenResp\n        }*/\n        NegotiationToken_tag, len, lenlen,\n        \n        NegTokenInit_tag,\n        NegTokenInit_choice,\n        NegTokenResp_tag,\n        NegTokenResp_choice,\n        mechType_tag,\n        \n        negState_tag,\n        supportedMech_tag,\n        responseToken_tag,\n        mechListMIC_tag,\n        \n        mechTypes_tag,\n        reqFlags_tag,\n        mechToken_tag,\n        \n        mechToken_content,\n        responseToken_content,\n        mechToken_content2,\n        responseToken_content2,\n\n        UnknownContents,\n        \n        \n    };\n    \n#define GOTO_ERROR(state, i, length) (state)=0xFFFFFFFF;(i)=(length);continue\n    \n    /* 'for all bytes in the current fragment ...'\n     *   'process that byte, causing a state-transition '\n     */\n    for (i=0; i<length; i++) {\n        \n        \n        /*\n         * If we've reached the end of the current field, then we need to\n         * pop up the stack and resume parsing the parent field. Since we\n         * reach the end of several levels simultaneously, we may need to\n         * pop several levels at once\n         */\n        while (x->stack.remainings[0] == 0) {\n            if (x->stack.depth == 0)\n                return;\n            state = ASN1_pop(x);\n        }\n        \n        /*\n         * Decrement the current 'remaining' length field.\n         */\n        x->stack.remainings[0]--;\n        \n        /*\n         * Jump to the current current state\n         */\n        switch (state) {\n            case NegotiationToken_tag:\n                x->brother_state = UnknownContents;\n                switch (px[i]) {\n                    case 0xa0:\n                        x->child_state = NegTokenInit_tag;\n                        break;\n                    case 0xa1:\n                        x->child_state = NegTokenResp_tag;\n                        break;\n                    case 0x60:\n                        x->child_state = mechType_tag;\n                        break;\n                    default:\n                        x->child_state = UnknownContents;\n                        break;\n                }\n                state = len;\n                break;\n                \n            case NegTokenResp_choice:\n                /*\n                 NegTokenResp ::= SEQUENCE {\n                 negState       [0] ENUMERATED {\n                    accept-completed    (0),\n                    accept-incomplete   (1),\n                    reject              (2),\n                    request-mic         (3)\n                    }                                 OPTIONAL,\n                 -- REQUIRED in the first reply from the target\n                 supportedMech   [1] MechType      OPTIONAL,\n                 -- present only in the first reply from the target\n                 responseToken   [2] OCTET STRING  OPTIONAL,\n                 mechListMIC     [3] OCTET STRING  OPTIONAL,\n                 ...\n                 }*/\n                x->brother_state = NegTokenResp_choice;\n                switch (px[i]) {\n                    case 0xa0:\n                        x->child_state = negState_tag;\n                        break;\n                    case 0xa1:\n                        x->child_state = supportedMech_tag;\n                        break;\n                    case 0xa2:\n                        x->child_state = responseToken_tag;\n                        break;\n                    case 0xa3:\n                        x->child_state = mechListMIC_tag;\n                        break;\n                    default:\n                        x->child_state = UnknownContents;\n                        break;\n                }\n                state = len;\n                break;\n                \n            case NegTokenResp_tag:\n                if (px[i] != 0x30) {\n                    x->brother_state = UnknownContents;\n                    x->child_state = UnknownContents;\n                } else {\n                    x->brother_state = UnknownContents;\n                    x->child_state = NegTokenResp_choice;\n                }\n                state = len;\n                break;\n                \n            case NegTokenInit_choice:\n                /*\n                 NegTokenInit ::= SEQUENCE {\n                 mechTypes       [0] MechTypeList,\n                 reqFlags        [1] ContextFlags  OPTIONAL,\n                 -- inherited from RFC 2478 for backward compatibility,\n                 -- RECOMMENDED to be left out\n                 mechToken       [2] OCTET STRING  OPTIONAL,\n                 mechListMIC     [3] OCTET STRING  OPTIONAL,\n                 ...\n                 }\n                 }*/\n                x->brother_state = NegTokenInit_choice;\n                switch (px[i]) {\n                    case 0xa0:\n                        x->child_state = mechTypes_tag;\n                        break;\n                    case 0xa1:\n                        x->child_state = reqFlags_tag;\n                        break;\n                    case 0xa2:\n                        x->child_state = mechToken_tag;\n                        break;\n                    case 0xa3:\n                        x->child_state = mechListMIC_tag;\n                        break;\n                    default:\n                        x->child_state = UnknownContents;\n                        break;\n                }\n                state = len;\n                break;\n            \n            case NegTokenInit_tag:\n                if (px[i] != 0x30) {\n                    x->brother_state = UnknownContents;\n                    x->child_state = UnknownContents;\n                } else {\n                    x->brother_state = UnknownContents;\n                    x->child_state = NegTokenInit_choice;\n                }\n                state = len;\n                break;\n\n            case mechType_tag:\n                if (px[i] == 0x06) {\n                    x->brother_state = NegotiationToken_tag;\n                    x->child_state = UnknownContents;\n                } else {\n                    x->brother_state = NegotiationToken_tag;\n                    x->child_state = UnknownContents;\n                }\n                state = len;\n                break;\n            \n            case negState_tag:\n            case supportedMech_tag:\n            case mechListMIC_tag:\n            case mechTypes_tag:\n            case reqFlags_tag:\n                x->brother_state = UnknownContents;\n                x->child_state = UnknownContents;\n                state = len;\n                break;\n            \n            case responseToken_tag:\n                x->brother_state = UnknownContents;\n                x->child_state = responseToken_content;\n                state = len;\n                break;\n                \n            case mechToken_tag:\n                x->brother_state = UnknownContents;\n                x->child_state = mechToken_content;\n                state = len;\n                break;\n            \n            case mechToken_content:\n            case mechToken_content2:\n                break;\n             \n                /************************************************************************\n                 ************************************************************************\n                 ************************************************************************\n                 ************************************************************************\n                 ************************************************************************\n                 ************************************************************************\n                 ************************************************************************\n                 */\n            case responseToken_content:\n                ntlmssp_decode_init(&spnego->ntlmssp, x->stack.remainings[0] + 1);\n                state = responseToken_content2;\n                /* fall through */\n            case responseToken_content2:\n            {\n                size_t new_max = length - i;\n                \n                if (new_max > x->stack.remainings[0] + 1U)\n                    new_max = x->stack.remainings[0] + 1;\n                \n                ntlmssp_decode(&spnego->ntlmssp, px+i, new_max, banout);\n                \n                x->stack.remainings[0] -= (unsigned short)(new_max - 1);\n                if (x->stack.remainings[0] == 0) {\n                    if (spnego->ntlmssp.buf)\n                        free(spnego->ntlmssp.buf);\n                }\n            }\n                break;\n                \n            case len:\n                /* We do the same processing for all the various length fields.\n                 * There are three possible length fields:\n                 * 0x7F - for lengths 127 and below\n                 * 0x81 XX - for lengths 127 to 255\n                 * 0x82 XX XX - for length 256 to 65535\n                 * This state processes the first byte, and if it's an extended\n                 * field, switches to the corresponding xxx_LENLEN state\n                 */\n                if (px[i] & 0x80) {\n                    x->u.tag.length_of_length = px[i]&0x7F;\n                    x->u.tag.remaining = 0;\n                    state = lenlen;\n                    break;\n                } else {\n                    x->u.tag.remaining = px[i];\n                    ASN1_push(x, x->brother_state, x->u.tag.remaining);\n                    state = x->child_state;\n                    memset(&x->u, 0, sizeof(x->u));\n                    break;\n                }\n                break;\n            case lenlen:\n                /* We process all multibyte lengths the same way in this\n                 * state.\n                 */\n                \n                /* [ASN1-DER-LENGTH]\n                 * Check for strict DER compliance, which says that there should\n                 * be no leading zero bytes */\n                if (x->u.tag.remaining == 0 && px[i] == 0)\n                    x->is_der_failure = 1;\n                \n                /* parse this byte */\n                x->u.tag.remaining = (x->u.tag.remaining)<<8 | px[i];\n                x->u.tag.length_of_length--;\n                \n                /* If we aren't finished yet, loop around and grab the next */\n                if (x->u.tag.length_of_length)\n                    continue;\n                \n                /* [ASN1-DER-LENGTH]\n                 * Check for strict DER compliance, which says that for lengths\n                 * 127 and below, we need only 1 byte to encode it, not many */\n                if (x->u.tag.remaining < 128)\n                    x->is_der_failure = 1;\n                \n                /*\n                 * We have finished parsing the tag-length fields, and are now\n                 * ready to parse the 'value'. Push the current state on the\n                 * stack, then descend into the child field.\n                 */\n                ASN1_push(x, x->brother_state, x->u.tag.remaining);\n                state = x->child_state;\n                memset(&x->u, 0, sizeof(x->u));\n                break;\n            default:\n                ;\n        }\n    }\n}\n\n\n/****************************************************************************\n * This function must be called to set the initial state.\n * @param length\n *      The size of the certificate. This is parsed from the SSL/TLS field.\n *      We know that if we exceed this number of bytes, then an overflow has\n *      occurred.\n ****************************************************************************/\nvoid\nx509_decode_init(struct CertDecode *x, size_t length)\n{\n    memset(x, 0, sizeof(*x));\n    ASN1_push(x, 0xFFFFFFFF, length);\n}\nvoid\nspnego_decode_init(struct SpnegoDecode *x, size_t length)\n{\n    memset(x, 0, sizeof(*x));\n    \n    ASN1_push(x->x509, 0xFFFFFFFF, length);\n}\n\n\n"
  },
  {
    "path": "src/proto-x509.h",
    "content": "#ifndef PROTO_X509_H\n#define PROTO_X509_H\n#include <time.h>\n#include <stdint.h>\nstruct BannerOutput;\n\n/****************************************************************************\n * This stores the \"state\" of the X.509 certificate parser\n ****************************************************************************/\nstruct CertDecode {\n    /** This is the master 'state' variable in the massive switch statement */\n    unsigned state;\n    \n    /** ASN.1 nests fields within fields. Therefore, as we parse down into\n     * the structure, we push the parent length/state info on the stack,\n     * and then when we exit a field, we pop it back off the stack.\n     * NOTE: since space is at a premium, we have separate arrays\n     * for the length/state, instead of an array of objects containing\n     * both. */\n    struct {\n        unsigned short remainings[9];\n        unsigned char states[9];\n        unsigned char depth;\n    } stack;\n    \n    /** We catch some DER non-canonical encoding errors, but not all. Someday\n     * we'll improve the parser to catch all of them */\n    unsigned is_der_failure:1;\n    unsigned is_capture_subject:1;\n    unsigned is_capture_issuer:1;\n\n\n\n    /** Number of certificates we've processed */\n    unsigned char count;\n    \n    /** ??? */\n    time_t prev;\n    \n    /** This parser was originally written just to grab the \"subect name\"\n     * of a certificate, i.e. \"*.google.com\" for Google's certificates.\n     * However, there are many different types of subject names. Each\n     * subject name comes in two parts, the first part being an OID\n     * saying the type of subject, then the subject itself. We need to stash\n     * the result of parsing the OID somewhere before parsing the subject\n     */\n    struct {\n        unsigned type;\n    } subject;\n\n    unsigned child_state;\n    unsigned brother_state;\n    \n    /**\n     * This union contains the intermediate/partial values as we are decoding\n     * them. Since a packet may end with a field only partially decoded,\n     * we have to stash that value someplace before the next bytes arive\n     * that complete the decoding\n     */\n    union {\n        struct {\n            unsigned short remaining;\n            unsigned char length_of_length;\n        } tag;\n        uint64_t num;\n        unsigned next_state;\n        struct {\n            uint64_t num;\n            unsigned short state;\n            unsigned char last_id;\n        } oid;\n        struct {\n            unsigned state;\n            unsigned year:7;\n            unsigned month:4;\n            unsigned day:5;\n            unsigned hour:5;\n            unsigned minute:6;\n            unsigned second:6;\n        } timestamp;\n    } u;\n};\n\n/**\n * Called before parsing the first fragment of an X.509 certificate\n */\nvoid\nx509_decode_init(struct CertDecode *x, size_t length);\n\n/**\n * Called to decode the next fragment of an X.509 certificate.\n * Must call x509_decode_init() first.\n */\nvoid\nx509_decode(struct CertDecode *x, \n            const unsigned char *px, size_t length, \n            struct BannerOutput *banout);\n\n/**\n * Called at program startup to initialize internal parsing structures\n * for certificates. Once called, it creates static read-only thread-safe\n * structures\n */\nvoid\nx509_init(void);\n\n#endif\n\n"
  },
  {
    "path": "src/proto-zeroaccess.c",
    "content": "/*\n    ZeroAccess botnet\n\n    This scans for the P2P ports on the \"ZeroAccess\" botnet.\n\n    http://www.symantec.com/connect/blogs/grappling-zeroaccess-botnet\n    http://www.sophos.com/en-us/medialibrary/PDFs/technical%20papers/Sophos_ZeroAccess_Botnet.pdf\n\n*/\n#include \"proto-zeroaccess.h\"\n#include \"proto-preprocess.h\"\n#include \"output.h\"\n#include \"proto-banner1.h\"\n#include \"util-safefunc.h\"\n#include <stdio.h>\n#include <string.h>\n\n\n/***************************************************************************\n * I hand-crafted this \"getL\" request packet. It has the ID set to \"mass\",\n * then has been CRCed and encrypted.\n ***************************************************************************/\nconst unsigned char zeroaccess_getL[] = {\n    0x46, 0x5d, 0x49, 0x9e, 0x28, 0x94, 0x8d, 0xab,\n    0xc9, 0xc0, 0xd1, 0x99, 0xe0, 0xf2, 0xc2, 0x5e,\n};\n\n/***************************************************************************\n * Table for the standard CRC32 algorithm used everywhere.\n ***************************************************************************/\nstatic const unsigned crc32_table[256] = {\n    0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,\n    0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,\n    0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,\n    0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,\n    0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,\n    0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,\n    0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,\n    0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,\n    0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,\n    0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,\n    0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,\n    0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,\n    0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,\n    0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,\n    0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,\n    0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,\n    0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,\n    0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,\n    0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,\n    0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,\n    0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,\n    0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,\n    0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,\n    0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,\n    0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,\n    0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,\n    0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,\n    0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,\n    0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,\n    0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,\n    0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,\n    0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,\n    0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,\n    0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,\n    0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,\n    0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,\n    0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,\n    0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,\n    0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,\n    0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,\n    0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,\n    0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,\n    0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,\n    0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,\n    0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,\n    0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,\n    0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,\n    0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,\n    0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,\n    0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,\n    0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,\n    0x2d02ef8dL\n};\n\n\n/***************************************************************************\n * Standard CRC32 calculation.\n ***************************************************************************/\nstatic unsigned\ncrc_calc(const unsigned char *px, unsigned length)\n{\n    unsigned i;\n    unsigned crc;\n\n    crc = (unsigned)~0;\n    for (i = 0; i < length; i++) {\n        crc = crc32_table[(crc ^ px[i]) & 0xff] ^ (crc >> 8);\n    }\n    crc = ~crc;\n\n    return crc;\n}\n\n/***************************************************************************\n * Zero-Access encrypts packets with a simple encryption of starting\n * with the key \"ftp2\" XORed with each 4-byte word, then rotated left\n * by one bit after every XOR. Because it's XOR, encryption is also\n * decryption.\n ***************************************************************************/\nstatic unsigned\nzadecrypt(const unsigned char *src, size_t src_len, unsigned char *dst, size_t dst_len)\n{\n    unsigned key;\n    size_t i;\n\n    key = 'f'<<24 | 't'<<16 | 'p'<<8 | '2'<<0;\n\n    for (i=0; i<dst_len && i<src_len; i+=4) {\n        dst[i+0] = src[i+0] ^ (unsigned char)(key>> 0);\n        dst[i+1] = src[i+1] ^ (unsigned char)(key>> 8);\n        dst[i+2] = src[i+2] ^ (unsigned char)(key>>16);\n        dst[i+3] = src[i+3] ^ (unsigned char)(key>>24);\n\n        key = key<<1 | key>>31;\n    }\n\n    return (unsigned)src_len;\n}\n\n/***************************************************************************\n * Generate a \"getL\" request. I put this in the code, but I don't really\n * use it, because I ran it once to generate the hard-coded packet at\n * the top of this file.\n ***************************************************************************/\nstatic unsigned\ngenerate_getL(unsigned char *out_buf, size_t out_buf_len, unsigned xrand)\n{\n    unsigned char buf[16];\n    unsigned crc;\n\n    if (out_buf_len < 16)\n        return 0;\n    memset(buf, 0, 16);\n\n    memcpy(&buf[4], \"Lteg\", 4); /* \"getL\" */\n\n    buf[12] = (unsigned char)(xrand>>24);\n    buf[13] = (unsigned char)(xrand>>16);\n    buf[14] = (unsigned char)(xrand>> 8);\n    buf[15] = (unsigned char)(xrand>> 0);\n\n    crc = crc_calc(buf, 16);\n    buf[3] = (unsigned char)(crc>>24);\n    buf[2] = (unsigned char)(crc>>16);\n    buf[1] = (unsigned char)(crc>> 8);\n    buf[0] = (unsigned char)(crc>> 0);\n\n    zadecrypt(buf, 16, out_buf, 16);\n\n    return 16;\n}\n\n/***************************************************************************\n * Handles the response packet from our \"getL\" request, which is known\n * as a \"retL\". This contains a list of IP addresses of infected machines.\n * therefore, we want to parse the response and grab those IP addresses\n * so that we know about even more infected machines.\n ***************************************************************************/\nunsigned\nhandle_zeroaccess(  struct Output *out, time_t timestamp,\n                    const unsigned char *px, unsigned length,\n                    struct PreprocessedInfo *parsed,\n                    uint64_t entropy)\n{\n    unsigned char buf[2048];\n    unsigned len;\n    ipaddress ip_them = parsed->src_ip;\n    unsigned port_them = parsed->port_src;\n    unsigned port_me = parsed->port_dst;\n    struct BannerOutput banout[1];\n\n    banout->length = 0;\n    banout->next = 0;\n    banout->protocol = PROTO_UDP_ZEROACCESS;\n\n    UNUSEDPARM(entropy);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n    UNUSEDPARM(port_me);\n\n    /* Decrypt the response packet */\n    buf[0] = '\\0';\n    len = zadecrypt(px + parsed->app_offset,\n                    parsed->app_length,\n                    buf, sizeof(buf));\n    if (len != parsed->app_length) {\n        return 0; /* is not zeroaccess botnet */\n    }\n\n    /* Validate the CRC */\n    {\n        unsigned old_crc;\n        unsigned new_crc;\n\n        old_crc = buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;\n        memset(buf, 0, 4);\n        new_crc = crc_calc(buf, len);\n        if (old_crc != new_crc)\n            return 0; /* not zeroaccess, or corrupted */\n    }\n\n    /* Make sure this is a \"retl\" packet */\n    if (len < 16 || memcmp(buf+4, \"Lter\", 4) != 0)\n        return 0; /* not \"retL\" */\n\n    /* List IP addresses */\n    banout_append(banout, PROTO_UDP_ZEROACCESS, \"ZeroAccess:\", 11);\n\n    {\n        unsigned i;\n        unsigned ip_count = buf[12] | buf[13]<<8 | buf[14]<<16 | buf[15]<<24;\n        if (ip_count > 256)\n            return 0; /* too many addresses */\n        if (16 + ip_count*8 > len)\n            return 0; /* packet overflow */\n        for (i=0; i<ip_count; i++) {\n            unsigned ip_found;\n            char szaddr[20];\n\n            ip_found =  buf[16 + i*8 + 0] <<24\n                      | buf[16 + i*8 + 1] <<16\n                      | buf[16 + i*8 + 2] << 8\n                      | buf[16 + i*8 + 3] << 0;\n\n            snprintf(szaddr, sizeof(szaddr), \"%u.%u.%u.%u \",\n                    (unsigned char)(ip_found>>24),\n                    (unsigned char)(ip_found>>16),\n                    (unsigned char)(ip_found>> 8),\n                    (unsigned char)(ip_found>> 0)\n                    );\n            banout_append(banout, PROTO_UDP_ZEROACCESS, szaddr, strlen(szaddr));\n        }\n    }\n\n\n\n\n\n    output_report_banner(\n            out, timestamp,\n            ip_them, 17, port_them,\n            PROTO_UDP_ZEROACCESS,\n            parsed->ip_ttl,\n            banout_string(banout, PROTO_UDP_ZEROACCESS),\n            banout_string_length(banout, PROTO_UDP_ZEROACCESS));\n\n    return 0; /* is zeroaccess botnet*/\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic const unsigned char sample[] = {\n    0xda, 0xbe, 0x6e, 0xce,\n    0x28, 0x94, 0x8d, 0xab,\n    0xc9, 0xc0, 0xd1, 0x99,\n    0xec, 0xd6, 0xa9, 0x3c\n};\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nzeroaccess_selftest(void)\n{\n    unsigned char buf[128];\n    unsigned old_crc;\n    unsigned new_crc;\n\n    zadecrypt(sample, sizeof(sample), buf, sizeof(buf));\n\n    old_crc = buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;\n\n\n    memset(buf, 0, 4);\n\n    new_crc = crc_calc(buf, sizeof(sample));\n\n    generate_getL(buf, sizeof(buf), 0x7f570a0f);\n\n    if (memcmp(buf, sample, 16) != 0)\n        return 1; /*fail*/\n    if (old_crc != new_crc)\n        return 1; /*fail*/\n\n    /*generate_getL(buf, sizeof(buf), *(unsigned*)\"mass\");\n    {\n        unsigned i;\n        for (i=0; i<16; i++)\n            printf(\"0x%02x, \", buf[i]);\n    }*/\n\n    return 0; /*success*/\n}\n\n\n"
  },
  {
    "path": "src/proto-zeroaccess.h",
    "content": "#ifndef PROTO_ZEROACCESS_H\n#define PROTO_ZEROACCESS_H\n#include <time.h>\n#include <stdint.h>\nstruct PreprocessedInfo;\nstruct Output;\n\nunsigned\nhandle_zeroaccess(  struct Output *out, time_t timestamp,\n                    const unsigned char *px, unsigned length,\n                    struct PreprocessedInfo *parsed,\n                    uint64_t entropy);\n\nextern const unsigned char zeroaccess_getL[];\n#define zeroaccess_getL_length 16\n\n\n/**\n * Regression test this module.\n * @return\n *      0 on success, a positive integer otherwise.\n */\nint\nzeroaccess_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/rawsock-adapter.h",
    "content": "#ifndef RAWSOCK_ADAPTER_H\n#define RAWSOCK_ADAPTER_H\n\nstruct Adapter\n{\n    struct pcap *pcap;\n    struct pcap_send_queue *sendq;\n    struct __pfring *ring;\n    unsigned is_packet_trace:1; /* is --packet-trace option set? */\n    unsigned is_vlan:1;\n    unsigned vlan_id;\n    double pt_start;\n    int link_type;\n};\n\n\n/**\n * Retrieve the datalink type of the adapter\n *\n *  1 = Ethernet\n * 12 = Raw IP (no datalink)\n */\nint\nstack_if_datalink(struct Adapter *adapter);\n\n#endif\n"
  },
  {
    "path": "src/rawsock-getif.c",
    "content": "/*\n    get default route (gateway) IPv4 address of the named network\n    interface/adapter (like \"eth0\").\n\n    This works on both Linux and windows.\n*/\n#include \"rawsock.h\"\n#include \"util-safefunc.h\"\n#include \"util-malloc.h\"\n#include \"util-logger.h\"\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun__)\n#include <unistd.h>\n#include <sys/socket.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <net/if_dl.h>\n#include <ctype.h>\n\n#define ROUNDUP2(a, n)       ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))\n\n#if defined(__APPLE__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#elif defined(__NetBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(uint64_t))\n#elif defined(__FreeBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#elif defined(__OpenBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#else\n# error unknown platform\n#endif\n\n\nstatic struct sockaddr *\nget_rt_address(struct rt_msghdr *rtm, int desired)\n{\n    int i;\n    int bitmask = rtm->rtm_addrs;\n    struct sockaddr *sa = (struct sockaddr *)(rtm + 1);\n\n    for (i = 0; i < RTAX_MAX; i++) {\n        if (bitmask & (1 << i)) {\n            if ((1<<i) == desired)\n                return sa;\n            sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);\n        } else\n            ;\n    }\n    return NULL;\n\n}\n\nint\nrawsock_get_default_interface(char *ifname, size_t sizeof_ifname)\n{\n    int fd;\n    int seq = (int)time(0);\n    ssize_t err;\n    struct rt_msghdr *rtm;\n    size_t sizeof_buffer;\n\n\n    /*\n     * Requests/responses from the kernel are done with an \"rt_msghdr\"\n     * structure followed by an array of \"sockaddr\" structures.\n     */\n    sizeof_buffer = sizeof(*rtm) + 512;\n    rtm = calloc(1, sizeof_buffer);\n\n    /*\n     * Create a socket for querying the kernel\n     */\n    fd = socket(AF_ROUTE, SOCK_RAW, 0);\n    if (fd < 0) {\n        perror(\"socket(PF_ROUTE)\");\n        free(rtm);\n        return errno;\n    }\n    LOG(2, \"[+] getif: got socket handle\\n\");\n\n    /* Needs a timeout. Sometimes it'll hang indefinitely waiting for a \n     * response that will never arrive */\n    {\n        struct timeval timeout;      \n        timeout.tv_sec = 1;\n        timeout.tv_usec = 0;\n\n        err = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));\n        if (err < 0)\n            LOG(0, \"[-] SO_RCVTIMEO: %d %s\\n\", errno, strerror(errno));\n\n        err = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));\n        if (err < 0)\n            LOG(0, \"[-] SO_SNDTIMEO: %d %s\\n\", errno, strerror(errno));\n   }\n\n    /*\n     * Format and send request to kernel\n     */\n    rtm->rtm_msglen = sizeof(*rtm) + sizeof(struct sockaddr_in);\n    rtm->rtm_version = RTM_VERSION;\n    rtm->rtm_flags = RTF_UP;\n    rtm->rtm_type = RTM_GET;\n    rtm->rtm_addrs = RTA_DST | RTA_IFP;\n    rtm->rtm_pid = getpid();\n    rtm->rtm_seq = seq;\n\n    /*\n     * Create an empty address of 0.0.0.0\n     */\n    {\n        struct sockaddr_in *sin;\n        sin = (struct sockaddr_in *)(rtm + 1);\n        sin->sin_len = sizeof(*sin);\n        sin->sin_family = AF_INET;\n        sin->sin_addr.s_addr = 0;\n    }\n\n\n\n    err = write(fd, (char *)rtm, rtm->rtm_msglen);\n    if (err <= 0) {\n        LOG(0, \"[-] getif: write(): returned %d %s\\n\", errno, strerror(errno));\n        goto fail;\n    }\n\n    /*\n     * Read responses until we find one that belongs to us\n     */\n    for (;;) {\n        err = read(fd, (char *)rtm, sizeof_buffer);\n        if (err <= 0) {\n            LOG(0, \"[-] getif: read(): returned %d %s\\n\", errno, strerror(errno));\n            goto fail;\n        }\n\n        LOG(2, \"[+] getif: got response, len=%d\\n\", err);\n\n        if (rtm->rtm_seq != seq) {\n            printf(\"seq: %u %u\\n\", rtm->rtm_seq, seq);\n            continue;\n        }\n        if (rtm->rtm_pid != getpid()) {\n            printf(\"pid: %u %u\\n\", rtm->rtm_pid, getpid());\n            continue;\n        }\n        break;\n    }\n    close(fd);\n    fd = -1;\n\n    /*\n     * Parse our data\n     */\n    {\n        struct sockaddr_dl *sdl;\n\n        sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP);\n        if (sdl) {\n            size_t len = sdl->sdl_nlen;\n            if (len > sizeof_ifname-1)\n                len = sizeof_ifname-1;\n            memcpy(ifname, sdl->sdl_data, len);\n            ifname[len] = 0;\n            free(rtm);\n            return 0;\n        }\n    }\n\nfail:\n    free(rtm);\n    if (fd > 0)\n\tclose(fd);\n    return -1;\n}\n\n\n#elif defined(__linux__)\n#include <netinet/in.h>\n#include <net/if.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <linux/netlink.h>\n#include <linux/rtnetlink.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <arpa/inet.h>\n\n\n\nstruct route_info {\n    int priority;\n    struct in_addr dstAddr;\n    struct in_addr srcAddr;\n    struct in_addr gateWay;\n    char ifName[IF_NAMESIZE];\n};\n\nstatic int read_netlink(int fd, char *bufPtr, size_t sizeof_buffer, int seqNum, int pId)\n{\n    struct nlmsghdr *nlHdr;\n    int readLen = 0, msgLen = 0;\n\n do {\n        /* Receive response from the kernel */\n        if ((readLen = recv(fd, bufPtr, sizeof_buffer - msgLen, 0)) < 0) {\n            perror(\"SOCK READ: \");\n            return -1;\n        }\n\n        nlHdr = (struct nlmsghdr *) bufPtr;\n\n        /* Check if the header is valid */\n        if ((NLMSG_OK(nlHdr, readLen) == 0)\n            || (nlHdr->nlmsg_type == NLMSG_ERROR)) {\n            perror(\"Error in received packet\");\n            return -1;\n        }\n\n        /* Check if the its the last message */\n        if (nlHdr->nlmsg_type == NLMSG_DONE) {\n            break;\n        } else {\n            /* Else move the pointer to buffer appropriately */\n            bufPtr += readLen;\n            msgLen += readLen;\n        }\n\n        /* Check if its a multi part message */\n        if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {\n            /* return if its not */\n            break;\n        }\n    } while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));\n\n    return msgLen;\n}\n\n/* For parsing the route info returned */\nstatic int parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)\n{\n    struct rtmsg *rtMsg;\n    struct rtattr *rtAttr;\n    int rtLen = 0;\n\n    rtMsg = (struct rtmsg *) NLMSG_DATA(nlHdr);\n\n    /* This must be an IPv4 (AF_INET) route */\n    if (rtMsg->rtm_family != AF_INET)\n        return 1;\n\n    /* This must be in main routing table */\n    if (rtMsg->rtm_table != RT_TABLE_MAIN)\n        return 1;\n\n    /* Attributes field*/\n    rtAttr = (struct rtattr *)RTM_RTA(rtMsg);\n    rtLen = RTM_PAYLOAD(nlHdr);\n#define FORMATADDR(n) ((n)&0xFF), ((n>>8)&0xFF), ((n>>16)&0xFF), ((n>>24)&0xFF)\n    for (; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {\n        switch (rtAttr->rta_type) {\n        case RTA_OIF:\n            if_indextoname(*(int *) RTA_DATA(rtAttr), rtInfo->ifName);\n            //LOG(4, \"ifname=%s \", rtInfo->ifName);\n            break;\n        case RTA_GATEWAY:\n            rtInfo->gateWay.s_addr = *(u_int *)RTA_DATA(rtAttr);\n            //LOG(4, \"gw=%u.%u.%u.%u \", FORMATADDR(rtInfo->gateWay.s_addr));\n            break;\n        case RTA_PREFSRC:\n            rtInfo->srcAddr.s_addr = *(u_int *)RTA_DATA(rtAttr);\n            //LOG(4, \"src=%u.%u.%u.%u \", FORMATADDR(rtInfo->srcAddr.s_addr));\n            break;\n        case RTA_DST:\n            rtInfo->dstAddr .s_addr = *(u_int *)RTA_DATA(rtAttr);\n            //LOG(4, \"dst=%u.%u.%u.%u \", FORMATADDR(rtInfo->dstAddr.s_addr));\n            break;\n        case RTA_PRIORITY:\n            rtInfo->priority = *(int*)RTA_DATA(rtAttr);\n            //LOG(4, \"priority=0x%08x \", rtInfo->priority);\n            break;\n        default:\n            //LOG(4, \"rta_type=%d \", rtAttr->rta_type)\n            ;\n        }\n    }\n    //LOG(4, \"\\n\");\n\n    return 0;\n}\n\n\nint rawsock_get_default_interface(char *ifname, size_t sizeof_ifname)\n{\n    int fd;\n    struct nlmsghdr *nlMsg;\n    char msgBuf[16384];\n    int len;\n    int msgSeq = 0;\n    unsigned ipv4 = 0;\n    int priority = 0x7FFFFF;\n\n\n    /*\n     * Create 'netlink' socket to query kernel\n     */\n    fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);\n    if (fd < 0) {\n        fprintf(stderr, \"%s:%d: socket(NETLINK_ROUTE): %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n    /*\n     * format the netlink buffer\n     */\n    memset(msgBuf, 0, sizeof(msgBuf));\n    nlMsg = (struct nlmsghdr *)msgBuf;\n\n    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));\n    nlMsg->nlmsg_type = RTM_GETROUTE;\n    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;\n    nlMsg->nlmsg_seq = msgSeq++;\n    nlMsg->nlmsg_pid = getpid();\n\n    /*\n     * send first request to kernel\n     */\n    if (send(fd, nlMsg, nlMsg->nlmsg_len, 0) < 0) {\n        fprintf(stderr, \"%s:%d: send(NETLINK_ROUTE): %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n    /*\n     * Now read all the responses\n     */\n    len = read_netlink(fd, msgBuf, sizeof(msgBuf), msgSeq, getpid());\n    if (len <= 0) {\n        fprintf(stderr, \"%s:%d: read_netlink: %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n\n    /*\n     * Parse the response\n     */\n    for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {\n        struct route_info rtInfo[1];\n        int err;\n\n        memset(rtInfo, 0, sizeof(struct route_info));\n\n        //LOG(3, \"if: nlmsg_type=%d nlmsg_flags=0x%x\\n\", nlMsg->nlmsg_type, nlMsg->nlmsg_flags);\n        err = parseRoutes(nlMsg, rtInfo);\n        if (err != 0)\n            continue;\n\n        LOG(3, \"if: route: '%12s' dst=%u.%u.%u.%u src=%u.%u.%u.%u gw=%u.%u.%u.%u priority=%d\\n\",\n                rtInfo->ifName,\n                FORMATADDR(rtInfo->dstAddr.s_addr),\n                FORMATADDR(rtInfo->srcAddr.s_addr),\n                FORMATADDR(rtInfo->gateWay.s_addr),\n                rtInfo->priority\n            );\n\n        /* make sure destination = 0.0.0.0 for \"default route\" */\n        if (rtInfo->dstAddr.s_addr != 0)\n            continue;\n\n        /* found the gateway! */\n        if (rtInfo->priority < priority) {\n            priority = rtInfo->priority;\n            ipv4 = ntohl(rtInfo->gateWay.s_addr);\n            if (ipv4 == 0)\n                continue;\n            safe_strcpy(ifname, sizeof_ifname, rtInfo->ifName);\n        }\n\n    }\n\n    close(fd);\n\n    return 0;\n}\n\n#endif\n\n\n#if defined(WIN32)\n/* From:\n * https://stackoverflow.com/questions/10972794/undefined-reference-to-getadaptersaddresses20-but-i-included-liphlpapi\n * I think this fixed issue #734\n */\n#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x501\n#undef _WIN32_WINNT\n#define _WIN32_WINNT 0x501\n#endif\n\n#include <winsock2.h>\n#include <iphlpapi.h>\n#include \"massip-parse.h\"\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\n\n\nint rawsock_get_default_interface(char *ifname, size_t sizeof_ifname)\n{\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD err;\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n\n    /*\n     * Allocate a proper sized buffer\n     */\n    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO));\n    if (pAdapterInfo == NULL) {\n        fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n        return EFAULT;\n    }\n\n    /*\n     * Query the adapter info. If the buffer is not big enough, loop around\n     * and try again\n     */\nagain:\n    err = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);\n    if (err == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);\n        if (pAdapterInfo == NULL) {\n            fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n            return EFAULT;\n        }\n        goto again;\n    }\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"GetAdaptersInfo failed with error: %u\\n\", (unsigned)err);\n        return EFAULT;\n    }\n\n    /*\n     * loop through all adapters looking for ours\n     */\n    for (   pAdapter = pAdapterInfo;\n            pAdapter;\n            pAdapter = pAdapter->Next) {\n        unsigned ipv4 = 0;\n\n        if (pAdapter->Type != MIB_IF_TYPE_ETHERNET\n            && pAdapter->Type != 71 /*wifi*/)\n            continue;\n\n\n        /* See if this adapter has a default-route/gateway configured */\n        {\n            const IP_ADDR_STRING *addr;\n\n            for (addr = &pAdapter->GatewayList; addr; addr = addr->Next) {\n                unsigned x;\n\n                x = massip_parse_ipv4(addr->IpAddress.String);\n                if (x != 0xFFFFFFFF) {\n                    ipv4 = x;\n                    break;\n                }\n            }\n        }\n\n        /*\n         * When we reach the first adapter with an IP address, then\n         * we'll use that one\n         */\n        if (ipv4) {\n            snprintf(ifname, sizeof_ifname, \"\\\\Device\\\\NPF_%s\", pAdapter->AdapterName);\n        }\n\n    }\n    if (pAdapterInfo)\n        free(pAdapterInfo);\n\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/rawsock-getip.c",
    "content": "/*\n    retrieve IPv4 address of the named network interface/adapter\n    like \"eth0\"\n\n\n    This works on:\n        - Windows\n        - Linux\n        - Apple\n        - FreeBSD\n\n I think it'll work the same on any BSD system.\n*/\n#include \"rawsock.h\"\n#include \"util-safefunc.h\"\n#include \"massip-parse.h\"\n\n/*****************************************************************************\n *****************************************************************************/\n#if defined(__linux__)\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <netinet/in.h>\n#include <net/if.h>\n#include <arpa/inet.h>\nunsigned\nrawsock_get_adapter_ip(const char *ifname)\n{\n    int fd;\n    struct ifreq ifr;\n    struct sockaddr_in *sin;\n    struct sockaddr *sa;\n    int x;\n\n    fd = socket(AF_INET, SOCK_DGRAM, 0);\n\n    ifr.ifr_addr.sa_family = AF_INET;\n    safe_strcpy(ifr.ifr_name, IFNAMSIZ, ifname);\n\n    x = ioctl(fd, SIOCGIFADDR, &ifr);\n    if (x < 0) {\n        fprintf(stderr, \"ERROR:'%s': %s\\n\", ifname, strerror(errno));\n        //fprintf(stderr, \"ERROR:'%s': couldn't discover IP address of network interface\\n\", ifname);\n        close(fd);\n        return 0;\n    }\n\n    close(fd);\n\n    sa = &ifr.ifr_addr;\n    sin = (struct sockaddr_in *)sa;\n    return ntohl(sin->sin_addr.s_addr);\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(WIN32)\n /* From:\n  * https://stackoverflow.com/questions/10972794/undefined-reference-to-getadaptersaddresses20-but-i-included-liphlpapi\n  * I think this fixes issue #734\n  */\n#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x501\n#undef _WIN32_WINNT\n#define _WIN32_WINNT 0x501\n#endif\n\n#include <winsock2.h>\n#include <iphlpapi.h>\n#ifdef _MSC_VER\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\nunsigned\nrawsock_get_adapter_ip(const char *ifname)\n{\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD err;\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n    unsigned result = 0;\n\n    ifname = rawsock_win_name(ifname);\n\n    /*\n     * Allocate a proper sized buffer\n     */\n    pAdapterInfo = malloc(sizeof (IP_ADAPTER_INFO));\n    if (pAdapterInfo == NULL) {\n        fprintf(stderr, \"error:malloc(): for GetAdaptersinfo\\n\");\n        return 0;\n    }\n\n    /*\n     * Query the adapter info. If the buffer is not big enough, loop around\n     * and try again\n     */\nagain:\n    err = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);\n    if (err == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);\n        if (pAdapterInfo == NULL) {\n            fprintf(stderr, \"error:malloc(): for GetAdaptersinfo\\n\");\n            return 0;\n        }\n        goto again;\n    }\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"GetAdaptersInfo failed with error: %u\\n\", (unsigned)err);\n        return 0;\n    }\n\n    /*\n     * loop through all adapters looking for ours\n     */\n    for (   pAdapter = pAdapterInfo;\n            pAdapter;\n            pAdapter = pAdapter->Next) {\n        if (rawsock_is_adapter_names_equal(pAdapter->AdapterName, ifname))\n            break;\n    }\n\n    if (pAdapter) {\n        const IP_ADDR_STRING *addr;\n\n        for (addr = &pAdapter->IpAddressList; addr; addr = addr->Next) {\n            unsigned x;\n\n            x = massip_parse_ipv4(addr->IpAddress.String);\n            if (x != 0xFFFFFFFF) {\n                result = x;\n                goto end;\n            }\n        }\n    }\n\nend:\n    if (pAdapterInfo)\n        free(pAdapterInfo);\n\n    return result;\n}\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || 1\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <arpa/inet.h>\n#include <netinet/in.h>\n\n#ifdef AF_LINK\n#   include <net/if_dl.h>\n#endif\n#ifdef AF_PACKET\n#   include <netpacket/packet.h>\n#endif\n\nunsigned\nrawsock_get_adapter_ip(const char *ifname)\n{\n    int err;\n    struct ifaddrs *ifap;\n    struct ifaddrs *p;\n    unsigned ip;\n\n\n    /* Get the list of all network adapters */\n    err = getifaddrs(&ifap);\n    if (err != 0) {\n        perror(\"getifaddrs\");\n        return 0;\n    }\n\n    /* Look through the list until we get our adapter */\n    for (p = ifap; p; p = p->ifa_next) {\n        if (strcmp(ifname, p->ifa_name) == 0\n            && p->ifa_addr\n            && p->ifa_addr->sa_family == AF_INET)\n            break;\n    }\n    if (p == NULL)\n        goto error; /* not found */\n\n    /* Return the address */\n    {\n        struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr;\n\n        ip = ntohl(sin->sin_addr.s_addr);\n    }\n\n    freeifaddrs(ifap);\n    return ip;\nerror:\n    freeifaddrs(ifap);\n    return 0;\n}\n\n#endif\n\n"
  },
  {
    "path": "src/rawsock-getip6.c",
    "content": "/*\n    retrieve IPv4 address of the named network interface/adapter\n    like \"eth0\"\n\n\n    This works on:\n        - Windows\n        - Linux\n        - Apple\n        - FreeBSD\n\n I think it'll work the same on any BSD system.\n*/\n#include \"rawsock.h\"\n#include \"util-safefunc.h\"\n#include \"massip-parse.h\"\n\n/*****************************************************************************\n *****************************************************************************/\n#if defined(__linux__)\n#define _GNU_SOURCE\n#include <arpa/inet.h>\n#include <sys/socket.h>\n#include <netdb.h>\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <linux/if_link.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <netinet/in.h>\n#include <net/if.h>\n#include <arpa/inet.h>\n#include <ifaddrs.h>\n\nipv6address\nrawsock_get_adapter_ipv6(const char *ifname)\n{\n    struct ifaddrs *list = NULL;\n    struct ifaddrs *ifa;\n    int err;\n    ipv6address result = {0,0};\n\n    /* Fetch the list of addresses */\n    err = getifaddrs(&list);\n    if (err == -1) {\n        fprintf(stderr, \"[-] getifaddrs(): %s\\n\", strerror(errno));\n        return result;\n    }\n\n    for (ifa = list; ifa != NULL; ifa = ifa->ifa_next) {\n        ipv6address addr;\n\n        if (ifa->ifa_addr == NULL)\n            continue;\n        if (ifa->ifa_name == NULL)\n            continue;\n        if (strcmp(ifname, ifa->ifa_name) != 0)\n            continue;\n        if (ifa->ifa_addr->sa_family != AF_INET6)\n            continue;\n\n        addr = ipv6address_from_bytes((const unsigned char *)&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr);\n        \n        if (addr.hi>>56ULL >= 0xFC)\n            continue;\n        if (addr.hi>>32ULL == 0x20010db8)\n            continue;\n\n        result = addr;\n        break;\n    }\n\n    freeifaddrs(list);\n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(WIN32)\n/* From:\n * https://stackoverflow.com/questions/10972794/undefined-reference-to-getadaptersaddresses20-but-i-included-liphlpapi\n */\n#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x501\n#undef _WIN32_WINNT\n#define _WIN32_WINNT 0x501\n#endif\n#define WIN32_LEAN_AND_MEAN\n#include <winsock2.h>\n#include <WS2tcpip.h>\n#include <iphlpapi.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\n\nipv6address\nrawsock_get_adapter_ipv6(const char *ifname)\n{\n    ULONG err;\n    ipv6address result = {0,0};\n    IP_ADAPTER_ADDRESSES *adapters = NULL;\n    IP_ADAPTER_ADDRESSES *adapter;\n    IP_ADAPTER_UNICAST_ADDRESS *addr;\n    ULONG sizeof_addrs = 0;\n\n    ifname = rawsock_win_name(ifname);\n\nagain:\n    err = GetAdaptersAddresses(\n                        AF_INET6, /* Get IPv6 addresses only */\n                        0,\n                        0,\n                        adapters,\n                        &sizeof_addrs);\n    if (err == ERROR_BUFFER_OVERFLOW) {\n        free(adapters);\n        adapters = malloc(sizeof_addrs);\n        if (adapters == NULL) {\n            fprintf(stderr, \"GetAdaptersAddresses():malloc(): failed: out of memory\\n\");\n            return result;\n        }\n        goto again;\n    }\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"GetAdaptersAddresses(): failed: %u\\n\", (unsigned)err);\n        return result;\n    }\n\n    /*\n     * loop through all adapters looking for ours\n     */\n    for (adapter = adapters; adapter != NULL; adapter = adapter->Next) {\n        if (rawsock_is_adapter_names_equal(adapter->AdapterName, ifname))\n            break;\n    }\n\n    /*\n     * If our adapter isn't found, print an error.\n     */\n    if (adapters == NULL) {\n        fprintf(stderr, \"GetAdaptersInfo: adapter not found: %s\\n\", ifname);\n        goto end;\n    }\n\n\n    /*\n     * Search through the list of returned addresses looking for the first\n     * that matches an IPv6 address.\n     */\n    for (addr = adapter->FirstUnicastAddress; addr; addr = addr->Next) {\n        struct sockaddr_in6 *sa = (struct sockaddr_in6 *)addr->Address.lpSockaddr;\n        //char  buf[64];\n        ipv6address ipv6;\n\n\n        /* Ignore any address that isn't IPv6 */\n        if (sa->sin6_family != AF_INET6)\n            continue;\n\n        /* Ignore transient cluster addresses */\n        if (addr->Flags == IP_ADAPTER_ADDRESS_TRANSIENT)\n            continue;\n\n        /* Don't use operating-system function for this, because they aren't\n         * really portable or safe */\n        ipv6 = ipv6address_from_bytes((const unsigned char *)&sa->sin6_addr);\n\n        if (addr->PrefixOrigin == IpPrefixOriginWellKnown) {\n             /* This value applies to an IPv6 link-local address or an IPv6 loopback address */\n            continue;\n        }\n\n        if (addr->PrefixOrigin == IpPrefixOriginRouterAdvertisement && addr->SuffixOrigin == IpSuffixOriginRandom) {\n            /* This is a temporary IPv6 address\n             * See: http://technet.microsoft.com/en-us/ff568768(v=vs.60).aspx */\n            continue;\n        }\n\n        if (ipv6.hi>>56ULL >= 0xFC)\n            continue;\n\n        if (ipv6.hi>>32ULL == 0x20010db8)\n            continue;\n\n        result = ipv6;\n    }\n\nend:\n    free(adapters);\n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || 1\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <arpa/inet.h>\n#include <netinet/in.h>\n\n#ifdef AF_LINK\n#   include <net/if_dl.h>\n#endif\n#ifdef AF_PACKET\n#   include <netpacket/packet.h>\n#endif\n\nipv6address\nrawsock_get_adapter_ipv6(const char *ifname)\n{\n    struct ifaddrs *list = NULL;\n    struct ifaddrs *ifa;\n    int err;\n    ipv6address result = {0,0};\n\n    /* Fetch the list of addresses */\n    err = getifaddrs(&list);\n    if (err == -1) {\n        fprintf(stderr, \"[-] getifaddrs(): %s\\n\", strerror(errno));\n        return result;\n    }\n\n    for (ifa = list; ifa != NULL; ifa = ifa->ifa_next) {\n        ipv6address addr;\n\n        if (ifa->ifa_addr == NULL)\n            continue;\n        if (ifa->ifa_name == NULL)\n            continue;\n        if (strcmp(ifname, ifa->ifa_name) != 0)\n            continue;\n        if (ifa->ifa_addr->sa_family != AF_INET6)\n            continue;\n\n        addr = ipv6address_from_bytes((const unsigned char *)&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr);\n        \n        if (addr.hi>>56ULL >= 0xFC)\n            continue;\n        if (addr.hi>>32ULL == 0x20010db8)\n            continue;\n\n        result = addr;\n        break;\n    }\n\n    freeifaddrs(list);\n    return result;\n}\n\n#endif\n\n"
  },
  {
    "path": "src/rawsock-getmac.c",
    "content": "/*\n    get MAC address of named network interface/adapter like \"eth0\"\n\n    This works on:\n        - Windows\n        - Linux\n        - Apple\n        - FreeBSD\n\n    I think it'll work the same on any BSD system.\n*/\n#include \"rawsock.h\"\n#include \"util-safefunc.h\"\n#include \"util-logger.h\"\n\n/*****************************************************************************\n *****************************************************************************/\n#if defined(__linux__)\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <netinet/in.h>\n#include <net/if.h>\n#include <arpa/inet.h>\n\nint\nrawsock_get_adapter_mac(const char *ifname, unsigned char *mac)\n{\n    int fd;\n    int x;\n    struct ifreq ifr;\n\n\n    fd = socket(AF_INET, SOCK_STREAM, 0);\n    if(fd < 0){\n        perror(\"socket\");\n        goto end;\n    }\n\n    safe_strcpy(ifr.ifr_name, IFNAMSIZ, ifname);\n    x = ioctl(fd, SIOCGIFHWADDR, (char *)&ifr);\n    if (x < 0) {\n        perror(\"ioctl\");\n        goto end;\n    }\n\n    /* Log helpful info about the interface type */\n    switch (ifr.ifr_ifru.ifru_hwaddr.sa_family) {\n    case 1:\n        LOG(1, \"if:%s: type=ethernet(1)\\n\", ifname);\n        break;\n    default:\n        LOG(1, \"if:%s: type=0x%04x\\n\", ifname, ifr.ifr_ifru.ifru_hwaddr.sa_family);\n    }\n\n\n    memcpy(mac, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);\n\n    /*\n     * [KLUDGE]\n     *  For VPN tunnels with raw IP there isn't a hardware address, so just\n     *  return a fake one instead.\n     */\n    if (memcmp(mac, \"\\0\\0\\0\\0\\0\\0\", 6) == 0\n            && ifr.ifr_ifru.ifru_hwaddr.sa_family == 0xfffe) {\n        LOG(1, \"%s: creating fake address\\n\", ifname);\n        mac[5] = 1;\n    }\n\nend:\n    close(fd);\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(WIN32)\n /* From:\n  * https://stackoverflow.com/questions/10972794/undefined-reference-to-getadaptersaddresses20-but-i-included-liphlpapi\n  * I think this fixes issue #734\n  */\n#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x501\n#undef _WIN32_WINNT\n#define _WIN32_WINNT 0x501\n#endif\n#include <winsock2.h>\n#include <iphlpapi.h>\n#ifdef _MSC_VER\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\n\n\nint\nrawsock_get_adapter_mac(const char *ifname, unsigned char *mac)\n{\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD err;\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n\n    ifname = rawsock_win_name(ifname);\n\n    /*\n     * Allocate a proper sized buffer\n     */\n    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO));\n    if (pAdapterInfo == NULL) {\n        fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n        return EFAULT;\n    }\n\n    /*\n     * Query the adapter info. If the buffer is not big enough, loop around\n     * and try again\n     */\nagain:\n    err = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);\n    if (err == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);\n        if (pAdapterInfo == NULL) {\n            fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n            return EFAULT;\n        }\n        goto again;\n    }\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"if: GetAdaptersInfo failed with error: %u\\n\", (unsigned)err);\n        return EFAULT;\n    }\n\n    /*\n     * loop through all adapters looking for ours\n     */\n    for (   pAdapter = pAdapterInfo;\n            pAdapter;\n            pAdapter = pAdapter->Next) {\n        if (rawsock_is_adapter_names_equal(pAdapter->AdapterName, ifname))\n            break;\n    }\n\n    if (pAdapter) {\n        if (pAdapter->AddressLength != 6)\n            return EFAULT;\n        memcpy(mac, pAdapter->Address, 6);\n    }\n\n    if (pAdapterInfo)\n        free(pAdapterInfo);\n\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || 1\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <arpa/inet.h>\n\n#ifdef AF_LINK\n#   include <net/if_dl.h>\n#endif\n#ifdef AF_PACKET\n#   include <netpacket/packet.h>\n#endif\n\nint\nrawsock_get_adapter_mac(const char *ifname, unsigned char *mac)\n{\n    int err;\n    struct ifaddrs *ifap;\n    struct ifaddrs *p;\n\n\n    /* Get the list of all network adapters */\n    err = getifaddrs(&ifap);\n    if (err != 0) {\n        perror(\"getifaddrs\");\n        return 1;\n    }\n\n    /* Look through the list until we get our adapter */\n    for (p = ifap; p; p = p->ifa_next) {\n        if (strcmp(ifname, p->ifa_name) == 0\n            && p->ifa_addr\n            && p->ifa_addr->sa_family == AF_LINK)\n            break;\n    }\n    if (p == NULL) {\n        LOG(1, \"if:%s: not found\\n\", ifname);\n        goto error; /* not found */\n    }\n\n    /* Return the address */\n    {\n        size_t len = 6;\n        struct sockaddr_dl *link;\n\n        link = (struct sockaddr_dl *)p->ifa_addr;\n        if (len > link->sdl_alen) {\n            memset(mac, 0, 6);\n            len = link->sdl_alen;\n        }\n\n        LOG(1, \"[+] if(%s): family=%u, type=%u, len=%u\\n\",\n                ifname,\n                link->sdl_family,\n                link->sdl_type,\n\t\tlen);\n\n        memcpy(mac,\n               link->sdl_data + link->sdl_nlen,\n               len);\n\n    }\n\n    freeifaddrs(ifap);\n    return 0;\nerror:\n    freeifaddrs(ifap);\n    return -1;\n}\n\n#endif\n\n"
  },
  {
    "path": "src/rawsock-getroute.c",
    "content": "/*\n    get default route (gateway) IPv4 address of the named network\n    interface/adapter (like \"eth0\").\n\n    This works on both Linux and windows.\n*/\n#include \"rawsock.h\"\n#include \"util-safefunc.h\"\n#include \"util-malloc.h\"\n#include \"massip-parse.h\"\n#include \"util-logger.h\"\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun__)\n#include <unistd.h>\n#include <sys/socket.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <net/if_dl.h>\n#include <ctype.h>\n\n#define ROUNDUP2(a, n)       ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))\n\n#if defined(__APPLE__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#elif defined(__NetBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(uint64_t))\n#elif defined(__FreeBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#elif defined(__OpenBSD__)\n# define ROUNDUP(a)           ROUNDUP2((a), sizeof(int))\n#else\n# error unknown platform\n#endif\n\nstatic struct sockaddr *\nget_rt_address(struct rt_msghdr *rtm, int desired)\n{\n    int i;\n    int bitmask = rtm->rtm_addrs;\n    struct sockaddr *sa = (struct sockaddr *)(rtm + 1);\n\n    for (i = 0; i < RTAX_MAX; i++) {\n        if (bitmask & (1 << i)) {\n            if ((1<<i) == desired)\n                return sa;\n            sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);\n        } else\n            ;\n    }\n    return NULL;\n\n}\n\nstatic void\nhexdump(const void *v, size_t len)\n{\n    const unsigned char *p = (const unsigned char *)v;\n    size_t i;\n\n\n    for (i=0; i<len; i += 16) {\n        size_t j;\n\n        for (j=i; j<i+16 && j<len; j++)\n            printf(\"%02x \", p[j]);\n        for (;j<i+16; j++)\n            printf(\"   \");\n        printf(\"  \");\n        for (j=i; j<i+16 && j<len; j++)\n            if (isprint(p[j]) && !isspace(p[j]))\n                printf(\"%c\", p[j]);\n            else\n                printf(\".\");\n        printf(\"\\n\");\n    }\n}\n\n#if 0\n#define RTA_DST         0x1     /* destination sockaddr present */\n#define RTA_GATEWAY     0x2     /* gateway sockaddr present */\n#define RTA_NETMASK     0x4     /* netmask sockaddr present */\n#define RTA_GENMASK     0x8     /* cloning mask sockaddr present */\n#define RTA_IFP         0x10    /* interface name sockaddr present */\n#define RTA_IFA         0x20    /* interface addr sockaddr present */\n#define RTA_AUTHOR      0x40    /* sockaddr for author of redirect */\n#define RTA_BRD         0x80    /* for NEWADDR, broadcast or p-p dest addr */\n#endif\n\nvoid\ndump_rt_addresses(struct rt_msghdr *rtm);\n\nvoid\ndump_rt_addresses(struct rt_msghdr *rtm)\n{\n    int i;\n    int bitmask = rtm->rtm_addrs;\n    struct sockaddr *sa = (struct sockaddr *)(rtm + 1);\n\n    for (i = 0; i < RTAX_MAX; i++) {\n        if (bitmask & (1 << i)) {\n            printf(\"b=%u fam=%u len=%u\\n\", (1<<i), sa->sa_family, sa->sa_len);\n            hexdump(sa, sa->sa_len + sizeof(sa->sa_family));\n            sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);\n        } else\n            ;\n    }\n}\n\nint\nrawsock_get_default_gateway(const char *ifname, unsigned *ipv4)\n{\n    int fd;\n    int seq = (int)time(0);\n    ssize_t err;\n    struct rt_msghdr *rtm;\n    size_t sizeof_buffer;\n\n\n    /*\n     * Requests/responses from the kernel are done with an \"rt_msghdr\"\n     * structure followed by an array of \"sockaddr\" structures.\n     */\n    sizeof_buffer = sizeof(*rtm) + 512;\n    rtm = calloc(1, sizeof_buffer);\n    \n    /*\n     * Create a socket for querying the kernel\n     */\n    fd = socket(AF_ROUTE, SOCK_RAW, 0);\n    if (fd < 0) {\n        perror(\"socket(AF_ROUTE)\");\n        free(rtm);\n        return errno;\n    }\n\n    /* Needs a timeout. Sometimes it'll hang indefinitely waiting for a \n     * response that will never arrive */\n    {\n        struct timeval timeout;\n        timeout.tv_sec = 1;\n        timeout.tv_usec = 0;\n\n        err = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));\n        if (err < 0)\n            LOG(0, \"[-] SO_RCVTIMEO: %d %s\\n\", errno, strerror(errno));\n\n        err = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));\n        if (err < 0)\n            LOG(0, \"[-] SO_SNDTIMEO: %d %s\\n\", errno, strerror(errno));\n   }\n\n    /*\n     * Format and send request to kernel\n     */\n    rtm->rtm_msglen = sizeof(*rtm) + sizeof(struct sockaddr_in);\n    rtm->rtm_version = RTM_VERSION;\n    rtm->rtm_flags = RTF_UP;\n    rtm->rtm_type = RTM_GET;\n    rtm->rtm_addrs = RTA_DST | RTA_IFP;\n    rtm->rtm_pid = getpid();\n    rtm->rtm_seq = seq;\n\n    /*\n     * Create an empty address of 0.0.0.0 to query the route\n     */\n    {\n        struct sockaddr_in *sin;\n        sin = (struct sockaddr_in *)(rtm + 1);\n        sin->sin_len = sizeof(*sin);\n        sin->sin_family = AF_INET;\n        sin->sin_addr.s_addr = 0;\n    }\n\n    err = write(fd, (char *)rtm, rtm->rtm_msglen);\n    if (err <= 0) {\n        LOG(0, \"[-] getroute: write(): returned %d %s\\n\", errno, strerror(errno));\n        goto fail;\n    }\n\n    /*\n     * Read responses until we find one that belongs to us\n     */\n    for (;;) {\n        err = read(fd, (char *)rtm, sizeof_buffer);\n        if (err <= 0)\n            break;\n        if (rtm->rtm_seq != seq) {\n            printf(\"seq: %u %u\\n\", rtm->rtm_seq, seq);\n            continue;\n        }\n        if (rtm->rtm_pid != getpid()) {\n            printf(\"pid: %u %u\\n\", rtm->rtm_pid, getpid());\n            continue;\n        }\n        break;\n    }\n    close(fd);\n\n    /*\n     * Parse our data\n     */\n    {\n        struct sockaddr_in *sin;\n        struct sockaddr_dl *sdl;\n\n        sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP);\n        if (sdl) {\n            //hexdump(sdl, sdl->sdl_len);\n            //printf(\"%.*s\\n\", sdl->sdl_nlen, sdl->sdl_data);\n            if (memcmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0) {\n                fprintf(stderr, \"ERROR: ROUTE DOESN'T MATCH INTERFACE\\n\");\n                fprintf(stderr, \"YOU'LL HAVE TO SET --router-mac MANUALLY\\n\");\n                exit(1);\n            }\n        }\n\n        sin = (struct sockaddr_in *)get_rt_address(rtm, RTA_GATEWAY);\n        if (sin) {\n            *ipv4 = ntohl(sin->sin_addr.s_addr);\n            free(rtm);\n            return 0;\n        }\n\n    }\n\nfail:\n    free(rtm);\n    return -1;\n}\n\n#elif defined(__linux__)\n#include <netinet/in.h>\n#include <net/if.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <linux/netlink.h>\n#include <linux/rtnetlink.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <arpa/inet.h>\n\n\n\nstruct route_info {\n    struct in_addr dstAddr;\n    struct in_addr srcAddr;\n    struct in_addr gateWay;\n    char ifName[IF_NAMESIZE];\n};\n\nstatic int\nread_netlink(int fd, char *bufPtr, size_t sizeof_buffer, int seqNum, int pId)\n{\n    struct nlmsghdr *nlHdr;\n    int readLen = 0, msgLen = 0;\n\n do {\n        /* Receive response from the kernel */\n        if ((readLen = recv(fd, bufPtr, sizeof_buffer - msgLen, 0)) < 0) {\n            perror(\"SOCK READ: \");\n            return -1;\n        }\n\n        nlHdr = (struct nlmsghdr *) bufPtr;\n\n        /* Check if the header is valid */\n        if ((NLMSG_OK(nlHdr, readLen) == 0)\n            || (nlHdr->nlmsg_type == NLMSG_ERROR)) {\n            perror(\"Error in received packet\");\n            return -1;\n        }\n\n        /* Check if the its the last message */\n        if (nlHdr->nlmsg_type == NLMSG_DONE) {\n            break;\n        } else {\n            /* Else move the pointer to buffer appropriately */\n            bufPtr += readLen;\n            msgLen += readLen;\n        }\n\n        /* Check if its a multi part message */\n        if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {\n            /* return if its not */\n            break;\n        }\n    } while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));\n\n    return msgLen;\n}\n\n/* For parsing the route info returned */\nstatic int\nparseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)\n{\n    struct rtmsg *rtMsg;\n    struct rtattr *rtAttr;\n    int rtLen = 0;\n\n    rtMsg = (struct rtmsg *) NLMSG_DATA(nlHdr);\n\n    /* This must be an IPv4 (AF_INET) route */\n    if (rtMsg->rtm_family != AF_INET)\n        return 1;\n\n    /* This must be in main routing table */\n    if (rtMsg->rtm_table != RT_TABLE_MAIN)\n        return 1;\n\n    /* Attributes field*/\n    rtAttr = (struct rtattr *)RTM_RTA(rtMsg);\n    rtLen = RTM_PAYLOAD(nlHdr);\n    for (; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {\n        switch (rtAttr->rta_type) {\n        case RTA_OIF:\n            if_indextoname(*(int *) RTA_DATA(rtAttr), rtInfo->ifName);\n            break;\n        case RTA_GATEWAY:\n            rtInfo->gateWay.s_addr = *(u_int *)RTA_DATA(rtAttr);\n            break;\n        case RTA_PREFSRC:\n            rtInfo->srcAddr.s_addr = *(u_int *)RTA_DATA(rtAttr);\n            break;\n        case RTA_DST:\n            rtInfo->dstAddr .s_addr = *(u_int *)RTA_DATA(rtAttr);\n            break;\n        }\n    }\n\n    return 0;\n}\n\n\nint rawsock_get_default_gateway(const char *ifname, unsigned *ipv4)\n{\n    int fd;\n    struct nlmsghdr *nlMsg;\n    char msgBuf[16384];\n    int len;\n    int msgSeq = 0;\n\n    /*\n     * Set to zero, in case we cannot find it\n     */\n    *ipv4 = 0;\n\n    /*\n     * Create 'netlink' socket to query kernel\n     */\n    fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);\n    if (fd < 0) {\n        fprintf(stderr, \"%s:%d: socket(NETLINK_ROUTE): %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n    /*\n     * format the netlink buffer\n     */\n    memset(msgBuf, 0, sizeof(msgBuf));\n    nlMsg = (struct nlmsghdr *)msgBuf;\n\n    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));\n    nlMsg->nlmsg_type = RTM_GETROUTE;\n    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;\n    nlMsg->nlmsg_seq = msgSeq++;\n    nlMsg->nlmsg_pid = getpid();\n\n    /*\n     * send first request to kernel\n     */\n    if (send(fd, nlMsg, nlMsg->nlmsg_len, 0) < 0) {\n        fprintf(stderr, \"%s:%d: send(NETLINK_ROUTE): %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n    /*\n     * Now read all the responses\n     */\n    len = read_netlink(fd, msgBuf, sizeof(msgBuf), msgSeq, getpid());\n    if (len <= 0) {\n        fprintf(stderr, \"%s:%d: read_netlink: %d\\n\",\n            __FILE__, __LINE__, errno);\n        return errno;\n    }\n\n\n    /*\n     * Parse the response\n     */\n    for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {\n        struct route_info rtInfo[1];\n        int err;\n\n        memset(rtInfo, 0, sizeof(struct route_info));\n\n        err = parseRoutes(nlMsg, rtInfo);\n        if (err != 0)\n            continue;\n\n        /* make sure we match the desired network interface */\n        if (ifname && strcmp(rtInfo->ifName, ifname) != 0)\n            continue;\n\n        /* make sure destination = 0.0.0.0 for \"default route\" */\n        if (rtInfo->dstAddr.s_addr != 0)\n            continue;\n\n        /* found the gateway! */\n        *ipv4 = ntohl(rtInfo->gateWay.s_addr);\n    }\n\n    close(fd);\n\n    return 0;\n}\n\n#endif\n\n\n#if defined(WIN32)\n/* From:\n * https://stackoverflow.com/questions/10972794/undefined-reference-to-getadaptersaddresses20-but-i-included-liphlpapi\n * I think this fixes issue #734\n */\n#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x501\n#undef _WIN32_WINNT\n#define _WIN32_WINNT 0x501\n#endif\n\n#include <winsock2.h>\n#include <iphlpapi.h>\n#ifdef _MSC_VER\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\n\n\nint rawsock_get_default_gateway(const char *ifname, unsigned *ipv4)\n{\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD err;\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n\n    /*\n     * Translate numeric index (if it exists) to real name\n     */\n    ifname = rawsock_win_name(ifname);\n    //printf(\"------ %s -----\\n\", ifname);\n\n    /*\n     * Allocate a proper sized buffer\n     */\n    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO));\n    if (pAdapterInfo == NULL) {\n        fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n        return EFAULT;\n    }\n\n    /*\n     * Query the adapter info. If the buffer is not big enough, loop around\n     * and try again\n     */\nagain:\n    err = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);\n    if (err == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);\n        if (pAdapterInfo == NULL) {\n            fprintf(stderr, \"Error allocating memory needed to call GetAdaptersinfo\\n\");\n            return EFAULT;\n        }\n        goto again;\n    }\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"GetAdaptersInfo failed with error: %u\\n\", \n                            (unsigned)err);\n        return EFAULT;\n    }\n\n    /*\n     * loop through all adapters looking for ours\n     */\n    for (   pAdapter = pAdapterInfo;\n            pAdapter;\n            pAdapter = pAdapter->Next) {\n        if (rawsock_is_adapter_names_equal(pAdapter->AdapterName, ifname))\n            break;\n    }\n\n    if (pAdapter) {\n        //printf(\"\\tComboIndex: \\t%d\\n\", pAdapter->ComboIndex);\n        //printf(\"\\tAdapter Name: \\t%s\\n\", pAdapter->AdapterName);\n        //printf(\"\\tAdapter Desc: \\t%s\\n\", pAdapter->Description);\n\n\n        //printf(\"\\tAdapter Addr: \\t\");\n        /*for (i = 0; i < pAdapter->AddressLength; i++) {\n            if (i == (pAdapter->AddressLength - 1))\n                printf(\"%.2X\\n\", (int) pAdapter->Address[i]);\n            else\n                printf(\"%.2X-\", (int) pAdapter->Address[i]);\n        }*/\n        //printf(\"\\tIndex: \\t%d\\n\", pAdapter->Index);\n        //printf(\"\\tType: \\t\");\n        switch (pAdapter->Type) {\n        case MIB_IF_TYPE_OTHER:\n            //printf(\"Other\\n\");\n            break;\n        case MIB_IF_TYPE_ETHERNET:\n            //printf(\"Ethernet\\n\");\n            break;\n        case MIB_IF_TYPE_TOKENRING:\n            //printf(\"Token Ring\\n\");\n            break;\n        case MIB_IF_TYPE_FDDI:\n            //printf(\"FDDI\\n\");\n            break;\n        case MIB_IF_TYPE_PPP:\n            //printf(\"PPP\\n\");\n            break;\n        case MIB_IF_TYPE_LOOPBACK:\n            //printf(\"Lookback\\n\");\n            break;\n        case MIB_IF_TYPE_SLIP:\n            //printf(\"Slip\\n\");\n            break;\n        default:\n            //printf(\"Unknown type %ld\\n\", pAdapter->Type);\n            break;\n        }\n\n        //printf(\"\\tIP Address: \\t%s\\n\", pAdapter->IpAddressList.IpAddress.String);\n        //printf(\"\\tIP Mask: \\t%s\\n\", pAdapter->IpAddressList.IpMask.String);\n\n/*typedef struct _IP_ADDR_STRING {\n    struct _IP_ADDR_STRING* Next;\n    IP_ADDRESS_STRING IpAddress;\n    IP_MASK_STRING IpMask;\n    DWORD Context;\n} IP_ADDR_STRING, *PIP_ADDR_STRING;*/\n\n        {\n            const IP_ADDR_STRING *addr;\n\n            for (addr = &pAdapter->GatewayList; addr; addr = addr->Next) {\n                unsigned x = massip_parse_ipv4(addr->IpAddress.String);\n                if (x != 0xFFFFFFFF) {\n                    *ipv4 = x;\n                    goto end;\n                }\n            }\n        }\n\n\n        //printf(\"\\n\");\n    }\nend:\n    if (pAdapterInfo)\n        free(pAdapterInfo);\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/rawsock-pcapfile.c",
    "content": "/* Copyright (c) 2007 by Errata Security, All Rights Reserved\n * Programmer(s): Robert David Graham [rdg]\n */\n/*\n\n  PCAPFILE\n\n  This is a small bit of code for reading/writing libpcap files.\n  This is for offline use of the product in cases where people\n  want to post-process files without having to install libpcap.\n\n  Since the file format is trivial to parse, and a lot of people\n  may not have libpcap installed, we decode it ourselves in this\n  module rather than using the libpcap module.\n\n  Also, this has the feature of being able to read corrupted\n  files. When it encounters a malformed back (such as one with\n  an impossibly large packet), it skips the malformed data and\n  searches forward for a packet that looks good.\n\n*/\n#define _CRT_SECURE_NO_WARNINGS\n#define _FILE_OFFSET_BITS 64\n\n#include <errno.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <sys/stat.h>\n#include \"rawsock-pcapfile.h\"\n\n/****************************************************************************\n * <PORTABILITY BLOCK>\n ****************************************************************************/\n#ifdef _MSC_VER\n#define snprintf _snprintf\n#define PRId64 \"I64d\"\n#define PRIu64 \"I64u\"\n#define PRIx64 \"I64x\"\n#else\n#include <inttypes.h>\n#endif\nstatic int64_t ftell_x(FILE *fp)\n{\n#if defined(WIN32) && defined(__GNUC__)\n    return ftello64(fp);\n#elif defined(WIN32) && defined(_MSC_VER)\n    return _ftelli64(fp);\n#else\n    return ftello(fp);\n#endif\n}\nstatic int fseek_x(FILE *fp, int64_t offset, int origin)\n{\n#if defined(WIN32) && defined(__GNUC__)\n    return fseeko64(fp, offset, origin);\n#elif defined(WIN32) && defined(_MSC_VER)\n    return _fseeki64(fp, offset, origin);\n#else\n    return fseeko(fp, offset, origin);\n#endif\n}\n/****************************************************************************\n * </PORTABILITY BLOCK>\n ****************************************************************************/\n\n\n\n\n/* PCAP file-format\n\ntypedef struct pcap_hdr_s {\n        guint32 magic_number;   / * magic number * /\n        guint16 version_major;  / * major version number * /\n        guint16 version_minor;  / * minor version number * /\n        gint32  thiszone;       / * GMT to local correction * /\n        guint32 sigfigs;        / * accuracy of timestamps * /\n        guint32 snaplen;        / * max length of captured packets, in octets * /\n        guint32 network;        / * data link type * /\n} pcap_hdr_t;\n\n\n 0  32-bits - \"magic number\"\n 4  16-bits - major version\n    16-bits - minor version\n 8  32-bits - timezone offset (should be zero)\n12  32-bits - time stamp accuracy (should be zero)\n16  32-bits - snap/slice length (maximum packet size)\n20  32-bits - link layer type\n\nMagic number:\n    a1 b2 c3 d4 = big-endian\n    d4 c3 b2 a1 = little-endian\n\nVersion:\n    2.4 = most common version\n\nTimezone offset, Timestamp accuracy:\n    these fields are no longer used\n\nLink-layer type:\n    0        BSD loopback devices, except for later OpenBSD\n    1        Ethernet, and Linux loopback devices\n    6        802.5 Token Ring\n    7        ARCnet\n    8        SLIP\n    9        PPP\n    10        FDDI\n    100        LLC/SNAP-encapsulated ATM\n    101        \"raw IP\", with no link\n    102        BSD/OS SLIP\n    103        BSD/OS PPP\n    104        Cisco HDLC\n    105        802.11\n    108        later OpenBSD loopback devices (with the AF_\n            value in network byte order)\n    113        special Linux \"cooked\" capture\n    114        LocalTalk\n\n\n*/\n/*\n\n802.11\n    11     *  802.11b - 11-mbps\n    12     *  802.11d - operation in multiple regulatory domains\n    13     *  802.11e - wireless multimedia extensions\n    14     *  802.11g - 54-mbps\n    15     *  802.11h - power management\n    16     *  802.11i - MAC security enhancements\n\n */\n\nstruct PcapFile\n{\n    FILE *fp;\n\n    unsigned is_file_header_written:1;\n\n    unsigned start_sec;\n    unsigned start_usec;\n    unsigned end_sec;\n    unsigned end_usec;\n    char filename[256];\n    int byte_order;\n    int linktype;\n    long long frame_number;\n\n    uint64_t file_size;\n    uint64_t bytes_read;\n\n    /**\n     * This is for asynchronous reading of the file.\n     */\n    unsigned char *aio_buffer;\n    size_t aio_buffer_size;\n};\n\n#define CAPFILE_BIGENDIAN       1\n#define CAPFILE_LITTLEENDIAN   2\n#define CAPFILE_ENDIANUNKNOWN   3\n\n\n/** Read a 16-bit value from a capture file, depending upon the byte\n * order within that file */\nstatic unsigned PCAP16(unsigned byte_order, const unsigned char *buf)\n{\n    switch (byte_order) {\n    case CAPFILE_BIGENDIAN: return buf[0]*256 + buf[1];\n    case CAPFILE_LITTLEENDIAN: return buf[1]*256 + buf[0];\n    default: return (unsigned)0xa3a3;\n    }\n}\n/** Read a 32-bit value from a capture file, depending upon the byte\n * order within that file */\nstatic unsigned PCAP32(unsigned byte_order, const unsigned char *buf)\n{\n    switch (byte_order) {\n    case CAPFILE_BIGENDIAN: return buf[0]<<24 | buf[1]<<16 | buf[2] << 8 | buf[3];\n    case CAPFILE_LITTLEENDIAN: return buf[3]<<24 | buf[2]<<16 | buf[1] << 8 | buf[0];\n    default: return (unsigned)0xa3a3;\n    }\n}\n\n/**\n * Return the \"link\" type, such as Ethernet, WiFi, Token Ring, etc.\n */\nint\npcapfile_datalink(struct PcapFile *handle)\n{\n    if (handle)\n        return handle->linktype;\n    else\n        return 0;\n}\n\n\n/**\n * Determine if the blob (the chunk of from the file read at a certain offset)\n * looks like a valid packet\n */\nstatic unsigned\nsmells_like_valid_packet(const unsigned char *px, unsigned length, unsigned byte_order, unsigned link_type)\n{\n    unsigned secs, usecs, original_length, captured_length;\n\n    if (length < 16)\n        return 0;\n\n    secs = PCAP32(byte_order, px+0);\n    usecs = PCAP32(byte_order, px+4);\n    captured_length = PCAP32(byte_order, px+8);\n    original_length = PCAP32(byte_order, px+12);\n\n    if (secs > 0x50000000) return 0; /* after 2010 */\n    if (secs < 0x26000000) return 0; /* before 1990 */\n    if (usecs > 1000000) return 0;\n    if (captured_length > 10000) return 0;\n    if (captured_length < 16) return 0;\n    if (original_length < captured_length) return 0;\n    if (original_length > 10000) return 0;\n\n    if (captured_length + 16 < length) {\n        unsigned secs2, usecs2, original_length2, captured_length2;\n        const unsigned char *px2 = px + captured_length + 16;\n\n        secs2 = PCAP32(byte_order, px2+0);\n        usecs2 = PCAP32(byte_order, px2+4);\n        captured_length2 = PCAP32(byte_order, px2+8);\n        original_length2 = PCAP32(byte_order, px2+12);\n\n        if (secs2 > 0x50000000)\n            return 0;\n        if (secs2 < 0x26000000)\n            return 0;\n        if (usecs2 > 1000000)\n            return 0;\n        if (captured_length2 > 10000)\n            return 0;\n        if (captured_length2 < 16)\n            return 0;\n        if (original_length2 < captured_length2)\n            return 0;\n        if (original_length2 > 10000)\n            return 0;\n        return 1;\n    } else\n    switch (link_type) {\n    case 1: /*ethernet*/\n        if (px[12] == 0x08 && px[13] == 0x00 && px[14] == 0x45)\n            return 1;\n    }\n\n    return 0;\n}\n\n\nunsigned pcapfile_percentdone(struct PcapFile *capfile, uint64_t *r_bytes_read)\n{\n    if (r_bytes_read)\n        *r_bytes_read = capfile->bytes_read;\n\n    if (capfile->fp == NULL)\n        return 100;\n    return (unsigned)(capfile->bytes_read*100/capfile->file_size);\n}\n\n\n/**\n * Read the next packet from the file stream.\n */\nint pcapfile_readframe(\n    struct PcapFile *capfile,\n    unsigned *r_time_secs,\n    unsigned *r_time_usecs,\n    unsigned *r_original_length,\n    unsigned *r_captured_length,\n    unsigned char *buf,\n    unsigned sizeof_buf\n    )\n{\n    size_t bytes_read;\n    unsigned char header[16];\n    unsigned byte_order = capfile->byte_order;\n    unsigned is_corrupt = 0;\n\n    again:\n    /* Read in the 16-byte frame header. */\n    bytes_read = fread(header, 1, 16, capfile->fp);\n    if (bytes_read < 16) {\n        if (bytes_read <= 0) {\n            //fprintf(stderr, \"%s: failed to read header\\n\", capfile->filename);\n            //perror(capfile->filename);\n        } else if (bytes_read == 0)\n            ; /* normal end-of-file */\n        else\n            fprintf(stderr, \"%s: premature end-of-file\\n\", capfile->filename);\n        return 0;\n    }\n    capfile->bytes_read += bytes_read;\n\n    /* Parse the frame header into its four fields */\n    *r_time_secs = PCAP32(byte_order, header);\n    *r_time_usecs = PCAP32(byte_order, header+4);\n    *r_captured_length = PCAP32(byte_order, header+8);\n    *r_original_length = PCAP32(byte_order, header+12);\n\n\n    /* Test the frame heade fields to make sure they are sane */\n    if (*r_time_usecs > 1000100) {\n        if (*r_time_usecs < 1000100) {\n            *r_time_secs += 1;\n            *r_time_usecs -= 1000000;\n        } else if (*r_time_usecs > 0xFFFFFF00) {\n            *r_time_secs -= 1;\n            *r_time_usecs += 1000000;\n            *r_time_usecs &= 0xFFFFFFFF; /* mask off in case of 64-bit ints */\n        } else\n            is_corrupt = 1; /* shouldn't be more than 1-second, but some capture programs erroneously do that */\n    }\n    if (*r_time_usecs == 0\n        && *r_time_secs == 0\n        && *r_original_length == 0\n        && *r_captured_length == 0)\n        goto again;\n\n    if (*r_captured_length > sizeof_buf)\n        is_corrupt = 1;\n    if (*r_original_length < *r_captured_length)\n        is_corrupt = 1;\n    if (*r_original_length < 8)\n        is_corrupt = 1;\n    if (*r_original_length > 160000)\n        is_corrupt = 1;\n\n\n    /*\n     * If the file is corrupted, let's move forward in the\n     * stream and look for packets that aren't corrupted\n     */\n    while (is_corrupt) {\n        /* TODO: we should go backwards a bit in the file */\n        unsigned char tmp[16384];\n        int64_t position;\n        unsigned i;\n\n\n\n        /* Remember the current location. We are going to seek\n         * back to an offset from this location once we find a good\n         * packet.*/\n        position = ftell_x(capfile->fp);\n        if (position == -1) {\n            fprintf(stderr, \"%s:%lld: could not resolve file corruption (ftell)\\n\",\n                capfile->filename, capfile->frame_number);\n            perror(capfile->filename);\n            fseek_x(capfile->fp, 0, SEEK_END);\n            return 0;\n        }\n\n        /* Print an error message indicating corruption was found. Note\n         * that if corruption happens past 4-gigs on a 32-bit system, this\n         * will print an inaccurate number */\n        fprintf(stderr, \"%s:%lld: corruption found at 0x%08\" PRIx64 \" (%\" PRId64 \")\\n\",\n            capfile->filename,\n            capfile->frame_number,\n            position,\n            position\n            );\n\n\n\n        /* Read in the next chunk of data following the corruption. We'll search\n         * this chunk looking for a non-corrupt packet */\n        bytes_read = fread(tmp, 1, sizeof(tmp), capfile->fp);\n\n        /* If we reach the end without finding a good frame, then stop */\n        if (bytes_read == 0) {\n            if (bytes_read <= 0) {\n                fprintf(stderr, \"%s: error at end of file\\n\", capfile->filename);\n                perror(capfile->filename);\n            } else\n                fprintf(stderr, \"%s: premature end of file\\n\", capfile->filename);\n            return 0;\n        }\n        capfile->bytes_read += bytes_read;\n\n        /* Scan forward (one byte at a time ) looking for a non-corrupt\n         * packet located at that spot */\n        for (i=0; i<bytes_read; i++) {\n\n            /* Test the current location */\n            if (!smells_like_valid_packet(tmp+i, (unsigned)(bytes_read-i), byte_order, capfile->linktype))\n                continue;\n\n            /* Woot! We have a non-corrupt packet. Let's now change\n             * the current file-pointer to point to that location.\n             * Notice that we have to be careful when working with\n             * large (>4gig) files on 32-bit systems. The 'fpos_t' is\n             * usually a 64-bit value and can be used to set a position,\n             * but we cannot manipulate it directory (it's an opaque\n             * structure, not an integer), so we have to seek back to the\n             * saved value, then seek relatively forward to the\n             * known-good spot */\n            position = position + i;\n            if (fseek_x(capfile->fp, position, SEEK_SET) != 0) {\n                fprintf(stderr, \"%s: could not resolve file corruption (seek forward)\\n\", capfile->filename);\n                perror(capfile->filename);\n                fseek_x(capfile->fp, 0, SEEK_END);\n                return 0;\n            }\n\n#if 0\n            /* We could stop here, but we are going to try one more thing.\n             * Most cases of corruption will be because the PREVIOUS packet\n             * was truncated, not because the CURRENT packet was bad.\n             * Since we have seeked forward to find the NEXT packet, we\n             * want to now seek backwards and see if there is actually\n             * a good CURRENT packet. */\n            if (fseek(capfile->fp, -2000, SEEK_CUR) == 0) {\n                unsigned endpoint = 2000;\n                unsigned j;\n\n                /* We read in the 2000 bytes prior to the known-good\n                 * packet that we discovered above, and also 16 bytes\n                 * of the current frame (because the validity check\n                 * looks for back-to-back good headers */\n                bytes_read = fread(tmp, 1, endpoint+16, capfile->fp);\n\n                /* Scan BACKWARDS through this chunk looking for a\n                 * length field that points forward back to the known\n                 * good packet */\n                for (j=0; j<endpoint-16; j++) {\n\n                    /* Test the current 4-byte length field and see if it\n                     * matches it's reverse offset. In other words, 108 bytes\n                     * backwards in the data should be a 4-byte length field\n                     * with a value of 100 */\n                    if (PCAP32(byte_order, tmp+endpoint-j-8) != j)\n                        continue;\n\n                    /* Woot! Now that we have found the length field, let's\n                     * test the rest of the data around this point to see\n                     * if it also matches. Note that we are checking the\n                     * PREVIOUS 16-byte header, PREVIOUS contents, and the\n                     * CURRENT 16-byte header */\n                    if (smells_like_valid_packet(tmp+endpoint-j-16, j+16+16, byte_order, capfile->linktype)) {\n                        /* Woot! We have found a good packet. Let's now use that\n                         * as the new location. */\n                        fseek(capfile->fp, -(signed)(j+16+16), SEEK_CUR);\n                        break;\n                    }\n                }\n            } else {\n                /* Oops, there was an error seeking backwards. I'm\n                 * not quite sure what to do here, so we are just\n                 * going to repeat the reset of the file location\n                 * that we did above */\n                if (fseek_x(capfile->fp, position, SEEK_SET) != 0) {\n                    perror(capfile->filename);\n                    fseek_x(capfile->fp, 0, SEEK_END);\n                    return 0;\n                }\n                fseek_x(capfile->fp, i, SEEK_CUR);\n\n            }\n#endif\n\n            /* Print a message saying we've found a good packet. This will\n             * help people figure out where in the file the corruption\n             * happened, so they can figure out why it was corrupt.*/\n            position = ftell_x(capfile->fp);\n            fprintf(stderr, \"%s:%lld: good packet found at 0x%08\" PRIx64 \" (%\" PRId64 \")\\n\",\n                capfile->filename,\n                capfile->frame_number,\n                position,\n                position\n                );\n\n            /* Recurse, continue reading from where we know a good\n             * packet is within the file */\n            return pcapfile_readframe(capfile, r_time_secs, r_time_usecs, r_original_length, r_captured_length, buf, sizeof_buf);\n        }\n\n        /* If we get to this point, we are totally hosed and the corruption\n         * is more severe than a few packets. */\n        printf(\"No valid packet found in chunk\\n\");\n    }\n\n    /*\n     * Read the packet data\n     */\n    bytes_read = fread(buf, 1, *r_captured_length, capfile->fp);\n    if (bytes_read < *r_captured_length) {\n        if (bytes_read <= 0) {\n            fprintf(stderr, \"%s: could not read packet data, frame #%lld\\n\",\n                capfile->filename,\n                    (long long)capfile->frame_number);\n            perror(capfile->filename);\n        } else\n            fprintf(stderr, \"%s: premature end of file\\n\", capfile->filename);\n        return 0;\n    }\n    capfile->bytes_read += bytes_read;\n\n    if (capfile->frame_number == 0) {\n        capfile->start_sec = *r_time_secs;\n        capfile->start_usec = *r_time_usecs;\n    }\n    capfile->end_sec = *r_time_secs;\n    capfile->end_usec = *r_time_usecs;\n    capfile->frame_number++;\n    return 1;\n}\n\nvoid pcapfile_get_timestamps(struct PcapFile *capfile, time_t *start, time_t *end)\n{\n    *start = capfile->start_sec;\n    *end = capfile->end_sec;\n}\n\n\n/**\n * Open a capture file for reading.\n */\nstruct PcapFile *pcapfile_openread(const char *capfilename)\n{\n    FILE *fp;\n    size_t bytes_read;\n    unsigned char buf[24];\n    unsigned byte_order;\n    unsigned linktype;\n    uint64_t file_size = 0xFFFFffff;\n\n    if (capfilename == NULL)\n        return 0;\n\n    /*\n     * Open the file\n     */\n    fp = fopen(capfilename, \"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"%s: could not open capture file\\n\", capfilename);\n        perror(capfilename);\n        return 0;\n    }\n\n    /* Grab info about the file */\n    {\n        struct stat s;\n        memset(&s, 0, sizeof(s));\n        if (stat(capfilename, &s) == 0) {\n            file_size = s.st_size;\n        }\n    }\n\n    /*\n     * Read in the file header\n     */\n    bytes_read = fread(buf, 1, 24, fp);\n    if (bytes_read < 24) {\n        if (bytes_read <= 0) {\n            fprintf(stderr, \"%s: could not read PCAP header\\n\", capfilename);\n            perror(capfilename);\n        } else\n            fprintf(stderr, \"%s: file too short\\n\", capfilename);\n        fclose(fp);\n        return 0;\n    }\n\n    /*\n     * Find the \"Magic Number\", which will tell us what the byte-order\n     * is going to be. There are also odd magic number used by some\n     * speciality systems that hint at other features, such as a 64-bit\n     * version of the file.\n     */\n    switch (buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]) {\n    case 0xa1b2c3d4:   byte_order = CAPFILE_BIGENDIAN; break;\n    case 0xd4c3b2a1:   byte_order = CAPFILE_LITTLEENDIAN; break;\n    default:\n        fprintf(stderr, \"%s: unknown byte-order in cap file\\n\", capfilename);\n        byte_order = CAPFILE_ENDIANUNKNOWN; break;\n    }\n\n\n    /* Version (of the libpcap standard) */\n    {\n        unsigned major = PCAP16(byte_order, buf+4);\n        unsigned minor = PCAP16(byte_order, buf+6);\n\n        if (major != 2 || minor != 4)\n            fprintf(stderr, \"%s: unknown version %d.%d\\n\", capfilename, major, minor);\n    }\n\n    /* Protocol (ethernet, wifi, etc.) */\n    linktype = PCAP32(byte_order, buf+20);\n    if (linktype == 0)\n        linktype = 1;\n    switch (linktype) {\n    case 0x7f:   /* WiFi, with radiotap headers */\n    case 1:       /*ethernet*/\n    case 0x69:   /* WiFi, no radiotap headers */\n    case 119:   /* Prism II headers (also used for things like Atheros madwifi) */\n        break;\n    default:\n        fprintf(stderr, \"%s: unknown cap file linktype = %d (expected Ethernet or wifi)\\n\", capfilename, linktype);\n        fclose(fp);\n        return 0;\n        break;\n    }\n\n    /* Read the first frame's timestamp */\n    {\n        long loc;\n        char tsbuf[8];\n        size_t x;\n\n        loc = ftell(fp);\n        if (loc == -1) {\n            fprintf(stderr, \"%s: ftell failed (file system error? seen with VMware HGFS bug)\\n\", capfilename);\n            perror(capfilename);\n            fclose(fp);\n            return 0;\n        }\n        x = fread(tsbuf, 1, 8, fp);\n        if (x != 8) {\n            perror(capfilename);\n            fclose(fp);\n            return 0;\n        }\n\n        if (fseek(fp, loc, SEEK_SET) != 0) {\n            fprintf(stderr, \"%s: fseek failed (file system error?)\\n\", capfilename);\n            perror(capfilename);\n            fclose(fp);\n            return 0;\n        }\n    }\n\n    /*\n     * Now that the file is open and we have read in the header,\n     * allocate a structure that contains this information\n     * and return that structure.\n     */\n    {\n        struct PcapFile *capfile = 0;\n        capfile = (struct PcapFile*)malloc(sizeof(*capfile));\n        if (capfile == NULL)\n            exit(1);\n        memset(capfile,0,sizeof(*capfile));\n        capfile->byte_order = byte_order;\n\n        snprintf(capfile->filename, sizeof(capfile->filename),\n                 \"%s\", capfilename);\n        capfile->fp = fp;\n        capfile->byte_order = byte_order;\n        capfile->linktype = linktype;\n        capfile->file_size = file_size;\n        capfile->bytes_read = 24; /*from the header*/\n        return capfile;\n    }\n}\n\n\n/**\n * Open a capture file for writing\n */\nstruct PcapFile *pcapfile_openwrite(const char *capfilename, unsigned linktype)\n{\n    char buf[] =\n            \"\\xd4\\xc3\\xb2\\xa1\\x02\\x00\\x04\\x00\"\n            \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n            \"\\xff\\xff\\x00\\x00\\x69\\x00\\x00\\x00\";\n    FILE *fp;\n\n    buf[20] = (char)(linktype>>0);\n    buf[21] = (char)(linktype>>8);\n\n\n    fp = fopen(capfilename, \"wb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"Could not open capture file\\n\");\n        perror(capfilename);\n        return 0;\n    }\n\n\n    if (fwrite(buf, 1, 24, fp) != 24) {\n        fprintf(stderr, \"Could not write capture file header\\n\");\n        perror(capfilename);\n        fclose(fp);\n        return 0;\n    }\n\n    {\n        struct PcapFile *capfile = 0;\n        capfile = (struct PcapFile*)malloc(sizeof(*capfile));\n        if (capfile == NULL)\n            exit(1);\n        memset(capfile,0,sizeof(*capfile));\n\n        snprintf(capfile->filename, sizeof(capfile->filename),\n                 \"%s\", capfilename);\n\n        capfile->fp = fp;\n        capfile->byte_order = CAPFILE_LITTLEENDIAN;\n        capfile->linktype = linktype;\n        return capfile;\n    }\n\n}\n\n/**\n * Open a capture file for \"appending\". This requires that we first\n * read from it and find out how it's formatted, then figure out\n * where the end of the file is so that we can start adding\n * packets at that point.\n */\nstruct PcapFile *pcapfile_openappend(const char *capfilename, unsigned linktype)\n{\n    struct PcapFile *capfile;\n    unsigned char buf[24];\n    unsigned byte_order;\n    unsigned file_linktype;\n    FILE *fp;\n\n\n\n    /* open the file for appending and reading */\n    fp = fopen(capfilename, \"ab+\");\n    if (fp == NULL && errno == ENOENT) {\n        return pcapfile_openwrite(capfilename, linktype);\n    }\n    if (fp == NULL) {\n        fprintf(stderr, \"Could not open capture file to append frame\\n\");\n        perror(capfilename);\n        return pcapfile_openappend(capfilename, linktype);\n    }\n\n    /* Read in the header to discover link type and byte order */\n    if (fread(buf, 1, 24, fp) != 24) {\n        fprintf(stderr, \"Error reading capture file header\\n\");\n        perror(capfilename);\n        fclose(fp);\n        return pcapfile_openappend(capfilename, linktype);\n    }\n\n    /* Seek to the end of the file, where we will start writing\n     * frames from now on. Note that we aren't checking to see if the frames\n     * are corrupt at the end (which happens when the program crashes),\n     * so we may end up writing these frames in a way that cannot be read. */\n    if (fseek(fp, 0, SEEK_END) != 0) {\n        fprintf(stderr, \"Could not seek to end of capture file\\n\");\n        perror(capfilename);\n        fclose(fp);\n        return 0;\n    }\n\n\n    /* Find out the byte order */\n    switch (buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]) {\n    case 0xa1b2c3d4:   byte_order = CAPFILE_BIGENDIAN; break;\n    case 0xd4c3b2a1:   byte_order = CAPFILE_LITTLEENDIAN; break;\n    default:\n        fprintf(stderr, \"%s: unknown byte-order in cap file\\n\", capfilename);\n        fclose(fp);\n        return pcapfile_openappend(capfilename, linktype);\n    }\n\n\n    /* Version */\n    {\n        unsigned major = PCAP16(byte_order, buf+4);\n        unsigned minor = PCAP16(byte_order, buf+6);\n\n        if (major != 2 || minor != 4)\n            fprintf(stderr, \"%s: unknown version %u.%u\\n\", capfilename, major, minor);\n    }\n\n    /* Protocol */\n    file_linktype = PCAP32(byte_order, buf+20);\n    if (linktype != file_linktype) {\n        /* oops, the link types do not agree. Since we want a program to generate\n         * dumps while simultaneously processing multiple inputs, we are going to\n         * create a kludge. Instead of writing to the originally specified file,\n         * we are going to create a new file with the linktype added to it's name */\n        char linkspec[32];\n        size_t linkspec_length;\n        char newname[sizeof(capfile->filename)];\n        size_t i;\n\n        fclose(fp);\n\n        linkspec_length = snprintf(linkspec, sizeof(linkspec), \"-linktype%d\", linktype);\n\n        if (strstr(capfilename, linkspec) || strlen(capfilename) + linkspec_length + 1 > sizeof(newname)) {\n            /* Oops, we have a problem, it looks like the filename already\n             * has the previous linktype in its name for some reason. At this\n             * unlikely point, we just give up */\n            fprintf(stderr, \"Giving up on appending %u-type frames onto a %u-type file\\n\",\n                    linktype, file_linktype);\n            return 0;\n        }\n\n        if (strchr(capfilename, '.'))\n            i = strchr(capfilename, '.')-capfilename;\n        else\n            i = strlen(capfilename);\n\n        memcpy(newname, capfilename, i);\n        memcpy(newname+i, linkspec, linkspec_length);\n        memcpy(newname+i+linkspec_length, capfilename+i, strlen(capfilename+i)+1);\n\n        return pcapfile_openappend(newname, linktype);\n    }\n\n    /* Now that everything has checked out, create a file structure and\n     * return it */\n    {\n\n        capfile = (struct PcapFile*)malloc(sizeof(*capfile));\n        if (capfile == NULL)\n            exit(1);\n        memset(capfile,0,sizeof(*capfile));\n        capfile->byte_order = byte_order;\n        snprintf(capfile->filename, sizeof(capfile->filename),\n                 \"%s\", capfilename);\n        capfile->fp = fp;\n        capfile->byte_order = byte_order;\n        capfile->linktype = linktype;\n    }\n\n    return capfile;\n}\n\n\n/**\n * Close a capture file created by one of the open functions\n * such as 'pcapfile_openread()', 'pcapfile_openwrite()', or\n * 'pcapfile_openappend()'.\n */\nvoid pcapfile_close(struct PcapFile *handle)\n{\n    if (handle == NULL)\n        return;\n    if (handle->fp)\n        fclose(handle->fp);\n    free(handle);\n}\n\n\n/**\n * Called to write a frame of data in libpcap format. This format has a\n * 16-byte header (microseconds, seconds, sliced-length, original-length)\n * followed by the captured data */\nvoid pcapfile_writeframe(\n    struct PcapFile *capfile,\n    const void *buffer,\n    unsigned buffer_size,\n    unsigned original_length,\n    unsigned time_sec,\n    unsigned time_usec)\n{\n    unsigned char header[16];\n\n    if (capfile == NULL || capfile->fp == NULL)\n        return;\n\n    /*\n     * Write timestamp\n     */\n    if (capfile->byte_order == CAPFILE_BIGENDIAN) {\n        header[ 0] = (unsigned char)(time_sec>>24);\n        header[ 1] = (unsigned char)(time_sec>>16);\n        header[ 2] = (unsigned char)(time_sec>> 8);\n        header[ 3] = (unsigned char)(time_sec>> 0);\n\n        header[ 4] = (unsigned char)(time_usec>>24);\n        header[ 5] = (unsigned char)(time_usec>>16);\n        header[ 6] = (unsigned char)(time_usec>> 8);\n        header[ 7] = (unsigned char)(time_usec>> 0);\n\n        header[ 8] = (unsigned char)(buffer_size>>24);\n        header[ 9] = (unsigned char)(buffer_size>>16);\n        header[10] = (unsigned char)(buffer_size>> 8);\n        header[11] = (unsigned char)(buffer_size>> 0);\n\n        header[12] = (unsigned char)(original_length>>24);\n        header[13] = (unsigned char)(original_length>>16);\n        header[14] = (unsigned char)(original_length>> 8);\n        header[15] = (unsigned char)(original_length>> 0);\n\n    } else {\n        header[ 0] = (unsigned char)(time_sec>> 0);\n        header[ 1] = (unsigned char)(time_sec>> 8);\n        header[ 2] = (unsigned char)(time_sec>>16);\n        header[ 3] = (unsigned char)(time_sec>>24);\n\n        header[ 4] = (unsigned char)(time_usec>> 0);\n        header[ 5] = (unsigned char)(time_usec>> 8);\n        header[ 6] = (unsigned char)(time_usec>>16);\n        header[ 7] = (unsigned char)(time_usec>>24);\n\n        header[ 8] = (unsigned char)(buffer_size>> 0);\n        header[ 9] = (unsigned char)(buffer_size>> 8);\n        header[10] = (unsigned char)(buffer_size>>16);\n        header[11] = (unsigned char)(buffer_size>>24);\n\n        header[12] = (unsigned char)(original_length>> 0);\n        header[13] = (unsigned char)(original_length>> 8);\n        header[14] = (unsigned char)(original_length>>16);\n        header[15] = (unsigned char)(original_length>>24);\n\n    }\n\n    if (fwrite(header, 1, 16, capfile->fp) != 16) {\n        fprintf(stderr, \"%s:%lld: could not write packet header\\n\",\n            capfile->filename, capfile->frame_number);\n        perror(capfile->filename);\n        fclose(capfile->fp);\n        capfile->fp = NULL;\n    }\n\n    if (fwrite(buffer, 1, buffer_size, capfile->fp) != buffer_size) {\n        fprintf(stderr, \"%s:%lld: could not write packet contents\\n\",\n            capfile->filename, capfile->frame_number);\n        perror(capfile->filename);\n        fclose(capfile->fp);\n        capfile->fp = NULL;\n    }\n}\n\n"
  },
  {
    "path": "src/rawsock-pcapfile.h",
    "content": "/* Copyright (c) 2007 by Errata Security, All Rights Reserved\n * Programmer(s): Robert David Graham [rdg]\n */\n#ifndef __PCAPFILE_H\n#define __PCAPFILE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#include <stdint.h>\n#include <time.h>\n\nstruct PcapFile;\n\nenum pcapfile_datalink_t {\n    PCAPFILE_ETHERNET = 1,\n    PCAPFILE_WIFi = 105,\n};\n\nint pcapfile_datalink(struct PcapFile *handle);\n\nvoid pcapfile_writeframe(\n    struct PcapFile *capfile,\n    const void *buffer,\n    unsigned buffer_size,\n    unsigned original_length,\n    unsigned time_sec,\n    unsigned time_usec\n    );\n\nstruct PcapFile *pcapfile_openread(const char *capfilename);\nstruct PcapFile *pcapfile_openwrite(const char *capfilename, unsigned linktype);\nstruct PcapFile *pcapfile_openappend(const char *capfilename, unsigned linktype);\n\nunsigned pcapfile_percentdone(struct PcapFile *handle, uint64_t *r_bytes_read);\n\nvoid pcapfile_get_timestamps(struct PcapFile *handle, time_t *start, time_t *end);\n\n/**\n * Set a \"maximum\" size for a file. When the current file fills up with data,\n * it will close that file and open a new one, then continue to write\n * from that point on in the new file.\n */\nvoid pcapfile_set_max(struct PcapFile *capfile, unsigned max_megabytes, unsigned max_files);\n\n/**\n *  Read a single frame from the file.\n *  Returns 0 if failed to read (from error or end of file), and\n *  returns 1 if successful.\n */\nint pcapfile_readframe(\n    struct PcapFile *capfile,\n    unsigned *r_time_secs,\n    unsigned *r_time_usecs,\n    unsigned *r_original_length,\n    unsigned *r_captured_length,\n    unsigned char *buf,\n    unsigned sizeof_buf\n    );\n\n\nvoid pcapfile_close(struct PcapFile *handle);\n\n#ifdef __cplusplus\n}\n#endif\n#endif /*__PCAPFILE_H*/\n"
  },
  {
    "path": "src/rawsock.c",
    "content": "/*\n    portable interface to \"raw sockets\"\n\n    This uses both \"libpcap\" on systems, but on Linux, we try to use the\n    basic raw sockets, bypassing libpcap for better performance.\n*/\n#include \"rawsock.h\"\n#include \"templ-pkt.h\"\n#include \"util-logger.h\"\n#include \"main-ptrace.h\"\n#include \"util-safefunc.h\"\n#include \"stub-pcap.h\"\n#include \"stub-pfring.h\"\n#include \"pixie-timer.h\"\n#include \"main-globals.h\"\n#include \"proto-preprocess.h\"\n#include \"stack-arpv4.h\"\n#include \"stack-ndpv6.h\"\n\n#include \"unusedparm.h\"\n#include \"util-malloc.h\"\n#include <assert.h>\n#include <ctype.h>\n\nstatic int is_pcap_file = 0;\n\n#ifdef WIN32\n#include <winsock.h>\n#include <iphlpapi.h>\n\n#if defined(_MSC_VER)\n#pragma comment(lib, \"IPHLPAPI.lib\")\n#endif\n\n#elif defined(__GNUC__)\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/ioctl.h>\n#include <netinet/in.h>\n#include <net/if.h>\n#include <arpa/inet.h>\n\n#else\n#endif\n\n#include \"rawsock-adapter.h\"\n\n#define SENDQ_SIZE 65536 * 8\n\n\nstruct AdapterNames\n{\n    char *easy_name;\n    char *hard_name;\n};\n\nstruct AdapterNames adapter_names[64];\nunsigned adapter_name_count = 0;\n\n/***************************************************************************\n ***************************************************************************/\n#ifdef WIN32\nint pcap_setdirection(pcap_t *pcap, pcap_direction_t direction)\n{\n    static int (*real_setdirection)(pcap_t *, pcap_direction_t) = 0;\n\n    if (real_setdirection == 0) {\n        void* h = LoadLibraryA(\"wpcap.dll\");\n        if (h == NULL) {\n            fprintf(stderr, \"couldn't load wpcap.dll: %u\\n\", \n                                (unsigned)GetLastError());\n            return -1;\n        }\n\n        real_setdirection = (int (*)(pcap_t*,pcap_direction_t))\n                            GetProcAddress(h, \"pcap_setdirection\");\n        if (real_setdirection == 0) {\n            fprintf(stderr, \"couldn't find pcap_setdirection(): %u\\n\", \n                                (unsigned)GetLastError());\n            return -1;\n        }\n    }\n\n    return real_setdirection(pcap, direction);\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nrawsock_init(void)\n{\n#ifdef WIN32\n    /* Declare and initialize variables */\n\n// It is possible for an adapter to have multiple\n// IPv4 addresses, gateways, and secondary WINS servers\n// assigned to the adapter.\n//\n// Note that this sample code only prints out the\n// first entry for the IP address/mask, and gateway, and\n// the primary and secondary WINS server for each adapter.\n\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD dwRetVal = 0;\n    UINT i;\n\n/* variables used to print DHCP time info */\n    //struct tm newtime;\n    //char buffer[32];\n\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n    pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof (IP_ADAPTER_INFO));\n    if (pAdapterInfo == NULL) {\n        printf(\"Error allocating memory needed to call GetAdaptersinfo\\n\");\n        return;\n    }\n// Make an initial call to GetAdaptersInfo to get\n// the necessary size into the ulOutBufLen variable\n    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);\n        if (pAdapterInfo == NULL) {\n            printf(\"Error allocating memory needed to call GetAdaptersinfo\\n\");\n            return;\n        }\n    }\n\n    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {\n        for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {\n            if (pAdapter->Type != MIB_IF_TYPE_ETHERNET)\n                continue;\n\n            //printf(\"\\tComboIndex: \\t%d\\n\", pAdapter->ComboIndex);\n            //printf(\"\\tAdapter Name: \\t%s\\n\", pAdapter->AdapterName);\n            {\n                size_t name_len = strlen(pAdapter->AdapterName) + 12 + 1;\n                char *name = (char*)malloc(name_len);\n                size_t addr_len = pAdapter->AddressLength * 3 + 1;\n                char *addr = (char*)malloc(addr_len);\n\n                if (name == NULL || addr == NULL)\n                    exit(1);\n\n                snprintf(name, name_len, \"\\\\Device\\\\NPF_%s\", pAdapter->AdapterName);\n\n                //printf(\"\\tAdapter Desc: \\t%s\\n\", pAdapter->Description);\n                //printf(\"\\tAdapter Addr: \\t\");\n                for (i = 0; i < pAdapter->AddressLength; i++) {\n                    if (i == (pAdapter->AddressLength - 1))\n                        snprintf(addr+i*3, addr_len-i*3, \"%.2X\", pAdapter->Address[i]);\n                    else\n                        snprintf(addr+i*3, addr_len-i*3, \"%.2X-\", pAdapter->Address[i]);\n                }\n                //printf(\"%s  ->  %s\\n\", addr, name);\n                adapter_names[adapter_name_count].easy_name = addr;\n                adapter_names[adapter_name_count].hard_name = name;\n                adapter_name_count++;\n            }\n\n            //printf(\"\\tIndex: \\t%d\\n\", pAdapter->Index);\n\n            {\n                size_t name_len = strlen(pAdapter->AdapterName) + 12 + 1;\n                char *name = (char*)malloc(name_len);\n                size_t addr_len = strlen(pAdapter->IpAddressList.IpAddress.String) + 1;\n                char *addr = (char*)malloc(addr_len);\n                if (name == NULL || addr == NULL)\n                    exit(1);\n                snprintf(name, name_len, \"\\\\Device\\\\NPF_%s\", pAdapter->AdapterName);\n                snprintf(addr, addr_len, \"%s\", pAdapter->IpAddressList.IpAddress.String);\n                //printf(\"%s  ->  %s\\n\", addr, name);\n                adapter_names[adapter_name_count].easy_name = addr;\n                adapter_names[adapter_name_count].hard_name = name;\n                adapter_name_count++;\n            }\n\n        }\n    } else {\n        printf(\"GetAdaptersInfo failed with error: %u\\n\", \n                                                    (unsigned)dwRetVal);\n\n    }\n    if (pAdapterInfo)\n        free(pAdapterInfo);\n#else\n    PFRING_init();\n#endif\n    return;\n}\n\n/***************************************************************************\n  * This function prints to the command line a list of all the network\n  * interfaces/devices.\n ***************************************************************************/\nvoid\nrawsock_list_adapters(void)\n{\n    pcap_if_t *alldevs;\n    char errbuf[PCAP_ERRBUF_SIZE];\n    \n    if (PCAP.findalldevs(&alldevs, errbuf) != -1) {\n        int i;\n        const pcap_if_t *d;\n        i=0;\n        \n        if (alldevs == NULL) {\n            fprintf(stderr, \"ERR:libpcap: no adapters found, are you sure you are root?\\n\");\n        }\n        /* Print the list */\n        for(d=alldevs; d; d=PCAP.dev_next(d)) {\n            fprintf(stderr, \" %d  %s \\t\", i++, PCAP.dev_name(d));\n            if (PCAP.dev_description(d))\n                fprintf(stderr, \"(%s)\\n\", PCAP.dev_description(d));\n            else\n                fprintf(stderr, \"(No description available)\\n\");\n        }\n        fprintf(stderr,\"\\n\");\n        PCAP.freealldevs(alldevs);\n    } else {\n        fprintf(stderr, \"%s\\n\", errbuf);\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic const char *\nadapter_from_index(unsigned index)\n{\n    pcap_if_t *alldevs;\n    char errbuf[PCAP_ERRBUF_SIZE];\n    int x;\n\n    x = PCAP.findalldevs(&alldevs, errbuf);\n    if (x != -1) {\n        const pcap_if_t *d;\n\n        if (alldevs == NULL) {\n            fprintf(stderr, \"ERR:libpcap: no adapters found, are you sure you are root?\\n\");\n        }\n        /* Print the list */\n        for(d=alldevs; d; d=PCAP.dev_next(d)) {\n            if (index-- == 0)\n                return PCAP.dev_name(d);\n        }\n        return 0;\n    } else {\n        return 0;\n    }\n}\n\n/***************************************************************************\n * Some methods of transmit queue multiple packets in a buffer then\n * send all queued packets at once. At the end of a scan, we might have\n * some pending packets that haven't been transmitted yet. Therefore,\n * we'll have to flush them.\n ***************************************************************************/\nvoid\nrawsock_flush(struct Adapter *adapter)\n{\n    if (adapter->sendq) {\n        PCAP.sendqueue_transmit(adapter->pcap, adapter->sendq, 0);\n\n        /* Dude, I totally forget why this step is necessary. I vaguely\n         * remember there's a good reason for it though */\n        PCAP.sendqueue_destroy(adapter->sendq);\n        adapter->sendq =  PCAP.sendqueue_alloc(SENDQ_SIZE);\n    }\n\n}\n\n/***************************************************************************\n * wrapper for libpcap's sendpacket\n *\n * PORTABILITY: WINDOWS and PF_RING\n * For performance, Windows and PF_RING can queue up multiple packets, then\n * transmit them all in a chunk. If we stop and wait for a bit, we need\n * to flush the queue to force packets to be transmitted immediately.\n ***************************************************************************/\nint\nrawsock_send_packet(\n    struct Adapter *adapter,\n    const unsigned char *packet,\n    unsigned length,\n    unsigned flush)\n{\n\n    /* Why: this happens in \"offline mode\", when we are benchmarking the\n     * core algorithms without sending packets. */\n    if (adapter == 0)\n        return 0;\n\n    /* Print --packet-trace if debugging */\n    if (adapter->is_packet_trace) {\n        packet_trace(stdout, adapter->pt_start, packet, length, 1);\n    }\n\n    /* PF_RING */\n    if (adapter->ring) {\n        int err = PF_RING_ERROR_NO_TX_SLOT_AVAILABLE;\n\n        while (err == PF_RING_ERROR_NO_TX_SLOT_AVAILABLE) {\n            err = PFRING.send(adapter->ring, packet, length, (unsigned char)flush);\n        }\n        if (err < 0)\n            LOG(1, \"pfring:xmit: ERROR %d\\n\", err);\n        return err;\n    }\n\n    /* WINDOWS PCAP */\n    if (adapter->sendq) {\n        int err;\n        struct pcap_pkthdr hdr;\n        hdr.len = length;\n        hdr.caplen = length;\n\n        err = PCAP.sendqueue_queue(adapter->sendq, &hdr, packet);\n        if (err) {\n            rawsock_flush(adapter);\n            PCAP.sendqueue_queue(adapter->sendq, &hdr, packet);\n        }\n\n        if (flush) {\n            rawsock_flush(adapter);\n        }\n\n        return 0;\n    }\n\n    /* LIBPCAP */\n    if (adapter->pcap)\n        return PCAP.sendpacket(adapter->pcap, packet, length);\n\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint rawsock_recv_packet(\n    struct Adapter *adapter,\n    unsigned *length,\n    unsigned *secs,\n    unsigned *usecs,\n    const unsigned char **packet)\n{\n    \n    if (adapter->ring) {\n        /* This is for doing libpfring instead of libpcap */\n        struct pfring_pkthdr hdr;\n        int err;\n\n        again:\n        err = PFRING.recv(adapter->ring,\n                        (unsigned char**)packet,\n                        0,  /* zero-copy */\n                        &hdr,\n                        0   /* return immediately */\n                        );\n        if (err == PF_RING_ERROR_NO_PKT_AVAILABLE || hdr.caplen == 0) {\n            PFRING.poll(adapter->ring, 1);\n            if (is_tx_done)\n                return 1;\n            goto again;\n        }\n        if (err)\n            return 1;\n\n        *length = hdr.caplen;\n        *secs = (unsigned)hdr.ts.tv_sec;\n        *usecs = (unsigned)hdr.ts.tv_usec;\n\n    } else if (adapter->pcap) {\n        struct pcap_pkthdr hdr;\n\n        *packet = PCAP.next(adapter->pcap, &hdr);\n\n        if (*packet == NULL) {\n            if (is_pcap_file) {\n                //pixie_time_set_offset(10*100000);\n                is_tx_done = 1;\n                is_rx_done = 1;\n            }\n            return 1;\n        }\n\n        *length = hdr.caplen;\n        *secs = (unsigned)hdr.ts.tv_sec;\n        *usecs = (unsigned)hdr.ts.tv_usec;\n    }\n\n\n    return 0;\n}\n\n\n/***************************************************************************\n * Sends the TCP SYN probe packet.\n *\n * Step 1: format the packet\n * Step 2: send it in a portable manner\n ***************************************************************************/\nvoid\nrawsock_send_probe_ipv4(\n    struct Adapter *adapter,\n    ipv4address ip_them, unsigned port_them,\n    ipv4address ip_me, unsigned port_me,\n    unsigned seqno, unsigned flush,\n    struct TemplateSet *tmplset)\n{\n    unsigned char px[2048];\n    size_t packet_length;\n\n    /*\n     * Construct the destination packet\n     */\n    template_set_target_ipv4(tmplset, ip_them, port_them, ip_me, port_me, seqno,\n        px, sizeof(px), &packet_length);\n    \n    /*\n     * Send it\n     */\n    rawsock_send_packet(adapter, px, (unsigned)packet_length, flush);\n}\n\nvoid\nrawsock_send_probe_ipv6(\n    struct Adapter *adapter,\n    ipv6address ip_them, unsigned port_them,\n    ipv6address ip_me, unsigned port_me,\n    unsigned seqno, unsigned flush,\n    struct TemplateSet *tmplset)\n{\n    unsigned char px[2048];\n    size_t packet_length;\n\n    /*\n     * Construct the destination packet\n     */\n    template_set_target_ipv6(tmplset, ip_them, port_them, ip_me, port_me, seqno,\n        px, sizeof(px), &packet_length);\n    \n    /*\n     * Send it\n     */\n    rawsock_send_packet(adapter, px, (unsigned)packet_length, flush);\n}\n\n/***************************************************************************\n * Used on Windows: network adapters have horrible names, so therefore we\n * use numeric indexes instead. You can which adapter you are looking for\n * by typing \"--iflist\" as an option.\n ***************************************************************************/\nstatic int\nis_numeric_index(const char *ifname)\n{\n    int result = 1;\n    int i;\n\n    /* empty strings aren't numbers */\n    if (ifname[0] == '\\0')\n        return 0;\n\n    /* 'true' if all digits */\n    for (i=0; ifname[i]; i++) {\n        char c = ifname[i];\n\n        if (c < '0' || '9' < c)\n            result = 0;\n    }\n\n    return result;\n}\n\n\n/***************************************************************************\n * Used on Windows: if the adapter name is a numeric index, convert it to\n * the full name.\n ***************************************************************************/\nconst char *\nrawsock_win_name(const char *ifname)\n{\n    if (is_numeric_index(ifname)) {\n        const char *new_adapter_name;\n\n        new_adapter_name = adapter_from_index(atoi(ifname));\n        if (new_adapter_name)\n            return new_adapter_name;\n    }\n\n    return ifname;\n}\n\n\n/***************************************************************************\n * Configure the socket to not capture transmitted packets. This is needed\n * because we transmit packets at a rate of millions per second, which will\n * overwhelm the receive thread.\n *\n * PORTABILITY: Windows doesn't seem to support this feature, so instead\n * what we do is apply a BPF filter to ignore the transmits, so that they\n * still get filtered at a low level.\n ***************************************************************************/\nvoid\nrawsock_ignore_transmits(struct Adapter *adapter, const char *ifname)\n{\n    if (adapter->ring) {\n        /* PORTABILITY: don't do anything for PF_RING, because it's\n         * actually done when we create the adapter, because we can't\n         * reconfigure the adapter after it's been activated. */\n        return;\n    }\n\n    if (adapter->pcap) {\n        int err;\n        err = PCAP.setdirection(adapter->pcap, PCAP_D_IN);\n        if (err) {\n            ; //PCAP.perror(adapter->pcap, \"if: pcap_setdirection(IN)\");\n        } else {\n            LOG(2, \"if:%s: not receiving transmits\\n\", ifname);\n        }\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nrawsock_close_adapter(struct Adapter *adapter)\n{\n    if (adapter->ring) {\n        PFRING.close(adapter->ring);\n    }\n    if (adapter->pcap) {\n        PCAP.close(adapter->pcap);\n    }\n    if (adapter->sendq) {\n        PCAP.sendqueue_destroy(adapter->sendq);\n    }\n\n    free(adapter);\n}\n\n/***************************************************************************\n * Does the name look like a PF_RING DNA adapter? Common names are:\n * dna0\n * dna1\n * dna0@1\n *\n ***************************************************************************/\nstatic int\nis_pfring_dna(const char *name)\n{\n    if (strlen(name) < 4)\n        return 0;\n    if (memcmp(name, \"zc:\", 3) == 0)\n        return 1;\n    if (memcmp(name, \"dna\", 3) != 0)\n        return 0;\n\n    name +=3;\n\n    if (!isdigit(name[0]&0xFF))\n        return 0;\n    while (isdigit(name[0]&0xFF))\n        name++;\n\n    if (name[0] == '\\0')\n        return 1;\n\n    if (name[0] != '@')\n        return 0;\n    else\n        name++;\n\n    if (!isdigit(name[0]&0xFF))\n        return 0;\n    while (isdigit(name[0]&0xFF))\n        name++;\n\n    if (name[0] == '\\0')\n        return 1;\n    else\n        return 0;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstruct Adapter *\nrawsock_init_adapter(const char *adapter_name,\n                     unsigned is_pfring,\n                     unsigned is_sendq,\n                     unsigned is_packet_trace,\n                     unsigned is_offline,\n                     const char *bpf_filter,\n                     unsigned is_vlan,\n                     unsigned vlan_id)\n{\n    struct Adapter *adapter;\n    char errbuf[PCAP_ERRBUF_SIZE] = \"pcap\";\n\n    /* BPF filter not supported on some platforms, so ignore this compiler\n     * warning when unused */\n    UNUSEDPARM(bpf_filter);\n\n    adapter = CALLOC(1, sizeof(*adapter));\n    adapter->is_packet_trace = is_packet_trace;\n    adapter->pt_start = 1.0 * pixie_gettime() / 1000000.0;\n\n    adapter->is_vlan = is_vlan;\n    adapter->vlan_id = vlan_id;\n    \n    if (is_offline)\n        return adapter;\n\n    /*----------------------------------------------------------------\n     * PORTABILITY: WINDOWS\n     * If is all digits index, then look in indexed list\n     *----------------------------------------------------------------*/\n    if (is_numeric_index(adapter_name)) {\n        const char *new_adapter_name;\n\n        new_adapter_name = adapter_from_index(atoi(adapter_name));\n        if (new_adapter_name == 0) {\n            fprintf(stderr, \"pcap_open_live(%s) error: bad index\\n\",\n                    adapter_name);\n            return 0;\n        } else\n            adapter_name = new_adapter_name;\n    }\n\n    /*----------------------------------------------------------------\n     * PORTABILITY: PF_RING\n     *  If we've been told to use --pfring, then attempt to open the\n     *  network adapter using the PF_RING API rather than libpcap.\n     *  Since a lot of things can go wrong, we do a lot of extra\n     *  logging here.\n     *----------------------------------------------------------------*/\n    if(is_pfring && !is_pfring_dna(adapter_name)){ /*First ensure pfring dna adapter is available*/\n        fprintf(stderr,\"No pfring adapter available. Please install pfring or run masscan without the --pfring option.\\n\");\n        return 0;\n    }\n\n    if (is_pfring_dna(adapter_name)) {\n        int err;\n        unsigned version;\n\n        /*\n         * Open\n         *\n         * TODO: Do we need the PF_RING_REENTRANT flag? We only have one\n         * transmit and one receive thread, so I don't think we need it.\n         * Also, this reduces performance in half, from 12-mpps to\n         * 6-mpps.\n         * NOTE: I don't think it needs the \"re-entrant\" flag, because it\n         * transmit and receive are separate functions?\n         */\n        LOG(2, \"pfring:'%s': opening...\\n\", adapter_name);\n        adapter->ring = PFRING.open(adapter_name, 1500, 0);//PF_RING_REENTRANT);\n        adapter->pcap = (pcap_t*)adapter->ring;\n        adapter->link_type = 1;\n        if (adapter->ring == NULL) {\n            LOG(0, \"pfring:'%s': OPEN ERROR: %s\\n\",\n                adapter_name, strerror(errno));\n            return 0;\n        } else\n            LOG(1, \"pfring:'%s': successfully opened\\n\", adapter_name);\n\n        /*\n         * Housekeeping\n         */\n        PFRING.set_application_name(adapter->ring, \"masscan\");\n        PFRING.version(adapter->ring, &version);\n        LOG(1, \"pfring: version %d.%d.%d\\n\",\n                (version >> 16) & 0xFFFF,\n                (version >> 8) & 0xFF,\n                (version >> 0) & 0xFF);\n\n        LOG(2, \"pfring:'%s': setting direction\\n\", adapter_name);\n        err = PFRING.set_direction(adapter->ring, rx_only_direction);\n        if (err) {\n            fprintf(stderr, \"pfring:'%s': setdirection = %d\\n\",\n                    adapter_name, err);\n        } else\n            LOG(2, \"pfring:'%s': direction success\\n\", adapter_name);\n\n        /*\n         * Activate\n         *\n         * PF_RING requires a separate activation step.\n         */\n        LOG(2, \"pfring:'%s': activating\\n\", adapter_name);\n        err = PFRING.enable_ring(adapter->ring);\n        if (err != 0) {\n                LOG(0, \"pfring: '%s': ENABLE ERROR: %s\\n\",\n                    adapter_name, strerror(errno));\n                PFRING.close(adapter->ring);\n                adapter->ring = 0;\n                return 0;\n        } else\n            LOG(1, \"pfring:'%s': successfully enabled\\n\", adapter_name);\n\n        return adapter;\n    }\n\n    /*----------------------------------------------------------------\n     * Kludge: for using files\n     *----------------------------------------------------------------*/\n    if (memcmp(adapter_name, \"file:\", 5) == 0) {\n        LOG(1, \"pcap: file: %s\\n\", adapter_name+5);\n        is_pcap_file = 1;\n\n        adapter->pcap = PCAP.open_offline(adapter_name+5, errbuf);\n        adapter->link_type = PCAP.datalink(adapter->pcap);\n    }\n    /*----------------------------------------------------------------\n     * PORTABILITY: LIBPCAP\n     *\n     * This is the standard that should work everywhere.\n     *----------------------------------------------------------------*/\n    {\n        int err;\n        LOG(1, \"[+] if(%s): pcap: %s\\n\", adapter_name, PCAP.lib_version());\n        LOG(2, \"[+] if(%s): opening...\\n\", adapter_name);\n\n        /* This reserves resources, but doesn't actually open the \n         * adapter until we call pcap_activate */\n        adapter->pcap = PCAP.create(adapter_name, errbuf);\n        if (adapter->pcap == NULL) {\n            adapter->pcap = PCAP.open_live(\n                        adapter_name,           /* interface name */\n                        65536,                  /* max packet size */\n                        8,                      /* promiscuous mode */\n                        1000,                   /* read timeout in milliseconds */\n                        errbuf);\n            if (adapter->pcap == NULL) {\n                LOG(0, \"FAIL:%s: can't open adapter: %s\\n\", adapter_name, errbuf);\n                if (strstr(errbuf, \"perm\")) {\n                    LOG(0, \"FAIL: permission denied\\n\");\n                    LOG(0, \" [hint] need to sudo or run as root or something\\n\");\n                }\n                return 0;\n            }\n        } else {\n            err = PCAP.set_snaplen(adapter->pcap, 65536);\n            if (err) {\n                PCAP.perror(adapter->pcap, \"if: set_snaplen\");\n                goto pcap_error;\n            }\n\n            err = PCAP.set_promisc(adapter->pcap, 8);\n            if (err) {\n                PCAP.perror(adapter->pcap, \"if: set_promisc\");\n                goto pcap_error;\n            }\n\n            err = PCAP.set_timeout(adapter->pcap, 1000);\n            if (err) {\n                PCAP.perror(adapter->pcap, \"if: set_timeout\");\n                goto pcap_error;\n            }\n\n            err = PCAP.set_immediate_mode(adapter->pcap, 1);\n            if (err) {\n                PCAP.perror(adapter->pcap, \"if: set_immediate_mode\");\n                goto pcap_error;\n            }\n\n            /* If errors happen, they aren't likely to happen above, but will\n             * happen where when they are applied */\n            err = PCAP.activate(adapter->pcap);\n            switch (err) {\n            case 0:\n                /* drop down below */\n                break;\n            case PCAP_ERROR_PERM_DENIED:\n                LOG(0, \"[-] FAIL: permission denied\\n\");\n                LOG(0, \"    [hint] need to sudo or run as root or something\\n\");\n                goto pcap_error;\n            default:\n\t            LOG(0, \"[-] if(%s): activate:%d: %s\\n\", adapter_name, err, PCAP.geterr(adapter->pcap));\n                if (err < 0)\n                    goto pcap_error;\n            }\n        }\n\n        LOG(1, \"[+] if(%s): successfully opened\\n\", adapter_name);\n\n        \n\n        /* Figure out the link-type. We suport Ethernet and IP */\n        adapter->link_type = PCAP.datalink(adapter->pcap);\n        switch (adapter->link_type) {\n            case -1:\n                PCAP.perror(adapter->pcap, \"if: datalink\");\n                goto pcap_error;\n            case 0: /* Null/Loopback [VPN tunnel] */\n                LOG(1, \"[+] if(%s): VPN tunnel interface found\\n\", adapter_name);\n                break;\n            case 1: /* Ethernet */\n            case 12: /* IP Raw */\n                break;\n            default:\n                LOG(0, \"[-] if(%s): unknown data link type: %u(%s)\\n\",\n                        adapter_name,\n                        adapter->link_type,\n                        PCAP.datalink_val_to_name(adapter->link_type));\n                break;\n        }\n\n    }\n\n    /*----------------------------------------------------------------\n     * PORTABILITY: WINDOWS\n     *\n     * The transmit rate on Windows is really slow, like 40-kpps.\n     * The speed can be increased by using the \"sendqueue\" feature\n     * to roughly 300-kpps.\n     *----------------------------------------------------------------*/\n    adapter->sendq = 0;\n#if defined(WIN32)\n    if (is_sendq)\n        adapter->sendq = PCAP.sendqueue_alloc(SENDQ_SIZE);\n#endif\n\n\n    return adapter;\npcap_error:\n    if (adapter->pcap) {\n        PCAP.close(adapter->pcap);\n        adapter->pcap = NULL;\n    }\n    if (adapter->pcap == NULL) {\n        if (strcmp(adapter_name, \"vmnet1\") == 0) {\n            LOG(0, \" [hint] VMware on Macintosh doesn't support masscan\\n\");\n        }\n        return 0;\n    }\n\n    return NULL;\n}\n\n\n\n/***************************************************************************\n * for testing when two Windows adapters have the same name. Sometimes\n * the \\Device\\NPF_ string is prepended, sometimes not.\n ***************************************************************************/\nint\nrawsock_is_adapter_names_equal(const char *lhs, const char *rhs)\n{\n    if (memcmp(lhs, \"\\\\Device\\\\NPF_\", 12) == 0)\n        lhs += 12;\n    if (memcmp(rhs, \"\\\\Device\\\\NPF_\", 12) == 0)\n        rhs += 12;\n    return strcmp(lhs, rhs) == 0;\n}\n\n\n/***************************************************************************\n * Runs some tests when the \"--debug if\" option is given on the\n * command-line. This is useful to figure out why the interface you\n * are accessing doesn't work.\n ***************************************************************************/\nint\nrawsock_selftest_if(const char *ifname)\n{\n    int err;\n    ipv4address_t ipv4 = 0;\n    ipv6address_t ipv6;\n    ipv4address_t router_ipv4 = 0;\n    macaddress_t source_mac = {{0,0,0,0,0,0}};\n    struct Adapter *adapter;\n    char ifname2[246];\n    ipaddress_formatted_t fmt;\n\n    /*\n     * Get the interface\n     */\n    if (ifname == NULL || ifname[0] == 0) {\n        err = rawsock_get_default_interface(ifname2, sizeof(ifname2));\n        if (err) {\n            printf(\"[-] if = not found (err=%d)\\n\", err);\n            return -1;\n        }\n        ifname = ifname2;\n    }\n    printf(\"[+] if = %s\\n\", ifname);\n\n    /*\n     * Initialize the adapter.\n     */\n    adapter = rawsock_init_adapter(ifname, 0, 0, 0, 0, 0, 0, 0);\n    if (adapter == 0) {\n        printf(\"[-] pcap = failed\\n\");\n        return -1;\n    } else {\n        printf(\"[+] pcap = opened\\n\");\n    }\n\n    /* IPv4 address */\n    ipv4 = rawsock_get_adapter_ip(ifname);\n    if (ipv4 == 0) {\n        printf(\"[-] source-ipv4 = not found (err)\\n\");\n    } else {\n        fmt = ipv4address_fmt(ipv4);\n        printf(\"[+] source-ipv4 = %s\\n\", fmt.string);\n    }\n\n    /* IPv6 address */\n    ipv6 = rawsock_get_adapter_ipv6(ifname);\n    if (ipv6address_is_zero(ipv6)) {\n        printf(\"[-] source-ipv6 = not found\\n\");\n    } else {\n        fmt = ipv6address_fmt(ipv6);\n        printf(\"[+] source-ipv6 = [%s]\\n\", fmt.string);\n    }\n\n    /* MAC address */\n    err = rawsock_get_adapter_mac(ifname, source_mac.addr);\n    if (err) {\n        printf(\"[-] source-mac = not found (err=%d)\\n\", err);\n    } else {\n        fmt = macaddress_fmt(source_mac);\n        printf(\"[+] source-mac = %s\\n\", fmt.string);\n    }\n\n    switch (adapter->link_type) {\n    case 0:\n            printf(\"[+] router-ip = implicit\\n\");\n            printf(\"[+] router-mac = implicit\\n\");\n            break;\n    default:\n        /* IPv4 router IP address */\n        err = rawsock_get_default_gateway(ifname, &router_ipv4);\n        if (err) {\n            fprintf(stderr, \"[-] router-ip = not found(err=%d)\\n\", err);\n        } else {\n            fmt = ipv4address_fmt(router_ipv4);\n            printf(\"[+] router-ip = %s\\n\", fmt.string);\n        }\n\n        /* IPv4 router MAC address */\n        {\n            macaddress_t router_mac = {{0,0,0,0,0,0}};\n            \n            stack_arp_resolve(\n                    adapter,\n                    ipv4,\n                    source_mac,\n                    router_ipv4,\n                    &router_mac);\n\n            if (macaddress_is_zero(router_mac)) {\n                printf(\"[-] router-mac-ipv4 = not found\\n\");\n            } else {\n                fmt = macaddress_fmt(router_mac);\n                printf(\"[+] router-mac-ipv4 = %s\\n\", fmt.string);\n            }\n        }\n        \n\n        /*\n         * IPv6 router MAC address.\n         * If it's not configured, then we need to send a (synchronous) query\n         * to the network in order to discover the location of routers on\n         * the local network\n         */\n        if (!ipv6address_is_zero(ipv6)) {\n            macaddress_t router_mac = {{0,0,0,0,0,0}};\n            \n            stack_ndpv6_resolve(\n                    adapter,\n                    ipv6,\n                    source_mac,\n                    &router_mac);\n\n            if (macaddress_is_zero(router_mac)) {\n                printf(\"[-] router-mac-ipv6 = not found\\n\");\n            } else {\n                fmt = macaddress_fmt(router_mac);\n                printf(\"[+] router-mac-ipv6 = %s\\n\", fmt.string);\n            }\n        }\n    }\n    \n    rawsock_close_adapter(adapter);\n    return 0;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nrawsock_selftest()\n{\n\n    return 0;\n}\n\n"
  },
  {
    "path": "src/rawsock.h",
    "content": "/*\n    raw sockets stuff\n*/\n#ifndef RAWSOCK_H\n#define RAWSOCK_H\n#include \"massip-addr.h\"\n#include <stdio.h>\nstruct Adapter;\nstruct TemplateSet;\n#include \"stack-queue.h\"\n\n\n/**\n * @return\n *      1 on failure\n *      0 on success\n */\nint rawsock_selftest(void);\nint rawsock_selftest_if(const char *ifname);\n\nvoid rawsock_init(void);\n\n/**\n * Does an \"open\" on the network adapter. What actually happens depends upon\n * the operating system and drivers that we are using, but usually this just\n * calls \"pcap_open()\"\n * @param adapter_name\n *      The name of the adapter, like \"eth0\" or \"dna1\".\n * @param is_pfring\n *      Whether we should attempt to use the PF_RING driver (Linux-only)\n * @param is_sendq\n *      Whether we should attempt to use a ring-buffer for sending packets.\n *      Currently Windows-only, but it'll be enabled for Linux soon. Big\n *      performance gains for Windows, but insignificant performance\n *      difference for Linux.\n * @param is_packet_trace\n *      Whether then Nmap --packet-trace option was set on the command-line\n * @param is_offline\n *      Whether the --offline parameter was set on the command-line. If so,\n *      then no network adapter will actually be opened.\n * @return\n *      a fully instantiated network adapter\n */\nstruct Adapter *\nrawsock_init_adapter(const char *adapter_name,\n                     unsigned is_pfring,\n                     unsigned is_sendq,\n                     unsigned is_packet_trace,\n                     unsigned is_offline,\n                     const char *bpf_filter,\n                     unsigned is_vlan,\n                     unsigned vlan_id);\n\n\n/**\n * Print to the command-line the list of available adapters. It's called\n * when the \"--iflist\" option is specified on the command-line.\n */\nvoid rawsock_list_adapters(void);\n\nvoid\nrawsock_send_probe_ipv4(\n    struct Adapter *adapter,\n    ipv4address ip_them, unsigned port_them,\n    ipv4address ip_me, unsigned port_me,\n    unsigned seqno, unsigned flush,\n    struct TemplateSet *tmplset);\n\nvoid\nrawsock_send_probe_ipv6(\n    struct Adapter *adapter,\n    ipv6address ip_them, unsigned port_them,\n    ipv6address ip_me, unsigned port_me,\n    unsigned seqno, unsigned flush,\n    struct TemplateSet *tmplset);\n\n/**\n * Queries the operating-system's network-stack in order to discover\n * the best IPv4 address to use inside our own custom network-stack.\n */\nunsigned rawsock_get_adapter_ip(const char *ifname);\n\n/**\n * Queries the operating-system's network-stack in order to discover\n * the best IPv6 address to use inside our own custom network-stack.\n */\nipv6address rawsock_get_adapter_ipv6(const char *ifname);\n\n/**\n * Given the network adapter name, like 'eth0', find the hardware\n * MAC address. This is needed because we construct raw Ethernet\n * packets, and need to use the interface's MAC address as the\n * source address\n */\nint rawsock_get_adapter_mac(const char *ifname, unsigned char *mac);\n\nint rawsock_get_default_gateway(const char *ifname, unsigned *ipv4);\nint rawsock_get_default_interface(char *ifname, size_t sizeof_ifname);\n\nconst char *rawsock_win_name(const char *ifname);\n\nint rawsock_is_adapter_names_equal(const char *lhs, const char *rhs);\n\n/**\n * Transmit any queued (but not yet transmitted) packets. Useful only when\n * using a high-speed transmit mechanism. Since flushing happens automatically\n * whenever the transmit queue is full, this is only needed in boundary\n * cases, like when shutting down.\n */\nvoid\nrawsock_flush(struct Adapter *adapter);\n\nint rawsock_send_packet(\n    struct Adapter *adapter,\n    const unsigned char *packet,\n    unsigned length,\n    unsigned flush);\n\n/**\n * Called to read the next packet from the network.\n * @param adapter\n *      The network interface on which to receive packets.\n * @param length\n *      returns the length of the packet\n * @param secs\n *      returns the timestamp of the packet as a time_t value (the number\n *      of seconds since Jan 1 1970).\n * @param usecs\n *      returns part of the timestamp, the number of microseconds since the\n *      start of the current second\n * @param packet\n *      returns a pointer to the packet that was read from the network.\n *      The contents of this pointer are good until the next call to this\n *      function.\n * @return\n *      0 for success, something else for failure\n *\n */\nint rawsock_recv_packet(\n    struct Adapter *adapter,\n    unsigned *length,\n    unsigned *secs,\n    unsigned *usecs,\n    const unsigned char **packet);\n\n\n\n/**\n * Optimization functions to tell the underlying network stack\n * to not capture the packets we transmit. Most of the time, Ethernet\n * adapters receive the packets they send, which will cause us a lot\n * of work requiring us to process the flood of packets we generate.\n */\nvoid rawsock_ignore_transmits(struct Adapter *adapter,\n                              const char *ifname);\n\n#endif\n"
  },
  {
    "path": "src/read-service-probes.c",
    "content": "#include \"read-service-probes.h\"\n#include \"util-malloc.h\"\n#include \"massip-port.h\"\n#include \"unusedparm.h\"\n\n#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable:4996)\n#endif\n\n#if defined(WIN32)\n#define strncasecmp _strnicmp\n#endif\n\n/*****************************************************************************\n * Translate string name into enumerated type\n *****************************************************************************/\nstatic enum SvcP_RecordType\nparse_type(const char *line, size_t *r_offset, size_t line_length)\n{\n    static const struct {\n        const char *name;\n        size_t length;\n        enum SvcP_RecordType type;\n    } name_to_types[] = {\n        {\"exclude\",      7, SvcP_Exclude},\n        {\"probe\",        5, SvcP_Probe},\n        {\"match\",        5, SvcP_Match},\n        {\"softmatch\",    9, SvcP_Softmatch},\n        {\"ports\",        5, SvcP_Ports},\n        {\"sslports\",     8, SvcP_Sslports},\n        {\"totalwaitms\", 11, SvcP_Totalwaitms},\n        {\"tcpwrappedms\",12, SvcP_Tcpwrappedms},\n        {\"rarity\",       6, SvcP_Rarity},\n        {\"fallback\",     8, SvcP_Fallback},\n        {0, SvcP_Unknown}\n    };\n\n    size_t i;\n    size_t offset = *r_offset;\n    size_t name_length;\n    size_t name_offset;\n    enum SvcP_RecordType result;\n    \n    /* find length of command name */\n    name_offset = offset;\n    while (offset < line_length && !isspace(line[offset]))\n        offset++; /* name = all non-space chars until first space */\n    name_length = offset - name_offset;\n    while (offset < line_length && isspace(line[offset]))\n        offset++; /* trim whitespace after name */\n    *r_offset = offset;\n    \n    /* Lookup the command name */\n    for (i=0; name_to_types[i].name; i++) {\n        if (name_length != name_to_types[i].length)\n            continue;\n        if (strncasecmp(line+name_offset, name_to_types[i].name, name_length) == 0) {\n            break;\n        }\n    }\n    result = name_to_types[i].type;\n    \n    /* return the type */\n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int\nis_hexchar(int c)\n{\n    switch (c) {\n        case '0': case '1': case '2': case '3': case '4':\n        case '5': case '6': case '7': case '8': case '9':\n        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n            return 1;\n        default:\n            return 0;\n    }\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic unsigned\nhexval(int c)\n{\n    switch (c) {\n        case '0': case '1': case '2': case '3': case '4':\n        case '5': case '6': case '7': case '8': case '9':\n            return c - '0';\n        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n            return c - 'a' + 10;\n        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n            return c - 'A' + 10;\n        default:\n            return (unsigned)~0;\n    }\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic struct RangeList\nparse_ports(struct NmapServiceProbeList *list, const char *line, size_t offset, size_t line_length)\n{\n    /* Examples:\n        Exclude 53,T:9100,U:30000-40000\n        ports 21,43,110,113,199,505,540,1248,5432,30444\n        ports 111,4045,32750-32810,38978\n        sslports 443\n     */\n    unsigned is_error = 0;\n    const char *p;\n    struct RangeList ranges = {0};\n\n    UNUSEDPARM(line_length);\n    \n    p = rangelist_parse_ports(&ranges, line + offset, &is_error, 0);\n    \n    if (is_error) {\n        fprintf(stderr, \"%s:%u:%u: bad port spec\\n\", list->filename, list->line_number, (unsigned)(p-line));\n        rangelist_remove_all(&ranges);\n    }\n    \n    return ranges;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic unsigned\nparse_number(struct NmapServiceProbeList *list, const char *line, size_t offset, size_t line_length)\n{\n    /* Examples:\n     totalwaitms 6000\n     tcpwrappedms 3000\n     rarity 6\n     */\n    unsigned number = 0;\n    \n    while (offset < line_length && isdigit(line[offset])) {\n        number = number * 10;\n        number = number + (line[offset] - '0');\n        offset++;\n    }\n    while (offset < line_length && isspace(line[offset]))\n        offset++;\n    \n    if (offset != line_length) {\n        fprintf(stderr, \"%s:%u:%u: unexpected character '%c'\\n\", list->filename, list->line_number, (unsigned)offset, isprint(line[offset])?line[offset]:'.');\n    }\n    \n    return number;\n}\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic char *\nparse_name(const char *line, size_t *r_offset, size_t line_length)\n{\n    size_t name_offset = *r_offset;\n    size_t name_length;\n    char *result;\n    \n    /* grab all characters until first space */\n    while (*r_offset < line_length && !isspace(line[*r_offset]))\n        (*r_offset)++;\n    name_length = *r_offset - name_offset;\n    if (name_length == 0)\n        return 0;\n    \n    /* trim trailing white space */\n    while (*r_offset < line_length && isspace(line[*r_offset]))\n        (*r_offset)++;\n    \n    /* allocate result string */\n    result = MALLOC(name_length+1);\n    memcpy(result, line + name_offset, name_length+1);\n    result[name_length] = '\\0';\n    \n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic struct ServiceProbeFallback *\nparse_fallback(struct NmapServiceProbeList *list, const char *line, size_t offset, size_t line_length)\n{\n    /* Examples:\n     fallback GetRequest,GenericLines\n     */\n    struct ServiceProbeFallback *result = 0;\n    \n    while (offset < line_length) {\n        size_t name_offset;\n        size_t name_length;\n        struct ServiceProbeFallback *fallback;\n        struct ServiceProbeFallback **r_fallback;\n        \n        /* grab all characters until first space */\n        name_offset = offset;\n        while (offset < line_length && !isspace(line[offset]) && line[offset] != ',')\n            offset++;\n        name_length = offset - name_offset;\n        while (offset < line_length && (isspace(line[offset]) || line[offset] == ','))\n            offset++; /* trim trailing whitespace */\n        if (name_length == 0) {\n            fprintf(stderr, \"%s:%u:%u: name too short\\n\", list->filename, list->line_number, (unsigned)name_offset);\n            break;\n        }\n        \n        /* Allocate a record */\n        fallback = CALLOC(1, sizeof(*fallback));\n        \n        fallback->name = MALLOC(name_length+1);\n        memcpy(fallback->name, line+name_offset, name_length+1);\n        fallback->name[name_length] = '\\0';\n        \n        /* append to end of list */\n        for (r_fallback=&result; *r_fallback; r_fallback = &(*r_fallback)->next)\n            ;\n        fallback->next = *r_fallback;\n        *r_fallback = fallback;\n\n    }\n    \n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nparse_probe(struct NmapServiceProbeList *list, const char *line, size_t offset, size_t line_length)\n{\n    /* Examples:\n     Probe TCP GetRequest q|GET / HTTP/1.0\\r\\n\\r\\n|\n     Probe UDP DNSStatusRequest q|\\0\\0\\x10\\0\\0\\0\\0\\0\\0\\0\\0\\0|\n     Probe TCP NULL q||\n     */\n    const char *filename = list->filename;\n    unsigned line_number = list->line_number;\n    struct NmapServiceProbe *probe;\n    \n    /*\n     * We have a new 'Probe', so append a blank record to the end of\n     * our list\n     */\n    probe = CALLOC(1, sizeof(*probe));\n    if (list->count + 1 >= list->max) {\n        list->max = list->max * 2 + 1;\n        list->list = REALLOCARRAY(list->list, sizeof(list->list[0]), list->max);\n    }\n    list->list[list->count++] = probe;\n    \n    /*\n     * <protocol>\n     */\n    if (line_length - offset <= 3) {\n        fprintf(stderr, \"%s:%u:%u: line too short\\n\", filename, line_number, (unsigned)offset);\n        goto parse_error;\n    }\n    if (memcmp(line+offset, \"TCP\", 3) == 0)\n        probe->protocol = 6;\n    else if (memcmp(line+offset, \"UDP\", 3) == 0)\n        probe->protocol = 17;\n    else {\n        fprintf(stderr, \"%s:%u:%u: unknown protocol\\n\", filename, line_number, (unsigned)offset);\n        goto parse_error;\n    }\n    offset += 3;\n    if (!isspace(line[offset])) {\n        fprintf(stderr, \"%s:%u:%u: unexpected character\\n\", filename, line_number, (unsigned)offset);\n        goto parse_error;\n    }\n    while (offset < line_length && isspace(line[offset]))\n        offset++;\n    \n    /*\n     * <probename>\n     */\n    probe->name = parse_name(line, &offset, line_length);\n    if (probe->name == 0) {\n        fprintf(stderr, \"%s:%u:%u: probename parse error\\n\", filename, line_number, (unsigned)offset);\n        goto parse_error;\n    }\n    \n    /*\n     * <probestring>\n     *  - must start with a 'q' character\n     *  - a delimiter character starts/stop the string, typically '|'\n     *  - Traditional C-style escapes work:\n     *      \\\\ \\0, \\a, \\b, \\f, \\n, \\r, \\t, \\v, and \\xXX\n     */\n    {\n        char delimiter;\n        char *x;\n        size_t x_offset;\n        \n        if (line_length - offset <= 2) {\n            fprintf(stderr, \"%s:%u:%u: line too short\\n\", filename, line_number, (unsigned)offset);\n            goto parse_error;\n        }\n        if (line[offset++] != 'q') {\n            fprintf(stderr, \"%s:%u:%u: expected 'q', found '%c'\\n\", filename, line_number, (unsigned)offset, isprint(line[offset-1])?line[offset-1]:'.');\n            goto parse_error;\n        }\n        \n        /* The next character is a 'delimiter' that starts and stops the next\n         * string of characters, it it usually '|' but may be anything, like '/',\n         * as long as the delimiter itself is not contained inside the string */\n        delimiter = line[offset++];\n        \n        /* allocate a buffer at least as long as the remainder of the line. This is\n         * probably too large, but cannot be too small. It's okay if we waste a\n         * few characters. */\n        x = CALLOC(1, line_length - offset + 1);\n        probe->hellostring = x;\n        \n        /* Grab all the characters until the next delimiter, translating escaped\n         * characters as needed */\n        x_offset = 0;\n        while (offset < line_length && line[offset] != delimiter) {\n            \n            /* Normal case: unescaped characters */\n            if (line[offset] != '\\\\') {\n                x[x_offset++] = line[offset++];\n                continue;\n            }\n            \n            /* skip escape character '\\\\' */\n            offset++;\n            if (offset >= line_length || line[offset] == delimiter) {\n                fprintf(stderr, \"%s:%u:%u: premature end of field\\n\", filename, line_number, (unsigned)offset);\n                goto parse_error;\n            }\n            \n            /* Handled escape sequence */\n            switch (line[offset++]) {\n                default:\n                    fprintf(stderr, \"%s:%u: %.*s\\n\", filename, line_number, (unsigned)line_length, line);\n                    fprintf(stderr, \"%s:%u:%u: unexpected escape character '%c'\\n\", filename, line_number, (unsigned)offset-1, isprint(line[offset-1])?line[offset-1]:'.');\n                    goto parse_error;\n                case '\\\\':\n                    x[x_offset++] = '\\\\';\n                    break;\n                case '0':\n                    x[x_offset++] = '\\0';\n                    break;\n                case 'a':\n                    x[x_offset++] = '\\a';\n                    break;\n                case 'b':\n                    x[x_offset++] = '\\b';\n                    break;\n                case 'f':\n                    x[x_offset++] = '\\f';\n                    break;\n                case 'n':\n                    x[x_offset++] = '\\n';\n                    break;\n                case 'r':\n                    x[x_offset++] = '\\r';\n                    break;\n                case 't':\n                    x[x_offset++] = '\\t';\n                    break;\n                case 'v':\n                    x[x_offset++] = '\\v';\n                    break;\n                case 'x':\n                    /* make sure at least 2 characters exist in input, either due\n                     * to line-length or the delimiter */\n                    if (offset + 2 >= line_length || line[offset+0] == delimiter || line[offset+1] == delimiter) {\n                        fprintf(stderr, \"%s:%u:%u: line too short\\n\", filename, line_number, (unsigned)offset);\n                        goto parse_error;\n                    }\n                    \n                    /* make sure those two characters are hex digits */\n                    if (!is_hexchar(line[offset+0]) || !is_hexchar(line[offset+1])) {\n                        fprintf(stderr, \"%s:%u:%u: expected hex, found '%c%c'\\n\", filename, line_number, (unsigned)offset,\n                                isprint(line[offset+1])?line[offset+1]:'.',\n                                isprint(line[offset+2])?line[offset+2]:'.'\n                                );\n                        goto parse_error;\n                    }\n                    \n                    /* parse those two hex digits */\n                    x[x_offset++] = (char)(hexval(line[offset+0])<< 4 | hexval(line[offset+1]));\n                    offset += 2;\n                    break;\n            }\n        }\n        probe->hellolength = x_offset;\n        \n        if (offset >= line_length || line[offset] != delimiter) {\n            fprintf(stderr, \"%s:%u:%u: missing end delimiter '%c'\\n\", filename, line_number, (unsigned)offset, isprint(delimiter)?delimiter:'.');\n            goto parse_error;\n        }\n        //offset++;\n    }\n\n    \n    return;\n    \nparse_error:\n    if (probe->name != 0)\n        free(probe->name);\n    if (probe->hellostring != 0)\n        free(probe->hellostring);\n    probe->hellostring = 0;\n    free(probe);\n    list->count--;\n}\n\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic struct ServiceProbeMatch *\nparse_match(struct NmapServiceProbeList *list, const char *line, size_t offset, size_t line_length)\n{\n    /* Examples:\n     match ftp m/^220.*Welcome to .*Pure-?FTPd (\\d\\S+\\s*)/ p/Pure-FTPd/ v/$1/ cpe:/a:pureftpd:pure-ftpd:$1/\n     match ssh m/^SSH-([\\d.]+)-OpenSSH[_-]([\\w.]+)\\r?\\n/i p/OpenSSH/ v/$2/ i/protocol $1/ cpe:/a:openbsd:openssh:$2/\n     match mysql m|^\\x10\\0\\0\\x01\\xff\\x13\\x04Bad handshake$| p/MySQL/ cpe:/a:mysql:mysql/\n     match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ|\n     match uucp m|^login: login: login: $| p/NetBSD uucpd/ o/NetBSD/ cpe:/o:netbsd:netbsd/a\n     match printer m|^([\\w-_.]+): lpd: Illegal service request\\n$| p/lpd/ h/$1/\n     match afs m|^[\\d\\D]{28}\\s*(OpenAFS)([\\d\\.]{3}[^\\s\\0]*)\\0| p/$1/ v/$2/\n     */\n    const char *filename = list->filename;\n    unsigned line_number = list->line_number;\n    struct ServiceProbeMatch *match;\n    \n    \n    match = CALLOC(1, sizeof(*match));\n    \n    /*\n     * <servicename>\n     */\n    match->service = parse_name(line, &offset, line_length);\n    if (match->service == 0) {\n        fprintf(stderr, \"%s:%u:%u: servicename is empty\\n\", filename, line_number, (unsigned)offset);\n        goto parse_error;\n    }\n    \n    /*\n     * <pattern>\n     *  - must start with a 'm' character\n     *  - a delimiter character starts/stop the string, typically '/' or '|'\n     *  - contents are PCRE regex\n     */\n    {\n        char delimiter;\n        size_t regex_offset;\n        size_t regex_length;\n        \n        /* line must start with 'm' */\n        if (line_length - offset <= 2) {\n            fprintf(stderr, \"%s:%u:%u: line too short\\n\", filename, line_number, (unsigned)offset);\n            goto parse_error;\n        }\n        if (line[offset] != 'm') {\n            fprintf(stderr, \"%s:%u:%u: expected 'm', found '%c'\\n\", filename, line_number, (unsigned)offset, isprint(line[offset])?line[offset]:'.');\n            goto parse_error;\n        }\n        offset++;\n        \n        /* next character is the delimiter */\n        delimiter = line[offset++];\n        \n        /* Find the length of the regex */\n        regex_offset = offset;\n        while (offset < line_length && line[offset] != delimiter)\n            offset++;\n        regex_length = offset - regex_offset;\n        if (offset >= line_length || line[offset] != delimiter) {\n            fprintf(stderr, \"%s:%u:%u: missing ending delimiter '%c'\\n\", filename, line_number, (unsigned)offset, isprint(delimiter)?delimiter:'.');\n            goto parse_error;\n        } else\n            offset++;\n        \n        /* add regex pattern to record */\n        match->regex_length = regex_length;\n        match->regex = MALLOC(regex_length  + 1);\n        memcpy(match->regex, line+regex_offset, regex_length + 1);\n        match->regex[regex_length] = '\\0';\n        \n        \n        /* Verify the regex options characters */\n        while (offset<line_length && !isspace(line[offset])) {\n            switch (line[offset]) {\n                case 'i':\n                    match->is_case_insensitive = 1;\n                    break;\n                case 's':\n                    match->is_include_newlines = 1;\n                    break;\n                default:\n                    fprintf(stderr, \"%s:%u:%u: unknown regex pattern option '%c'\\n\", filename, line_number, (unsigned)offset, isprint(line[offset])?line[offset]:'.');\n                    goto parse_error;\n            }\n            offset++;\n        }\n        while (offset<line_length && isspace(line[offset]))\n            offset++;\n    }\n    \n    /*\n     * <versioninfo>\n     *  - several optional fields\n     *  - each file starts with identifier (p v i h o d cpe:)\n     *  - next comes the delimiter character (preferably '/' slash)\n     *  - next comes data\n     *  - ends with delimiter\n     */\n    while (offset < line_length) {\n        char id;\n        char delimiter;\n        size_t value_length;\n        size_t value_offset;\n        int is_a = 0;\n        enum SvcV_InfoType type;\n        \n        /* Make sure we have enough characters for a versioninfo string */\n        if (offset >= line_length)\n            break;\n        if (offset + 2 >= line_length) {\n            fprintf(stderr, \"%s:%u:%u: unexpected character at end of line '%c'\\n\", filename, line_number, (unsigned)offset, isprint(line[offset])?line[offset]:'.');\n            goto parse_error;\n        }\n        \n        /* grab the 'id' character, which is either singe letter or the string 'cpe:' */\n        id = line[offset++];\n        if (id == 'c') {\n            if (offset + 3 >= line_length) {\n                fprintf(stderr, \"%s:%u:%u: unexpected character at end of line '%c'\\n\", filename, line_number, (unsigned)offset, isprint(line[offset])?line[offset]:'.');\n                goto parse_error;\n            }\n            if (memcmp(line+offset, \"pe:\", 3) != 0) {\n                fprintf(stderr, \"%s:%u:%u: expected string 'cpe:'\\n\", filename, line_number, (unsigned)offset);\n                goto parse_error;\n            }\n            offset += 3;\n        }\n        switch (id) {\n            case 'p':\n                type = SvcV_ProductName;\n                break;\n            case 'v':\n                type = SvcV_Version;\n                break;\n            case 'i':\n                type = SvcV_Info;\n                break;\n            case 'h':\n                type = SvcV_Hostname;\n                break;\n            case 'o':\n                type = SvcV_OperatingSystem;\n                break;\n            case 'd':\n                type = SvcV_DeviceType;\n                break;\n            case 'c':\n                type = SvcV_CpeName;\n                break;\n            default:\n                fprintf(stderr, \"%s:%u:%u: versioninfo unknown identifier '%c'\\n\", filename, line_number, (unsigned)offset, isprint(id)?id:'.');\n                goto parse_error;\n        }\n        \n        /* grab the delimiter */\n        if (offset + 2 >= line_length) {\n            fprintf(stderr, \"%s:%u:%u: line too short\\n\", filename, line_number, (unsigned)offset);\n            goto parse_error;\n        }\n        delimiter = line[offset++];\n        \n        /* Grab the contents of this string */\n        value_offset = offset;\n        while (offset < line_length && line[offset] != delimiter)\n            offset++;\n        value_length = offset - value_offset;\n        if (offset >= line_length || line[offset] != delimiter) {\n            fprintf(stderr, \"%s:%u:%u: missing ending delimiter '%c'\\n\", filename, line_number, (unsigned)offset, isprint(delimiter)?delimiter:'.');\n            goto parse_error;\n        } else\n            offset++;\n        if (id == 'c' && offset + 1 <= line_length && line[offset] == 'a') {\n            is_a = 1;\n            offset++;\n        }\n        if (offset < line_length && !isspace(line[offset])) {\n            fprintf(stderr, \"%s:%u:%u: unexpected character after delimiter '%c'\\n\", filename, line_number, (unsigned)offset, isprint(delimiter)?delimiter:'.');\n            goto parse_error;\n        }\n        while (offset < line_length && isspace(line[offset]))\n            offset++;\n\n        /* Create a versioninfo record */\n        {\n            struct ServiceVersionInfo *v;\n            struct ServiceVersionInfo **r_v;\n            \n            \n            v = CALLOC(1, sizeof(*v));\n            v->type = type;\n            v->value = MALLOC(value_length + 1);\n            memcpy(v->value, line+value_offset, value_length+1);\n            v->value[value_length] = '\\0';\n            v->is_a = is_a;\n            \n            /* insert at end of list */\n            for (r_v = &match->versioninfo; *r_v; r_v = &(*r_v)->next)\n                ;\n            v->next = *r_v;\n            *r_v = v;\n            \n        }\n        \n    }\n    \n    return match;\n    \nparse_error:\n    free(match->regex);\n    free(match->service);\n    while (match->versioninfo) {\n        struct ServiceVersionInfo *v = match->versioninfo;\n        match->versioninfo = v->next;\n        if (v->value)\n            free(v->value);\n        free(v);\n    }\n    free(match);\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nparse_line(struct NmapServiceProbeList *list, const char *line)\n{\n    const char *filename = list->filename;\n    unsigned line_number = list->line_number;\n    size_t line_length;\n    size_t offset;\n    enum SvcP_RecordType type;\n    struct RangeList ranges = {0};\n    struct NmapServiceProbe *probe;\n    \n    \n    /* trim whitespace */\n    offset = 0;\n    line_length = strlen(line);\n    while (offset && isspace(line[offset]))\n        offset++;\n    while (line_length && isspace(line[line_length-1]))\n        line_length--;\n    \n    /* Ignore comment lines */\n    if (ispunct(line[offset]))\n        return;\n    \n    /* Ignore empty lines */\n    if (offset >= line_length)\n        return;\n    \n    /* parse the type field field */\n    type = parse_type(line, &offset, line_length);\n    \n    /* parse the remainder of the line, depending upon the type */\n    switch ((int)type) {\n        case SvcP_Unknown:\n            fprintf(stderr, \"%s:%u:%u: unknown type: '%.*s'\\n\", filename, line_number, (unsigned)offset, (int)offset-0, line);\n            return;\n        case SvcP_Exclude:\n            if (list->count) {\n                /* The 'Exclude' directive is only valid at the top of the file,\n                 * before any Probes */\n                fprintf(stderr, \"%s:%u:%u: 'Exclude' directive only valid before any 'Probe'\\n\", filename, line_number, (unsigned)offset);\n            } else {\n                ranges = parse_ports(list, line, offset, line_length);\n                if (ranges.count == 0) {\n                    fprintf(stderr, \"%s:%u:%u: 'Exclude' bad format\\n\", filename, line_number, (unsigned)offset);\n                } else {\n                    rangelist_merge(&list->exclude, &ranges);\n                    rangelist_remove_all(&ranges);\n                }\n            }\n            return;\n        case SvcP_Probe:\n            /* Creates a new probe record, all the other types (except 'Exclude') operate\n             * on the current probe record */\n            parse_probe(list, line, offset, line_length);\n            return;\n    }\n    \n    /*\n     * The remaining items only work in the context of the current 'Probe'\n     * directive\n     */\n    if (list->count == 0) {\n        fprintf(stderr, \"%s:%u:%u: 'directive only valid after a 'Probe'\\n\", filename, line_number, (unsigned)offset);\n        return;\n    }\n    probe = list->list[list->count-1];\n    \n    switch ((int)type) {\n        case SvcP_Ports:\n            ranges = parse_ports(list, line, offset, line_length);\n            if (ranges.count == 0) {\n                fprintf(stderr, \"%s:%u:%u: bad ports format\\n\", filename, line_number, (unsigned)offset);\n            } else {\n                rangelist_merge(&probe->ports, &ranges);\n                rangelist_remove_all(&ranges);\n            }\n            break;\n        case SvcP_Sslports:\n            ranges = parse_ports(list, line, offset, line_length);\n            if (ranges.count == 0) {\n                fprintf(stderr, \"%s:%u:%u: bad ports format\\n\", filename, line_number, (unsigned)offset);\n            } else {\n                rangelist_merge(&probe->sslports, &ranges);\n                rangelist_remove_all(&ranges);\n            }\n            break;\n        case SvcP_Match:\n        case SvcP_Softmatch:\n            {\n                struct ServiceProbeMatch *match;\n            \n                match = parse_match(list, line, offset, line_length);\n                if (match) {\n                    struct ServiceProbeMatch **r_match;\n                    \n                    /* put at end of list */\n                    for (r_match = &probe->match; *r_match; r_match = &(*r_match)->next)\n                        ;\n                    match->next = *r_match;\n                    *r_match = match;\n                    match->is_softmatch = (type == SvcP_Softmatch);\n                }\n            }\n            break;\n        \n        case SvcP_Totalwaitms:\n            probe->totalwaitms = parse_number(list, line, offset, line_length);\n            break;\n        case SvcP_Tcpwrappedms:\n            probe->tcpwrappedms = parse_number(list, line, offset, line_length);\n            break;\n        case SvcP_Rarity:\n            probe->rarity = parse_number(list, line, offset, line_length);\n            break;\n        case SvcP_Fallback:\n        {\n            struct ServiceProbeFallback *fallback;\n            fallback = parse_fallback(list, line, offset, line_length);\n            if (fallback) {\n                fallback->next = probe->fallback;\n                probe->fallback = fallback;\n            }\n        }\n            break;\n    }\n\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic struct NmapServiceProbeList *\nnmapserviceprobes_new(const char *filename)\n{\n    struct NmapServiceProbeList *result;\n    \n    result = CALLOC(1, sizeof(*result));\n    result->filename = filename;\n\n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstruct NmapServiceProbeList *\nnmapserviceprobes_read_file(const char *filename)\n{\n    FILE *fp;\n    char line[32768];\n    struct NmapServiceProbeList *result;\n    \n    /*\n     * Open the file\n     */\n    fp = fopen(filename, \"rt\");\n    if (fp == NULL) {\n        perror(filename);\n        return 0;\n    }\n\n    /*\n     * Create the result structure\n     */\n    result = nmapserviceprobes_new(filename);\n    \n    /*\n     * parse all lines in the text file\n     */\n    while (fgets(line, sizeof(line), fp)) {\n\n        /* Track line number for error messages */\n        result->line_number++;\n\n        /* Parse this string into a record */\n        parse_line(result, line);\n    }\n    \n    fclose(fp);\n    result->filename = 0; /* name no longer valid after this point */\n    result->line_number = (unsigned)~0; /* line number no longer valid after this point */\n    \n    nmapserviceprobes_print(result, stdout);\n    \n    return result;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nnmapserviceprobes_free_record(struct NmapServiceProbe *probe)\n{\n    if (probe->name)\n        free(probe->name);\n    if (probe->hellostring)\n        free(probe->hellostring);\n    rangelist_remove_all(&probe->ports);\n    rangelist_remove_all(&probe->sslports);\n    while (probe->match) {\n        struct ServiceProbeMatch *match = probe->match;\n        probe->match = match->next;\n        free(match->regex);\n        free(match->service);\n        while (match->versioninfo) {\n            struct ServiceVersionInfo *v = match->versioninfo;\n            match->versioninfo = v->next;\n            if (v->value)\n                free(v->value);\n            free(v);\n        }\n        free(match);\n    }\n    while (probe->fallback) {\n        struct ServiceProbeFallback *fallback;\n        \n        fallback = probe->fallback;\n        probe->fallback = fallback->next;\n        if (fallback->name)\n            free(fallback->name);\n        free(fallback);\n    }\n\n    free(probe);\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nnmapserviceprobes_print_ports(const struct RangeList *ranges, FILE *fp, const char *prefix, int default_proto)\n{\n    unsigned i;\n    \n    /* don't print anything if no ports */\n    if (ranges == NULL || ranges->count == 0)\n        return;\n    \n    /* 'Exclude', 'ports', 'sslports' */\n    fprintf(fp, \"%s \", prefix);\n    \n    /* print all ports */\n    for (i=0; i<ranges->count; i++) {\n        int proto;\n        int begin = ranges->list[i].begin;\n        int end = ranges->list[i].end;\n        \n        if (Templ_TCP <= begin && begin < Templ_UDP)\n            proto = Templ_TCP;\n        else if (Templ_UDP <= begin && begin < Templ_SCTP)\n            proto = Templ_UDP;\n        else\n            proto = Templ_SCTP;\n        \n        /* If UDP, shift down */\n        begin -= proto;\n        end -= proto;\n        \n        /* print comma between ports, but not for first port */\n        if (i)\n            fprintf(fp, \",\");\n        \n        /* Print either one number for a single port, or two numbers for a range */\n        if (default_proto != proto) {\n            default_proto = proto;\n            switch (proto) {\n                case Templ_TCP: fprintf(fp, \"T:\"); break;\n                case Templ_UDP: fprintf(fp, \"U:\"); break;\n                case Templ_SCTP: fprintf(fp, \"S\"); break;\n                case Templ_ICMP_echo: fprintf(fp, \"e\");  break;\n                case Templ_ICMP_timestamp: fprintf(fp, \"t\");  break;\n                case Templ_ARP: fprintf(fp, \"A\"); break;\n                case Templ_VulnCheck: fprintf(fp, \"v\"); break;\n            }\n        }\n        fprintf(fp, \"%u\", begin);\n        if (end > begin)\n            fprintf(fp, \"-%u\", end);\n    }\n    fprintf(fp, \"\\n\");\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic int\ncontains_char(const char *string, size_t length, int c)\n{\n    size_t i;\n    for (i=0; i<length; i++) {\n        if (string[i] == c)\n            return 1;\n    }\n    return 0;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nnmapserviceprobes_print_dstring(FILE *fp, const char *string, size_t length, int delimiter)\n{\n    size_t i;\n    \n    /* If the string contains the preferred delimiter, then choose a different\n     * delimiter */\n    if (contains_char(string, length, delimiter)) {\n        static const char *delimiters = \"|/\\\"'#*+-!@$%^&()_=\";\n        \n        for (i=0; delimiters[i]; i++) {\n            delimiter = delimiters[i];\n            if (!contains_char(string, length, delimiter))\n                break;\n        }\n    }\n    \n    /* print start delimiter */\n    fprintf(fp, \"%c\", delimiter);\n    \n    /* print the string */\n    for (i=0; i<length; i++) {\n        char c = string[i];\n        fprintf(fp, \"%c\", c);\n    }\n    \n    /* print end delimiter */\n    fprintf(fp, \"%c\", delimiter);\n    \n}\n/*****************************************************************************\n *****************************************************************************/\nstatic void\nnmapserviceprobes_print_hello(FILE *fp, const char *string, size_t length, int delimiter)\n{\n    size_t i;\n    \n    /* If the string contains the preferred delimiter, then choose a different\n     * delimiter */\n    if (contains_char(string, length, delimiter)) {\n        static const char *delimiters = \"|/\\\"'#*+-!@$%^&()_=\";\n        \n        for (i=0; delimiters[i]; i++) {\n            delimiter = delimiters[i];\n            if (!contains_char(string, length, delimiter))\n                break;\n        }\n    }\n    \n    /* print start delimiter */\n    fprintf(fp, \"%c\", delimiter);\n    \n    /* print the string */\n    for (i=0; i<length; i++) {\n        char c = string[i];\n        \n        switch (c) {\n            case '\\\\':\n                fprintf(fp, \"\\\\\\\\\");\n                break;\n            case '\\0':\n                fprintf(fp, \"\\\\0\");\n                break;\n            case '\\a':\n                fprintf(fp, \"\\\\a\");\n                break;\n            case '\\b':\n                fprintf(fp, \"\\\\b\");\n                break;\n            case '\\f':\n                fprintf(fp, \"\\\\f\");\n                break;\n            case '\\n':\n                fprintf(fp, \"\\\\n\");\n                break;\n            case '\\r':\n                fprintf(fp, \"\\\\r\");\n                break;\n            case '\\t':\n                fprintf(fp, \"\\\\t\");\n                break;\n            case '\\v':\n                fprintf(fp, \"\\\\v\");\n                break;\n            default:\n                if (isprint(c))\n                    fprintf(fp, \"%c\", c);\n                else\n                    fprintf(fp, \"\\\\x%02x\", ((unsigned)c)&0xFF);\n                break;\n                \n        }\n    }\n    \n    /* print end delimiter */\n    fprintf(fp, \"%c\", delimiter);\n    \n}\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nnmapserviceprobes_print(const struct NmapServiceProbeList *list, FILE *fp)\n{\n    unsigned i;\n    if (list == NULL)\n        return;\n    \n    nmapserviceprobes_print_ports(&list->exclude, fp, \"Exclude\", ~0);\n    \n    for (i=0; i<list->count; i++) {\n        struct NmapServiceProbe *probe = list->list[i];\n        struct ServiceProbeMatch *match;\n        \n        /* print the first part of the probe */\n        fprintf(fp, \"Probe %s %s q\",\n                (probe->protocol==6)?\"TCP\":\"UDP\",\n                probe->name);\n        \n        /* print the query/hello string */\n        nmapserviceprobes_print_hello(fp, probe->hellostring, probe->hellolength, '|');\n        \n        fprintf(fp, \"\\n\");\n        if (probe->rarity)\n            fprintf(fp, \"rarity %u\\n\", probe->rarity);\n        if (probe->totalwaitms)\n            fprintf(fp, \"totalwaitms %u\\n\", probe->totalwaitms);\n        if (probe->tcpwrappedms)\n            fprintf(fp, \"tcpwrappedms %u\\n\", probe->tcpwrappedms);\n        nmapserviceprobes_print_ports(&probe->ports, fp, \"ports\", (probe->protocol==6)?Templ_TCP:Templ_UDP);\n        nmapserviceprobes_print_ports(&probe->sslports, fp, \"sslports\", (probe->protocol==6)?Templ_TCP:Templ_UDP);\n        \n        for (match=probe->match; match; match = match->next) {\n            struct ServiceVersionInfo *vi;\n            \n            fprintf(fp, \"match %s m\", match->service);\n            nmapserviceprobes_print_dstring(fp, match->regex, match->regex_length, '/');\n            if (match->is_case_insensitive)\n                fprintf(fp, \"i\");\n            if (match->is_include_newlines)\n                fprintf(fp, \"s\");\n            fprintf(fp, \" \");\n            \n            for (vi=match->versioninfo; vi; vi=vi->next) {\n                const char *tag;\n                switch (vi->type) {\n                    case SvcV_Unknown:          tag = \"u\"; break;\n                    case SvcV_ProductName:      tag = \"p\"; break;\n                    case SvcV_Version:          tag = \"v\"; break;\n                    case SvcV_Info:             tag = \"i\"; break;\n                    case SvcV_Hostname:         tag = \"h\"; break;\n                    case SvcV_OperatingSystem:  tag = \"o\"; break;\n                    case SvcV_DeviceType:       tag = \"e\"; break;\n                    case SvcV_CpeName:          tag = \"cpe:\"; break;\n                    default: tag = \"\";\n                }\n                fprintf(fp, \"%s\", tag);\n                nmapserviceprobes_print_dstring(fp, vi->value, strlen(vi->value), '/');\n                if (vi->is_a)\n                    fprintf(fp, \"a\");\n                fprintf(fp, \" \");\n            }\n            fprintf(fp, \"\\n\");\n        }\n        \n    }\n}\n\n/*****************************************************************************\n *****************************************************************************/\nvoid\nnmapserviceprobes_free(struct NmapServiceProbeList *list)\n{\n    unsigned i;\n    \n    if (list == NULL)\n        return;\n    \n    for (i=0; list->count; i++) {\n        nmapserviceprobes_free_record(list->list[i]);\n    }\n    \n    if (list->list)\n        free(list->list);\n    free(list);\n}\n\n/*****************************************************************************\n *****************************************************************************/\nint\nnmapserviceprobes_selftest(void)\n{\n    const char *lines[] = {\n        \"Exclude 53,T:9100,U:30000-40000\\n\",\n        \"Probe UDP DNSStatusRequest q|\\\\0\\\\0\\\\x10\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0|\\n\",\n        \"Probe TCP GetRequest q|GET / HTTP/1.0\\r\\n\\r\\n|\\n\",\n        \"ports 80\\n\",\n        \"sslports 443\\n\",\n        \"Probe TCP NULL q||\\n\",\n        \"ports 21,43,110,113,199,505,540,1248,5432,30444\\n\",\n        \"match ftp m/^220.*Welcome to .*Pure-?FTPd (\\\\d\\\\S+\\\\s*)/ p/Pure-FTPd/ v/$1/ cpe:/a:pureftpd:pure-ftpd:$1/\\n\",\n        \"match ssh m/^SSH-([\\\\d.]+)-OpenSSH[_-]([\\\\w.]+)\\\\r?\\\\n/i p/OpenSSH/ v/$2/ i/protocol $1/ cpe:/a:openbsd:openssh:$2/\\n\",\n        \"match mysql m|^\\\\x10\\\\0\\\\0\\\\x01\\\\xff\\\\x13\\\\x04Bad handshake$| p/MySQL/ cpe:/a:mysql:mysql/\\n\",\n        \"match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ|\\n\",\n        \"match uucp m|^login: login: login: $| p/NetBSD uucpd/ o/NetBSD/ cpe:/o:netbsd:netbsd/a\\n\",\n        \"match printer m|^([\\\\w-_.]+): lpd: Illegal service request\\\\n$| p/lpd/ h/$1/\\n\",\n        \"match afs m|^[\\\\d\\\\D]{28}\\\\s*(OpenAFS)([\\\\d\\\\.]{3}[^\\\\s\\\\0]*)\\\\0| p/$1/ v/$2/\\n\",\n        0\n    };\n    unsigned i;\n    struct NmapServiceProbeList *list = nmapserviceprobes_new(\"<selftest>\");\n    \n    for (i=0; lines[i]; i++) {\n        list->line_number = i;\n        parse_line(list, lines[i]);\n    }\n    \n    //nmapserviceprobes_print(list, stdout);\n    return 0;\n}\n\n\n"
  },
  {
    "path": "src/read-service-probes.h",
    "content": "/*\n    Reads the 'nmap-service-probes' file.\n */\n#ifndef READ_SERVICE_PROBES_H\n#define READ_SERVICE_PROBES_H\n#include <stdio.h>\n#include \"massip-rangesv4.h\"\n\n/*\n Exclude <port specification>\n Probe <protocol> <probename> <probestring>\n match <service> <pattern> [<versioninfo>]\n softmatch <service> <pattern>\n ports <portlist>\n sslports <portlist>\n totalwaitms <milliseconds>\n tcpwrappedms <milliseconds>\n rarity <value between 1 and 9>\n fallback <Comma separated list of probes>\n */\nenum SvcP_RecordType {\n    SvcP_Unknown,\n    SvcP_Exclude,\n    SvcP_Probe,\n    SvcP_Match,\n    SvcP_Softmatch,\n    SvcP_Ports,\n    SvcP_Sslports,\n    SvcP_Totalwaitms,\n    SvcP_Tcpwrappedms,\n    SvcP_Rarity,\n    SvcP_Fallback,\n};\n\nenum SvcV_InfoType {\n    SvcV_Unknown,\n    SvcV_ProductName,\n    SvcV_Version,\n    SvcV_Info,\n    SvcV_Hostname,\n    SvcV_OperatingSystem,\n    SvcV_DeviceType,\n    SvcV_CpeName,\n};\n\nstruct ServiceVersionInfo {\n    enum SvcV_InfoType type;\n    char *value;\n    struct ServiceVersionInfo *next;\n    unsigned is_a:1;\n};\n\nstruct ServiceProbeFallback {\n    char *name;\n    struct ServiceProbeFallback *next;\n};\n\nstruct ServiceProbeMatch {\n    struct ServiceProbeMatch *next;\n    char *service;\n    char *regex;\n    size_t regex_length;\n    struct ServiceVersionInfo *versioninfo;\n    unsigned is_case_insensitive:1;\n    unsigned is_include_newlines:1;\n    unsigned is_softmatch:1;\n};\n\nstruct NmapServiceProbe {\n    char *name;\n    char *hellostring;\n    size_t hellolength;\n    unsigned protocol;\n    unsigned totalwaitms;\n    unsigned tcpwrappedms;\n    unsigned rarity;\n    struct RangeList ports;\n    struct RangeList sslports;\n    struct ServiceProbeMatch *match;\n    struct ServiceProbeFallback *fallback;\n};\n\nstruct NmapServiceProbeList {\n    struct NmapServiceProbe **list;\n    struct RangeList exclude;\n    unsigned count;\n    unsigned max;\n    const char *filename;\n    unsigned line_number;\n};\n\n\nstruct NmapServiceProbeList *\nnmapserviceprobes_read_file(const char *filename);\n\nvoid\nnmapserviceprobes_free(struct NmapServiceProbeList *service_probes);\n\nint\nnmapserviceprobes_selftest(void);\n\n/**\n * Print to a file for testing purposes\n */\nvoid\nnmapserviceprobes_print(const struct NmapServiceProbeList *list, FILE *fp);\n\n#endif\n\n"
  },
  {
    "path": "src/rte-ring.c",
    "content": "/*\n    RING\n\n    DERIVED FROM INTEL DPDK\n    DERIVED FROM FREEBSD BUFRING\n*/\n/*-\n *   BSD LICENSE\n *\n *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.\n *   All rights reserved.\n *\n *   Redistribution and use in source and binary forms, with or without\n *   modification, are permitted provided that the following conditions\n *   are met:\n *\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in\n *       the documentation and/or other materials provided with the\n *       distribution.\n *     * Neither the name of Intel Corporation nor the names of its\n *       contributors may be used to endorse or promote products derived\n *       from this software without specific prior written permission.\n *\n *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n/*\n * Derived from FreeBSD's bufring.c\n *\n **************************************************************************\n *\n * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. The name of Kip Macy nor the names of other\n *    contributors may be used to endorse or promote products derived from\n *    this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n *\n ***************************************************************************/\n#include \"util-safefunc.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <stdint.h>\n#include <stddef.h>\n#include <signal.h>\n#include <errno.h>\n\n#include \"pixie-threads.h\"\n#include \"pixie-timer.h\"\n\n#if 0\n#include <rte_common.h>\n#include <rte_log.h>\n#include <rte_memory.h>\n#include <rte_memzone.h>\n#include <rte_launch.h>\n#include <rte_tailq.h>\n#include <rte_eal.h>\n#include <rte_eal_memconfig.h>\n#include <rte_atomic.h>\n#include <rte_per_lcore.h>\n#include <rte_lcore.h>\n#include <rte_branch_prediction.h>\n#include <rte_errno.h>\n#include <rte_string_fns.h>\n#include <rte_spinlock.h>\n#endif\n\n\n#include \"rte-ring.h\"\n\n\n/* true if x is a power of 2 */\n#define POWEROF2(x) ((((x)-1) & (x)) == 0)\n\n/* create the ring */\nstruct rte_ring *\nrte_ring_create(unsigned count, unsigned flags)\n{\n    struct rte_ring *r;\n    size_t ring_size;\n\n#if 0\n    /* compilation-time checks */\n    RTE_BUILD_BUG_ON((sizeof(struct rte_ring) &\n              CACHE_LINE_MASK) != 0);\n    RTE_BUILD_BUG_ON((offsetof(struct rte_ring, cons) &\n              CACHE_LINE_MASK) != 0);\n    RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &\n              CACHE_LINE_MASK) != 0);\n#ifdef RTE_LIBRTE_RING_DEBUG\n    RTE_BUILD_BUG_ON((sizeof(struct rte_ring_debug_stats) &\n              CACHE_LINE_MASK) != 0);\n    RTE_BUILD_BUG_ON((offsetof(struct rte_ring, stats) &\n              CACHE_LINE_MASK) != 0);\n#endif\n#endif\n\n    /* count must be a power of 2 */\n    if ((!POWEROF2(count)) || (count > RTE_RING_SZ_MASK )) {\n        rte_errno = EINVAL;\n        fprintf(stderr, \"Requested size is invalid, must be power of 2, and \"\n                \"do not exceed the size limit %u\\n\", RTE_RING_SZ_MASK);\n        return NULL;\n    }\n\n    ring_size = count * sizeof(void *) + sizeof(struct rte_ring);\n\n    r = (struct rte_ring*)malloc(ring_size);\n    if (r == NULL)\n        abort();\n\n    /* init the ring structure */\n    memset(r, 0, sizeof(*r));\n\n    r->flags = flags;\n    r->prod.watermark = count;\n    r->prod.sp_enqueue = !!(flags & RING_F_SP_ENQ);\n    r->cons.sc_dequeue = !!(flags & RING_F_SC_DEQ);\n    r->prod.size = r->cons.size = count;\n    r->prod.mask = r->cons.mask = count-1;\n    r->prod.head = r->cons.head = 0;\n    r->prod.tail = r->cons.tail = 0;\n\n    return r;\n}\n\n/*\n * change the high water mark. If *count* is 0, water marking is\n * disabled\n */\nint\nrte_ring_set_water_mark(struct rte_ring *r, unsigned count)\n{\n    if (count >= r->prod.size)\n        return -EINVAL;\n\n    /* if count is 0, disable the watermarking */\n    if (count == 0)\n        count = r->prod.size;\n\n    r->prod.watermark = count;\n    return 0;\n}\n\n/* dump the status of the ring on the console */\nvoid\nrte_ring_dump(const struct rte_ring *r)\n{\n#ifdef RTE_LIBRTE_RING_DEBUG\n    struct rte_ring_debug_stats sum;\n    unsigned lcore_id;\n#endif\n\n    printf(\"  flags=%x\\n\", r->flags);\n    printf(\"  size=%u\\n\", r->prod.size);\n    printf(\"  ct=%u\\n\", r->cons.tail);\n    printf(\"  ch=%u\\n\", r->cons.head);\n    printf(\"  pt=%u\\n\", r->prod.tail);\n    printf(\"  ph=%u\\n\", r->prod.head);\n    printf(\"  used=%u\\n\", rte_ring_count(r));\n    printf(\"  avail=%u\\n\", rte_ring_free_count(r));\n    if (r->prod.watermark == r->prod.size)\n        printf(\"  watermark=0\\n\");\n    else\n        printf(\"  watermark=%u\\n\", r->prod.watermark);\n\n    /* sum and dump statistics */\n#ifdef RTE_LIBRTE_RING_DEBUG\n    memset(&sum, 0, sizeof(sum));\n    for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n        sum.enq_success_bulk += r->stats[lcore_id].enq_success_bulk;\n        sum.enq_success_objs += r->stats[lcore_id].enq_success_objs;\n        sum.enq_quota_bulk += r->stats[lcore_id].enq_quota_bulk;\n        sum.enq_quota_objs += r->stats[lcore_id].enq_quota_objs;\n        sum.enq_fail_bulk += r->stats[lcore_id].enq_fail_bulk;\n        sum.enq_fail_objs += r->stats[lcore_id].enq_fail_objs;\n        sum.deq_success_bulk += r->stats[lcore_id].deq_success_bulk;\n        sum.deq_success_objs += r->stats[lcore_id].deq_success_objs;\n        sum.deq_fail_bulk += r->stats[lcore_id].deq_fail_bulk;\n        sum.deq_fail_objs += r->stats[lcore_id].deq_fail_objs;\n    }\n    printf(\"  size=%u\\n\", r->prod.size);\n    printf(\"  enq_success_bulk=%\"PRIu64\"\\n\", sum.enq_success_bulk);\n    printf(\"  enq_success_objs=%\"PRIu64\"\\n\", sum.enq_success_objs);\n    printf(\"  enq_quota_bulk=%\"PRIu64\"\\n\", sum.enq_quota_bulk);\n    printf(\"  enq_quota_objs=%\"PRIu64\"\\n\", sum.enq_quota_objs);\n    printf(\"  enq_fail_bulk=%\"PRIu64\"\\n\", sum.enq_fail_bulk);\n    printf(\"  enq_fail_objs=%\"PRIu64\"\\n\", sum.enq_fail_objs);\n    printf(\"  deq_success_bulk=%\"PRIu64\"\\n\", sum.deq_success_bulk);\n    printf(\"  deq_success_objs=%\"PRIu64\"\\n\", sum.deq_success_objs);\n    printf(\"  deq_fail_bulk=%\"PRIu64\"\\n\", sum.deq_fail_bulk);\n    printf(\"  deq_fail_objs=%\"PRIu64\"\\n\", sum.deq_fail_objs);\n#else\n    printf(\"  no statistics available\\n\");\n#endif\n}\n\n/* dump the status of all rings on the console */\n#if 0\nvoid\nrte_ring_list_dump(void)\n{\n    const struct rte_ring *mp;\n    struct rte_ring_list *ring_list;\n\n    /* check that we have an initialised tail queue */\n    if ((ring_list =\n         RTE_TAILQ_LOOKUP_BY_IDX(RTE_TAILQ_RING, rte_ring_list)) == NULL) {\n        rte_errno = E_RTE_NO_TAILQ;\n        return;\n    }\n\n    rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);\n\n    TAILQ_FOREACH(mp, ring_list, next) {\n        rte_ring_dump(mp);\n    }\n\n    rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);\n}\n#endif\n\n\ntypedef size_t Element;\n\n/***************************************************************************\n ***************************************************************************/\nstruct Test\n{\n    struct rte_ring *ring;\n    unsigned producer_started;\n    unsigned producer_done;\n    unsigned consumer_done;\n    unsigned long long total_count;\n    volatile int not_active;\n    volatile unsigned test_count;\n} *x_test;\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntest_consumer_thread(void *v)\n{\n    struct Test *test = (struct Test *)v;\n    struct rte_ring *ring = test->ring;\n    int err;\n\n    test->total_count = 0;\n\n    while (!test->not_active) {\n        Element e;\n\n        err = rte_ring_sc_dequeue(ring, (void**)&e);\n        if (err == 0)\n            test->total_count += e;\n        else {\n            ;\n        }\n    }\n\n\n    /* Wait until ring is empty before exiting */\n    while (!rte_ring_empty(ring)) {\n        Element e;\n\n        err = rte_ring_sc_dequeue(ring, (void**)&e);\n        if (err == 0)\n            test->total_count += e;\n        else {\n            ;\n        }\n    }\n\n    test->consumer_done = 1;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntest_producer_thread(void *v)\n{\n    struct Test *test = (struct Test *)v;\n    unsigned i = 1000;\n    struct rte_ring *ring = test->ring;\n\n    pixie_locked_add_u32(&test->producer_started, 1);\n    while (i) {\n        int err;\n        for (;;) {\n            err = rte_ring_sp_enqueue(ring, (void*)(size_t)i);\n            if (err == 0)\n                break;\n        }\n        i--;\n    }\n    pixie_locked_add_u32(&test->producer_done, 1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic uint64_t\nrun_test(struct Test *test)\n{\n    unsigned i;\n    const unsigned THREADS = 1;\n\n    memset(test, 0, sizeof(*test));\n    test->ring = rte_ring_create(16, RING_F_SP_ENQ|RING_F_SC_DEQ);\n\n    /* Generate producer threads */\n    for (i=0; i<THREADS; i++) {\n        pixie_begin_thread(test_producer_thread, 0, test);\n    }\n\n    /* Wait for threads to start */\n    while (test->producer_started < THREADS)\n        pixie_usleep(10);\n    /* Now start consuming */\n    pixie_begin_thread(test_consumer_thread, 0, test);\n\n    /* Wait for producer threads to end */\n    while (test->producer_done < THREADS)\n        pixie_usleep(10);\n\n\n    /* Tell consumer thread to end */\n    test->not_active = 1;\n\n\n    /* Wait for consumer thread to end */\n    while (!test->consumer_done)\n        pixie_usleep(10);\n\n    return test->total_count;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nrte_ring_selftest(void)\n{\n    unsigned i;\n\n\n    for (i=0; i<100; i++) {\n        uint64_t result;\n        struct Test test[1];\n\n        x_test = test;\n\n        result = run_test(test);\n        if (result != 500500) {\n            printf(\"xring: selftest failed with %\" PRIu64 \"\\n\", result);\n            return 1;\n        } else\n            ;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/rte-ring.h",
    "content": "#ifndef _RTE_RING_H_\n#define _RTE_RING_H_\n\n\n/*\n    RING\n\n    DERIVED FROM INTEL DPDK\n    DERIVED FROM FREEBSD BUFRING\n*/\n/*-\n *   BSD LICENSE\n *\n *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.\n *   All rights reserved.\n *\n *   Redistribution and use in source and binary forms, with or without\n *   modification, are permitted provided that the following conditions\n *   are met:\n *\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in\n *       the documentation and/or other materials provided with the\n *       distribution.\n *     * Neither the name of Intel Corporation nor the names of its\n *       contributors may be used to endorse or promote products derived\n *       from this software without specific prior written permission.\n *\n *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n */\n\n/*\n * Derived from FreeBSD's bufring.h\n *\n **************************************************************************\n *\n * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. The name of Kip Macy nor the names of other\n *    contributors may be used to endorse or promote products derived from\n *    this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n *\n ***************************************************************************/\n#include \"pixie-threads.h\"\n#include <errno.h>\n\n#ifndef ENOBUFS\n#define ENOBUFS         119\n#endif\n#ifndef EDQUOT\n#define EDQUOT          122\n#endif\n\n\n#if defined(_MSC_VER)\n#define inline __inline\n#define unlikely(x) x\n#define likely(x) x\n#include <intrin.h>\n#define rte_wmb() _WriteBarrier()\n#define rte_pause() _mm_pause()\n#define rte_rmb() _ReadBarrier()\n#ifndef EDQUOT\n#define EDQUOT EOVERFLOW\n#endif\n#define rte_snprintf snprintf\n#define PRIu32 \"u\"\n#endif\n\n/**\n * @file\n * RTE Ring\n *\n * The Ring Manager is a fixed-size queue, implemented as a table of\n * pointers. Head and tail pointers are modified atomically, allowing\n * concurrent access to it. It has the following features:\n *\n * - FIFO (First In First Out)\n * - Maximum size is fixed; the pointers are stored in a table.\n * - Lockless implementation.\n * - Multi- or single-consumer dequeue.\n * - Multi- or single-producer enqueue.\n * - Bulk dequeue.\n * - Bulk enqueue.\n *\n * Note: the ring implementation is not preemptable. A lcore must not\n * be interrupted by another task that uses the same ring.\n *\n */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <errno.h>\n\n#ifndef __rte_cache_aligned\n#define __rte_cache_aligned\n#endif\n#ifndef RTE_MEMZONE_NAMESIZE\n#define RTE_MEMZONE_NAMESIZE 32\n#endif\n#ifndef CACHE_LINE_SIZE\n#define CACHE_LINE_SIZE 64\n#endif\n#ifndef CACHE_LINE_MASK\n#define CACHE_LINE_MASK (CACHE_LINE_SIZE-1)\n#endif\n#define rte_errno errno\n\n#ifndef likely\n#define likely(expr)    __builtin_expect((expr), !0)\n#endif\n#ifndef unlikely\n#define unlikely(expr)  __builtin_expect((expr), 0)\n#endif\n\n#define RTE_BUILD_BUG_ON\n#define xRTE_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))\n\nenum rte_ring_queue_behavior {\n    RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items from a ring */\n    RTE_RING_QUEUE_VARIABLE   /* Enq/Deq as many items a possible from ring */\n};\n\n\n/**\n * An RTE ring structure.\n *\n * The producer and the consumer have a head and a tail index. The particularity\n * of these index is that they are not between 0 and size(ring). These indexes\n * are between 0 and 2^32, and we mask their value when we access the ring[]\n * field. Thanks to this assumption, we can do subtractions between 2 index\n * values in a modulo-32bit base: that's why the overflow of the indexes is not\n * a problem.\n */\nstruct rte_ring {\n    int flags;                       /**< Flags supplied at creation. */\n\n    /** Ring producer status. */\n    struct prod {\n        uint32_t watermark;      /**< Maximum items before EDQUOT. */\n        uint32_t sp_enqueue;     /**< True, if single producer. */\n        uint32_t size;           /**< Size of ring. */\n        uint32_t mask;           /**< Mask (size-1) of ring. */\n        volatile uint32_t head;  /**< Producer head. */\n        volatile uint32_t tail;  /**< Producer tail. */\n    } prod __rte_cache_aligned;\n\n    /** Ring consumer status. */\n    struct cons {\n        uint32_t sc_dequeue;     /**< True, if single consumer. */\n        uint32_t size;           /**< Size of the ring. */\n        uint32_t mask;           /**< Mask (size-1) of ring. */\n        volatile uint32_t head;  /**< Consumer head. */\n        volatile uint32_t tail;  /**< Consumer tail. */\n    } cons __rte_cache_aligned;\n\n\n#ifdef RTE_LIBRTE_RING_DEBUG\n    struct rte_ring_debug_stats stats[RTE_MAX_LCORE];\n#endif\n\n    void * volatile ring[1] \\\n            __rte_cache_aligned; /**< Memory space of ring starts here. */\n};\n\n#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is \"single-producer\". */\n#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is \"single-consumer\". */\n#define RTE_RING_QUOT_EXCEED (1 << 31)  /**< Quota exceed for burst ops */\n#define RTE_RING_SZ_MASK  (unsigned)(0x0fffffff) /**< Ring size mask */\n\n/**\n * @internal When debug is enabled, store ring statistics.\n * @param r\n *   A pointer to the ring.\n * @param name\n *   The name of the statistics field to increment in the ring.\n * @param n\n *   The number to add to the object-oriented statistics.\n */\n#ifdef RTE_LIBRTE_RING_DEBUG\n#define __RING_STAT_ADD(r, name, n) do {       \\\n        unsigned __lcore_id = rte_lcore_id(); \\\n        r->stats[__lcore_id].name##_objs += n;  \\\n        r->stats[__lcore_id].name##_bulk += 1;  \\\n    } while(0)\n#else\n#define __RING_STAT_ADD(r, name, n)\n#endif\n\n/**\n * Create a new ring named *name* in memory.\n *\n * This function uses ``memzone_reserve()`` to allocate memory. Its size is\n * set to *count*, which must be a power of two. Water marking is\n * disabled by default.\n * Note that the real usable ring size is *count-1* instead of\n * *count*.\n *\n * @param count\n *   The size of the ring (must be a power of 2).\n * @param flags\n *   An OR of the following:\n *    - RING_F_SP_ENQ: If this flag is set, the default behavior when\n *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``\n *      is \"single-producer\". Otherwise, it is \"multi-producers\".\n *    - RING_F_SC_DEQ: If this flag is set, the default behavior when\n *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``\n *      is \"single-consumer\". Otherwise, it is \"multi-consumers\".\n * @return\n *   On success, the pointer to the new allocated ring. NULL on error with\n *    rte_errno set appropriately. Possible errno values include:\n *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure\n *    - E_RTE_SECONDARY - function was called from a secondary process instance\n *    - E_RTE_NO_TAILQ - no tailq list could be got for the ring list\n *    - EINVAL - count provided is not a power of 2\n *    - ENOSPC - the maximum number of memzones has already been allocated\n *    - EEXIST - a memzone with the same name already exists\n *    - ENOMEM - no appropriate memory area found in which to create memzone\n */\nstruct rte_ring *rte_ring_create(unsigned count, unsigned flags);\n\n/**\n * Change the high water mark.\n *\n * If *count* is 0, water marking is disabled. Otherwise, it is set to the\n * *count* value. The *count* value must be greater than 0 and less\n * than the ring size.\n *\n * This function can be called at any time (not necessarily at\n * initialization).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param count\n *   The new water mark value.\n * @return\n *   - 0: Success; water mark changed.\n *   - -EINVAL: Invalid water mark value.\n */\nint rte_ring_set_water_mark(struct rte_ring *r, unsigned count);\n\n/**\n * Dump the status of the ring to the console.\n *\n * @param r\n *   A pointer to the ring structure.\n */\nvoid rte_ring_dump(const struct rte_ring *r);\n\n/**\n * @internal Enqueue several objects on the ring (multi-producers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * producer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @param behavior\n *   RTE_RING_QUEUE_FIXED:    Enqueue a fixed number of items from a ring\n *   RTE_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring\n * @return\n *   Depend on the behavior value\n *   if behavior = RTE_RING_QUEUE_FIXED\n *   - 0: Success; objects enqueue.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.\n *   if behavior = RTE_RING_QUEUE_VARIABLE\n *   - n: Actual number of objects enqueued.\n */\nstatic inline int\n__rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,\n             unsigned n, enum rte_ring_queue_behavior behavior)\n{\n    uint32_t prod_head, prod_next;\n    uint32_t free_entries;\n    const unsigned max = n;\n    int success;\n    unsigned i;\n    uint32_t mask = r->prod.mask;\n    int ret;\n\n    /* move prod.head atomically */\n    do {\n        uint32_t cons_tail;\n        \n        /* Reset n to the initial burst count */\n        n = max;\n\n        prod_head = r->prod.head;\n        cons_tail = r->cons.tail;\n        /* The subtraction is done between two unsigned 32bits value\n         * (the result is always modulo 32 bits even if we have\n         * prod_head > cons_tail). So 'free_entries' is always between 0\n         * and size(ring)-1. */\n        free_entries = (mask + cons_tail - prod_head);\n\n        /* check that we have enough room in ring */\n        if (unlikely(n > free_entries)) {\n            if (behavior == RTE_RING_QUEUE_FIXED) {\n                __RING_STAT_ADD(r, enq_fail, n);\n                return -ENOBUFS;\n            }\n            else {\n                /* No free entry available */\n                if (unlikely(free_entries == 0)) {\n                    __RING_STAT_ADD(r, enq_fail, n);\n                    return 0;\n                }\n\n                n = free_entries;\n            }\n        }\n\n        prod_next = prod_head + n;\n        success = rte_atomic32_cmpset(&r->prod.head, prod_head,\n                          prod_next);\n    } while (unlikely(success == 0));\n\n    /* write entries in ring */\n    for (i = 0; likely(i < n); i++)\n        r->ring[(prod_head + i) & mask] = obj_table[i];\n    rte_wmb();\n\n    /* if we exceed the watermark */\n    if (unlikely(((mask + 1) - free_entries + n) > r->prod.watermark)) {\n        ret = (behavior == RTE_RING_QUEUE_FIXED) ? -EDQUOT :\n                (int)(n | RTE_RING_QUOT_EXCEED);\n        __RING_STAT_ADD(r, enq_quota, n);\n    }\n    else {\n        ret = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;\n        __RING_STAT_ADD(r, enq_success, n);\n    }\n\n    /*\n     * If there are other enqueues in progress that preceded us,\n     * we need to wait for them to complete\n     */\n    while (unlikely(r->prod.tail != prod_head))\n        rte_pause();\n\n    r->prod.tail = prod_next;\n    return ret;\n}\n\n/**\n * @internal Enqueue several objects on a ring (NOT multi-producers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @param behavior\n *   RTE_RING_QUEUE_FIXED:    Enqueue a fixed number of items from a ring\n *   RTE_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring\n * @return\n *   Depend on the behavior value\n *   if behavior = RTE_RING_QUEUE_FIXED\n *   - 0: Success; objects enqueue.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.\n *   if behavior = RTE_RING_QUEUE_VARIABLE\n *   - n: Actual number of objects enqueued.\n */\nstatic inline int\n__rte_ring_sp_do_enqueue(struct rte_ring *r, void * const *obj_table,\n             unsigned n, enum rte_ring_queue_behavior behavior)\n{\n    uint32_t prod_head, cons_tail;\n    uint32_t prod_next, free_entries;\n    unsigned i;\n    uint32_t mask = r->prod.mask;\n    int ret;\n\n    prod_head = r->prod.head;\n    cons_tail = r->cons.tail;\n    /* The subtraction is done between two unsigned 32bits value\n     * (the result is always modulo 32 bits even if we have\n     * prod_head > cons_tail). So 'free_entries' is always between 0\n     * and size(ring)-1. */\n    free_entries = mask + cons_tail - prod_head;\n\n    /* check that we have enough room in ring */\n    if (unlikely(n > free_entries)) {\n        if (behavior == RTE_RING_QUEUE_FIXED) {\n            __RING_STAT_ADD(r, enq_fail, n);\n            return -ENOBUFS;\n        }\n        else {\n            /* No free entry available */\n            if (unlikely(free_entries == 0)) {\n                __RING_STAT_ADD(r, enq_fail, n);\n                return 0;\n            }\n\n            n = free_entries;\n        }\n    }\n\n    prod_next = prod_head + n;\n    r->prod.head = prod_next;\n\n    /* write entries in ring */\n    for (i = 0; likely(i < n); i++)\n        r->ring[(prod_head + i) & mask] = obj_table[i];\n    rte_wmb();\n\n    /* if we exceed the watermark */\n    if (unlikely(((mask + 1) - free_entries + n) > r->prod.watermark)) {\n        ret = (behavior == RTE_RING_QUEUE_FIXED) ? -EDQUOT :\n            (int)(n | RTE_RING_QUOT_EXCEED);\n        __RING_STAT_ADD(r, enq_quota, n);\n    }\n    else {\n        ret = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;\n        __RING_STAT_ADD(r, enq_success, n);\n    }\n\n    r->prod.tail = prod_next;\n    return ret;\n}\n\n/**\n * @internal Dequeue several objects from a ring (multi-consumers safe). When\n * the request objects are more than the available objects, only dequeue the\n * actual number of objects\n *\n * This function uses a \"compare and set\" instruction to move the\n * consumer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @param behavior\n *   RTE_RING_QUEUE_FIXED:    Dequeue a fixed number of items from a ring\n *   RTE_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring\n * @return\n *   Depend on the behavior value\n *   if behavior = RTE_RING_QUEUE_FIXED\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue; no object is\n *     dequeued.\n *   if behavior = RTE_RING_QUEUE_VARIABLE\n *   - n: Actual number of objects dequeued.\n */\n\nstatic inline int\n__rte_ring_mc_do_dequeue(struct rte_ring *r, void **obj_table,\n         unsigned n, enum rte_ring_queue_behavior behavior)\n{\n    uint32_t cons_head;\n    uint32_t cons_next;\n    const unsigned max = n;\n    int success;\n    unsigned i;\n    uint32_t mask = r->prod.mask;\n\n    /* move cons.head atomically */\n    do {\n        uint32_t prod_tail;\n        uint32_t entries;\n        \n        /* Restore n as it may change every loop */\n        n = max;\n\n        cons_head = r->cons.head;\n        prod_tail = r->prod.tail;\n        /* The subtraction is done between two unsigned 32bits value\n         * (the result is always modulo 32 bits even if we have\n         * cons_head > prod_tail). So 'entries' is always between 0\n         * and size(ring)-1. */\n        entries = (prod_tail - cons_head);\n\n        /* Set the actual entries for dequeue */\n        if (unlikely(n > entries)) {\n            if (behavior == RTE_RING_QUEUE_FIXED) {\n                __RING_STAT_ADD(r, deq_fail, n);\n                return -ENOENT;\n            }\n            else {\n                if (unlikely(entries == 0)){\n                    __RING_STAT_ADD(r, deq_fail, n);\n                    return 0;\n                }\n\n                n = entries;\n            }\n        }\n\n        cons_next = cons_head + n;\n        success = rte_atomic32_cmpset(&r->cons.head, cons_head,\n                          cons_next);\n    } while (unlikely(success == 0));\n\n    /* copy in table */\n    rte_rmb();\n    for (i = 0; likely(i < n); i++) {\n        obj_table[i] = r->ring[(cons_head + i) & mask];\n    }\n\n    /*\n     * If there are other dequeues in progress that preceded us,\n     * we need to wait for them to complete\n     */\n    while (unlikely(r->cons.tail != cons_head))\n        rte_pause();\n\n    __RING_STAT_ADD(r, deq_success, n);\n    r->cons.tail = cons_next;\n\n    return behavior == RTE_RING_QUEUE_FIXED ? 0 : n;\n}\n\n/**\n * @internal Dequeue several objects from a ring (NOT multi-consumers safe).\n * When the request objects are more than the available objects, only dequeue\n * the actual number of objects\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @param behavior\n *   RTE_RING_QUEUE_FIXED:    Dequeue a fixed number of items from a ring\n *   RTE_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring\n * @return\n *   Depend on the behavior value\n *   if behavior = RTE_RING_QUEUE_FIXED\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue; no object is\n *     dequeued.\n *   if behavior = RTE_RING_QUEUE_VARIABLE\n *   - n: Actual number of objects dequeued.\n */\nstatic inline int\n__rte_ring_sc_do_dequeue(struct rte_ring *r, void **obj_table,\n         unsigned n, enum rte_ring_queue_behavior behavior)\n{\n    uint32_t cons_head, prod_tail;\n    uint32_t cons_next, entries;\n    unsigned i;\n    uint32_t mask = r->prod.mask;\n\n    cons_head = r->cons.head;\n    prod_tail = r->prod.tail;\n    /* The subtraction is done between two unsigned 32bits value\n     * (the result is always modulo 32 bits even if we have\n     * cons_head > prod_tail). So 'entries' is always between 0\n     * and size(ring)-1. */\n    entries = prod_tail - cons_head;\n\n    if (unlikely(n > entries)) {\n        if (behavior == RTE_RING_QUEUE_FIXED) {\n            __RING_STAT_ADD(r, deq_fail, n);\n            return -ENOENT;\n        }\n        else {\n            if (unlikely(entries == 0)){\n                __RING_STAT_ADD(r, deq_fail, n);\n                return 0;\n            }\n\n            n = entries;\n        }\n    }\n\n    cons_next = cons_head + n;\n    r->cons.head = cons_next;\n\n    /* copy in table */\n    rte_rmb();\n    for (i = 0; likely(i < n); i++) {\n        /* WTF??? WHY DOES THIS CODE GIVE STRICT-ALIASING WARNINGS\n         * ON SOME GCC. THEY ARE FREAKING VOID* !!! */\n        obj_table[i] = r->ring[(cons_head + i) & mask];\n    }\n\n    __RING_STAT_ADD(r, deq_success, n);\n    r->cons.tail = cons_next;\n    return behavior == RTE_RING_QUEUE_FIXED ? 0 : n;\n}\n\n/**\n * Enqueue several objects on the ring (multi-producers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * producer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - 0: Success; objects enqueue.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.\n */\nstatic inline int\nrte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,\n             unsigned n)\n{\n    return __rte_ring_mp_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED);\n}\n\n/**\n * Enqueue several objects on a ring (NOT multi-producers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - 0: Success; objects enqueued.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.\n */\nstatic inline int\nrte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,\n             unsigned n)\n{\n    return __rte_ring_sp_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED);\n}\n\n/**\n * Enqueue several objects on a ring.\n *\n * This function calls the multi-producer or the single-producer\n * version depending on the default behavior that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - 0: Success; objects enqueued.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.\n */\nstatic inline int\nrte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,\n              unsigned n)\n{\n    if (r->prod.sp_enqueue)\n        return rte_ring_sp_enqueue_bulk(r, obj_table, n);\n    else\n        return rte_ring_mp_enqueue_bulk(r, obj_table, n);\n}\n\n/**\n * Enqueue one object on a ring (multi-producers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * producer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj\n *   A pointer to the object to be added.\n * @return\n *   - 0: Success; objects enqueued.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.\n */\nstatic inline int\nrte_ring_mp_enqueue(struct rte_ring *r, void *obj)\n{\n    return rte_ring_mp_enqueue_bulk(r, &obj, 1);\n}\n\n/**\n * Enqueue one object on a ring (NOT multi-producers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj\n *   A pointer to the object to be added.\n * @return\n *   - 0: Success; objects enqueued.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.\n */\nstatic inline int\nrte_ring_sp_enqueue(struct rte_ring *r, void *obj)\n{\n    return rte_ring_sp_enqueue_bulk(r, &obj, 1);\n}\n\n/**\n * Enqueue one object on a ring.\n *\n * This function calls the multi-producer or the single-producer\n * version, depending on the default behaviour that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj\n *   A pointer to the object to be added.\n * @return\n *   - 0: Success; objects enqueued.\n *   - -EDQUOT: Quota exceeded. The objects have been enqueued, but the\n *     high water mark is exceeded.\n *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.\n */\nstatic inline int\nrte_ring_enqueue(struct rte_ring *r, void *obj)\n{\n    if (r->prod.sp_enqueue)\n        return rte_ring_sp_enqueue(r, obj);\n    else\n        return rte_ring_mp_enqueue(r, obj);\n}\n\n/**\n * Dequeue several objects from a ring (multi-consumers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * consumer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @return\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue; no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    return __rte_ring_mc_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED);\n}\n\n/**\n * Dequeue several objects from a ring (NOT multi-consumers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table,\n *   must be strictly positive.\n * @return\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue; no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    return __rte_ring_sc_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED);\n}\n\n/**\n * Dequeue several objects from a ring.\n *\n * This function calls the multi-consumers or the single-consumer\n * version, depending on the default behaviour that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @return\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue, no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    if (r->cons.sc_dequeue)\n        return rte_ring_sc_dequeue_bulk(r, obj_table, n);\n    else\n        return rte_ring_mc_dequeue_bulk(r, obj_table, n);\n}\n\n/**\n * Dequeue one object from a ring (multi-consumers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * consumer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_p\n *   A pointer to a void * pointer (object) that will be filled.\n * @return\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue; no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_mc_dequeue(struct rte_ring *r, void **obj_p)\n{\n    return rte_ring_mc_dequeue_bulk(r, obj_p, 1);\n}\n\n/**\n * Dequeue one object from a ring (NOT multi-consumers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_p\n *   A pointer to a void * pointer (object) that will be filled.\n * @return\n *   - 0: Success; objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue, no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_sc_dequeue(struct rte_ring *r, void **obj_p)\n{\n    return rte_ring_sc_dequeue_bulk(r, obj_p, 1);\n}\n\n/**\n * Dequeue one object from a ring.\n *\n * This function calls the multi-consumers or the single-consumer\n * version depending on the default behaviour that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_p\n *   A pointer to a void * pointer (object) that will be filled.\n * @return\n *   - 0: Success, objects dequeued.\n *   - -ENOENT: Not enough entries in the ring to dequeue, no object is\n *     dequeued.\n */\nstatic inline int\nrte_ring_dequeue(struct rte_ring *r, void **obj_p)\n{\n    if (r->cons.sc_dequeue)\n        return rte_ring_sc_dequeue(r, obj_p);\n    else\n        return rte_ring_mc_dequeue(r, obj_p);\n}\n\n/**\n * Test if a ring is full.\n *\n * @param r\n *   A pointer to the ring structure.\n * @return\n *   - 1: The ring is full.\n *   - 0: The ring is not full.\n */\nstatic inline int\nrte_ring_full(const struct rte_ring *r)\n{\n    uint32_t prod_tail = r->prod.tail;\n    uint32_t cons_tail = r->cons.tail;\n    return (((cons_tail - prod_tail - 1) & r->prod.mask) == 0);\n}\n\n/**\n * Test if a ring is empty.\n *\n * @param r\n *   A pointer to the ring structure.\n * @return\n *   - 1: The ring is empty.\n *   - 0: The ring is not empty.\n */\nstatic inline int\nrte_ring_empty(const struct rte_ring *r)\n{\n    uint32_t prod_tail = r->prod.tail;\n    uint32_t cons_tail = r->cons.tail;\n    return !!(cons_tail == prod_tail);\n}\n\n/**\n * Return the number of entries in a ring.\n *\n * @param r\n *   A pointer to the ring structure.\n * @return\n *   The number of entries in the ring.\n */\nstatic inline unsigned\nrte_ring_count(const struct rte_ring *r)\n{\n    uint32_t prod_tail = r->prod.tail;\n    uint32_t cons_tail = r->cons.tail;\n    return ((prod_tail - cons_tail) & r->prod.mask);\n}\n\n/**\n * Return the number of free entries in a ring.\n *\n * @param r\n *   A pointer to the ring structure.\n * @return\n *   The number of free entries in the ring.\n */\nstatic inline unsigned\nrte_ring_free_count(const struct rte_ring *r)\n{\n    uint32_t prod_tail = r->prod.tail;\n    uint32_t cons_tail = r->cons.tail;\n    return ((cons_tail - prod_tail - 1) & r->prod.mask);\n}\n\n/**\n * Dump the status of all rings on the console\n */\nvoid rte_ring_list_dump(void);\n\n/**\n * Search a ring from its name\n *\n * @param name\n *   The name of the ring.\n * @return\n *   The pointer to the ring matching the name, or NULL if not found,\n *   with rte_errno set appropriately. Possible rte_errno values include:\n *    - ENOENT - required entry not available to return.\n */\nstruct rte_ring *rte_ring_lookup(const char *name);\n\n/**\n * Enqueue several objects on the ring (multi-producers safe).\n *\n * This function uses a \"compare and set\" instruction to move the\n * producer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - n: Actual number of objects enqueued.\n */\nstatic inline int\nrte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,\n             unsigned n)\n{\n    return __rte_ring_mp_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE);\n}\n\n/**\n * Enqueue several objects on a ring (NOT multi-producers safe).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - n: Actual number of objects enqueued.\n */\nstatic inline int\nrte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,\n             unsigned n)\n{\n    return __rte_ring_sp_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE);\n}\n\n/**\n * Enqueue several objects on a ring.\n *\n * This function calls the multi-producer or the single-producer\n * version depending on the default behavior that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects).\n * @param n\n *   The number of objects to add in the ring from the obj_table.\n * @return\n *   - n: Actual number of objects enqueued.\n */\nstatic inline int\nrte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,\n              unsigned n)\n{\n    if (r->prod.sp_enqueue)\n        return    rte_ring_sp_enqueue_burst(r, obj_table, n);\n    else\n        return    rte_ring_mp_enqueue_burst(r, obj_table, n);\n}\n\n/**\n * Dequeue several objects from a ring (multi-consumers safe). When the request\n * objects are more than the available objects, only dequeue the actual number\n * of objects\n *\n * This function uses a \"compare and set\" instruction to move the\n * consumer index atomically.\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @return\n *   - n: Actual number of objects dequeued, 0 if ring is empty\n */\nstatic inline int\nrte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    return __rte_ring_mc_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE);\n}\n\n/**\n * Dequeue several objects from a ring (NOT multi-consumers safe).When the\n * request objects are more than the available objects, only dequeue the\n * actual number of objects\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @return\n *   - n: Actual number of objects dequeued, 0 if ring is empty\n */\nstatic inline int\nrte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    return __rte_ring_sc_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE);\n}\n\n/**\n * Dequeue multiple objects from a ring up to a maximum number.\n *\n * This function calls the multi-consumers or the single-consumer\n * version, depending on the default behaviour that was specified at\n * ring creation time (see flags).\n *\n * @param r\n *   A pointer to the ring structure.\n * @param obj_table\n *   A pointer to a table of void * pointers (objects) that will be filled.\n * @param n\n *   The number of objects to dequeue from the ring to the obj_table.\n * @return\n *   - Number of objects dequeued, or a negative error code on error\n */\nstatic inline int\nrte_ring_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned n)\n{\n    if (r->cons.sc_dequeue)\n        return rte_ring_sc_dequeue_burst(r, obj_table, n);\n    else\n        return rte_ring_mc_dequeue_burst(r, obj_table, n);\n}\n\nint rte_ring_selftest(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _RTE_RING_H_ */\n"
  },
  {
    "path": "src/scripting-banner.c",
    "content": "/*\n    Using \"banner\" system for TCP scripting\n */\n#include \"scripting.h\"\n#include \"stub-lua.h\"\n#include \"proto-banner1.h\"\n#include \"smack.h\"\n#include \"unusedparm.h\"\n#include \"util-logger.h\"\n#include \"masscan-app.h\"\n#include \"output.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-ssl.h\"\n#include \"proto-udp.h\"\n#include \"syn-cookie.h\"\n#include \"unusedparm.h\"\n#include \"massip-rangesv4.h\" /* kludge: TODO: FIXME: change this */\n#include \"massip-port.h\"\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nscripting_transmit_hello(const struct Banner1 *banner1, struct stack_handle_t *socket)\n{\n    UNUSEDPARM(banner1); UNUSEDPARM(socket);\n    LOG(0, \"SCRIPTING: HELLO\\n\");\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nscripting_tcp_parse(\n                     const struct Banner1 *banner1,\n                     void *banner1_private,\n                     struct StreamState *pstate,\n                     const unsigned char *px, size_t length,\n                     struct BannerOutput *banout,\n                     struct stack_handle_t *socket)\n{\n    unsigned state = pstate->state;\n    \n    \n    UNUSEDPARM(banner1_private);\n    UNUSEDPARM(banner1);\n    UNUSEDPARM(socket);\n    UNUSEDPARM(banout);\n    UNUSEDPARM(px);\n    UNUSEDPARM(length);\n\n    pstate->state = state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nregister_script_for_port(struct Banner1 *b, int port)\n{\n    LOG(0, \"SCRIPTING: using port %d\\n\", port);\n    b->payloads.tcp[port] = (const struct ProtocolParserStream *)&banner_scripting;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nregister_script_for_ports(struct Banner1 *b, const char *value)\n{\n    struct RangeList ports = {0};\n    unsigned is_error = 0;\n    unsigned i;\n    \n    rangelist_parse_ports(&ports, value, &is_error, 0);\n    if (is_error) {\n        LOG(0, \"SCRIPTING: invalid 'setTcpPorts' range: %s\\n\", value);\n        exit(1);\n    }\n\n    for (i=0; i<ports.count; i++) {\n        struct Range *range = &ports.list[i];\n        unsigned j;\n        \n        for (j=range->begin; j<=range->end; j++) {\n            register_script_for_port(b, j);\n        }\n    }\n    \n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void *\nscripting_banner_init(struct Banner1 *b)\n{\n    struct lua_State *L = b->L;\n    \n    /* Kludge: this gets called prematurely, without scripting, so\n     * just return */\n    if (L == NULL)\n        return 0;\n    \n    LOG(0, \"SCRIPTING: banner init          \\n\");\n    \n    /*\n     * Register TCP ports to run on\n     */\n    lua_getglobal(L, \"setTcpPorts\");\n    if (lua_isstring(L, -1)) {\n        register_script_for_ports(b, lua_tostring(L, -1));\n    } else if (lua_isinteger(L, -1)) {\n        register_script_for_port(b, (int)lua_tointeger(L, -1));\n    } else if (lua_istable(L, -1)) {\n        lua_Integer n = luaL_len(L, -1);\n        int i;\n        for (i=1; i<=n; i++) {\n            lua_geti(L, -1, i);\n            if (lua_isstring(L, -1)) {\n                register_script_for_ports(b, lua_tostring(L, -1));\n            } else if (lua_isinteger(L, -1)) {\n                register_script_for_port(b, (int)lua_tointeger(L, -1));\n            }\n        }\n    }\n    \n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\n#if 0\nstatic unsigned\nscripting_udp_parse(struct Output *out, time_t timestamp,\n                     const unsigned char *px, unsigned length,\n                     struct PreprocessedInfo *parsed,\n                     uint64_t entropy\n                     )\n{\n    \n    return default_udp_parse(out, timestamp, px, length, parsed, entropy);\n}\n#endif\n\n/****************************************************************************\n ****************************************************************************/\n#if 0\nstatic unsigned\nscripting_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno)\n{\n    return 0;\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nscripting_banner_selftest(void)\n{\n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nconst struct ProtocolParserStream banner_scripting = {\n    \"scripting\", 11211, \"stats\\r\\n\", 7, 0,\n    scripting_banner_selftest,\n    scripting_banner_init,\n    scripting_tcp_parse,\n    0,\n    scripting_transmit_hello\n};\n\n"
  },
  {
    "path": "src/scripting-masscan.c",
    "content": "#include \"masscan.h\"\n#include \"scripting.h\"\n#include \"stub-lua.h\"\n#include \"unusedparm.h\"\n\n#define MASSCAN_CLASS \"Masscan Class\"\n\nstruct MasscanWrapper\n{\n    struct Masscan *masscan;\n};\n\n/***************************************************************************\n * \"setconfig\" function in Lua.\n *\n * Called to set a generic name=value parameter. Any configuration\n * option that can be set on the command-line, or from within a config\n * file, can be set via this function.\n ***************************************************************************/\nstatic int mass_setconfig(struct lua_State *L)\n{\n    struct MasscanWrapper *wrapper;\n    struct Masscan *masscan;\n    const char *name;\n    const char *value;\n    \n    wrapper = luaL_checkudata(L, 1, MASSCAN_CLASS);\n    masscan = wrapper->masscan;\n    name = luaL_checkstring(L, 2);\n    value = luaL_checkstring(L, 3);\n    \n    masscan_set_parameter(masscan, name, value);\n    \n    return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int mass_gc(struct lua_State *L)\n{\n    //struct MasscanWrapper *wrapper;\n    //struct Masscan *masscan;\n\n    UNUSEDPARM(L);\n\n    //wrapper = luaL_checkudata(L, 1, MASSCAN_CLASS);\n    //masscan = wrapper->masscan;\n\n    /* I'm hot sure what I should do here for shutting down this object,\n     * but I'm registering a garbage collection function anyway */\n    \n    return 0;\n}\n\n\n/***************************************************************************\n * This function creases the object called \"Masscan\" in the global\n * variable space of a Lua script. The script can then interact\n * with this object in order to setup the scan that it wants to\n * do.\n ***************************************************************************/\nvoid scripting_masscan_init(struct Masscan *masscan)\n{\n    struct MasscanWrapper *wrapper;\n    struct lua_State *L = masscan->scripting.L;\n\n    static const luaL_Reg my_methods[] = {\n        {\"setconfig\",   mass_setconfig},\n        {\"__gc\",        mass_gc},\n        {NULL, NULL}\n    };\n\n    /*\n     * Lua: Create a class to wrap a 'socket'\n     */\n    \n    luaL_newmetatable(L, MASSCAN_CLASS);\n    lua_pushvalue(L, -1);\n    lua_setfield(L, -2, \"__index\");\n    luaL_setfuncs(L, my_methods, 0);\n    lua_pop(L, 1);\n    \n    /* Lua: create a  wrapper object and push it onto the stack */\n    wrapper = lua_newuserdata(L, sizeof(*wrapper));\n    memset(wrapper, 0, sizeof(*wrapper));\n    wrapper->masscan = masscan;\n    \n    /* Lua: set the class/type */\n    luaL_setmetatable(L, MASSCAN_CLASS);\n    \n    lua_setglobal(L, \"Masscan\");\n    \n}\n"
  },
  {
    "path": "src/scripting.c",
    "content": "#include \"masscan.h\"\n#include \"scripting.h\"\n#include \"stub-lua.h\"\n#include \"util-logger.h\"\n\n#include <stdlib.h>\n\n/***************************************************************************\n ***************************************************************************/\nvoid\nscripting_init(struct Masscan *masscan)\n{\n    int version;\n    struct lua_State *L;\n    const char *filename = masscan->scripting.name;\n    int x;\n\n    \n    if (filename == 0 || filename[0] == '\\0') {\n        LOG(0, \"%s: no script specified, use --script option\\n\", \"SCRIPTING\");\n        exit(1);\n    }\n    \n    /* Dynamically link the library */\n    stublua_init();\n    \n    /* Test to see if the loading was successful */\n    version = (int)*lua_version(0);\n    LOG(1, \"Lua version = %d\\n\", version);\n    if (version != 503 && version != 502) {\n        LOG(0, \"Unable to load Lua library\\n\");\n        exit(1);\n    }\n    \n    /*\n     * Create a Lua VM\n     */\n    L = luaL_newstate();\n    luaL_openlibs(L);\n    masscan->scripting.L = L;\n    \n    /*\n     * TODO: Sandbox stuff\n     */\n    /* We need to do a bunch of sandboxing here to prevent hostile or badly\n     * written scripts from disrupting the system */\n    \n    /*\n     * Create the Masscan object\n     */\n    scripting_masscan_init(masscan);\n    \n    /*\n     * Load the script. This will verify the syntax.\n     */\n    x = luaL_loadfile(L, filename);\n    if (x != LUA_OK) {\n        LOG(0, \"%s error loading: %s: %s\\n\", \"SCRIPTING:\", filename, lua_tostring(L, -1));\n        lua_close(L);\n        exit(1);\n    }\n    \n    /*\n     * Lua: Start running the script. At this stage, the \"onConnection()\" function doesn't\n     * run. Instead, it's registered as a global function to be called later.\n     */\n    LOG(1, \"%s running script: %s\\n\", \"SCRIPTING:\", filename);\n    x = lua_pcall(L, 0, 0, 0);\n    if (x != LUA_OK) {\n        LOG(0, \"%s error running: %s: %s\\n\", \"SCRIPTING:\", filename, lua_tostring(L, -1));\n        lua_close(L);\n        exit(1);\n    }\n\n}\n"
  },
  {
    "path": "src/scripting.h",
    "content": "/*\n    Masscan scripting subsystem\n*/\n#ifndef SCRIPTING_H\n#define SCRIPTING_H\n#include \"proto-banner1.h\"\nstruct Masscan;\n\nextern const struct ProtocolParserStream banner_scripting;\n\n/**\n * Load the Lua scripting library and run the initialization\n * stage of all the specified scripts\n */\nvoid scripting_init(struct Masscan *masscan);\n\n/**\n * Create the \"Masscan\" object within the scripting subsystem\n */\nvoid scripting_masscan_init(struct Masscan *masscan);\n\n#endif\n\n"
  },
  {
    "path": "src/smack.h",
    "content": "#ifndef _SMACK_H\n#define _SMACK_H\n#include <stdio.h>\n\n#define SMACK_NOT_FOUND ((size_t)(~0))\n\n/**\n * \"Anchor\" flags are specified only for patterns that must\n * match at the start of input, at the end, or both.\n * These are equivalent to the regex specifiers \"^\" and \"$\"\n * respectively.\n */\nenum {\n    SMACK_ANCHOR_BEGIN  = 0x01,\n    SMACK_ANCHOR_END    = 0x02,\n    SMACK_SNMP_HACK     = 0x04,\n    SMACK_WILDCARDS     = 0x08,\n};\n\nenum {\n    SMACK_CASE_SENSITIVE = 0,\n    SMACK_CASE_INSENSITIVE = 1,\n};\n\n\n/**\n * This is the function that will be called whenever SMACK\n * finds a pattern.\n */\ntypedef int (*FOUND_CALLBACK)(size_t id, int offset, void *data);\n\n\n/**\n * Create the Aho-Corasick search object. After creation, you can start\n * adding patterns, but you cannot use it for searching until you've\n * compiled the patterns.\n */\nstruct SMACK *\nsmack_create(const char *name, unsigned nocase);\n\n\n/**\n * Cleans up and frees an object created with smack_create().\n */\nvoid\nsmack_destroy(struct SMACK *smack);\n\n\n/**\n * Registers a pattern with the search engine. The 'smack' object\n * must have been created with 'smack_create()', but you must not\n * have yet called 'smack_compile()' to compile the patterns. The\n * \"id\" field can contain a pointer (size_t is 64-bit on 64-bit\n * systems).\n */\nvoid\nsmack_add_pattern(        struct SMACK *  smack,\n                        const void *    pattern,\n                        unsigned        pattern_length,\n                        size_t          id,\n                        unsigned        flags);\n\n/**\n * You call this function after you have registered all the patterns\n * using 'smack_add_pattern()' in order to compile the state-machine.\n * Don't use the state-machine with 'smack_search()' until you have\n * compiled all the patterns with this function.\n */\nvoid\nsmack_compile(struct SMACK *smack);\n\n\n/**\n * Run the state-machine, searching for the compiled patterns within\n * a block of data/text. This can only be called after \"smack_compile()\"\n * has created the state-machine.\n *\n * If the input is fragmented, this function can be called repeatedly\n * for each fragment. Patterns that cross fragments will still be\n * detected.\n *\n * The caller must initialize \"*state\" to zero \"0\" before running this\n * function on the first fragment, but must thereafter leave it\n * unchanged between fragments. (If the caller resets the *state variable\n * to zero between each fragment, then patterns that cross fragment\n * boundaries cannot be detected).\n */\nunsigned\nsmack_search(           struct SMACK *  smack,\n                        const void *    px,\n                        unsigned        length,\n                        FOUND_CALLBACK  cb_found,\n                        void *          cb_data,\n                        unsigned *      state);\n\nsize_t\nsmack_search_next(      struct SMACK *  smack,\n                        unsigned *      state,\n                        const void *    px,\n                        unsigned *       offset,\n                        unsigned        length\n                        );\n\n/**\n * Called to terminate a search (after multiple calls to `smack_search_next()`.\n * This triggers any patterns that SMACK_ANCHOR_END attribute on them.\n * If more than one pattern can match at the end of the search text, then\n * this should be called multiple times until SMACK_NOT_FOUND is\n * returned.\n * @return The 'id' field of a pattenr registered with the SMACK_ANCHOR_END\n *      attribute if that was found in the searched buffer, or SMACK_NOT_FOUND.\n */\nsize_t\nsmack_search_next_end(      struct SMACK *  smack,\n                        unsigned *      state\n                     );\n\n#define smack_search_start(state) (*(state)) = 0\n\n/**\n * If there are multiple matches at the current state, returns the next\n * one. Otherwise, returns NOT_FOUND. Used with \"smack_search_next()\".\n */\nsize_t\nsmack_next_match(      struct SMACK *  smack,\n                        unsigned *      state);\n\n/**\n * Call this after search is done. This is not generally necessary.\n * It's only purpose is to detect patterns that have the\n * SMACK_ANCHOR_END flag set. If no pattern has that flag, then\n * this function will do nothing.\n */\nunsigned\nsmack_search_end(       struct SMACK *  smack,\n                        FOUND_CALLBACK  cb_found,\n                        void *          cb_data,\n                        unsigned *      state);\n\n\n\n/**\n * Runs a regression test on the module to make sure it's compiled\n * correctly for the current platform.\n *\n * @return\n *      zero if regression test succeeds, non-zero on failure\n */\nint\nsmack_selftest(void);\n\nint\nsmack_benchmark(void);\n\n#endif /*_SMACK_H*/\n"
  },
  {
    "path": "src/smack1.c",
    "content": "/****************************************************************************\n\n          SMACK1 - an Aho-Corasick search engine\n\n  This creates a state-machine out of patterns, like a DFA implementation\n  of a regex. This can be used for intrusion-detection \"signature\" matching\n  to search network traffic for a lot of signatures. This can also be used\n  for protocol parsers, where fields are \"matched\" using a state-machine\n  rather than buffered and compared. In other words, instead of extracting\n  the \"method\" from HTTP and later comparing against GET, PUT, POST, etc.,\n  we create an Aho-Corasick pattern matcher for those patterns, match all\n  known ones, and otherwise generate an error for unknown methods.\n\n\n  In addition to normal and nocase patterns, SMACK also supports \"anchored\"\n  patterns. This is like the (^) and ($) symbols in regex patterns,\n  although we use flags in this code when adding patterns.\n\n  THE ALGORITHM\n\n  The basic engine is TEXTBOOK \"Aho-Corasic\". I've used macros to capture\n  the flavor of the textbook example pseudo-code. Therefore, you see code\n  that looks like the following:\n\n    while (queue_has_more_items(queue)) {\n        r = dequeue(queue);\n        for (a=0; a<ALPHABET_SIZE; a++) {\n            if (GOTO(r,a) == FAIL)\n                GOTO(r,a) = GOTO(GOTO_FAIL(r),a);\n            else\n                enqueue(queue, GOTO(r,a));\n        }\n    }\n\n  You aren't supposed to understand the code so much that you are supposed\n  to be able to confirm the code matches the textbook pseudo-code.\n\n\n  COMPRESSION\n\n  Bytes/characters in the patterns are converted to \"symbols\". This is done\n  for two reasons.\n\n  The first is for case-insensitive pattern-matches. Both upper and lower\n  case letters in incoming bytes will map to the same symbol (both for\n  patterns as well as the searched text).\n\n  The second reason is to shrink the table size. Normally, rows would be\n  256 elements wide. When only a few patterns are being matched, the table\n  can be as small as 16-characters wide. Even when searching for a 100\n  patterns, the table is still often only 64 elements wide.\n\n  The row width is done as a power-of-2, which means widths of 2, 4, 8, 16,\n  32, 64, 128, and 256. When doing the calculation table[row][column], we\n  have to multiple the \"row\" index by row width. Because it's a power-of-2,\n  we convert that into a shift for performance reasons.\n\n  Ideally, we should do even more optimizations, like a shift-add, allowing\n  half widths (3, 6, 24, 48, 96, 192) that would more closely match the\n  table width to the number of characters. Maybe I'll get around to adding\n  that.\n\n\n  COMPILATION\n\n  Once the patterns have been entered and compiled into a typical state\n  machine, I've added one more compilation step. I create a block of\n  memory that contains all the transitions.\n\n  I then DISCARD all the original pattern information. The only memory\n  used is that one block.\n\n  This reflects how the fast-SMACK works, where the simple Aho-Corasick\n  state tables are compiled into a complicated memory structure. In this\n  case, the primary optimization is simply that row-transitions, being\n  powers-of-2, are faster.\n\n  However, the main reason I discard the original state is one of purity.\n  Like compiling source into machine language, state-machines are supposed\n  to be purely compiled states, with no reference to the original set of\n  patterns that created them.\n\n\n  16-BIT STATE\n\n  While the engine compiles using 32-bit states, the last compilation\n  step reduces this to 16-bits states. This can be trivially changed\n  by redefining the type \"transition_t\".\n\n\n  64-BIT COMPILATION\n\n  The \"id\" that triggers for a pattern is declared as \"size_t\". This allows\n  it to hold a pointer as well as an integer. On most 64-bit systems\n  (Windows 7, Linux, Mac OS X), the 'size_t' will be a 64-bit value, while\n  'unsigned' will be a 32-bit value. The 'unsigned short' type will still\n  be 16-bits, which means the tables will still be small.\n\n\n  TODO\n  Make it so that the longest match triggers first.\n\n ****************************************************************************/\n#include \"smack.h\"\n#include \"smackqueue.h\"\n#include \"util-logger.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n#include <time.h>\n#include <assert.h>\n\n\n#ifndef NOBENCHMARK\n#include \"pixie-timer.h\"\n#if defined(_MSC_VER)\n#include <intrin.h>\n#elif defined(__FreeBSD__)\n#include <sys/types.h>\n#include <machine/cpufunc.h>\n#if (__ARM_ARCH >= 6 && __ARM_ARCH <= 7)  // V6 is the earliest arch that has a standard cyclecount\nunsigned long long __rdtsc(void)\n{\n  uint32_t pmccntr;\n  uint32_t pmuseren;\n  uint32_t pmcntenset;\n  // Read the user mode perf monitor counter access permissions.\n  asm volatile(\"mrc p15, 0, %0, c9, c14, 0\" : \"=r\"(pmuseren));\n  if (pmuseren & 1) {  // Allows reading perfmon counters for user mode code.\n    asm volatile(\"mrc p15, 0, %0, c9, c12, 1\" : \"=r\"(pmcntenset));\n    if (pmcntenset & 0x80000000ul) {  // Is it counting?\n      asm volatile(\"mrc p15, 0, %0, c9, c13, 0\" : \"=r\"(pmccntr));\n      // The counter is set up to count every 64th cycle\n      return (unsigned long long)(pmccntr) * 64ULL; \n    }\n  }\n  return 0;\n}\n#elif defined(__powerpc64__)\nunsigned long long __rdtsc(void)\n{\n  unsigned long long rval;\n  __asm__ __volatile__(\"mfspr %%r3, 268\": \"=r\" (rval));\n  return rval;\n}\n#elif defined(__aarch64__)\n#define __rdtsc() 0\n#else\n#define __rdtsc rdtsc\n#endif\n#elif defined (__llvm__)\n#if defined(i386) || defined(__i386__)\n#include <x86intrin.h>\n#else\n#define __rdtsc() 0\n#endif\n#elif defined(__GNUC__) || defined(__llvm__)\nstatic __inline__ unsigned long long __rdtsc(void)\n{\n#if defined(i386) || defined(__i386__)\n    unsigned long hi = 0, lo = 0;\n    __asm__ __volatile__ (\"lfence\\n\\trdtsc\" : \"=a\"(lo), \"=d\"(hi));\n    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );\n#else\n    return 0;\n#endif\n}\n#endif\n#endif\n\n/**\n * By default, the table holds only 64k states using 2-byte\n * integers. If you want more states, simply change this to\n * a 4-byte or 8-byte integer\n */\ntypedef unsigned short transition_t;\n\n\n/**\n * These constants represent the anchor-start (^) and anchor-end ($) symbols.\n * Since we use all 256 combinations of a byte, these values are set to\n * 0x100 and 0x101, so they don't collide with bytes that might otherwise\n * be used\n */\nenum {\n    CHAR_ANCHOR_START=256,\n    CHAR_ANCHOR_END=257,\n};\n\n/**\n * The alphabet consists of all combinations for a byte PLUS two special\n * symbols: the anchor-start (^) and anchor-end ($) symbol.\n */\n#define ALPHABET_SIZE  (256+2)\n\n\n/**\n * During the initial phases of compilation, the \"FAIL\" state points to\n * an impossible state. Later phases of compilation then figure out a\n * better fail state (one that shares many of the same trailing\n * characters of the current prefix).\n */\n#define FAIL (unsigned)(-1)\n\n\nstatic const unsigned BASE_STATE = 0;\nstatic const unsigned UNANCHORED_STATE = 1;\n#define GOTO(r, a)      smack->m_state_table[r].m_next_state[a]\n#define GOTO_FAIL(r)   smack->m_state_table[r].m_fail_state\n\n\n\n/**\n * This variable can be used to visualize transitions while debugging\n */\n#ifdef _DEBUG\n#define DEBUG\n#endif\n#ifdef DEBUG\nunsigned print_transitions = 0;\n#endif\n\n/****************************************************************************\n ****************************************************************************/\nstruct SmackPattern\n{\n    /** The 'id' is what's reported back when the pattern matches.\n     * This value can be either an integer, or a pointer to some\n     * private data structure */\n    size_t                    id;\n\n    /** This holds a malloc-ed copy of the pattern the caller gave us.\n     * If the engine is running \"nocase\", then this is converted to\n     * lower case */\n    unsigned char *          pattern;\n\n    /** The number of characters in the pattern */\n    unsigned                pattern_length;\n\n    /** Whether this pattern is \"anchored\" (^) at the start of the\n     * input. This means the pattern will only trigger when it's at the\n     * very start, but not when it's in the middle */\n    unsigned                is_anchor_begin:1;\n\n    /** Whether this pattern is \"anchored\" ($) at the END of the\n     * input. This means the pattern will only trigger when it's\n     * the last characters of the input, and the caller also calls\n     * \"smack_search_end()\" */\n    unsigned                is_anchor_end:1;\n\n    unsigned                is_snmp_hack:1;\n    \n    unsigned                is_wildcards:1;\n};\n\n\n/****************************************************************************\n * This is an INTERMEDIATE structure created and freed during compilation.\n * It holds the expanded state-table before it is compressed.\n ****************************************************************************/\nstruct SmackRow\n{\n    unsigned                m_next_state[ALPHABET_SIZE];\n    unsigned                m_fail_state;\n};\n\n\n/****************************************************************************\n * This table indicates which states are matches. A state may have more than\n * one match. If we are debugging this, this table will also have a name\n * for the state, based on the pattern.\n ****************************************************************************/\nstruct SmackMatches {\n    size_t *               m_ids;\n    unsigned                m_count;\n\n#ifdef DEBUG\n    char *DEBUG_name;\n#endif\n};\n\n/****************************************************************************\n * This is the master structure for the SMACK engine.\n ****************************************************************************/\nstruct SMACK {\n    /**\n     * Since a typical application may have multiple instances of this\n     * structure for different pattern sets, we allow the application to\n     * give a helpful name to this table\n     */\n    char *              name;\n\n    /**\n     * Whether or not this table is case-sensitive or case-insensitive\n     */\n    unsigned            is_nocase:1;\n\n    /**\n     * Whether one of the patterns contains an anchor (^) at the beginning\n     * of the pattern. If so, we need to add a symbol in our symbol table\n     * for the anchor.\n     */\n    unsigned            is_anchor_begin:1;\n\n\n    /**\n     * Whether one of the patterns contains an anchor ($) at the end\n     * of the pattern. If so, we need to add a symbol in our symbol table\n     * for the anchor.\n     */\n    unsigned            is_anchor_end:1;\n\n\n    /**\n     * Temporary pattern list. Patterns are added here at the beginning.\n     * However, after the patterns have been compiled, this structure can\n     * be freed.\n     */\n    struct SmackPattern **m_pattern_list;\n    unsigned            m_pattern_count;\n    unsigned            m_pattern_max;\n\n    /**\n     * Temporary place holder for DFA state transitions. After we\n     * compress the table, this is thrown away */\n    struct SmackRow *  m_state_table;\n    unsigned            m_state_count;\n    unsigned            m_state_max;\n    struct SmackMatches *m_match;\n    unsigned            m_match_limit;\n\n\n    /**\n     * The opposite of \"char_to_symbol\", this table takes a symbol and\n     * converts it back to a  character. This can be useful in debugging,\n     * but it's real purpose is just during compilation in order to\n     * count the number of characters used in patterns, and consequently,\n     * how wide 'rows' need to be. */\n    unsigned            symbol_to_char[ALPHABET_SIZE];\n\n    /**\n     * The \"symbol compression dictionary\". As we parse incoming bytes,\n     * they are first translated to a symbol. This is useful for two reasons.\n     * The first reason is that this allows us to create \"case-insensitive\"\n     * pattern-matches, where upper-case is converted to lower-case. The\n     * second reason is that it allows us to compress the table. If only\n     * 32 different characters are used in the patterns, then rows only\n     * have to be 32 symbols wide, instead of 256 characters wide.\n     */\n    unsigned char       char_to_symbol[ALPHABET_SIZE];\n\n    /**\n     * The number different characters used in all the patterns we are\n     * looking for. See \"char_to_symbol\" for more information.\n     */\n    unsigned            symbol_count;\n\n    /**\n     * This is the row width, log2. Rows are expanded to the nearest\n     * power-of-2. Thus, if we have 26 different characters used in\n     * patterns, then we'll use row sizes of 32 elements. This allows\n     * use to optimize row lookups using the fast \"shift\" operation\n     * rather than the slow \"multiplication\" operation.\n     */\n    unsigned            row_shift;\n\n    /**\n     * This is the final compressed table. It contains one row for each\n     * sub-pattern, and each row is wide enough to hold all the symbols\n     * (must be a power of two) */\n    transition_t *       table;\n};\n\n\n/****************************************************************************\n * Given a row-width, figure out the nearest power-of-two (16,32,64,128,etc.)\n * that can hold that row. Return the number of bits needed to left-shift\n * in order to multiple by that number (shifts are faster than multiply).\n ****************************************************************************/\nstatic unsigned\nrow_shift_from_symbol_count(unsigned symbol_count)\n{\n    unsigned row_shift = 1;\n\n    symbol_count++;\n\n    while ((unsigned)(1 << row_shift) < symbol_count)\n        row_shift++;\n\n    return row_shift;\n}\n\n\n/****************************************************************************\n * Creates this engine, use \"smack_destroy()\" to free all the resources\n ****************************************************************************/\nstruct SMACK *\nsmack_create(const char *name, unsigned nocase)\n{\n    struct SMACK *smack;\n\n    smack = (struct SMACK *)malloc(sizeof (struct SMACK));\n    if (smack == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memset (smack, 0, sizeof (struct SMACK));\n\n    smack->is_nocase = nocase;\n    smack->name = (char*)malloc(strlen(name)+1);\n    if (smack->name == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memcpy(smack->name, name, strlen(name)+1);\n    return smack;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ncreate_intermediate_table(struct SMACK *smack, unsigned size)\n{\n    struct SmackRow *x;\n\n    x = (struct SmackRow *)malloc(sizeof(*x) * size);\n    if (x == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memset(x, 0, sizeof(*x) * size);\n    smack->m_state_table = x;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ndestroy_intermediate_table(struct SMACK *smack)\n{\n    if (smack->m_state_table) {\n        free(smack->m_state_table);\n        smack->m_state_table = 0;\n    }\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ncreate_matches_table(struct SMACK *smack, unsigned size)\n{\n    struct SmackMatches *x;\n\n    x = (struct SmackMatches *)malloc(sizeof(*x) * size);\n    if (x == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memset(x, 0, sizeof(*x) * size);\n\n    smack->m_match = x;\n}\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\ndestroy_matches_table(struct SMACK *smack)\n{\n    unsigned i;\n\n    if (!smack->m_match)\n        return;\n\n\n    for (i=0; i<smack->m_state_count; i++) {\n        struct SmackMatches *match;\n        match = &smack->m_match[i];\n\n        if (match->m_count) {\n            free(match->m_ids);\n        } else {\n            assert(match->m_ids == NULL);\n        }\n#ifdef DEBUG\n        if (match->DEBUG_name)\n            free(match->DEBUG_name);\n#endif\n    }\n\n    free(smack->m_match);\n    smack->m_match = 0;\n}\n\n\n/****************************************************************************\n * Destroy the patterns that were registered by the caller. This will be\n * called during the compilation process to free the memory, since we no\n * longer need the original patterns during searching.\n ****************************************************************************/\nstatic void\ndestroy_pattern_table(struct SMACK *smack)\n{\n    unsigned i;\n\n    if (!smack->m_pattern_list)\n        return;\n\n    for (i=0; i<smack->m_pattern_count; i++) {\n        struct SmackPattern *pat;\n        pat = smack->m_pattern_list[i];\n        free(pat->pattern);\n        free(pat);\n    }\n\n    free(smack->m_pattern_list);\n    smack->m_pattern_list = 0;\n}\n\n\n/****************************************************************************\n * Frees everything allocated by \"smack_create()\", and further allocated\n * during compilation.\n ****************************************************************************/\nvoid\nsmack_destroy(struct SMACK *smack)\n{\n    destroy_intermediate_table(smack);\n    destroy_matches_table(smack);\n    destroy_pattern_table(smack);\n\n    if (smack->table)\n        free(smack->table);\n\n    free(smack);\n}\n\n/****************************************************************************\n * In the function \"smack_copy_matches()\", this tests to see if the match\n * already exists in the old list, in which case it won't copy a duplicate\n * from the new list.\n ****************************************************************************/\nstatic unsigned\nid_already_exists(const size_t *ids, unsigned count, size_t new_id)\n{\n    unsigned i;\n\n    for (i=0; i<count; i++) {\n        if (ids[i] == new_id)\n            return 1;\n    }\n    return 0;\n}\n\n/****************************************************************************\n * When combining two match lists (when two patterns overlap, like the\n * pattern \"BERT\" and \"ROBERT\"), we need to merge the two lists of matches.\n ****************************************************************************/\nstatic void\nsmack_copy_matches(\n    struct SmackMatches *row,\n    const size_t *new_ids,\n    unsigned new_count)\n{\n    size_t *total_ids;\n    unsigned total_count;\n    size_t *old_ids = row->m_ids;\n    unsigned old_count = row->m_count;\n    unsigned i;\n\n    /* Allocate space for both lists */\n    total_ids = (size_t *)malloc((old_count + new_count)*sizeof(*total_ids));\n    if (total_ids == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n\n    /* Copy existing matches */\n    for (i=0; i<old_count; i++)\n        total_ids[i] = old_ids[i];\n    total_count = old_count;\n\n    /* Copy new matches, if needed */\n    for (i=0; i<new_count; i++) {\n        if (!id_already_exists(old_ids, old_count, new_ids[i]))\n            total_ids[total_count++] = new_ids[i];\n    }\n\n    /* Free the old list */\n    if (row->m_ids) {\n        free(row->m_ids);\n    }\n\n    /* Replace old list with total combined list */\n    row->m_ids = total_ids;\n    row->m_count = total_count;\n}\n\n\n/****************************************************************************\n * In order to compress the size of the table, and to do case-insensitive\n * pattern-matches, we convert characters into symbols. We need to create\n * a new symbol for different type of character in a pattern. Note that this\n * function will be called with the pseudo-characters representing anchors,\n * which have a value of 256 and 257.\n ****************************************************************************/\nstatic unsigned\nsmack_add_symbol(struct SMACK *smack, unsigned c)\n{\n    unsigned i;\n    unsigned symbol;\n\n    /* See if we already know the symbol */\n    for (i=1; i<=smack->symbol_count; i++) {\n        if (smack->symbol_to_char[i] == c)\n            return i;\n    }\n\n    /* Add the symbol to our list */\n    smack->symbol_count++;\n    symbol = smack->symbol_count;\n\n    /* Map it in both directions */\n    smack->symbol_to_char[symbol] = c;\n    smack->char_to_symbol[c] = (unsigned char)symbol;\n\n    return symbol;\n}\n\n\n/****************************************************************************\n * Add all the symbols in a pattern.\n ****************************************************************************/\nstatic void\nsmack_add_symbols(struct SMACK *smack, const unsigned char *pattern, unsigned pattern_length)\n{\n    unsigned i;\n\n    /* Add all the bytes in this pattern to the symbol table */\n    for (i=0; i<pattern_length; i++) {\n        if (smack->is_nocase)\n            smack_add_symbol(smack, tolower(pattern[i]));\n        else\n            smack_add_symbol(smack, pattern[i]);\n    }\n}\n\n\n/****************************************************************************\n * Make a copy of the pattern. We need to do this for two reasons. The first\n * is that the caller may immediately release the memory in the pattern\n * he gave us. Therefore, we have to allocate our own memory to hold it.\n * The second is if it's a case-insensitive pattern. In that case, we are\n * going to normalize it to all lower case.\n ****************************************************************************/\nstatic unsigned char *\nmake_copy_of_pattern(   const unsigned char *pattern,\n                        unsigned pattern_length,\n                        unsigned is_nocase)\n{\n    unsigned char *result;\n\n    /* allocate space */\n    result = (unsigned char *)malloc(pattern_length+1);\n    if (result == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n\n    /* copy, removing case if necessary */\n    if (is_nocase) {\n        unsigned i;\n        for (i=0; i<pattern_length; i++) {\n            result[i] = (unsigned char)(tolower(pattern[i]));\n        }\n    } else\n        memcpy(result, pattern, pattern_length);\n\n    /* NUL terminate the string. This makes debugging easier when patterns\n     * are text. However, the NUL terminator is never used by the program\n     * to end the string -- we always use the length instead. */\n    result[pattern_length] = '\\0';\n\n    return result;\n}\n\n\n/****************************************************************************\n * Called to register a pattern with SMACK.\n ****************************************************************************/\nvoid\nsmack_add_pattern(\n    struct SMACK *  smack,\n    const void *    v_pattern,\n    unsigned        pattern_length,\n    size_t          id,\n    unsigned        flags)\n{\n    const unsigned char *pattern = (const unsigned char*)v_pattern;\n    struct SmackPattern *pat;\n\n\n    /*\n     * Create a pattern structure based on the input\n     */\n    pat = (struct SmackPattern *)malloc(sizeof (struct SmackPattern));\n    if (pat == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    pat->pattern_length = pattern_length;\n    pat->is_anchor_begin = ((flags & SMACK_ANCHOR_BEGIN) > 0);\n    pat->is_anchor_end = ((flags & SMACK_ANCHOR_END) > 0);\n    pat->is_snmp_hack = ((flags & SMACK_SNMP_HACK) > 0);\n    pat->is_wildcards = ((flags & SMACK_WILDCARDS) > 0);\n    pat->id = id;\n    pat->pattern = make_copy_of_pattern(pattern, pattern_length, smack->is_nocase);\n    if (pat->is_anchor_begin)\n        smack->is_anchor_begin = 1;\n    if (pat->is_anchor_end)\n        smack->is_anchor_end = 1;\n\n\n    /*\n     * Register the symbols used in the pattern. Hopefully, not all 256\n     * possible combinations will be used, allowing us to shrink the\n     * size of the rows in the final table\n     */\n    smack_add_symbols(smack, pattern, pattern_length);\n    if (pat->is_snmp_hack)\n        smack_add_symbols(smack, (const unsigned char *)\"\\x80\", 1);\n\n\n    /*\n     * Automatically expand the table in order to hold more patterns,\n     * as the caller keeps adding more.\n     */\n    if (smack->m_pattern_count + 1 >= smack->m_pattern_max) {\n        struct SmackPattern **new_list;\n        unsigned new_max;\n\n        new_max = smack->m_pattern_max * 2 + 1;\n        new_list = (struct SmackPattern **)malloc(sizeof(*new_list)*new_max);\n        if (new_list == NULL) {\n            fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n            exit(1);\n        }\n\n        if (smack->m_pattern_list) {\n            memcpy(    new_list,\n                    smack->m_pattern_list,\n                    sizeof(*new_list) * smack->m_pattern_count);\n            free(smack->m_pattern_list);\n        }\n\n        smack->m_pattern_list = new_list;\n        smack->m_pattern_max = new_max;\n    }\n\n\n    /*\n     * Put this pattern onto the end of our list\n     */\n    smack->m_pattern_list[smack->m_pattern_count] = pat;\n    smack->m_pattern_count++;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\n#ifdef DEBUG\nstatic void\nDEBUG_set_name(struct SMACK *smack, const void *pattern,\n               unsigned length, unsigned state)\n{\n    char *name = (char*)malloc(length+1);\n    if (name == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memcpy(name, pattern, length);\n    name[length] = '\\0';\n    smack->m_match[state].DEBUG_name = name;\n}\n#else\n#define DEBUG_set_name(a,b,c,d);\n#endif\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsmack_add_prefixes(struct SMACK *smack, struct SmackPattern *pat)\n{\n    unsigned i;\n    unsigned pattern_length;\n    unsigned char *pattern;\n    int state=0;\n\n    pattern_length = pat->pattern_length;\n    pattern = pat->pattern;\n\n    /*\n     * If we anchor at the beginning, then start with that\n     */\n    if (pat->is_anchor_begin)\n        state = GOTO(state, CHAR_ANCHOR_START);\n\n    /*\n     * Match the existing prefix patterns. For example, if we add all the\n     * prefixes for \"football\", then add \"foobar\", there will already be\n     * prefixes for 'f', 'fo', and 'foo'. We won't start adding new states\n     * until we reach 'foob', 'fooba', and 'foobar'.\n     */\n    for (i=0; i<pattern_length && GOTO(state,pattern[i]) != FAIL; i++)\n        state = GOTO(state,pattern[i]);\n\n    /*\n     * Now that we've matched existing states, start creating new states to\n     * complete this pattern.\n     */\n    for ( ; i<pattern_length; i++) {\n        unsigned new_state = smack->m_state_count++;\n        if (pat->is_snmp_hack)\n            GOTO(state, 0x80) = state; /* snmp_hack, space_hack */\n        GOTO(state, pattern[i]) = new_state;\n        state = new_state;\n        DEBUG_set_name(smack, pattern, i+1, new_state);\n    }\n\n    /*\n     * If there is an anchor at the end, then create one more state\n     */\n    if (pat->is_anchor_end) {\n        unsigned new_state = smack->m_state_count++;\n        GOTO(state, CHAR_ANCHOR_END) = new_state;\n        state = new_state;\n#ifdef DEBUG\n        DEBUG_set_name(smack, pattern, i+1, new_state);\n        smack->m_match[new_state].DEBUG_name[i] = '$';\n#endif\n    }\n\n    /*\n     * Now mark the final state as a \"match\" state.\n     */\n    smack_copy_matches(&smack->m_match[state], &pat->id, 1);\n}\n\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsmack_stage0_compile_prefixes(struct SMACK *smack)\n{\n    unsigned s;\n    unsigned a;\n\n    /*\n     * Initialize the base-state.\n     */\n    smack->m_state_count = 1;\n    for (s=0; s<smack->m_state_max; s++) {\n        for (a=0; a<ALPHABET_SIZE; a++)\n            GOTO(s,a) = FAIL;\n    }\n    DEBUG_set_name(smack, \"*\", 1, 0);\n\n    /*\n     * Initialize the anchor-state\n     */\n    if (smack->is_anchor_begin) {\n        unsigned anchor_begin = smack->m_state_count++;\n        GOTO(BASE_STATE, CHAR_ANCHOR_START) = anchor_begin;\n        DEBUG_set_name(smack, \"^\", 1, anchor_begin);\n    }\n\n    /*\n     * Split a pattern into its sub patterns and add each of them\n     * to the table.\n     */\n    for (a=0; a<(int)smack->m_pattern_count; a++)\n        smack_add_prefixes(smack, smack->m_pattern_list[a]);\n\n    /* Set all failed state transitions to return to the 0'th state */\n    for (a=0; a<ALPHABET_SIZE; a++) {\n        if (GOTO(BASE_STATE,a) == FAIL)\n            GOTO(BASE_STATE,a) = BASE_STATE;\n    }\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsmack_stage1_generate_fails(struct SMACK * smack)\n{\n    unsigned s;\n    unsigned a;\n    struct Queue *queue;\n\n    /* Create a queue for breadth-first enumeration of the patterns*/\n    queue = queue_create();\n\n    /* Do the base-state first */\n    for (a=0; a<ALPHABET_SIZE; a++) {\n        s = GOTO(BASE_STATE,a);\n        if (s != BASE_STATE) {\n            enqueue(queue, s);\n            GOTO_FAIL(s) = BASE_STATE;\n        }\n    }\n\n    /* Build the fail state transitions for each valid state */\n    while (queue_has_more_items(queue)) {\n        unsigned r;\n\n        r = dequeue(queue);\n\n        /* Find Final States for any Failure */\n        for (a=0; a<ALPHABET_SIZE; a++) {\n            unsigned f;\n\n            s = GOTO(r, a);\n            if (s == FAIL)\n                continue;\n            if (s == r)\n                continue; /* snmp_hack, space_hack */\n\n            enqueue(queue, s); /* Breadth first search on states */\n\n            f = GOTO_FAIL(r);\n\n            while (GOTO(f,a) == FAIL)\n                f = GOTO_FAIL(f);\n\n            GOTO_FAIL(s) = GOTO(f,a);\n\n            if (smack->m_match[GOTO(f,a)].m_count)\n                smack_copy_matches(\n                    &smack->m_match[s],\n                    smack->m_match[GOTO(f,a)].m_ids,\n                    smack->m_match[GOTO(f,a)].m_count\n                    );\n        }\n    }\n\n    queue_destroy(queue);\n}\n\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsmack_stage2_link_fails(struct SMACK * smack)\n{\n    unsigned a;\n    struct Queue *queue;\n\n    queue = queue_create();\n\n    for (a=0; a<ALPHABET_SIZE; a++) {\n        if (GOTO(BASE_STATE, a) != BASE_STATE)\n            enqueue(queue, GOTO(BASE_STATE, a));\n    }\n\n    while (queue_has_more_items(queue)) {\n        unsigned r;\n\n        r = dequeue(queue);\n\n        for (a=0; a<ALPHABET_SIZE; a++) {\n            if (GOTO(r,a) == FAIL)\n                GOTO(r,a) = GOTO(GOTO_FAIL(r),a);\n            else if (GOTO(r,a) == r)\n                ; /* snmp_hack, space_hack */\n            else\n                enqueue(queue, GOTO(r,a));\n        }\n    }\n\n    queue_destroy(queue);\n}\n\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nsmack_stage4_make_final_table(struct SMACK *smack)\n{\n    unsigned row;\n    unsigned row_count = smack->m_state_count;\n    unsigned column_count;\n    transition_t *table;\n    unsigned char *char_to_symbol = smack->char_to_symbol;\n\n    /*\n     * Figure out the row-size-shift. Instead of doing a multiply by the\n     * row-width, we expand it out to the nearest pattern of two, and\n     * then use shifts instead of multiplies.\n     */\n    smack->row_shift = row_shift_from_symbol_count(smack->symbol_count);\n    column_count = 1 << smack->row_shift;\n\n    /*\n     * Allocate table:\n     * rows*columns\n     */\n    table = malloc(sizeof(transition_t) * row_count * column_count);\n    if (table == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memset(table, 0, sizeof(transition_t) * row_count * column_count);\n\n\n    for (row=0; row<row_count; row++) {\n        unsigned col;\n\n        for (col=0; col<ALPHABET_SIZE; col++) {\n            unsigned transition;\n            unsigned symbol = char_to_symbol[col];\n\n            transition = GOTO(row,col);\n\n            *(table + row*column_count + symbol) = (transition_t)transition;\n        }\n    }\n\n    smack->table = table;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nswap_rows(struct SMACK *smack, unsigned row0, unsigned row1)\n{\n    struct SmackRow swap;\n    struct SmackMatches swapm;\n    unsigned s;\n\n    /* Swap the first two states */\n    memcpy(&swap,                       &smack->m_state_table[row0],   sizeof(swap));\n    memcpy(&smack->m_state_table[row0], &smack->m_state_table[row1],   sizeof(swap));\n    memcpy(&smack->m_state_table[row1], &swap,                         sizeof(swap));\n\n    /* Swap the 'match' info */\n    memcpy(&swapm,                      &smack->m_match[row0],         sizeof(swapm));\n    memcpy(&smack->m_match[row0],       &smack->m_match[row1],         sizeof(swapm));\n    memcpy(&smack->m_match[row1],       &swapm,                        sizeof(swapm));\n\n\n    /* Now reset any pointers to the swapped states in existing states */\n    for (s=0; s<smack->m_state_count; s++) {\n        unsigned a;\n        for (a=0; a<ALPHABET_SIZE; a++) {\n            if (GOTO(s,a) == row0)\n                GOTO(s,a) = row1;\n            else if (GOTO(s,a) == row1)\n                GOTO(s,a) = row0;\n        }\n    }\n}\n\n/****************************************************************************\n * Sort the states so that all MATCHES are at the end\n ****************************************************************************/\nstatic void\nsmack_stage3_sort(struct SMACK *smack)\n{\n    unsigned start = 0;\n    unsigned end = smack->m_state_count;\n\n    for (;;) {\n\n        while (start < end && smack->m_match[start].m_count == 0)\n            start++;\n        while (start < end && smack->m_match[end-1].m_count != 0)\n            end--;\n\n        if (start >= end)\n            break;\n\n        swap_rows(smack, start, end-1);\n    }\n\n    smack->m_match_limit = start;\n}\n\n/****************************************************************************\n *\n * KLUDGE KLUDGE KLUDGE KLUDGE KLUDGE\n *\n * This function currently only works in a very narrow case, for the SMB\n * parser, where all the patterns are \"anchored\" and none overlap with\n * the SMB patterns. This allows us to modify existing states with\n * the wildcards, without adding new states. Do do this right we need\n * to duplicate states in order to track wildcards\n ****************************************************************************/\nstatic void\nsmack_fixup_wildcards(struct SMACK *smack)\n{\n    size_t i;\n    \n    for (i=0; i<smack->m_pattern_count; i++) {\n        size_t j;\n        struct SmackPattern *pat = smack->m_pattern_list[i];\n        \n        /* skip patterns that aren't wildcards */\n        if (!pat->is_wildcards)\n            continue;\n        \n        /* find the state leading up to the wilcard * character */\n        for (j=0; j<pat->pattern_length; j++) {\n            unsigned row = 0;\n            unsigned offset = 0;\n            size_t row_size = ((size_t)1 << smack->row_shift);\n            transition_t *table;\n            transition_t next_pattern;\n            transition_t base_state = (smack->is_anchor_begin?1:0);\n            size_t k;\n            \n            /* Skip non-wildcard characters */\n            if (pat->pattern[j] != '*')\n                continue;\n            \n            /* find the current 'row' */\n            while (offset < j)\n                smack_search_next(smack, &row, pat->pattern, &offset, (unsigned)j);\n            \n            row = row & 0xFFFFFF;\n            table = smack->table + (row << smack->row_shift);\n            next_pattern = table[smack->char_to_symbol['*']];\n            \n            for (k=0; k<row_size; k++) {\n                if (table[k] == base_state)\n                    table[k] = next_pattern;\n            }\n        }\n    }\n\n}\n/****************************************************************************\n ****************************************************************************/\nvoid\nsmack_compile(struct SMACK *smack)\n{\n    unsigned i;\n\n    /*\n     * Fix up the symbol table to handle \"anchors\" and \"nocase\" conditions.\n     */\n    if (smack->is_anchor_begin)\n        smack_add_symbol(smack, CHAR_ANCHOR_START);\n    if (smack->is_anchor_end)\n        smack_add_symbol(smack, CHAR_ANCHOR_END);\n    if (smack->is_nocase) {\n        for (i='A'; i<='Z'; i++) {\n            smack->char_to_symbol[i] = smack->char_to_symbol[tolower(i)];\n        }\n    }\n\n\n    /*\n     * Calculate the maximum possible number of states. This will be somewhat\n     * larger than the number of states we'll actually use because there can\n     * be overlaps\n     */\n    smack->m_state_max = 1;\n    for (i=0; i<(int)smack->m_pattern_count; i++) {\n        struct SmackPattern *pat = smack->m_pattern_list[i];\n\n        smack->m_state_max += pat->pattern_length;\n        smack->m_state_max += pat->is_anchor_begin;\n        smack->m_state_max += pat->is_anchor_end;\n    }\n\n    /*\n     * Allocate a state-table that can hold that number of states\n     */\n    create_intermediate_table(smack, smack->m_state_max);\n    create_matches_table(smack, smack->m_state_max);\n\n\n    /*\n     * Go through the various compilation stages\n     */\n    smack_stage0_compile_prefixes(smack);\n    smack_stage1_generate_fails(smack);\n    smack_stage2_link_fails(smack);\n\n\n    /* If we have an anchor pattern, then swap\n     * the first two states. */\n    if (smack->is_anchor_begin) {\n        swap_rows(smack, BASE_STATE, UNANCHORED_STATE);\n    }\n\n    /* prettify table for debugging */\n    smack_stage3_sort(smack);\n\n    /*\n     * Build the final table we use for evaluation\n     */\n    smack_stage4_make_final_table(smack);\n    \n    /*\n     * Fixup the wildcard states\n     */\n    smack_fixup_wildcards(smack);\n\n    /*\n     * Get rid of the original pattern tables, since we no longer need them.\n     * However, if this is a debug build, keep the tables around to make\n     * debugging easier\n     */\n#ifndef DEBUG\n    destroy_pattern_table(smack);\n    destroy_intermediate_table(smack);\n#endif\n}\n\n\n/****************************************************************************\n * Found!\n *\n * We found one or more patterns in the input stream. Go through the list\n * and notify the caller of \"smack_search()\" which ones we found.\n ****************************************************************************/\nstatic unsigned\nhandle_match(    struct SMACK * smack,\n                unsigned index,\n                int (*callback_function)(size_t id, int index, void *callback_data),\n                void *callback_data,\n                unsigned state)\n{\n    unsigned i;\n    struct SmackMatches *match = &smack->m_match[state];\n\n    /*\n     * Notify caller of all possible matches.\n     */\n    for (i=0; i<match->m_count; i++) {\n        size_t id = match->m_ids[i];\n        callback_function(id, index, callback_data);\n    }\n\n    return match->m_count;\n}\n\n\n\n\n\n\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\nsmack_search(    struct SMACK * smack,\n                const void *v_px,\n                unsigned length,\n                FOUND_CALLBACK cb_found,\n                void *callback_data,\n                unsigned *current_state)\n{\n    const unsigned char *px = (const unsigned char*)v_px;\n    unsigned row;\n    unsigned i;\n    const unsigned char *char_to_symbol = smack->char_to_symbol;\n    transition_t *table = smack->table;\n    unsigned row_shift = smack->row_shift;\n    unsigned found_count = 0;\n    const struct SmackMatches *match = smack->m_match;\n\n    /* Get the row. This is encoded as the lower 24-bits of the state\n     * variable */\n    row = *current_state & 0xFFFFFF;\n\n    /* 'for all bytes in this block' */\n    for (i=0; i<length; i++) {\n        unsigned char column;\n        unsigned char c;\n\n        /* Get the next character of input */\n        c = px[i];\n\n        /* Convert that character into a symbol. This compresses the table.\n         * Even though there are 256 possible combinations for a byte, we\n         * are probably using fewer than 32 individual characters in the\n         * patterns we are looking for. This step allows us to create tables\n         * that are only 32 elements wide, instead of 256 elements wide */\n        column = char_to_symbol[c];\n\n        /*\n         * If debugging, and the variable is set, then print out the\n         * transition to the command line. This is a good way of visualizing\n         * how they work.\n         */\n#ifdef DEBUG\n        if (print_transitions) {\n            printf(\"%s+%c = %s%s\\n\",\n                    smack->m_match[row].DEBUG_name,\n                    c,\n                    smack->m_match[*(table + (row<<row_shift) + column)].DEBUG_name,\n                    smack->m_match[*(table + (row<<row_shift) + column)].m_count?\"$$\":\"\");\n            print_transitions--;\n        }\n#endif\n\n        /*\n         * STATE TRANSITION\n         * Given the current row, lookup the symbol, and find the next row.\n         * Logically, this is the following  calculation:\n         *    row = table[row][column]\n         * However, since row can have a variable width (depending on the\n         * number of characters in a pattern), we have to do the calculation\n         * manually.\n         */\n        row = *(table + (row<<row_shift) + column);\n\n        /* Test to see if we have one (or more) matches, and if so, call\n         * the callback function */\n        if (match[row].m_count)\n            found_count = handle_match(smack, i, cb_found, callback_data, row);\n    }\n    *current_state = row;\n    return found_count;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\ninner_match(    const unsigned char *px, \n                size_t length,\n                const unsigned char *char_to_symbol,\n                const transition_t *table, \n                unsigned *state, \n                unsigned match_limit,\n                unsigned row_shift) \n{\n    const unsigned char *px_start = px;\n    const unsigned char *px_end = px + length;\n    unsigned row = *state;\n    \n    for ( ; px<px_end; px++) {\n        unsigned char column;\n        \n        /* Convert that character into a symbol. This compresses the table.\n         * Even though there are 256 possible combinations for a byte, we\n         * are probably using fewer than 32 individual characters in the\n         * patterns we are looking for. This step allows us to create tables\n         * that are only 32 elements wide, instead of 256 elements wide */\n        column = char_to_symbol[*px];\n        \n        /*\n         * STATE TRANSITION\n         * Given the current row, lookup the symbol, and find the next row.\n         * Logically, this is the following  calculation:\n         *    row = table[row][column]\n         * However, since row can have a variable width (depending on the\n         * number of characters in a pattern), we have to do the calculation\n         * manually.\n         */\n        row = *(table + (row<<row_shift) + column);\n        \n        if (row >= match_limit)\n            break;\n        \n    }\n\n    *state = row;\n    return px - px_start;\n}\n/*****************************************************************************\n *****************************************************************************/\nstatic size_t\ninner_match_shift7(    const unsigned char *px, \n            size_t length,\n            const unsigned char *char_to_symbol,\n            const transition_t *table, \n            unsigned *state, \n            unsigned match_limit) \n{\n    const unsigned char *px_start = px;\n    const unsigned char *px_end = px + length;\n    unsigned row = *state;\n    \n    for ( ; px<px_end; px++) {\n        unsigned char column;\n        column = char_to_symbol[*px];\n        row = *(table + (row<<7) + column);\n        if (row >= match_limit)\n            break;\n    }\n    \n    *state = row;\n    return px - px_start;\n}\n\n/*****************************************************************************\n *****************************************************************************/\nsize_t\nsmack_search_next(      struct SMACK *  smack,\n                        unsigned *      current_state,\n                        const void *    v_px,\n                        unsigned *       offset,\n                        unsigned        length\n                        )\n{\n    const unsigned char *px = (const unsigned char*)v_px;\n    unsigned row;\n    register size_t i = *offset;\n    const unsigned char *char_to_symbol = smack->char_to_symbol;\n    const transition_t *table = smack->table;\n    register unsigned row_shift = smack->row_shift;\n    const struct SmackMatches *match = smack->m_match;\n    unsigned current_matches = 0;\n    size_t id = (size_t)-1;\n    register unsigned match_limit = smack->m_match_limit;\n\n    /* Get the row. This is encoded as the lower 24-bits of the state\n     * variable */\n    row = *current_state & 0xFFFFFF;\n\n    /* See if there are current matches we are processing */\n    current_matches = (*current_state)>>24;\n \n    /* 'for all bytes in this block' */\n    if (current_matches == 0 /*no previous matches*/) {\n        /*if ((length-i) & 1)\n            i += inner_match(px + i, \n                             length - i,\n                             char_to_symbol,\n                             table, \n                             &row, \n                             match_limit,\n                             row_shift);\n        if (row < match_limit && i < length)*/\n        switch (row_shift) {\n            case 7:\n                i += inner_match_shift7(px + i, \n                                 length - i,\n                                 char_to_symbol,\n                                 table, \n                                 &row, \n                                 match_limit);\n                break;\n            default:\n                i += inner_match(px + i, \n                                 length - i,\n                                 char_to_symbol,\n                                 table, \n                                 &row, \n                                 match_limit,\n                                 row_shift);\n                break;\n\n        }\n\n        //printf(\"*** row=%u, i=%u, limit=%u\\n\", row, i, match_limit);\n\n        /* Test to see if we have one (or more) matches, and if so, call\n         * the callback function */\n        if (match[row].m_count) {\n            i++; /* points to first byte after match */\n            current_matches = match[row].m_count;\n        }\n    }\n\n    *offset = (unsigned)i;\n\n    /* If we broke early because we found a match, return that match */\n    if (current_matches) {\n        current_matches--;\n        id = match[row].m_ids[current_matches];\n    }\n\n    *current_state = row | (current_matches<<24);\n    return id;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nsize_t\nsmack_next_match(struct SMACK *smack, unsigned *current_state)\n{\n    unsigned row, current_matches;\n    size_t id = SMACK_NOT_FOUND;\n\n    /* split the state variable */\n    row = *current_state & 0xFFFFFF;\n    current_matches = (*current_state)>>24;\n\n    /* If we broke early because we found a match, return that match */\n    if (current_matches) {\n        const struct SmackMatches *match = smack->m_match;\n        id = match[row].m_ids[current_matches-1];\n        current_matches--;\n    }\n\n    /* Recombine the state */\n    *current_state = row | (current_matches<<24);\n\n    return id;\n}\n\n\n/****************************************************************************\n ****************************************************************************/\nunsigned\nsmack_search_end(       struct SMACK *  smack,\n                        FOUND_CALLBACK  cb_found,\n                        void *          callback_data,\n                        unsigned *      current_state)\n{\n    unsigned found_count = 0;\n    transition_t *table = smack->table;\n    unsigned row_shift = smack->row_shift;\n    unsigned row = *current_state;\n    const struct SmackMatches *match = smack->m_match;\n    unsigned column = smack->char_to_symbol[CHAR_ANCHOR_END];\n\n    /*\n     * This is the same logic as for \"smack_search()\", except there is\n     * only one byte of input -- the virtual character ($) that represents\n     * the anchor at the end of some patterns.\n     */\n    row = *(table + (row<<row_shift) + column);\n    if (match[row].m_count)\n        found_count = handle_match(smack, 0, cb_found, callback_data, row);\n\n    *current_state = row;\n    return found_count;\n}\n\nsize_t\nsmack_search_next_end(  struct SMACK *  smack,\n                        unsigned *      current_state)\n{\n    transition_t *table = smack->table;\n    unsigned row_shift = smack->row_shift;\n    unsigned row = *current_state & 0xFFFFFF;\n    unsigned current_matches = (*current_state)>>24;\n    const struct SmackMatches *match = smack->m_match;\n    unsigned column = smack->char_to_symbol[CHAR_ANCHOR_END];\n    size_t id = SMACK_NOT_FOUND;\n\n    /*\n     * We can enumerate more than one matching end patterns. When we\n     * reach the end of that list, return NOT FOUND.\n     */\n    if (current_matches == 0xFF) {\n        return SMACK_NOT_FOUND;\n    }\n\n\n    /*\n     * If we've already returned the first result in our list,\n     * then return the next result.\n     */\n    if (current_matches) {\n        current_matches -= 1;\n        id = match[row].m_ids[current_matches];\n    } else {\n        /*\n         * This is the same logic as for \"smack_search()\", except there is\n         * only one byte of input -- the virtual character ($) that represents\n         * the anchor at the end of some patterns.\n         */\n        row = *(table + (row<<row_shift) + column);\n        if (match[row].m_count == 0) {\n            /* There was no match, so therefore return NOT FOUND */\n            return SMACK_NOT_FOUND;\n        }\n\n\n        /*\n         * If we reach this point, we have found matches, but\n         * haven't started returning them. So start returning\n         * them. This returns the first one in the list.\n         */\n        current_matches = match[row].m_count;\n        id = match[row].m_ids[current_matches - 1];\n        current_matches--;\n    }\n    \n    *current_state = row | (current_matches<<24);\n    return id;\n}\n\n/*****************************************************************************\n * Provide my own rand() simply to avoid static-analysis warning me that\n * 'rand()' is unrandom, when in fact we want the non-random properties of\n * rand() for regression testing.\n *****************************************************************************/\nstatic unsigned\nr_rand(unsigned *seed)\n{\n    static const unsigned a = 214013;\n    static const unsigned c = 2531011;\n    \n    *seed = (*seed) * a + c;\n    return (*seed)>>16 & 0x7fff;\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nsmack_benchmark(void)\n{\n    char *buf;\n    unsigned seed = 0;\n    static unsigned BUF_SIZE = 1024*1024;\n    static uint64_t ITERATIONS = 30;\n    unsigned i;\n    struct SMACK *s;\n    uint64_t start, stop;\n    uint64_t result = 0;\n    uint64_t cycle1, cycle2;\n\n    printf(\"-- smack-1 -- \\n\");\n    \n    s = smack_create(\"benchmark1\", 1);\n\n    /* Fill a buffer full of junk */\n    buf = (char*)malloc(BUF_SIZE);\n    if (buf == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }          \n    for (i=0; i<BUF_SIZE; i++)\n        buf[i] = (char)r_rand(&seed)&0x7F;\n\n\n    /* Create 20 patterns */\n    for (i=0; i<20; i++) {\n        unsigned pattern_length = r_rand(&seed)%3 + r_rand(&seed)%4 + 4;\n        char pattern[20];\n        unsigned j;\n\n        for (j=0; j<pattern_length; j++)\n            pattern[j] = (char)(r_rand(&seed)&0x7F) | 0x80;\n        \n        smack_add_pattern(s, pattern, pattern_length, i, 0);\n    }\n\n    smack_compile(s);\n\n    start = pixie_nanotime();\n    cycle1 = __rdtsc();\n    for (i=0; i<ITERATIONS; i++) {\n        unsigned state = 0;\n        unsigned offset = 0;\n\n        while (offset < BUF_SIZE)\n            result += smack_search_next(s, &state, buf, &offset, BUF_SIZE);\n    }\n    cycle2 = __rdtsc();\n    stop = pixie_nanotime();\n\n    if (result) {\n        double elapsed = ((double)(stop - start))/(1000000000.0);\n        double rate = (BUF_SIZE*ITERATIONS*8ULL)/elapsed;\n        double cycles = (BUF_SIZE*ITERATIONS*1.0)/(1.0*(cycle2-cycle1));\n\n        rate /= 1000000.0;\n\n        printf(\"bits/second = %5.3f-million\\n\", rate);\n        printf(\"clocks/byte = %5.3f\\n\", (1.0/cycles));\n        printf(\"clockrate = %5.3f-GHz\\n\", ((cycle2-cycle1)*1.0/elapsed)/1000000000.0);\n\n        \n    }\n\n    free(buf);\n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nsmack_selftest(void)\n{\n    struct SMACK *s;\n    const char *patterns[] = {\n        \"GET\",      \"PUT\",      \"POST\",     \"OPTIONS\",\n        \"HEAD\",     \"DELETE\",   \"TRACE\",    \"CONNECT\",\n        \"PROPFIND\", \"PROPPATCH\",\"MKCOL\",    \"MKWORKSPACE\",\n        \"MOVE\",     \"LOCK\",     \"UNLOCK\",   \"VERSION-CONTROL\",\n        \"REPORT\",   \"CHECKOUT\", \"CHECKIN\",  \"UNCHECKOUT\",\n        \"COPY\",     \"UPDATE\",   \"LABEL\",    \"BASELINE-CONTROL\",\n        \"MERGE\",    \"SEARCH\",   \"ACL\",      \"ORDERPATCH\",\n        \"PATCH\",    \"MKACTIVITY\", 0};\n    unsigned i;\n    const char *text = \"ahpropfindhf;orderpatchposearchmoversion-controlockasldhf\";\n    unsigned text_length = (unsigned)strlen(text);\n    size_t id, id2;\n    unsigned state = 0;\n    static const size_t END_TEST_THINGY1 = 9001;\n    static const size_t END_TEST_THINGY2 = 9002;\n\n    LOG(1, \"[ ] smack: selftest started\\n\");\n\n    /*\n     * using SMACK is 5 steps:\n     * #1 create an instance at program startup\n     * #2 add patterns to it\n     * #3 compile the patterns\n     * #4 do your searches while running the program\n     * #5 destroy the instance at program exit\n     */\n    s = smack_create(\"test1\", 1);\n\n    for (i=0; patterns[i]; i++)\n        smack_add_pattern(s, patterns[i], (unsigned)strlen(patterns[i]), i, 0);\n\n    /* additional pattern for testing the end condition */\n    smack_add_pattern(s, \"dhf\",  3, END_TEST_THINGY1, SMACK_ANCHOR_END);\n    smack_add_pattern(s, \"ldhf\", 4, END_TEST_THINGY2, SMACK_ANCHOR_END);\n\n    smack_compile(s);\n\n    i = 0;\n#define TEST(pat, offset, str) if (pat != id || offset != i) return 1 + fprintf(stderr, \"smack: fail %s\\n\", str)\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST(  8,  10, \"PROPFIND\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 28,  23, \"PATCH\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 27,  23, \"ORDERPATCH\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 25,  31, \"SEARCH\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 12,  35, \"MOVE\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 15,  48, \"VERSION-CONTROL\");\n    id = smack_search_next(s,&state,text, &i,text_length);\n    TEST( 13,  51, \"LOCK\");\n\n    /* SMACK_ANCHOR_END test\n     * The next patterns we should find are at the end of the string\n     * (\"dhf\" and \"ldhf\"). However, simply doing a search with \"next\"\n     * won't find them, because when we call this function call, we\n     * can't know that we've reached the end of input yet. We have\n     * to explicitly make a \"search end\" call before they are found */\n    id = smack_search_next(s,&state,text, &i,text_length);\n    if (id != SMACK_NOT_FOUND) {\n        /* At this point, we should no more patterns, and reach the end\n         * of the string */\n        fprintf(stderr, \"[-] smack: fail: line=%u, file=%s\\n\", __LINE__, __FILE__);\n        return 1;\n    }\n    \n    /* SMACK_ANCHOR_END search end test\n     * We've reached the end of input, so now we tell this to the module.\n     * The only purpose for calling this is if we have \"ANCHOR_END\"\n     * patterns that won't match until we tell the system we've\n     * reached the end of input. */\n    id = smack_search_next_end(s, &state);\n    if (id != END_TEST_THINGY1 && id != END_TEST_THINGY2) {\n        /* We didn't find one of the two end-patterns we were looking for, so fail */\n        fprintf(stderr, \"[-] smack: fail: line=%u, file=%s\\n\", __LINE__, __FILE__);\n        return 1;\n    }\n    \n    /* We have TWO end patterns that will match. We need to make sure the\n     * second also was triggered, and that it's different from the first.\n     * Note that this text is agnostic which of the two ending patterns\n     * is found first. The order is undefined, and may change in future\n     * versions. */\n    id2 = smack_search_next_end(s, &state);\n    if (id2 != END_TEST_THINGY1 && id2 != END_TEST_THINGY2) {\n        fprintf(stderr, \"[-] smack: fail: line=%u, file=%s\\n\", __LINE__, __FILE__);\n        return 1;\n    } else if (id2 == id) {\n        /* The two ending patterns should give two different results */\n        fprintf(stderr, \"[-] smack: fail: line=%u, file=%s\\n\", __LINE__, __FILE__);\n        return 1;\n    }\n    \n    /* We have only two ending patterns, so if we try for a third, we'll get\n     * a NOT FOUND */\n    id2 = smack_search_next_end(s, &state);\n    if (id2 != SMACK_NOT_FOUND) {\n        fprintf(stderr, \"[-] smack: fail: line=%u, file=%s\\n\", __LINE__, __FILE__);\n        return 1;\n    }\n\n\n    smack_destroy(s);\n\n    \n    LOG(1, \"[+] smack: success!\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "src/smackqueue.c",
    "content": "#include \"smackqueue.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/****************************************************************************\n * Build a queue so that we can do a breadth-first enumeration of the\n * sub-patterns\n ****************************************************************************/\nstruct QueueElement\n{\n    unsigned m_data;\n    struct QueueElement *m_next;\n};\nstruct Queue\n{\n    struct QueueElement *m_head;\n    struct QueueElement *m_tail;\n};\n\nstruct Queue *\nqueue_create(void)\n{\n    struct Queue *queue;\n    queue = (struct Queue *)malloc(sizeof(*queue));\n    if (queue == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n    memset(queue, 0, sizeof(*queue));\n    return queue;\n}\n\nvoid\nqueue_destroy(struct Queue * queue)\n{\n    if (queue == NULL)\n        return;\n    while (queue_has_more_items(queue))\n        dequeue(queue);\n    free(queue);\n}\n\nvoid\nenqueue(struct Queue *queue, unsigned data)\n{\n    struct QueueElement *element;\n\n    element = (struct QueueElement *)malloc(sizeof (struct QueueElement));\n    if (element == NULL) {\n        fprintf(stderr, \"%s: out of memory error\\n\", \"smack\");\n        exit(1);\n    }\n\n    if (queue->m_head == NULL) {\n        /* If nothing in the queue, initialize the queue with the\n         * first data */\n        queue->m_head = element;\n    } else {\n        /* Else, add the data to the tail of the queue */\n        queue->m_tail->m_next = element;\n    }\n\n    element->m_data = data;\n    element->m_next = NULL;\n    queue->m_tail = element;\n}\n\nunsigned\ndequeue(struct Queue *queue)\n{\n    if (queue->m_head == NULL)\n        return 0;\n    else {\n        struct QueueElement *element;\n        unsigned result;\n\n        element = queue->m_head;\n        result = element->m_data;\n        queue->m_head = element->m_next;\n\n        free(element);\n        return result;\n    }\n}\n\nunsigned queue_has_more_items(struct Queue * queue)\n{\n  return queue->m_head != NULL;\n}\n"
  },
  {
    "path": "src/smackqueue.h",
    "content": "#ifndef SMACKQUEUE_H\n#define SMACKQUEUE_H\n\nstruct Queue *\nqueue_create(void);\n\n\nvoid\nqueue_destroy(struct Queue *queue);\n\n\nvoid\nenqueue(struct Queue *queue, unsigned data);\n\n\nunsigned\ndequeue(struct Queue *queue);\n\n\nunsigned\nqueue_has_more_items(struct Queue *queue);\n\n\n#endif\n"
  },
  {
    "path": "src/stack-arpv4.c",
    "content": "/*\n    handle ARP\n\n    Usage #1:\n        At startup, we make a synchronous request for the local router.\n        We'll wait several seconds for a response, but abort the program\n        if we don't receive a response.\n\n    Usage #2:\n        While running, we'll need to respond to ARPs. That's because we\n        may be bypassing the stack of the local machine with a \"spoofed\"\n        IP address. Every so often, the local router may drop it's route\n        entry and re-request our address.\n*/\n#include \"rawsock.h\"\n#include \"rawsock-adapter.h\"\n#include \"stack-src.h\"\n#include \"stack-arpv4.h\"\n#include \"stack-queue.h\"\n#include \"util-safefunc.h\"\n#include \"util-logger.h\"\n#include \"pixie-timer.h\"\n#include \"proto-preprocess.h\"\n#include \"util-checksum.h\"\n\n#define VERIFY_REMAINING(n) if (offset+(n) > max) return;\n\n/**\n * A structure representing the information parsed from an incoming\n * ARP packet. Note: unlike normal programming style, this isn't\n * overlayed on the incoming ARP header, but instead each field\n * is parsed one-by-one and converted into this internal structure.\n */\nstruct ARP_IncomingRequest\n{\n    unsigned is_valid;\n    unsigned opcode;\n    unsigned hardware_type;\n    unsigned protocol_type;\n    unsigned hardware_length;\n    unsigned protocol_length;\n    unsigned ip_src;\n    unsigned ip_dst;\n    const unsigned char *mac_src;\n    const unsigned char *mac_dst;\n};\n\n\n/****************************************************************************\n ****************************************************************************/\nstatic void\nproto_arp_parse(struct ARP_IncomingRequest *arp,\n                const unsigned char px[], unsigned offset, unsigned max)\n{\n\n    /*\n     * parse the header\n     */\n    VERIFY_REMAINING(8);\n    arp->is_valid = 0; /* not valid yet */\n\n    arp->hardware_type = px[offset]<<8 | px[offset+1];\n    arp->protocol_type = px[offset+2]<<8 | px[offset+3];\n    arp->hardware_length = px[offset+4];\n    arp->protocol_length = px[offset+5];\n    arp->opcode = px[offset+6]<<8 | px[offset+7];\n    offset += 8;\n\n    /* We only support IPv4 and Ethernet addresses */\n    if (arp->protocol_length != 4 && arp->hardware_length != 6)\n        return;\n    if (arp->protocol_type != 0x0800)\n        return;\n    if (arp->hardware_type != 1 && arp->hardware_type != 6)\n        return;\n\n    /*\n     * parse the addresses\n     */\n    VERIFY_REMAINING(2 * arp->hardware_length + 2 * arp->protocol_length);\n    arp->mac_src = px+offset;\n    offset += arp->hardware_length;\n\n    arp->ip_src = px[offset+0]<<24 | px[offset+1]<<16 | px[offset+2]<<8 | px[offset+3];\n    offset += arp->protocol_length;\n\n    arp->mac_dst = px+offset;\n    offset += arp->hardware_length;\n\n    arp->ip_dst = px[offset+0]<<24 | px[offset+1]<<16 | px[offset+2]<<8 | px[offset+3];\n    //offset += arp->protocol_length;\n\n    arp->is_valid = 1;\n}\n\n\n/****************************************************************************\n * Resolve the IP address into a MAC address. Do this synchronously, meaning,\n * we'll stop and wait for the response. This is done at program startup,\n * but not during then normal asynchronous operation during the scan.\n ****************************************************************************/\nint\nstack_arp_resolve(struct Adapter *adapter,\n    ipv4address_t my_ipv4, macaddress_t my_mac_address,\n    ipv4address_t your_ipv4, macaddress_t *your_mac_address)\n{\n    unsigned char xarp_packet[64];\n    unsigned char *arp_packet = &xarp_packet[0];\n    unsigned i;\n    time_t start;\n    unsigned is_arp_notice_given = 0;\n    struct ARP_IncomingRequest response;\n    int is_delay_reported = 0;\n\n    /*\n     * [KLUDGE]\n     *  If this is a VPN connection\n     */\n    if (stack_if_datalink(adapter) == 12) {\n        memcpy(your_mac_address->addr, \"\\0\\0\\0\\0\\0\\2\", 6);\n        return 0; /* success */\n    }\n\n    memset(&response, 0, sizeof(response));\n\n    /* zero out bytes in packet to avoid leaking stuff in the padding\n     * (ARP is 42 byte packet, Ethernet is 60 byte minimum) */\n    memset(arp_packet, 0, sizeof(xarp_packet));\n\n    /*\n     * Create the request packet\n     */\n    memcpy(arp_packet +  0, \"\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\", 6);\n    memcpy(arp_packet +  6, my_mac_address.addr, 6);\n    \n    if (adapter->is_vlan) {\n        memcpy(arp_packet + 12, \"\\x81\\x00\", 2);\n        arp_packet[14] = (unsigned char)(adapter->vlan_id>>8);\n        arp_packet[15] = (unsigned char)(adapter->vlan_id&0xFF);\n        arp_packet += 4;\n    }\n    \n    memcpy(arp_packet + 12, \"\\x08\\x06\", 2);\n\n    \n    memcpy(arp_packet + 14,\n            \"\\x00\\x01\" /* hardware = Ethernet */\n            \"\\x08\\x00\" /* protocol = IPv4 */\n            \"\\x06\\x04\" /* MAC length = 6, IPv4 length = 4 */\n            \"\\x00\\x01\" /* opcode = request */\n            , 8);\n\n    memcpy(arp_packet + 22, my_mac_address.addr, 6);\n    arp_packet[28] = (unsigned char)(my_ipv4 >> 24);\n    arp_packet[29] = (unsigned char)(my_ipv4 >> 16);\n    arp_packet[30] = (unsigned char)(my_ipv4 >>  8);\n    arp_packet[31] = (unsigned char)(my_ipv4 >>  0);\n\n    memcpy(arp_packet + 32, \"\\x00\\x00\\x00\\x00\\x00\\x00\", 6);\n    arp_packet[38] = (unsigned char)(your_ipv4 >> 24);\n    arp_packet[39] = (unsigned char)(your_ipv4 >> 16);\n    arp_packet[40] = (unsigned char)(your_ipv4 >>  8);\n    arp_packet[41] = (unsigned char)(your_ipv4 >>  0);\n\n\n    /* Kludge: handle VLNA header if it exists. This is probably\n     * the wrong way to handle this. */\n    if (adapter->is_vlan)\n        arp_packet -= 4;\n    \n    /*\n     * Now loop for a few seconds looking for the response\n     */\n    rawsock_send_packet(adapter, arp_packet, 60, 1);\n    start = time(0);\n    i = 0;\n    for (;;) {\n        unsigned length;\n        unsigned secs;\n        unsigned usecs;\n        const unsigned char *px;\n        int err;\n\n        if (time(0) != start) {\n            start = time(0);\n            rawsock_send_packet(adapter, arp_packet, 60, 1);\n            if (i++ >= 10)\n                break; /* timeout */\n\n            /* It's taking too long, so notify the user */\n            if (!is_delay_reported) {\n                ipaddress_formatted_t fmt = ipv4address_fmt(your_ipv4);\n                LOG(0, \"[+] resolving router %s with ARP (may take some time)...\\n\", fmt.string);\n                is_delay_reported = 1;\n            }\n        }\n\n        /* If we aren't getting a response back to our ARP, then print a\n         * status message */\n        if (time(0) > start+1 && !is_arp_notice_given) {\n            ipaddress_formatted_t fmt = ipv4address_fmt(your_ipv4);\n            LOG(0, \"[+] arping local router %s\\n\", fmt.string);\n            is_arp_notice_given = 1;\n        }\n\n        err =  rawsock_recv_packet(\n                    adapter,\n                    &length,\n                    &secs,\n                    &usecs,\n                    &px);\n\n        if (err != 0)\n            continue;\n\n        if (adapter->is_vlan && px[17] != 6)\n            continue;\n        if (!adapter->is_vlan && px[13] != 6)\n            continue;\n\n\n        /*\n         * Parse the response as an ARP packet\n         */\n        if (adapter->is_vlan)\n            proto_arp_parse(&response, px, 18, length);\n        else\n            proto_arp_parse(&response, px, 14, length);\n\n        /* Is this an ARP packet? */\n        if (!response.is_valid) {\n            LOG(2, \"[-] arp: etype=0x%04x, not ARP\\n\", px[12]*256 + px[13]);\n            continue;\n        }\n\n        /* Is this an ARP \"reply\"? */\n        if (response.opcode != 2) {\n            LOG(2, \"[-] arp: opcode=%u, not reply(2)\\n\", response.opcode);\n            continue;\n        }\n\n        /* Is this response directed at us? */\n        if (response.ip_dst != my_ipv4) {\n            LOG(2, \"[-] arp: dst=%08x, not my ip 0x%08x\\n\", response.ip_dst, my_ipv4);\n            continue;\n        }\n        if (memcmp(response.mac_dst, my_mac_address.addr, 6) != 0)\n            continue;\n\n        /* Is this the droid we are looking for? */\n        if (response.ip_src != your_ipv4) {\n            ipaddress_formatted_t fmt1 = ipv4address_fmt(response.ip_src);\n            ipaddress_formatted_t fmt2 = ipv4address_fmt(your_ipv4);\n            LOG(2, \"[-] arp: target=%s, not desired %s\\n\", fmt1.string, fmt2.string);\n            continue;\n        }\n\n        /*\n         * GOT IT!\n         *  we've got a valid response, so save the results and\n         *  return.\n         */\n        memcpy(your_mac_address->addr, response.mac_src, 6);\n        {\n            ipaddress_formatted_t fmt1 = ipv4address_fmt(response.ip_src);\n            ipaddress_formatted_t fmt2 = macaddress_fmt(*your_mac_address);\n            LOG(1, \"[+] arp: %s == %s\\n\", fmt1.string, fmt2.string);\n        }\n        return 0;\n    }\n\n    return 1;\n}\n\n    \n\n\n/****************************************************************************\n * Handle an incoming ARP request.\n ****************************************************************************/\nint\nstack_arp_incoming_request( struct stack_t *stack,\n    ipv4address_t my_ip, macaddress_t my_mac,\n    const unsigned char *px, unsigned length)\n{\n    struct PacketBuffer *response = 0;\n    struct ARP_IncomingRequest request;\n\n    memset(&request, 0, sizeof(request));\n\n\n    /* Get a buffer for sending the response packet. This thread doesn't\n     * send the packet itself. Instead, it formats a packet, then hands\n     * that packet off to a transmit thread for later transmission. */\n    response = stack_get_packetbuffer(stack);\n    if (response == NULL)\n        return -1;\n\n    /* ARP packets are too short, so increase the packet size to\n     * the Ethernet minimum */\n    response->length = 60;\n\n    /* Fill the padded area with zeroes to avoid leaking data */\n    memset(response->px, 0, response->length);\n\n    /*\n     * Parse the response as an ARP packet\n     */\n    proto_arp_parse(&request, px, 14, length);\n\n    /* Is this an ARP packet? */\n    if (!request.is_valid) {\n        LOG(2, \"arp: etype=0x%04x, not ARP\\n\", px[12]*256 + px[13]);\n        return -1;\n    }\n\n    /* Is this an ARP \"request\"? */\n    if (request.opcode != 1) {\n        LOG(2, \"arp: opcode=%u, not request(1)\\n\", request.opcode);\n        return -1;\n    }\n\n    /* Is this response directed at us? */\n    if (request.ip_dst != my_ip) {\n        LOG(2, \"arp: dst=%08x, not my ip 0x%08x\\n\", request.ip_dst, my_ip);\n        return -1;\n    }\n\n    /*\n     * Create the response packet\n     */\n    memcpy(response->px +  0, request.mac_src, 6);\n    memcpy(response->px +  6, my_mac.addr, 6);\n    memcpy(response->px + 12, \"\\x08\\x06\", 2);\n\n    memcpy(response->px + 14,\n            \"\\x00\\x01\" /* hardware = Ethernet */\n            \"\\x08\\x00\" /* protocol = IPv4 */\n            \"\\x06\\x04\" /* MAC length = 6, IPv4 length = 4 */\n            \"\\x00\\x02\" /* opcode = reply(2) */\n            , 8);\n\n    memcpy(response->px + 22, my_mac.addr, 6);\n    response->px[28] = (unsigned char)(my_ip >> 24);\n    response->px[29] = (unsigned char)(my_ip >> 16);\n    response->px[30] = (unsigned char)(my_ip >>  8);\n    response->px[31] = (unsigned char)(my_ip >>  0);\n\n    memcpy(response->px + 32, request.mac_src, 6);\n    response->px[38] = (unsigned char)(request.ip_src >> 24);\n    response->px[39] = (unsigned char)(request.ip_src >> 16);\n    response->px[40] = (unsigned char)(request.ip_src >>  8);\n    response->px[41] = (unsigned char)(request.ip_src >>  0);\n\n\n    /*\n     * Now queue the packet up for transmission\n     */\n    stack_transmit_packetbuffer(stack, response);\n\n    return 0;\n}\n"
  },
  {
    "path": "src/stack-arpv4.h",
    "content": "#ifndef STACK_ARP_H\n#define STACK_ARP_H\nstruct Adapter;\n#include \"stack-queue.h\"\n#include \"massip-addr.h\"\n\n/**\n * Response to an ARP request for our IP address.\n *\n * @param my_ip\n *      My IP address\n * @param my_mac\n *      My Ethernet MAC address that matches this IP address.\n * @param px\n *      The incoming ARP request\n * @param length\n *      The length of the incoming ARP request.\n * @param packet_buffers\n *      Free packet buffers I can use to format the request\n * @param transmit_queue\n *      I put the formatted response onto this queue for later\n *      transmission by a transmit thread.\n */\nint stack_arp_incoming_request(struct stack_t *stack,\n        ipv4address_t my_ip, macaddress_t my_mac,\n        const unsigned char *px, unsigned length);\n\n/**\n * Send an ARP request in order to resolve an IPv4 address into a\n * MAC address. Usually done in order to find the local router's \n * MAC address when given the IPv4 address of the router.\n */\nint stack_arp_resolve(struct Adapter *adapter,\n    ipv4address_t my_ipv4, macaddress_t my_mac_address,\n    ipv4address_t your_ipv4, macaddress_t *your_mac_address);\n\n#endif\n"
  },
  {
    "path": "src/stack-if.c",
    "content": "#include \"rawsock.h\"\n#include \"rawsock-adapter.h\"\n\n/***************************************************************************\n ***************************************************************************/\nint\nstack_if_datalink(struct Adapter *adapter)\n{\n    if (adapter->ring)\n        return 1; /* ethernet */\n    else {\n        return adapter->link_type;\n    }\n}\n"
  },
  {
    "path": "src/stack-ndpv6.c",
    "content": "#include \"stack-ndpv6.h\"\n#include \"proto-preprocess.h\"\n#include \"stack-src.h\"\n#include \"util-checksum.h\"\n#include \"rawsock-adapter.h\"\n#include \"rawsock.h\"\n#include \"util-logger.h\"\n#include <string.h>\n\n\n\nstatic inline void _append(unsigned char *buf, size_t *r_offset, size_t max, unsigned x)\n{\n    if (*r_offset >= max)\n        return;\n    buf[(*r_offset)++] = (unsigned char)x;\n}\nstatic inline void _append_bytes(unsigned char *buf, size_t *r_offset, size_t max, const void *v_bytes, size_t len)\n{\n    const unsigned char *bytes = (const unsigned char *)v_bytes;\n    if (*r_offset + len >= max)\n        return;\n    memcpy(buf + *r_offset, bytes, len);\n    *r_offset += len;\n}\n\nstatic inline void\n_append_short(unsigned char *buf, size_t *offset, size_t max, unsigned num)\n{\n    if (2 > max - *offset) {\n        *offset = max;\n        return;\n    }\n    buf[(*offset)++] = (unsigned char)(num>>8);\n    buf[(*offset)++] = (unsigned char)(num & 0xFF);\n}\n\nstatic inline unsigned\n_read_byte(const unsigned char *buf, size_t *offset, size_t max)\n{\n    if (*offset + 1 < max) {\n        return buf[(*offset)++];\n    } else\n        return (unsigned)~0;\n}\nstatic inline unsigned\n_read_short(const unsigned char *buf, size_t *offset, size_t max)\n{\n    if (*offset + 2  <= max) {\n        unsigned result;\n        result = buf[(*offset)++] << 8;\n        result |= buf[(*offset)++];\n        return result;\n    } else\n        return (unsigned)~0;\n}\n\nstatic inline unsigned\n_read_number(const unsigned char *buf, size_t *offset, size_t max)\n{\n    if (*offset + 4  <= max) {\n        unsigned result;\n        result = buf[(*offset)++] << 24;\n        result |= buf[(*offset)++] << 16;\n        result |= buf[(*offset)++] << 8;\n        result |= buf[(*offset)++];\n        return result;\n    } else\n        return (unsigned)~0;\n}\n\nstatic inline ipv6address_t\n_read_ipv6(const unsigned char *buf, size_t *offset, size_t max)\n{\n    ipv6address_t result = {0,0};\n    \n    if (*offset + 16 <= max) {\n        result = ipv6address_from_bytes(buf + *offset);\n        *offset += 16;\n    } else {\n        *offset = max;\n    }\n    return result;\n}\n\n\n/**\n * Handle the IPv6 Neighbor Solicitation request.\n * This happens after we've transmitted a packet, a response is on\n * it's way back, and the router needs to give us the response\n * packet. The router sends us a solicitation, like an ARP request, \n * to which we must respond.\n */\nint\nstack_ndpv6_incoming_request(struct stack_t *stack, struct PreprocessedInfo *parsed,  const unsigned char *px, size_t length)\n{\n    struct PacketBuffer *response = 0;\n    size_t offset;\n    size_t remaining;\n    ipaddress target_ip;\n    const unsigned char *target_ip_buf;\n    macaddress_t target_mac = stack->source_mac;\n    unsigned xsum;\n    unsigned char *buf2;\n    static const size_t max = sizeof(response->px);\n    size_t offset_ip = parsed->ip_offset;\n    size_t offset_ip_src = offset_ip + 8; /* offset in packet to the source IPv6 address */\n    size_t offset_ip_dst = offset_ip + 24;\n    size_t offset_icmpv6 = parsed->transport_offset;\n    \n    /* Verify it's a \"Neighbor Solitication\" opcode */\n    if (parsed->opcode != 135)\n        return -1;\n\n    /* Make sure there's at least a full header */\n    offset = parsed->transport_offset;\n    remaining = length - offset;\n    if (remaining < 24)\n        return -1;\n\n    /* Make sure it's looking for our own address */\n    target_ip_buf = px + offset + 8;\n    target_ip.version = 6;\n    target_ip.ipv6 = ipv6address_from_bytes(target_ip_buf);\n    if (!is_my_ip(stack->src, target_ip))\n        return -1;\n\n    /* Print a log message */\n    {\n        ipv6address_t a = ipv6address_from_bytes(px + offset_ip_src);\n        ipaddress_formatted_t fmt1 = ipv6address_fmt(a);\n        ipaddress_formatted_t fmt2 = ipaddress_fmt(target_ip);\n        LOG(1, \"[+] received NDP request from %s for %s\\n\", fmt1.string, fmt2.string);\n    }\n    \n    /* Get a buffer for sending the response packet. This thread doesn't\n     * send the packet itself. Instead, it formats a packet, then hands\n     * that packet off to a transmit thread for later transmission. */\n    response = stack_get_packetbuffer(stack);\n    if (response == NULL)\n        return -1; \n\n\n    /* Use the request packet as a template for the response */\n    memcpy(response->px, px, length);\n    buf2 = response->px;\n    \n    /* Set the destination MAC address and destination IPv6 address*/\n    memcpy(buf2 + 0, px + 6, 6);\n    memcpy(buf2 + offset_ip_dst, px + offset_ip_src, 16);\n\n    /* Set the source MAC address and source IPv6 address */\n    memcpy(buf2 + offset_ip_src, target_ip_buf, 16);\n    memcpy(buf2 + 6, target_mac.addr, 6);\n    \n    /* Format the response */\n    _append(buf2, &offset, max, 136); /* type */\n    _append(buf2, &offset, max, 0); /* code */\n    _append(buf2, &offset, max, 0); /*checksum[hi] */\n    _append(buf2, &offset, max, 0); /*checksum[lo] */\n    _append(buf2, &offset, max, 0x60); /* flags*/ \n    _append(buf2, &offset, max, 0);\n    _append(buf2, &offset, max, 0);\n    _append(buf2, &offset, max, 0);\n    _append_bytes(buf2, &offset, max, target_ip_buf, 16);\n    _append(buf2, &offset, max, 2);\n    _append(buf2, &offset, max, 1);\n    _append_bytes(buf2, &offset, max, target_mac.addr, 6);\n\n    xsum = checksum_ipv6(   buf2 + offset_ip_src, \n                            buf2 + offset_ip_dst, \n                            58,  \n                            offset - offset_icmpv6, \n                            buf2 +offset_icmpv6);\n    buf2[offset_icmpv6 + 2] = (unsigned char)(xsum >> 8);\n    buf2[offset_icmpv6 + 3] = (unsigned char)(xsum >> 0);\n\n    /* Transmit the packet-buffer */\n    response->length = offset;\n    stack_transmit_packetbuffer(stack, response);\n    return 0;\n}\n\n\n\nstatic int \n_extract_router_advertisement(\n    const unsigned char *buf, \n    size_t length,\n    struct PreprocessedInfo *parsed,\n    ipv6address my_ipv6,\n    ipv6address *router_ip, \n    macaddress_t *router_mac)\n{\n    size_t offset;\n    int is_same_prefix = 1;\n    int is_mac_explicit = 0;\n\n    if (parsed->ip_version != 6)\n        return 1;\n    \n    *router_ip = parsed->src_ip.ipv6;\n\n    if (parsed->ip_protocol != 58)\n        return 1;\n    offset = parsed->transport_offset;\n    \n    /* type = Router Advertisement */\n    if (_read_byte(buf, &offset, length) != 134)\n        return 1;\n\n    /* code = 0 */\n    if (_read_byte(buf, &offset, length) != 0)\n        return 1;\n\n    /* checksum */\n    _read_short(buf, &offset, length);\n\n    /* hop limit */\n    _read_byte(buf, &offset, length);\n\n    /* flags */\n    _read_byte(buf, &offset, length);\n\n    /* router life time */\n    _read_short(buf, &offset, length);\n\n    /* reachable time */\n    _read_number(buf, &offset, length);\n\n    /* retrans timer */\n    _read_number(buf, &offset, length);\n\n    while (offset + 8 <= length) {\n        unsigned type = buf[offset + 0];\n        size_t len2 = buf[offset + 1] * 8;\n        size_t off2 = 2;\n        const unsigned char *buf2 = buf + offset;\n\n        switch (type) {\n            case 3: /* prefix info */\n            {\n                unsigned prefix_len;\n                ipv6address prefix;\n                ipaddress_formatted_t fmt;\n                \n                prefix_len = _read_byte(buf2, &off2, len2);\n                _read_byte(buf2, &off2, len2); /* flags */\n                _read_number(buf2, &off2, len2); /* valid lifetime */\n                _read_number(buf2, &off2, len2); /* preferred lifetime */\n                _read_number(buf2, &off2, len2); /* reserved */\n                prefix = _read_ipv6(buf2, &off2, len2);\n                \n                fmt = ipv6address_fmt(prefix);\n                LOG(1, \"[+] IPv6.prefix = %s/%u\\n\", fmt.string, prefix_len);\n                if (ipv6address_is_equal_prefixed(my_ipv6, prefix, prefix_len)) {\n                    is_same_prefix = 1;\n                } else {\n                    ipaddress_formatted_t fmt1 = ipv6address_fmt(my_ipv6);\n                    ipaddress_formatted_t fmt2 = ipv6address_fmt(prefix);\n                    \n                    LOG(0, \"[-] WARNING: our source-ip is %s, but router prefix announces %s/%u\\n\",\n                            fmt1.string, fmt2.string, prefix_len);\n                    is_same_prefix = 0;\n                }\n\n            }\n                break;\n            case 25: /* recursive DNS server */\n                _read_short(buf2, &off2, len2);\n                _read_number(buf2, &off2, len2);\n                \n                while (off2 + 16 <= len2) {\n                    ipv6address resolver = _read_ipv6(buf2, &off2, len2);\n                    ipaddress_formatted_t fmt = ipv6address_fmt(resolver);\n                    LOG(1, \"[+] IPv6.DNS = %s\\n\", fmt.string);\n                }\n                break;\n            case 1:\n                if (len2 == 8) {\n                    memcpy(router_mac->addr, buf2 + 2, 6);\n                    is_mac_explicit = 1;\n                }\n                break;\n        }\n\n        offset += len2;\n    }\n\n    if (!is_mac_explicit) {\n        /* The router advertisement didn't include an explicit\n         * source address. Therefore, pull the response from\n         * the Ethernet header of the packet instead */\n        memcpy(router_mac->addr, parsed->mac_src, 6);\n    }\n    \n    if (!is_same_prefix) {\n        /* We had a valid router advertisement, but it didn't\n         * match the IPv6 address we are using. This presumably\n         * means there are multiple possible IPv6 routers on the\n         * network. Therefore, we are going to discard this\n         * packet and wait for another one */\n        return 1;\n    }\n    \n    return 0;\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\nstack_ndpv6_resolve(struct Adapter *adapter,\n    ipv6address my_ipv6,\n    macaddress_t my_mac_address,\n    macaddress_t *router_mac)\n{\n    unsigned char buf[128];\n    size_t max = sizeof(buf);\n    size_t offset = 0;\n    unsigned i;\n    time_t start;\n    unsigned is_arp_notice_given = 0;\n    int is_delay_reported = 0;\n    size_t offset_ip;\n    size_t offset_ip_src;\n    size_t offset_ip_dst;\n    size_t offset_icmpv6;\n    unsigned xsum;\n    struct PreprocessedInfo parsed = {0};\n\n    /*\n     * [KLUDGE]\n     *  If this is a VPN connection, then there is no answer\n     */\n    if (stack_if_datalink(adapter) == 12) {\n        memcpy(router_mac->addr, \"\\0\\0\\0\\0\\0\\2\", 6);\n        return 0; /* success */\n    }\n\n    \n    /*\n     * Ethernet header\n     */\n    _append_bytes(buf, &offset, max, \"\\x33\\x33\\x00\\x00\\x00\\x02\", 6);\n    _append_bytes(buf, &offset, max, my_mac_address.addr, 6);\n    \n    if (adapter->is_vlan) {\n        _append_short(buf, &offset, max, 0x8100);\n        _append_short(buf, &offset, max, adapter->vlan_id);\n    }\n    _append_short(buf, &offset, max, 0x86dd);\n\n    /*\n     * Create IPv6 header\n     */\n    offset_ip = offset;\n    _append(buf, &offset, max, 0x60); /* version = 6 */\n    _append(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0); /* length = 0 */\n    _append(buf, &offset, max, 58); /* proto = ICMPv6 */\n    _append(buf, &offset, max, 255); /*hop limit = 255 */\n\n    /* Link local source address based on MAC address */\n    offset_ip_src = offset;\n    _append_short(buf, &offset, max, 0xfe80);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_bytes(buf, &offset, max, my_mac_address.addr, 3);\n    buf[offset-3] |= 2;\n    _append_short(buf, &offset, max, 0xfffe);\n    _append_bytes(buf, &offset, max, my_mac_address.addr+3, 3);\n\n    /* All-routers link local address */\n    offset_ip_dst = offset;\n    _append_short(buf, &offset, max, 0xff02);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 2);\n    \n    /* ICMPv6 Router Solicitation */\n    offset_icmpv6 = offset;\n    _append(buf, &offset, max, 133); /* type = Router Solicitation */\n    _append(buf, &offset, max, 0);\n    _append_short(buf, &offset, max, 0); /* checksum = 0 (for the moment) */\n    _append_short(buf, &offset, max, 0); /* reserved */\n    _append_short(buf, &offset, max, 0); /* reserved */\n    _append(buf, &offset, max, 1); /* option = source link layer address */\n    _append(buf, &offset, max, 1); /* length = 2 + 6 / 8*/\n    _append_bytes(buf, &offset, max, my_mac_address.addr, 6);\n    \n    buf[offset_ip + 4] = (unsigned char)( (offset - offset_icmpv6) >> 8);\n    buf[offset_ip + 5] = (unsigned char)( (offset - offset_icmpv6) & 0xFF);\n    xsum = checksum_ipv6(   buf + offset_ip_src, \n                            buf + offset_ip_dst, \n                            58,  \n                            offset - offset_icmpv6, \n                            buf + offset_icmpv6);\n    buf[offset_icmpv6 + 2] = (unsigned char)(xsum >> 8);\n    buf[offset_icmpv6 + 3] = (unsigned char)(xsum >> 0);\n    rawsock_send_packet(adapter, buf, (unsigned)offset, 1);\n\n    /*\n     * Send a shorter version after the long version. I don't know\n     * why, but some do this on the Internet.\n     */\n    offset -= 8;\n    buf[offset_ip + 4] = (unsigned char)( (offset - offset_icmpv6) >> 8);\n    buf[offset_ip + 5] = (unsigned char)( (offset - offset_icmpv6) & 0xFF);\n    xsum = checksum_ipv6(   buf + offset_ip_src, \n                            buf + offset_ip_dst, \n                            58,  \n                            offset - offset_icmpv6, \n                            buf + offset_icmpv6);\n    buf[offset_icmpv6 + 2] = (unsigned char)(xsum >> 8);\n    buf[offset_icmpv6 + 3] = (unsigned char)(xsum >> 0);\n    rawsock_send_packet(adapter, buf, (unsigned)offset, 1);\n    \n\n    start = time(0);\n    i = 0;\n    for (;;) {\n        unsigned length2;\n        unsigned secs;\n        unsigned usecs;\n        const unsigned char *buf2;\n        int err;\n        ipv6address router_ip;\n\n        /* Resend every so often */\n        if (time(0) != start) {\n            start = time(0);\n            rawsock_send_packet(adapter, buf, (unsigned)offset, 1);\n            if (i++ >= 10)\n                break; /* timeout */\n\n            /* It's taking too long, so notify the user */\n            if (!is_delay_reported) {\n                fprintf(stderr, \"[ ] resolving IPv6 router MAC address (may take some time)...\\n\");\n                is_delay_reported = 1;\n            }\n        }\n\n        /* If we aren't getting a response back to our ARP, then print a\n         * status message */\n        if (time(0) > start+1 && !is_arp_notice_given) {\n            fprintf(stderr, \"[ ] resolving local IPv6 router\\n\");\n            is_arp_notice_given = 1;\n        }\n\n        err =  rawsock_recv_packet(\n                    adapter,\n                    &length2,\n                    &secs,\n                    &usecs,\n                    &buf2);\n\n        if (err != 0)\n            continue;\n\n        /*\n         * Parse the packet. We'll get lots of packets we aren't interested\n         * in,so we'll just loop around and keep searching until we find\n         * one.\n         */\n        err = preprocess_frame(buf2, length2, 1, &parsed);\n        if (err != 1)\n            continue;\n        if (parsed.found != FOUND_NDPv6)\n            continue;\n        \n        /* We've found a packet that may be the one we want, so parse it */\n        err = _extract_router_advertisement(buf2, length2, &parsed, my_ipv6, &router_ip, router_mac);\n        if (err)\n            continue;\n        \n        /* The previous call found 'router_mac\", so now return */\n        return 0;\n    }\n\n    return 1;\n}\n"
  },
  {
    "path": "src/stack-ndpv6.h",
    "content": "/*\n    IPv6 Neighbor Discovery Protocol\n \n    This module is needed to talk to the local IPv6 router.\n    It does two things:\n \n    1. find the local router, so that we can send packets to\n       it\n    2. response to Neighbor Discovery Requests, to the router\n       can find us\n */\n#ifndef STACK_NDPV6_H\n#define STACK_NDPV6_H\n#include <stddef.h>\n#include <time.h>\n#include \"stack-queue.h\"\n#include \"massip-addr.h\"\nstruct PreprocessedInfo;\n\n/**\n * Handle an incoming IPv6 neighbor notification request. We must send\n * back our MAC address.\n */\nint\nstack_ndpv6_incoming_request(struct stack_t *stack, struct PreprocessedInfo *parsed,  const unsigned char *px, size_t length);\n\n/**\n * Find the MAC address for the local router.\n */\nint\nstack_ndpv6_resolve(struct Adapter *adapter,\n    ipv6address my_ipv6,\n    macaddress_t my_mac_address,\n    macaddress_t *your_mac_address);\n\n#endif\n\n"
  },
  {
    "path": "src/stack-queue.c",
    "content": "#include \"stack-queue.h\"\n#include \"pixie-timer.h\"\n#include \"rawsock.h\"\n#include \"util-malloc.h\"\n#include <string.h>\n#include <stdio.h>\n\nstruct PacketBuffer *\nstack_get_packetbuffer(struct stack_t *stack)\n{\n    int err;\n    struct PacketBuffer *response = NULL;\n\n    for (err=1; err; ) {\n        err = rte_ring_sc_dequeue(stack->packet_buffers, (void**)&response);\n        if (err != 0) {\n            /* Pause and wait for a buffer to become available */\n            pixie_usleep(1000);\n        }\n    }\n    return response;\n}\n\nvoid\nstack_transmit_packetbuffer(struct stack_t *stack, struct PacketBuffer *response)\n{\n    int err;\n    for (err=1; err; ) {\n        err = rte_ring_sp_enqueue(stack->transmit_queue, response);\n        if (err) {\n            fprintf(stderr, \"[-] transmit queue full (should be impossible)\\n\");\n            pixie_usleep(1000);\n        }\n    }\n}\n\n/***************************************************************************\n * The receive thread doesn't transmit packets. Instead, it queues them\n * up on the transmit thread. Every so often, the transmit thread needs\n * to flush this transmit queue and send everything.\n *\n * This is an inherent design issue trying to send things as batches rather\n * than individually. It increases latency, but increases performance. We\n * don't really care about latency.\n ***************************************************************************/\nvoid\nstack_flush_packets(\n    struct stack_t *stack,\n    struct Adapter *adapter,\n    uint64_t *packets_sent,\n    uint64_t *batchsize)\n{\n    /*\n     * Send a batch of queued packets\n     */\n    for ( ; (*batchsize); (*batchsize)--) {\n        int err;\n        struct PacketBuffer *p;\n\n        /*\n         * Get the next packet from the transmit queue. This packet was\n         * put there by a receive thread, and will contain things like\n         * an ACK or an HTTP request\n         */\n        err = rte_ring_sc_dequeue(stack->transmit_queue, (void**)&p);\n        if (err) {\n            break; /* queue is empty, nothing to send */\n        }\n\n\n        /*\n         * Actually send the packet\n         */\n        rawsock_send_packet(adapter, p->px, (unsigned)p->length, 1);\n\n        /*\n         * Now that we are done with the packet, put it on the free list\n         * of buffers that the transmit thread can reuse\n         */\n        for (err=1; err; ) {\n            err = rte_ring_sp_enqueue(stack->packet_buffers, p);\n            if (err) {\n                fprintf(stderr, \"[-] transmit queue full (should be impossible)\\n\");\n                pixie_usleep(10000);\n            }\n        }\n\n\n        /*\n         * Remember that we sent a packet, which will be used in\n         * throttling.\n         */\n        (*packets_sent)++;\n    }\n\n}\n\nstruct stack_t *\nstack_create(macaddress_t source_mac, struct stack_src_t *src)\n{\n    struct stack_t *stack;\n    size_t i;\n\n    stack = CALLOC(1, sizeof(*stack));\n    stack->source_mac = source_mac;\n    stack->src = src;\n\n    /*\n     * Allocate packet buffers for sending\n     */\n#define BUFFER_COUNT 16384\n    stack->packet_buffers = rte_ring_create(BUFFER_COUNT, RING_F_SP_ENQ|RING_F_SC_DEQ);\n    stack->transmit_queue = rte_ring_create(BUFFER_COUNT, RING_F_SP_ENQ|RING_F_SC_DEQ);\n    for (i=0; i<BUFFER_COUNT-1; i++) {\n        struct PacketBuffer *p;\n        int err;\n\n        p = MALLOC(sizeof(*p));\n        err = rte_ring_sp_enqueue(stack->packet_buffers, p);\n        if (err) {\n            /* I dunno why but I can't queue all 256 packets, just 255 */\n            fprintf(stderr, \"[-] packet_buffers: enqueue: error %d\\n\", err);\n        }\n    }\n\n    return stack;\n}\n\n\n\n"
  },
  {
    "path": "src/stack-queue.h",
    "content": "#ifndef PACKET_QUEUE_H\n#define PACKET_QUEUE_H\n#include \"rte-ring.h\"\n#include \"massip-addr.h\"\n#include <limits.h>\nstruct stack_src_t;\nstruct Adapter;\n\ntypedef struct rte_ring PACKET_QUEUE;\n\nstruct PacketBuffer {\n    size_t length;\n    unsigned char px[2040];\n};\n\nstruct stack_t {\n    PACKET_QUEUE *packet_buffers;\n    PACKET_QUEUE *transmit_queue;\n    macaddress_t source_mac;\n    struct stack_src_t *src;\n};\n\n/**\n * Get a packet-buffer that we can use to create a packet before\n * sending\n */\nstruct PacketBuffer *\nstack_get_packetbuffer(struct stack_t *stack);\n\n/**\n * Queue up the packet for sending. This doesn't send the packet immediately,\n * but puts it into a queue to be sent later, when the throttler allows it\n * to be sent.\n */\nvoid\nstack_transmit_packetbuffer(struct stack_t *stack, struct PacketBuffer *response);\n\nvoid\nstack_flush_packets(\n    struct stack_t *stack,\n    struct Adapter *adapter,\n    uint64_t *packets_sent,\n    uint64_t *batchsize);\n\nstruct stack_t *\nstack_create(macaddress_t source_mac, struct stack_src_t *src);\n\n#endif\n"
  },
  {
    "path": "src/stack-src.c",
    "content": "#include \"stack-src.h\"\n\nint is_myself(const struct stack_src_t *src, ipaddress ip, unsigned port)\n{\n    return is_my_ip(src, ip) && is_my_port(src, port);\n}\n\nint is_my_ip(const struct stack_src_t *src, ipaddress ip)\n{\n    switch (ip.version) {\n    case 4:\n        return src->ipv4.first <= ip.ipv4 && ip.ipv4 <= src->ipv4.last;\n    case 6:\n        return src->ipv6.first.hi == ip.ipv6.hi && src->ipv6.first.lo == ip.ipv6.lo;\n    default:\n        return 0;\n    }\n}\n\nint is_my_port(const struct stack_src_t *src, unsigned port)\n{\n    return src->port.first <= port && port <= src->port.last;\n}\n"
  },
  {
    "path": "src/stack-src.h",
    "content": "#ifndef STACK_SOURCE_H\n#define STACK_SOURCE_H\n#include \"massip-addr.h\"\n\n/**\n * These the source IP addresses that we'll be spoofing. IP addresses\n * and port numbers come from this list.\n */\nstruct stack_src_t\n{\n    struct {\n        unsigned first;\n        unsigned last;\n        unsigned range;\n    } ipv4;\n    struct {\n        unsigned first;\n        unsigned last;\n        unsigned range;\n    } port;\n \n    struct {\n        ipv6address first;\n        ipv6address last;\n        unsigned range;\n    } ipv6;\n};\n\nint is_myself(const struct stack_src_t *src, ipaddress ip, unsigned port);\nint is_my_ip(const struct stack_src_t *src, ipaddress ip);\nint is_my_port(const struct stack_src_t *src, unsigned ip);\n\n\n\n#endif\n"
  },
  {
    "path": "src/stack-tcp-api.h",
    "content": "#ifndef STACK_HANDLE_H\n#define STACK_HANDLE_H\n#include <stdio.h>\n#include \"util-bool.h\" /* <stdbool.h> */\n\nstruct ProtocolParserStream;\n\nenum TCP__flags {\n    TCP__static,/* it's static data, so the send function can point to it */\n    TCP__copy,  /* the send function must copy the data */\n    TCP__adopt,  /* the buffer was just allocated, so the send function can adopt the pointer */\n    TCP__close_fin /* close connection */\n};\n\nenum {\n    SOCKERR_NONE=0, /* no error */\n    SOCKERR_EBADF=10,  /* bad socket descriptor */\n};\n\ntypedef struct stack_handle_t {\n    void *tcpcon;\n    void *tcb;\n    unsigned secs;\n    unsigned usecs;\n} stack_handle_t;\n\n\n\n/**\n * Set a new default timeout.\n */\nint\ntcpapi_set_timeout(struct stack_handle_t *socket,\n                   unsigned secs,\n                   unsigned usecs\n                   );\n\n/**\n * Change from the \"send\" state to the \"receive\" state.\n * Has no effect if in any state other than \"send\".\n * This is none-blocking, an event will be triggered\n * later that has the data.\n */\nint\ntcpapi_recv(struct stack_handle_t *socket);\n\nint\ntcpapi_send(struct stack_handle_t *socket,\n            const void *buf, size_t length,\n            enum TCP__flags flags);\n\n/**\n * Re-connect to the target, same IP and port, creating a new connection\n * from a different port on this side.\n */\nint\ntcpapi_reconnect(struct stack_handle_t *old_socket,\n                 struct ProtocolParserStream *new_stream,\n                 unsigned new_app_state);\n\n/**\n * The \"app state\" variable is stored opaquely in the `tcb` structure, so\n * to reset it, we need an access function.\n */\nunsigned\ntcpapi_change_app_state(struct stack_handle_t *socket, unsigned new_app_state);\n\n\n/** Perform the sockets half-close function (calling `close()`). This\n * doesn't actually get rid of the socket, but only stops sending.\n * It sends a FIN packet to the other side, and transitions to the\n * TCP CLOSE-WAIT state.\n * The socket will continue to receive from the opposing side until they\n * give us a FIN packet. */\nint\ntcpapi_close(struct stack_handle_t *socket);\n\n\n\n#endif\n"
  },
  {
    "path": "src/stack-tcp-app.c",
    "content": "#include \"stack-tcp-app.h\"\n#include \"stack-tcp-api.h\"\n#include \"proto-banner1.h\"\n#include \"proto-ssl.h\"\n#include \"unusedparm.h\"\n#include \"util-malloc.h\"\n#include \"util-logger.h\"\n#include \"util-errormsg.h\"\n#include <stdlib.h>\n\nenum {\n    App_Connect,\n    App_ReceiveHello,\n    App_ReceiveNext,\n    App_SendFirst,\n    App_SendNext,\n    App_Close,\n};\nstatic const char *state_to_string(unsigned state) {\n    switch (state) {\n    case App_Connect: return \"connect\";\n    case App_ReceiveHello: return \"wait-for-hello\";\n    case App_ReceiveNext: return \"receive\";\n    case App_SendFirst: return \"send-first\";\n    case App_SendNext: return \"send\";\n    case App_Close: return \"close\";\n    default: return \"unknown\";\n    }\n}\nstatic const char *event_to_string(enum App_Event ev) {\n    switch (ev) {\n    case APP_CONNECTED: return \"connected\";\n    case APP_RECV_TIMEOUT: return \"timeout\";\n    case APP_RECV_PAYLOAD: return \"payload\";\n    case APP_SEND_SENT: return \"sent\";\n    case APP_CLOSE: return \"close\";\n    case APP_SENDING: return \"sending\";\n    default: return \"unknown\";\n    }\n}\n  \nunsigned\napplication_event(struct stack_handle_t *socket,\n                  unsigned state, enum App_Event event,\n                  const struct ProtocolParserStream *stream,\n                  struct Banner1 *banner1,\n                  const void *payload, size_t payload_length\n                  ) {\n\n\n\nagain:\n    switch (state) {\n        case App_Connect:\n            switch (event) {\n                case APP_CONNECTED:\n                    /* We have a receive a SYNACK here. If there are multiple handlers\n                     * for this port, then attempt another connection using the\n                     * other protocol handlers. For example, for SSL, we might want\n                     * to try both TLSv1.0 and TLSv1.3 */\n                    if (stream && stream->next) {\n                        tcpapi_reconnect(socket, stream->next, App_Connect);\n                    }\n\n                    /*\n                     * By default, wait for the \"hello timeout\" period\n                     * receiving any packets they send us. If nothing is\n                     * received in this period, then timeout will cause us\n                     * to switch to sending\n                     */\n                    if (stream != NULL && (stream->flags & SF__nowait_hello) != 0) {\n                        tcpapi_change_app_state(socket, App_SendFirst);\n                        state = App_SendFirst;\n                        goto again;\n                    } else {\n                        tcpapi_set_timeout(socket, 2 /*tcpcon->timeout_hello*/, 0);\n                        tcpapi_recv(socket);\n                        tcpapi_change_app_state(socket, App_ReceiveHello);\n                    }\n                    break;\n                default:\n                    ERRMSG(\"TCP.app: unhandled event: state=%s event=%s\\n\",\n                        state_to_string(state), event_to_string(event));\n                    break;\n            }\n\n            break;\n        case App_ReceiveHello:\n            switch (event) {\n                case APP_RECV_TIMEOUT:\n                    /* We've got no response from the initial connection,\n                     * so switch from them being responsible for communications\n                     * to us being responsible, and start sending */\n                    if (stream) {\n                        tcpapi_change_app_state(socket, App_SendFirst);\n                        state = App_SendFirst;\n                        goto again;\n                    }\n                    break;\n                case APP_RECV_PAYLOAD:\n                    /* We've receive some data from them, so wait for some more.\n                     * This means we won't be transmitting anything to them. */\n                    tcpapi_change_app_state(socket, App_ReceiveNext);\n                    state = App_ReceiveNext;\n                    goto again;\n                case APP_CLOSE:\n                    banner_flush(socket);\n                    tcpapi_close(socket);\n                    break;\n                default:\n                    ERRMSG(\"TCP.app: unhandled event: state=%s event=%s\\n\",\n                        state_to_string(state), event_to_string(event));\n                    break;\n            }\n            break;\n\n        case App_ReceiveNext:\n            switch (event) {\n                case APP_RECV_PAYLOAD:\n                    /* [--banners]\n                     * This is an important part of the system, where the TCP\n                     * stack passes incoming packet payloads off to the application\n                     * layer protocol parsers. This is where, in Sockets API, you\n                     * might call the 'recv()' function.\n                     */\n                    banner_parse(socket,\n                                 payload,\n                                 payload_length\n                                 );\n                    break;\n                case APP_CLOSE:\n                    /* The other side has sent us a FIN, therefore, we need\n                     * to likewise close our end. */\n                    banner_flush(socket);\n                    tcpapi_close(socket);\n                    break;\n                case APP_RECV_TIMEOUT:\n                    break;\n                case APP_SENDING:\n                    /* A higher level protocol has started sending packets while processing\n                     * a receive, therefore, change to the SEND state */\n                    tcpapi_change_app_state(socket, App_SendNext);\n                    break;\n                case APP_SEND_SENT:\n                    /* FIXME */\n                    break;\n                default:\n                    ERRMSG(\"TCP.app: unhandled event: state=%s event=%s\\n\",\n                        state_to_string(state), event_to_string(event));\n                    break;\n            }\n            break;\n\n        case App_SendFirst:\n            /* This isn't called from the outside, but from one of the\n             * states internally whhen we transmit for the first time */\n            if (stream == &banner_ssl || stream == &banner_ssl_12) {\n                /*\n                 * Kludge, extreme kludge\n                 * I don't even know what this does any longer\n                 */\n                banner_set_sslhello(socket, true);\n            }\n\n            if (banner_is_heartbleed(socket)) {\n                /*\n                 * Kludge, extreme kludge\n                 * I don't even know what this does any longer\n                 */\n                banner_set_small_window(socket, true);\n            }\n\n            /*\n             * We either have a CALLBACK that will handle the\n             * sending/receiving of packets, or we will send a fixed\n             * \"probe\" string that will hopefull trigger a response.\n             */\n            if (stream && stream->transmit_hello) {\n                /* We have a callback function for the protocol stream that will\n                 * craft a packet, such as maybe generate an HTTP request containing\n                 * valid \"Host:\" field. */\n                stream->transmit_hello(banner1, socket);\n            } else if (stream && stream->hello_length) {\n\n                /* We just have a template to blindly copy some bytes onto the wire\n                 * in order to trigger/probe for a response */\n                tcpapi_send(socket, stream->hello, stream->hello_length, TCP__static);\n\n                /* If specified, then send a FIN right after the hello data.\n                 * This will complete a reponse faster from the server. */\n                if ((stream->flags & SF__close) != 0)\n                    tcpapi_close(socket);\n            }\n            tcpapi_change_app_state(socket, App_SendNext);\n            break;\n        case App_SendNext:\n            switch (event) {\n                case APP_SEND_SENT:\n                    /* We've got an acknowledgement that all our data\n                     * was sent. Therefore, change the receive state */\n                    tcpapi_recv(socket);\n                    tcpapi_change_app_state(socket, App_ReceiveNext);\n                    break;\n                case APP_SENDING:\n                    break;\n                default:\n                    ERRMSG(\"TCP.app: unhandled event: state=%s event=%s\\n\",\n                        state_to_string(state), event_to_string(event));\n                    break;\n            }\n            break;\n        default:\n            ERRMSG(\"TCP.app: unhandled event: state=%s event=%s\\n\",\n                state_to_string(state), event_to_string(event));\n            break;\n    }\n    return 0;\n}\n\n"
  },
  {
    "path": "src/stack-tcp-app.h",
    "content": "#ifndef STACK_TCP_APP_H\n#define STACK_TCP_APP_H\n#include <stdio.h>\n#include \"util-bool.h\" /* <stdbool.h> */\nstruct stack_handle_t;\nstruct ProtocolParserStream;\nstruct Banner1;\n\n\nenum App_Event {\n    APP_CONNECTED,\n    APP_RECV_TIMEOUT,\n    APP_RECV_PAYLOAD,\n    APP_SENDING,\n    APP_SEND_SENT,\n    APP_CLOSE /*FIN received */\n};\n\n/**\n * This is the interface between the underlying custom TCP/IP stack and\n * the rest of masscan. SCRIPTING will eventually go in here.\n */\nunsigned\napplication_event(  struct stack_handle_t *socket,\n                  unsigned state, enum App_Event event,\n                  const struct ProtocolParserStream *stream,\n                  struct Banner1 *banner1,\n                  const void *payload, size_t payload_length\n                  );\n\nvoid\nbanner_set_sslhello(struct stack_handle_t *socket, bool is_true);\n\nvoid\nbanner_set_small_window(struct stack_handle_t *socket, bool is_true);\n\nbool\nbanner_is_heartbleed(const struct stack_handle_t *socket);\n\nvoid\nbanner_flush(struct stack_handle_t *socket);\n\nsize_t\nbanner_parse(\n             struct stack_handle_t *socket,\n             const unsigned char *payload,\n             size_t payload_length\n             );\n\n#endif\n\n"
  },
  {
    "path": "src/stack-tcp-core.c",
    "content": "/*\n * This is the core TCP layer in the stack. It's notified of incoming\n * IP datagrams containing TCP protocols. This is where the TCP state\n * diagram is handled.\n *\n *                                    \n *                              +---------+ ---------\\      active OPEN  \n *                              |  CLOSED |            \\    -----------  \n *                              +---------+<---------\\   \\   create TCB  \n *                                |     ^              \\   \\  snd SYN    \n *                   passive OPEN |     |   CLOSE        \\   \\           \n *                   ------------ |     | ----------       \\   \\         \n *                    create TCB  |     | delete TCB         \\   \\       \n *                                V     |                      \\   \\     \n *                              +---------+            CLOSE    |    \\   \n *                              |  LISTEN |          ---------- |     |  \n *                              +---------+          delete TCB |     |  \n *                   rcv SYN      |     |     SEND              |     |  \n *                  -----------   |     |    -------            |     V  \n * +---------+      snd SYN,ACK  /       \\   snd SYN          +---------+\n * |         |<-----------------           ------------------>|         |\n * |   SYN   |                    rcv SYN                     |   SYN   |\n * |   RCVD  |<-----------------------------------------------|   SENT  |\n * |         |                    snd ACK                     |         |\n * |         |------------------           -------------------|         |\n * +---------+   rcv ACK of SYN  \\       /  rcv SYN,ACK       +---------+\n *   |           --------------   |     |   -----------                  \n *   |                  x         |     |     snd ACK                    \n *   |                            V     V                                \n *   |  CLOSE                   +---------+                              \n *   | -------                  |  ESTAB  |                              \n *   | snd FIN                  +---------+                              \n *   |                   CLOSE    |     |    rcv FIN                     \n *   V                  -------   |     |    -------                     \n * +---------+          snd FIN  /       \\   snd ACK          +---------+\n * |  FIN    |<-----------------           ------------------>|  CLOSE  |\n * | WAIT-1  |------------------                              |   WAIT  |\n * +---------+          rcv FIN  \\                            +---------+\n *   | rcv ACK of FIN   -------   |                            CLOSE  |  \n *   | --------------   snd ACK   |                           ------- |  \n *   V        x                   V                           snd FIN V  \n * +---------+                  +---------+                   +---------+\n * |FINWAIT-2|                  | CLOSING |                   | LAST-ACK|\n * +---------+                  +---------+                   +---------+\n *   |                rcv ACK of FIN |                 rcv ACK of FIN |  \n *   |  rcv FIN       -------------- |    Timeout=2MSL -------------- |  \n *   |  -------              x       V    ------------        x       V  \n *    \\ snd ACK                 +---------+delete TCB         +---------+\n *     ------------------------>|TIME WAIT|------------------>| CLOSED  |\n *                              +---------+                   +---------+\n *\n */\n#include \"stack-tcp-core.h\"\n#include \"stack-tcp-api.h\"\n#include \"stack-tcp-app.h\"\n#include <assert.h>\n#include <ctype.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <stddef.h>\n#include <stdarg.h>\n#include \"syn-cookie.h\"\n#include \"event-timeout.h\"      /* for tracking future events */\n#include \"rawsock.h\"\n#include \"util-logger.h\"\n#include \"templ-pkt.h\"\n#include \"pixie-timer.h\"\n#include \"stack-queue.h\"\n#include \"proto-banner1.h\"\n#include \"proto-ssl.h\"\n#include \"proto-http.h\"\n#include \"proto-smb.h\"\n#include \"proto-versioning.h\"\n#include \"output.h\"\n#include \"util-safefunc.h\"\n#include \"main-globals.h\"\n#include \"crypto-base64.h\"\n#include \"util-malloc.h\"\n#include \"util-errormsg.h\"\n#include \"scripting.h\"\n\n\n#ifdef _MSC_VER\n#pragma warning(disable:4204)\n#define snprintf _snprintf\n#pragma warning(disable:4996)\n#endif\n\nstruct TCP_Segment {\n    unsigned seqno;\n    unsigned char *buf;\n    size_t length;\n    enum TCP__flags flags;\n    bool is_fin; /* was fin sent */\n    struct TCP_Segment *next;\n};\n\n\n\n/***************************************************************************\n * A \"TCP control block\" is what most operating-systems/network-stack\n * calls the structure that corresponds to a TCP connection. It contains\n * things like the IP addresses, port numbers, sequence numbers, timers,\n * and other things.\n ***************************************************************************/\nstruct TCP_Control_Block\n{\n    ipaddress ip_me;\n    ipaddress ip_them;\n\n    unsigned short port_me;\n    unsigned short port_them;\n\n    uint32_t seqno_me;      /* next seqno I will use for transmit */\n    uint32_t seqno_them;    /* the next seqno I expect to receive */\n    uint32_t ackno_me;\n    uint32_t ackno_them;\n\n    uint32_t seqno_me_first;\n    uint32_t seqno_them_first;\n    \n    struct TCP_Control_Block *next;\n    struct TimeoutEntry timeout[1];\n\n    unsigned char ttl;\n    unsigned char syns_sent; /* reconnect */\n    unsigned short mss; /* maximum segment size 1460 */\n    unsigned tcpstate:4;\n    unsigned is_ipv6:1;\n    unsigned is_small_window:1; /* send with smaller window */\n    unsigned is_their_fin:1;\n\n    /** Set to true when the TCB is in-use/allocated, set to zero\n     * when it's about to be deleted soon */\n    unsigned is_active:1;\n    \n    /* If the payload we've sent was dynamically allocated with\n     * malloc() from the heap, in which case we'll have to free()\n     * it. (Most payloads are static memory) */\n    unsigned is_payload_dynamic:1;\n\n    unsigned app_state;\n\n    struct TCP_Segment *segments;\n\n    /*\n    unsigned short payload_length;\n    const unsigned char *payload;\n    */\n    time_t when_created;\n\n    /*\n     * If Running a script, the thread object\n     */\n    struct ScriptingThread *scripting_thread;\n    const struct ProtocolParserStream *stream;\n    \n    struct BannerOutput banout;\n\n    struct StreamState banner1_state;\n\n    unsigned packet_number;\n};\n\nstruct TCP_ConnectionTable {\n    struct TCP_Control_Block **entries;\n    struct TCP_Control_Block *freed_list;\n    unsigned count;\n    unsigned mask;\n    unsigned timeout_connection;\n    unsigned timeout_hello;\n\n    uint64_t active_count;\n    uint64_t entropy;\n\n    struct Timeouts *timeouts;\n    struct TemplatePacket *pkt_template;\n    struct stack_t *stack;\n\n    struct Banner1 *banner1;\n    OUTPUT_REPORT_BANNER report_banner;\n    struct Output *out;\n    \n    struct ScriptingVM *scripting_vm;\n\n    /** This is for creating follow-up connections based on the first\n     * connection. Given an existing IP/port, it returns a different\n     * one for the new conenction. */\n    struct {\n        const void *data;\n        void *(*cb)(const void *in_src, const ipaddress ip, unsigned port,\n                    ipaddress *next_ip, unsigned *next_port);\n    } next_ip_port;\n};\n\nenum {\n    STATE_SYN_SENT=0, /* must be zero */\n    //STATE_SYN_RECEIVED,\n    STATE_ESTABLISHED_SEND, /* our own special state, can only send */\n    STATE_ESTABLISHED_RECV, /* our own special state, can only receive */\n    STATE_CLOSE_WAIT,\n    STATE_LAST_ACK,\n    STATE_FIN_WAIT1_SEND,\n    STATE_FIN_WAIT1_RECV,\n    STATE_FIN_WAIT2,\n    STATE_CLOSING,\n    STATE_TIME_WAIT,\n};\n\n/***************************************************************************\n * DEBUG: when printing debug messages (-d option), this prints a string\n * for the given state.\n ***************************************************************************/\nstatic const char *\nstate_to_string(int state)\n{\n    static char buf[64];\n    switch (state) {\n            //STATE_SYN_RECEIVED,\n        case STATE_CLOSE_WAIT:      return \"CLOSE-WAIT\";\n        case STATE_LAST_ACK:        return \"LAST-ACK\";\n        case STATE_FIN_WAIT1_SEND:  return \"FIN-WAIT-1-SEND\";\n        case STATE_FIN_WAIT1_RECV:  return \"FIN-WAIT-1-RECV\";\n        case STATE_FIN_WAIT2:       return \"FIN-WAIT-2\";\n        case STATE_CLOSING:         return \"CLOSING\";\n        case STATE_TIME_WAIT:       return \"TIME-WAIT\";\n        case STATE_SYN_SENT:        return \"SYN_SENT\";\n        case STATE_ESTABLISHED_SEND:return \"ESTABLISHED_SEND\";\n        case STATE_ESTABLISHED_RECV:return \"ESTABLISHED_RECV\";\n\n        default:\n            snprintf(buf, sizeof(buf), \"%d\", state);\n            return buf;\n    }\n}\n\nstatic void\nvLOGtcb(const struct TCP_Control_Block *tcb, int dir, const char *fmt, va_list marker)\n{\n    char sz[256];\n    ipaddress_formatted_t fmt1 = ipaddress_fmt(tcb->ip_them);\n\n    snprintf(sz, sizeof(sz), \"[%s:%u %4u,%4u] %s:%5u [%4u,%4u] {%s} \",\n             fmt1.string, tcb->port_them,\n             tcb->seqno_them - tcb->seqno_them_first,\n             tcb->ackno_me - tcb->seqno_them_first,\n             (dir > 0) ? \"-->\" : \"<--\",\n             tcb->port_me,\n             tcb->seqno_me - tcb->seqno_me_first,\n             tcb->ackno_them - tcb->seqno_me_first,\n             state_to_string(tcb->tcpstate)\n             );\n    if (dir == 2) {\n        char *brace = strchr(sz, '{');\n        memset(sz, ' ', brace-sz);\n    }\n    fprintf(stderr, \"%s\", sz);\n    vfprintf(stderr, fmt, marker);\n    fflush(stderr);\n}\nint is_tcp_debug = 0;\n\nstatic void\nLOGtcb(const struct TCP_Control_Block *tcb, int dir, const char *fmt, ...)\n{\n    va_list marker;\n\n    if (!is_tcp_debug)\n        return;\n    va_start(marker, fmt);\n    vLOGtcb(tcb, dir, fmt, marker);\n    va_end(marker);\n}\n\n\n\n/***************************************************************************\n * Process all events, up to the current time, that need timing out.\n ***************************************************************************/\nvoid\ntcpcon_timeouts(struct TCP_ConnectionTable *tcpcon, unsigned secs, unsigned usecs)\n{\n    uint64_t timestamp = TICKS_FROM_TV(secs, usecs);\n\n    for (;;) {\n        struct TCP_Control_Block *tcb;\n        enum TCB_result x;\n\n        /*\n         * Get the next event that is older than the current time\n         */\n        tcb = (struct TCP_Control_Block *)timeouts_remove(tcpcon->timeouts,\n                                                          timestamp);\n\n        /*\n         * If everything up to the current time has already been processed,\n         * then exit this loop\n         */\n        if (tcb == NULL)\n            break;\n\n        /*\n         * Process this timeout\n         */\n        x = stack_incoming_tcp(tcpcon, tcb, TCP_WHAT_TIMEOUT,\n            0, 0,\n            secs, usecs,\n            tcb->seqno_them,\n            tcb->ackno_them);\n\n        /* If the TCB hasn't been destroyed, then we need to make sure\n         * there is a timeout associated with it. KLUDGE: here is the problem:\n         * there must ALWAYS be a 'timeout' associated with a TCB, otherwise,\n         * we'll lose track of it and leak memory. In theory, this should be\n         * automatically handled elsewhere, but I have bugs, and it's not,\n         * so I put some code here as a catch-all: if the TCB hasn't been\n         * deleted, but hasn't been inserted back into the timeout system,\n         * then insert it here. */\n        if (x != TCB__destroyed && timeout_is_unlinked(tcb->timeout)) {\n            timeouts_add(   tcpcon->timeouts,\n                            tcb->timeout,\n                            offsetof(struct TCP_Control_Block, timeout),\n                            TICKS_FROM_TV(secs+2, usecs));\n        }\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nname_equals(const char *lhs, const char *rhs)\n{\n    for (;;) {\n        while (*lhs == '-' || *lhs == '.' || *lhs == '_')\n            lhs++;\n        while (*rhs == '-' || *rhs == '.' || *rhs == '_')\n            rhs++;\n        if (*lhs == '\\0' && *rhs == '[')\n            return 1; /*arrays*/\n        if (*rhs == '\\0' && *lhs == '[')\n            return 1; /*arrays*/\n        if (tolower(*lhs & 0xFF) != tolower(*rhs & 0xFF))\n            return 0;\n        if (*lhs == '\\0')\n            return 1;\n        lhs++;\n        rhs++;\n    }\n}\n\n/***************************************************************************\n * When setting parameters, this will parse integers from the config\n * parameter strings.\n ***************************************************************************/\nstatic uint64_t\nparseInt(const void *vstr, size_t length)\n{\n    const char *str = (const char *)vstr;\n    uint64_t result = 0;\n    size_t i;\n\n    for (i=0; i<length; i++) {\n        result = result * 10 + (str[i] - '0');\n    }\n    return result;\n}\n\n/***************************************************************************\n * Called at startup, when processing command-line options, to set\n * an HTTP field.\n ***************************************************************************/\nvoid\ntcpcon_set_http_header(struct TCP_ConnectionTable *tcpcon,\n                        const char *name,\n                        size_t value_length,\n                        const void *value,\n                        enum http_field_t what)\n{\n    UNUSEDPARM(tcpcon);\n    banner_http.hello_length = http_change_field(\n                            (unsigned char**)&banner_http.hello,\n                            banner_http.hello_length,\n                            name,\n                            (const unsigned char *)value,\n                            value_length,\n                            what);\n}\n\n\n/***************************************************************************\n * Called at startup, when processing command-line options, to set\n * parameters specific to TCP processing.\n ***************************************************************************/\nvoid\ntcpcon_set_parameter(struct TCP_ConnectionTable *tcpcon,\n                        const char *name,\n                        size_t value_length,\n                        const void *value)\n{\n    struct Banner1 *banner1 = tcpcon->banner1;\n\n    if (name_equals(name, \"http-payload\")) {\n        char lenstr[64];\n        snprintf(lenstr, sizeof(lenstr), \"%u\", (unsigned)value_length);\n\n        banner_http.hello_length = http_change_requestline(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                (const unsigned char *)value,\n                                value_length,\n                                3); /* payload*/\n\n        banner_http.hello_length = http_change_field(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                \"Content-Length:\",\n                                (const unsigned char *)lenstr,\n                                strlen(lenstr),\n                                http_field_replace);\n        return;\n    }\n\n    /*\n     * You can reset your user-agent here. Whenever I do a scan, I always\n     * reset my user-agent. That's now you know it's not me scanning\n     * you on the open Internet -- I would never use the default user-agent\n     * string built into masscan\n     */\n    if (name_equals(name, \"http-user-agent\")) {\n        banner_http.hello_length = http_change_field(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                \"User-Agent:\",\n                                (const unsigned char *)value,\n                                value_length,\n                                http_field_replace);\n        return;\n    }\n    if (name_equals(name, \"http-host\")) {\n        banner_http.hello_length = http_change_field(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                \"Host:\",\n                                (const unsigned char *)value,\n                                value_length,\n                                http_field_replace);\n        return;\n    }\n\n    /**\n     * Changes the URL\n     */\n    if (name_equals(name, \"http-method\")) {\n        banner_http.hello_length = http_change_requestline(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                (const unsigned char *)value,\n                                value_length,\n                                0); /* method*/\n        return;\n    }\n    if (name_equals(name, \"http-url\")) {\n        banner_http.hello_length = http_change_requestline(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                (const unsigned char *)value,\n                                value_length,\n                                1); /* url */\n        return;\n    }\n    if (name_equals(name, \"http-version\")) {\n        banner_http.hello_length = http_change_requestline(\n                                (unsigned char**)&banner_http.hello,\n                                banner_http.hello_length,\n                                (const unsigned char *)value,\n                                value_length,\n                                2); /* version */\n        return;\n    }\n\n    if (name_equals(name, \"timeout\") || name_equals(name, \"connection-timeout\")) {\n        uint64_t n = parseInt(value, value_length);\n        tcpcon->timeout_connection = (unsigned)n;\n        LOG(1, \"TCP connection-timeout = %u\\n\", tcpcon->timeout_connection);\n        return;\n    }\n    if (name_equals(name, \"hello-timeout\")) {\n        uint64_t n = parseInt(value, value_length);\n        tcpcon->timeout_hello = (unsigned)n;\n        LOG(1, \"TCP hello-timeout = \\\"%.*s\\\"\\n\", (int)value_length, (const char *)value);\n        LOG(1, \"TCP hello-timeout = %u\\n\", (unsigned)tcpcon->timeout_hello);\n        return;\n    }\n\n    /*\n     * Force SSL processing on all ports\n     */\n    if (name_equals(name, \"hello\") && name_equals(value, \"ssl\")) {\n        unsigned i;\n        \n        LOG(2, \"HELLO: setting SSL hello message\\n\");\n        for (i=0; i<65535; i++) {\n            banner1->payloads.tcp[i] = &banner_ssl;\n        }\n        \n        return;\n    }\n    \n    /*\n     * Force HTTP processing on all ports\n     */\n    if (name_equals(name, \"hello\") && name_equals(value, \"http\")) {\n        unsigned i;\n        \n        LOG(2, \"HELLO: setting HTTP hello message\\n\");\n        for (i=0; i<65535; i++) {\n            banner1->payloads.tcp[i] = &banner_http;\n        }\n        \n        return;\n    }\n    \n    /*\n     * Downgrade SMB hello from v1/v2 to use only v1\n     */\n    if (name_equals(name, \"hello\") && name_equals(value, \"smbv1\")) {\n        smb_set_hello_v1(&banner_smb1);        \n        return;\n    }\n\n    /*\n     * 2014-04-08: scan for Neel Mehta's \"heartbleed\" bug\n     */\n    if (name_equals(name, \"heartbleed\")) {\n        unsigned i;\n\n        /* Change the hello message to including negotiating the use of \n         * the \"heartbeat\" extension */\n        banner_ssl.hello = ssl_hello(ssl_hello_heartbeat_template);\n        banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);\n        tcpcon->banner1->is_heartbleed = 1;\n\n        for (i=0; i<65535; i++) {\n            banner1->payloads.tcp[i] = &banner_ssl;\n        }\n\n        return;\n    }\n\n    if (name_equals(name, \"ticketbleed\")) {\n        unsigned i;\n\n        /* Change the hello message to including negotiating the use of \n         * the \"heartbeat\" extension */\n        banner_ssl.hello = ssl_hello(ssl_hello_ticketbleed_template);\n        banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);\n        tcpcon->banner1->is_ticketbleed = 1;\n\n        for (i=0; i<65535; i++) {\n            banner1->payloads.tcp[i] = &banner_ssl;\n        }\n\n        return;\n    }\n\n    /*\n     * 2014-10-16: scan for SSLv3 servers (POODLE)\n     */\n    if (name_equals(name, \"poodle\") || name_equals(name, \"sslv3\")) {\n        unsigned i;\n        void *px;\n        \n        /* Change the hello message to including negotiating the use of \n         * the \"heartbeat\" extension */\n        px = ssl_hello(ssl_hello_sslv3_template);\n        banner_ssl.hello = ssl_add_cipherspec(px, 0x5600, 1);\n        banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);\n        tcpcon->banner1->is_poodle_sslv3 = 1;\n\n        for (i=0; i<65535; i++) {\n            banner1->payloads.tcp[i] = &banner_ssl;\n        }\n        \n        return;\n    }\n\n    \n    /*\n     * You can reconfigure the \"hello\" message to be anything\n     * you want.\n     */\n    if (name_equals(name, \"hello-string\")) {\n        struct ProtocolParserStream *x;\n        const char *p = strchr(name, '[');\n        unsigned port;\n\n\n        if (p == NULL) {\n            ERRMSG(\"tcpcon: parameter: expected array []: %s\\n\", name);\n            return;\n        }\n        port = (unsigned)strtoul(p+1, 0, 0);\n\n        x = CALLOC(1, sizeof(*x));\n        if (banner1->payloads.tcp[port])\n            memcpy(x, banner1->payloads.tcp[port], sizeof (*x));\n        x->name = \"(allocated)\";\n\n        x->hello = MALLOC(value_length);\n        x->hello_length = base64_decode((char*)x->hello, value_length, value, value_length);\n\n        banner1->payloads.tcp[port] = x;\n    }\n\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nvoid\ntcpcon_set_banner_flags(struct TCP_ConnectionTable *tcpcon,\n    unsigned is_capture_cert,\n    unsigned is_capture_servername,\n    unsigned is_capture_html,\n    unsigned is_capture_heartbleed,\n\tunsigned is_capture_ticketbleed)\n{\n    tcpcon->banner1->is_capture_cert = is_capture_cert;\n    tcpcon->banner1->is_capture_servername = is_capture_servername;\n    tcpcon->banner1->is_capture_html = is_capture_html;\n    tcpcon->banner1->is_capture_heartbleed = is_capture_heartbleed;\n    tcpcon->banner1->is_capture_ticketbleed = is_capture_ticketbleed;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid scripting_init_tcp(struct TCP_ConnectionTable *tcpcon, struct lua_State *L)\n{\n    tcpcon->banner1->L = L;\n    \n    banner_scripting.init(tcpcon->banner1);\n}\n\n/***************************************************************************\n * Called at startup, by a receive thread, to create a TCP connection\n * table.\n ***************************************************************************/\nstruct TCP_ConnectionTable *\ntcpcon_create_table(    size_t entry_count,\n                        struct stack_t *stack,\n                        struct TemplatePacket *pkt_template,\n                        OUTPUT_REPORT_BANNER report_banner,\n                        struct Output *out,\n                        unsigned connection_timeout,\n                        uint64_t entropy\n                        )\n{\n    struct TCP_ConnectionTable *tcpcon;\n    \n    \n    tcpcon = CALLOC(1, sizeof(*tcpcon));\n    tcpcon->timeout_connection = connection_timeout;\n    if (tcpcon->timeout_connection == 0)\n        tcpcon->timeout_connection = 30; /* half a minute before destroying tcb */\n    tcpcon->timeout_hello = 2;\n    tcpcon->entropy = entropy;\n\n    /* Find nearest power of 2 to the tcb count, but don't go\n     * over the number 16-million */\n    {\n        size_t new_entry_count;\n        new_entry_count = 1;\n        while (new_entry_count < entry_count) {\n            new_entry_count *= 2;\n            if (new_entry_count == 0) {\n                new_entry_count = (1<<24);\n                break;\n            }\n        }\n        if (new_entry_count > (1<<24))\n            new_entry_count = (1<<24);\n        if (new_entry_count < (1<<10))\n            new_entry_count = (1<<10);\n        entry_count = new_entry_count;\n    }\n\n    /* Create the table. If we can't allocate enough memory, then shrink\n     * the desired size of the table */\n    while (tcpcon->entries == 0) {\n        tcpcon->entries = malloc(entry_count * sizeof(*tcpcon->entries));\n        if (tcpcon->entries == NULL) {\n            entry_count >>= 1;\n        }\n    }\n    memset(tcpcon->entries, 0, entry_count * sizeof(*tcpcon->entries));\n\n\n    /* fill in the table structure */\n    tcpcon->count = (unsigned)entry_count;\n    tcpcon->mask = (unsigned)(entry_count-1);\n\n    /* create an event/timeouts structure */\n    tcpcon->timeouts = timeouts_create(TICKS_FROM_SECS(time(0)));\n\n\n    tcpcon->pkt_template = pkt_template;\n\n    tcpcon->stack = stack;\n    \n\n    tcpcon->banner1 = banner1_create();\n\n    tcpcon->report_banner = report_banner;\n    tcpcon->out = out;\n    return tcpcon;\n}\n\nstatic int TCB_EQUALS(const struct TCP_Control_Block *lhs, const struct TCP_Control_Block *rhs)\n{\n    if (lhs->port_me != rhs->port_me || lhs->port_them != rhs->port_them)\n        return 0;\n    if (lhs->ip_me.version != rhs->ip_me.version)\n        return 0;\n    if (lhs->ip_me.version == 6) {\n        if (memcmp(&lhs->ip_me.ipv6, &rhs->ip_me.ipv6, sizeof(rhs->ip_me.ipv6)) != 0)\n            return 0;\n        if (memcmp(&lhs->ip_them.ipv6, &rhs->ip_them.ipv6, sizeof(rhs->ip_them.ipv6)) != 0)\n            return 0;\n    } else {\n        if (lhs->ip_me.ipv4 != rhs->ip_me.ipv4)\n            return 0;\n        if (lhs->ip_them.ipv4 != rhs->ip_them.ipv4)\n            return 0;\n    }\n\n    return 1;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_tcb_change_state_to(struct TCP_Control_Block *tcb, unsigned new_state) {\n\n    LOGtcb(tcb, 2, \"to {%s}\\n\", state_to_string(new_state));\n    tcb->tcpstate = new_state;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcb_hash(   ipaddress ip_me, unsigned port_me, \n            ipaddress ip_them, unsigned port_them,\n            uint64_t entropy)\n{\n    unsigned index;\n\n    /* TCB hash table uses symmetric hash, so incoming/outgoing packets\n     * get the same hash. */\n    if (ip_me.version == 6) {\n        ipv6address ipv6 = ip_me.ipv6;\n        ipv6.hi ^= ip_them.ipv6.hi;\n        ipv6.lo ^= ip_them.ipv6.lo;\n        index = (unsigned)syn_cookie_ipv6(\n                                    ipv6, \n                                    port_me ^ port_them,\n                                    ipv6, \n                                    port_me ^ port_them,\n                                    entropy);\n\n    } else {\n        index = (unsigned)syn_cookie_ipv4(   ip_me.ipv4   ^ ip_them.ipv4,\n                                        port_me ^ port_them,\n                                        ip_me.ipv4   ^ ip_them.ipv4,\n                                        port_me ^ port_them,\n                                        entropy\n                                        );\n    }\n    return index;\n}\n\nenum DestroyReason {\n    Reason_Timeout = 1,\n    Reason_FIN = 2,\n    Reason_RST = 3,\n    Reason_Foo = 4,\n    Reason_Shutdown = 5,\n    Reason_StateDone = 6,\n\n};\n\n/***************************************************************************\n * Flush all the banners associated with this TCP connection. This always\n * called when TCB is destroyed. This may also be called earlier, such\n * as when a FIN is received.\n ***************************************************************************/\nvoid\nbanner_flush(struct stack_handle_t *socket)\n{\n    struct TCP_ConnectionTable *tcpcon = socket->tcpcon;\n    struct TCP_Control_Block *tcb = socket->tcb;\n    struct BannerOutput *banout;\n    \n    /* Go through and print all the banners. Some protocols have \n     * multiple banners. For example, web servers have both\n     * HTTP and HTML banners, and SSL also has several \n     * X.509 certificate banners */\n    for (banout = &tcb->banout; banout != NULL; banout = banout->next) {\n        if (banout->length && banout->protocol) {\n            tcpcon->report_banner(\n                                  tcpcon->out,\n                                  global_now,\n                                  tcb->ip_them,\n                                  6, /*TCP protocol*/\n                                  tcb->port_them,\n                                  banout->protocol & 0x0FFFFFFF,\n                                  tcb->ttl,\n                                  banout->banner,\n                                  banout->length);\n        }\n    }\n    \n    /*\n     * Free up all the banners.\n     */\n    banout_release(&tcb->banout);\n\n}\n\n/***************************************************************************\n * Destroy a TCP connection entry. We have to unlink both from the\n * TCB-table as well as the timeout-table.\n * Called from \n ***************************************************************************/\nstatic void\ntcpcon_destroy_tcb(\n    struct TCP_ConnectionTable *tcpcon,\n    struct TCP_Control_Block *tcb,\n    enum DestroyReason reason)\n{\n    unsigned index;\n    struct TCP_Control_Block **r_entry;\n    \n    UNUSEDPARM(reason);\n\n    /*\n     * The TCB doesn't point to it's location in the table. Therefore, we\n     * have to do a lookup to find the head pointer in the table.\n     */\n    index = tcb_hash(   tcb->ip_me, tcb->port_me, \n                        tcb->ip_them, tcb->port_them, \n                        tcpcon->entropy);\n    \n    /*\n     * At this point, we have the head of a linked list of TCBs. Now,\n     * traverse that linked list until we find our TCB\n     */\n    r_entry = &tcpcon->entries[index & tcpcon->mask];\n    while (*r_entry && *r_entry != tcb)\n        r_entry = &(*r_entry)->next;\n\n    if (*r_entry == NULL) {\n        LOG(1, \"tcb: double free\\n\");\n        return;\n    }\n\n    /*\n     * Print out any banners associated with this TCP session. Most of the\n     * time, there'll only be one. After printing them out, delete the\n     * banners.\n     */\n    {\n        struct stack_handle_t socket = {tcpcon, tcb, 0, 0};\n        banner_flush(&socket);\n    }\n\n    LOGtcb(tcb, 2, \"--DESTROYED--\\n\");\n\n    /*\n     * If there are any queued segments to transmit, then free them\n     */\n    while (tcb->segments) {\n        struct TCP_Segment *seg;\n        seg = tcb->segments;\n        tcb->segments = seg->next;\n        if (seg->flags == TCP__copy || seg->flags == TCP__adopt) {\n            free(seg->buf);\n            seg->buf = 0;\n        }\n        free(seg);\n    }\n    \n    if (tcb->scripting_thread)\n        ; //scripting_thread_close(tcb->scripting_thread);\n    tcb->scripting_thread = 0;\n    \n    /* KLUDGE: this needs to be made elegant */\n    switch (tcb->banner1_state.app_proto) {\n        case PROTO_SMB:\n            banner_smb1.cleanup(&tcb->banner1_state);\n            break;\n    }\n\n    /*\n     * Unlink this from the timeout system.\n     */\n    timeout_unlink(tcb->timeout);\n\n    tcb->ip_them.ipv4 = (unsigned)~0;\n    tcb->port_them = (unsigned short)~0;\n    tcb->ip_me.ipv4 = (unsigned)~0;\n    tcb->port_me = (unsigned short)~0;\n\n    tcb->is_active = 0;\n\n\n\n\n    (*r_entry) = tcb->next;\n    tcb->next = tcpcon->freed_list;\n    tcpcon->freed_list = tcb;\n    tcpcon->active_count--;\n}\n\n\n/***************************************************************************\n * Called at shutdown to free up all the memory used by the TCP\n * connection table.\n ***************************************************************************/\nvoid\ntcpcon_destroy_table(struct TCP_ConnectionTable *tcpcon)\n{\n    unsigned i;\n\n    if (tcpcon == NULL)\n        return;\n\n    /*\n     * Do a graceful destruction of all the entires. If they have banners,\n     * they will be sent to the output\n     */\n    for (i=0; i<=tcpcon->mask; i++) {\n        while (tcpcon->entries[i])\n            tcpcon_destroy_tcb(tcpcon, tcpcon->entries[i], Reason_Shutdown);\n    }\n\n    /*\n     * Now free the memory\n     */\n    while (tcpcon->freed_list) {\n        struct TCP_Control_Block *tcb = tcpcon->freed_list;\n        tcpcon->freed_list = tcb->next;\n        free(tcb);\n    }\n\n    banner1_destroy(tcpcon->banner1);\n    free(tcpcon->entries);\n    free(tcpcon);\n}\n\n\n/***************************************************************************\n *\n * Called when we receive a \"SYN-ACK\" packet with the correct SYN-cookie.\n *\n ***************************************************************************/\nstruct TCP_Control_Block *\ntcpcon_create_tcb(\n    struct TCP_ConnectionTable *tcpcon,\n    ipaddress ip_me, ipaddress ip_them,\n    unsigned port_me, unsigned port_them,\n    unsigned seqno_me, unsigned seqno_them,\n    unsigned ttl,\n    const struct ProtocolParserStream *stream,\n    unsigned secs, unsigned usecs)\n{\n    unsigned index;\n    struct TCP_Control_Block tmp;\n    struct TCP_Control_Block *tcb;\n\n\n    assert(ip_me.version != 0 && ip_them.version != 0);\n\n    tmp.ip_me = ip_me;\n    tmp.ip_them = ip_them;\n    tmp.port_me = (unsigned short)port_me;\n    tmp.port_them = (unsigned short)port_them;\n\n    /* Lookup the location in the hash table where this tcb should be\n     * placed */\n    index = tcb_hash(ip_me, port_me, ip_them, port_them, tcpcon->entropy);\n    tcb = tcpcon->entries[index & tcpcon->mask];\n    while (tcb && !TCB_EQUALS(tcb, &tmp)) {\n        tcb = tcb->next;\n    }\n    if (tcb != NULL) {\n        /* If it already exists, just return the existing one */\n        return tcb;\n    }\n\n    /* Allocate a new TCB, using a pool */\n    if (tcpcon->freed_list) {\n        tcb = tcpcon->freed_list;\n        tcpcon->freed_list = tcb->next;\n    } else {\n        tcb = MALLOC(sizeof(*tcb));\n    }\n    memset(tcb, 0, sizeof(*tcb));\n\n    /* Add it to this spot in the hash table */\n    tcb->next = tcpcon->entries[index & tcpcon->mask];\n    tcpcon->entries[index & tcpcon->mask] = tcb;\n\n    /*\n     * Initialize the entry\n     */\n    tcb->ip_me = ip_me;\n    tcb->ip_them = ip_them;\n    tcb->port_me = (unsigned short)port_me;\n    tcb->port_them = (unsigned short)port_them;\n    tcb->seqno_them_first = seqno_them;\n    tcb->seqno_me_first = seqno_me;\n    tcb->seqno_me = seqno_me;\n    tcb->seqno_them = seqno_them;\n    tcb->ackno_me = seqno_them;\n    tcb->ackno_them = seqno_me;\n    tcb->when_created = global_now;\n    tcb->ttl = (unsigned char)ttl;\n    tcb->mss = 1400;\n\n    /* Insert the TCB into the timeout. A TCB must always have a timeout\n     * active. */\n    timeout_init(tcb->timeout);\n    timeouts_add(tcpcon->timeouts,\n                 tcb->timeout,\n                 offsetof(struct TCP_Control_Block, timeout),\n                 TICKS_FROM_TV(secs+1,usecs)\n                 );\n\n    /* Get the protocol handler assigned to this port */\n    tcb->banner1_state.port = (unsigned short)port_them;\n    if (stream == NULL) {\n        struct Banner1 *banner1 = tcpcon->banner1;\n        stream = banner1->payloads.tcp[port_them];\n    }\n    tcb->stream = stream;\n    banout_init(&tcb->banout);\n\n    /* The TCB is now allocated/in-use */\n    assert(tcb->ip_me.version != 0 && tcb->ip_them.version != 0);\n    tcb->is_active = 1;\n\n    tcpcon->active_count++;\n\n    tcpcon_lookup_tcb(tcpcon, ip_me, ip_them, port_me, port_them);\n\n    return tcb;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstruct TCP_Control_Block *\ntcpcon_lookup_tcb(\n    struct TCP_ConnectionTable *tcpcon,\n    ipaddress ip_me, ipaddress ip_them,\n    unsigned port_me, unsigned port_them)\n{\n    unsigned index;\n    struct TCP_Control_Block tmp;\n    struct TCP_Control_Block *tcb;\n    ipaddress_formatted_t fmt1;\n    ipaddress_formatted_t fmt2;\n\n    tmp.ip_me = ip_me;\n    tmp.ip_them = ip_them;\n    tmp.port_me = (unsigned short)port_me;\n    tmp.port_them = (unsigned short)port_them;\n\n    index = tcb_hash(ip_me, port_me, ip_them, port_them, tcpcon->entropy);\n\n    fmt1 = ipaddress_fmt(ip_me);\n    fmt2 = ipaddress_fmt(ip_them);\n    LOG(1, \"tcb_hash(0x%08x) = %s %u %s %u\\n\", \n        (unsigned)index,\n        fmt1.string, port_me,\n        fmt2.string, port_them);\n\n    /* Hash to an entry in the table, then follow a linked list from\n     * that point forward. */\n    tcb = tcpcon->entries[index & tcpcon->mask];\n    while (tcb && !TCB_EQUALS(tcb, &tmp)) {\n        tcb = tcb->next;\n    }\n\n\n    return tcb;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntcpcon_send_packet(\n    struct TCP_ConnectionTable *tcpcon,\n    struct TCP_Control_Block *tcb,\n    unsigned tcp_flags,\n    const unsigned char *payload, size_t payload_length)\n{\n    struct PacketBuffer *response = 0;\n    unsigned is_syn = (tcp_flags == 0x02);\n    \n    assert(tcb->ip_me.version != 0 && tcb->ip_them.version != 0);\n\n    /* If sending an ACK, print a message */\n    if ((tcp_flags & 0x10) == 0x10) {\n        LOGtcb(tcb, 0, \"xmit ACK ackingthem=%u\\n\", tcb->seqno_them-tcb->seqno_them_first);\n    }\n\n    /* Get a buffer for sending the response packet. This thread doesn't\n     * send the packet itself. Instead, it formats a packet, then hands\n     * that packet off to a transmit thread for later transmission. */\n    response = stack_get_packetbuffer(tcpcon->stack);\n    if (response == NULL) {\n        static int is_warning_printed = 0;\n        if (!is_warning_printed) {\n            LOG(0, \"packet buffers empty (should be impossible)\\n\");\n            is_warning_printed = 1;\n        }\n        fflush(stdout);\n        \n        /* FIXME: I'm no sure the best way to handle this.\n         * This would result from a bug in the code,\n         * but I'm not sure what should be done in response */\n        pixie_usleep(100); /* no packet available */\n    }\n    if (response == NULL)\n        return;\n\n    /* Format the packet as requested. Note that there are really only\n     * four types of packets:\n     * 1. a SYN-ACK packet with no payload\n     * 2. an ACK packet with no payload\n     * 3. a RST packet with no payload\n     * 4. a PSH-ACK packet WITH PAYLOAD\n     */\n    response->length = tcp_create_packet(\n        tcpcon->pkt_template,\n        tcb->ip_them, tcb->port_them,\n        tcb->ip_me, tcb->port_me,\n        tcb->seqno_me - is_syn, tcb->seqno_them,\n        tcp_flags,\n        payload, payload_length,\n        response->px, sizeof(response->px)\n        );\n\n    /*\n     * KLUDGE:\n     */\n    if (tcb->is_small_window)\n        tcp_set_window(response->px, response->length, 600);\n    \n    /* Put this buffer on the transmit queue. Remember: transmits happen\n     * from a transmit-thread only, and this function is being called\n     * from a receive-thread. Therefore, instead of transmiting ourselves,\n     * we hae to queue it up for later transmission. */\n    stack_transmit_packetbuffer(tcpcon->stack, response);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\ntcp_send_RST(\n    struct TemplatePacket *templ,\n    struct stack_t *stack,\n    ipaddress ip_them, ipaddress ip_me,\n    unsigned port_them, unsigned port_me,\n    unsigned seqno_them, unsigned seqno_me\n)\n{\n    struct PacketBuffer *response = 0;\n    \n\n    /* Get a buffer for sending the response packet. This thread doesn't\n     * send the packet itself. Instead, it formats a packet, then hands\n     * that packet off to a transmit thread for later transmission. */\n    response = stack_get_packetbuffer(stack);\n    if (response == NULL) {\n        static int is_warning_printed = 0;\n        if (!is_warning_printed) {\n            LOG(0, \"packet buffers empty (should be impossible)\\n\");\n            is_warning_printed = 1;\n        }\n        fflush(stdout);\n        pixie_usleep(100); /* no packet available */\n    }\n    if (response == NULL)\n        return;\n\n    response->length = tcp_create_packet(\n        templ,\n        ip_them, port_them,\n        ip_me, port_me,\n        seqno_me, seqno_them,\n        0x04, /*RST*/\n        0, 0,\n        response->px, sizeof(response->px)\n        );\n\n\n    /* Put this buffer on the transmit queue. Remember: transmits happen\n     * from a transmit-thread only, and this function is being called\n     * from a receive-thread. Therefore, instead of transmitting ourselves,\n     * we have to queue it up for later transmission. */\n    stack_transmit_packetbuffer(stack, response);\n}\n\n\n/***************************************************************************\n * DEBUG: when printing debug messages (-d option), this prints a string\n * for the given state.\n ***************************************************************************/\nstatic const char *\nwhat_to_string(enum TCP_What state)\n{\n    static char buf[64];\n    switch (state) {\n        case TCP_WHAT_TIMEOUT: return \"TIMEOUT\";\n        case TCP_WHAT_SYNACK: return \"SYNACK\";\n        case TCP_WHAT_RST: return \"RST\";\n        case TCP_WHAT_FIN: return \"FIN\";\n        case TCP_WHAT_ACK: return \"ACK\";\n        case TCP_WHAT_DATA: return \"DATA\";\n        case TCP_WHAT_CLOSE: return \"CLOSE\";\n        default:\n            snprintf(buf, sizeof(buf), \"%d\", state);\n            return buf;\n    }\n}\n\n\n/***************************************************************************\n ***************************************************************************/\n\nstatic void\nLOGSEND(struct TCP_Control_Block *tcb, const char *what)\n{\n    if (tcb == NULL)\n        return;\n    LOGip(5, tcb->ip_them, tcb->port_them, \"=%s : --->> %s                  \\n\",\n          state_to_string(tcb->tcpstate),\n          what);\n}\n\n\n\nvoid\ntcpcon_send_RST(\n                struct TCP_ConnectionTable *tcpcon,\n                ipaddress ip_me, ipaddress ip_them,\n                unsigned port_me, unsigned port_them,\n                uint32_t seqno_them, uint32_t ackno_them)\n{\n    struct TCP_Control_Block tcb;\n    \n    memset(&tcb, 0, sizeof(tcb));\n    \n    tcb.ip_me = ip_me;\n    tcb.ip_them = ip_them;\n    tcb.port_me = (unsigned short)port_me;\n    tcb.port_them = (unsigned short)port_them;\n    tcb.seqno_me = ackno_them;\n    tcb.ackno_me = seqno_them + 1;\n    tcb.seqno_them = seqno_them + 1;\n    tcb.ackno_them = ackno_them;\n    \n    LOGSEND(&tcb, \"send RST\");\n    tcpcon_send_packet(tcpcon, &tcb, 0x04 /*RST*/, 0, 0);\n}\n\n\n/***************************************************************************\n * Called upon timeouts when an acknowledgement hasn't been received in\n * time. Will resend the segments.\n ***************************************************************************/\nstatic void\n_tcb_seg_resend(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb) {\n    struct TCP_Segment *seg = tcb->segments;\n\n    if (seg) {\n        if (tcb->seqno_me != seg->seqno) {\n            ERRMSG(\"SEQNO FAILURE diff=%d %s\\n\", tcb->seqno_me - seg->seqno, seg->is_fin?\"FIN\":\"\");\n            return;\n        }\n\n        if (seg->is_fin && seg->length == 0) {\n            tcpcon_send_packet(tcpcon, tcb,\n                                0x11, /*FIN-ACK*/\n                                0, /*FIN has no data */\n                                0 /*logically is 1 byte, but not payload byte */);\n        } else {\n            tcpcon_send_packet(tcpcon, tcb,\n                                0x18 | (seg->is_fin?0x01:0x00),\n                                seg->buf,\n                                seg->length);\n        }\n    }\n                        \n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\napplication_notify(struct TCP_ConnectionTable *tcpcon,\n                   struct TCP_Control_Block *tcb,\n                   enum App_Event event, const void *payload, size_t payload_length,\n                   unsigned secs, unsigned usecs)\n{\n    struct Banner1 *banner1 = tcpcon->banner1;\n    const struct ProtocolParserStream *stream = tcb->stream;\n    struct stack_handle_t socket = {\n        tcpcon, tcb, secs, usecs};\n\n    return application_event(&socket,\n                             tcb->app_state, event,\n                             stream, banner1,\n                             payload, payload_length\n                             );\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void \n_tcb_seg_send(void *in_tcpcon, void *in_tcb, \n        const void *buf, size_t length, \n        enum TCP__flags flags) {\n\n    struct TCP_ConnectionTable *tcpcon = (struct TCP_ConnectionTable *)in_tcpcon;\n    struct TCP_Control_Block *tcb = (struct TCP_Control_Block *)in_tcb;\n    struct TCP_Segment *seg;\n    struct TCP_Segment **next;\n    unsigned seqno = tcb->seqno_me;\n    size_t length_more = 0;\n    bool is_fin = (flags == TCP__close_fin);\n\n    if (length > tcb->mss) {\n        length_more = length - tcb->mss;\n        length = tcb->mss;\n    }\n\n\n    if (length == 0 && !is_fin)\n        return;\n\n    /* Go to the end of the segment list */\n    for (next = &tcb->segments; *next; next = &(*next)->next) {\n        seqno = (unsigned)((*next)->seqno + (*next)->length);\n        if ((*next)->is_fin) {\n            /* can't send past a FIN */\n            LOGip(0, tcb->ip_them, tcb->port_them, \"can't send past a FIN\\n\");\n            if (flags == TCP__adopt) {\n                free((void*)buf); /* discard const */\n                buf = NULL;\n            }\n            return;\n        }\n    }\n\n    /* Append this segment to the list */\n    seg = calloc(1, sizeof(*seg));\n    *next = seg;\n\n    /* Fill in this segment's members */\n    seg->seqno = seqno;\n    seg->length = length;\n    seg->flags = flags;\n    switch (flags) {\n        case TCP__static:\n        case TCP__adopt:\n            seg->buf = (void *)buf;\n            break;\n        case TCP__copy:\n            seg->buf = malloc(length);\n            memcpy(seg->buf, buf, length);\n            break;\n        case TCP__close_fin:\n            seg->buf = 0;\n            break;\n    }\n    if (length_more == 0)\n        seg->is_fin = is_fin;\n\n    if (!seg->is_fin && seg->length && tcb->tcpstate != STATE_ESTABLISHED_SEND)\n        application_notify(tcpcon, tcb, APP_SENDING, seg->buf, seg->length, 0, 0);\n\n    LOGtcb(tcb, 0, \"send = %u-bytes %s @ %u\\n\", length, is_fin?\"FIN\":\"\",\n           seg->seqno-tcb->seqno_me_first);\n    \n\n\n    /* If this is the head of the segment list, then transmit right away */\n    if (tcb->segments == seg) {\n        LOGtcb(tcb, 0, \"xmit = %u-bytes %s @ %u\\n\", length, is_fin?\"FIN\":\"\",\n               seg->seqno-tcb->seqno_me_first);\n        tcpcon_send_packet(tcpcon, tcb, 0x18 | (is_fin?1:0), seg->buf, seg->length);\n        if (!is_fin)\n            _tcb_change_state_to(tcb, STATE_ESTABLISHED_SEND);\n    }\n\n    /* If the input buffer was too large to fit a single segment, then\n     * split it up into multiple segments */\n    if (length_more) {\n        if (flags == TCP__adopt)\n            flags = TCP__copy;\n\n        _tcb_seg_send(tcpcon, tcb,\n                      (unsigned char*)buf + length, length_more,\n                      flags);\n    }\n\n    //tcb->established = App_SendNext;\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\n_tcp_seg_acknowledge(\n    struct TCP_Control_Block *tcb,\n    uint32_t ackno)\n{\n\n    /*LOG(4,  \"%s - %u-sending, %u-reciving\\n\",\n            fmt.string,\n            tcb->seqno_me - ackno,\n            ackno - tcb->ackno_them\n            );*/\n    /* Normal: just discard repeats */\n    if (ackno == tcb->seqno_me) {\n        return 0;\n    }\n\n    /* Make sure this isn't a duplicate ACK from past\n     * WRAPPING of 32-bit arithmetic happens here */\n    if (ackno - tcb->seqno_me > 100000) {\n        ipaddress_formatted_t fmt = ipaddress_fmt(tcb->ip_them);\n        LOG(4,  \"%s - \"\n                \"tcb: ackno from past: \"\n                \"old ackno = 0x%08x, this ackno = 0x%08x\\n\",\n                fmt.string,\n                tcb->ackno_me, ackno);\n        return 0;\n    }\n\n    /* Make sure this isn't invalid ACK from the future\n     * WRAPPING of 32-bit arithmetic happens here */\n    if (tcb->seqno_me - ackno < 100000) {\n        ipaddress_formatted_t fmt = ipaddress_fmt(tcb->ip_them);\n        LOG(0, \"%s - \"\n                \"tcb: ackno from future: \"\n                \"my seqno = 0x%08x, their ackno = 0x%08x\\n\",\n                fmt.string,\n                tcb->seqno_me, ackno);\n        return 0;\n    }\n\n    /* Handle FIN specially */\nhandle_fin:\n    if (tcb->segments && tcb->segments->is_fin) {\n        struct TCP_Segment *seg = tcb->segments;\n\n        if (seg->seqno+1 == ackno) {\n            LOGtcb(tcb, 1, \"ACKed FIN\\n\");\n            tcb->seqno_me += 1;\n            tcb->ackno_them += 1;\n            return 1;\n        } else if (seg->seqno == ackno) {\n            return 0;\n        } else {\n            LOGtcb(tcb, 1, \"@@@@@BAD ACK of FIN@@@@\\n\", seg->length);\n            return 0;\n        }\n    }\n\n    /* Retire outstanding segments */\n    {\n        unsigned length = ackno - tcb->seqno_me;\n        while (tcb->segments && length >= tcb->segments->length) {\n            struct TCP_Segment *seg = tcb->segments;\n\n            if (seg->is_fin)\n                goto handle_fin;\n\n            tcb->segments = seg->next;\n\n            length -= seg->length;\n            tcb->seqno_me += seg->length;\n            tcb->ackno_them += seg->length;\n            \n            LOGtcb(tcb, 1, \"ACKed %u-bytes\\n\", seg->length);\n\n            /* free the old segment */\n            switch (seg->flags) {\n                case TCP__static:\n                    break;\n                case TCP__adopt:\n                case TCP__copy:\n                    if (seg->buf) {\n                        free(seg->buf);\n                        seg->buf = NULL;\n                    }\n                    break;\n                default:\n                    ;\n            }\n            free(seg);\n            if (ackno == tcb->ackno_them)\n                return 1; /* good ACK */\n        }\n\n        if (tcb->segments && length < tcb->segments->length) {\n            struct TCP_Segment *seg = tcb->segments;\n            \n            tcb->seqno_me += length + seg->is_fin;\n            tcb->ackno_them += length + seg->is_fin;\n            LOGtcb(tcb, 1, \"ACKed %u-bytes %s\\n\", length, seg->is_fin?\"FIN\":\"\");\n\n            /* This segment needs to be reduced */\n            if (seg->flags == TCP__adopt || seg->flags == TCP__copy) {\n                size_t new_length = seg->length - length;\n                unsigned char *buf = malloc(new_length);\n                memcpy(buf, seg->buf + length, new_length);\n                free(seg->buf);\n                seg->buf = buf;\n                seg->length -= length;\n                seg->flags = TCP__copy;\n            } else {\n                seg->buf += length;\n            }\n            \n        }\n    }\n    \n    /* Mark that this was a good ack */\n    return 1;\n}\n\n\nvoid\nbanner_set_sslhello(struct stack_handle_t *socket, bool is_true) {\n    struct TCP_Control_Block *tcb = socket->tcb;\n    tcb->banner1_state.is_sent_sslhello = is_true;\n}\n\nvoid\nbanner_set_small_window(struct stack_handle_t *socket, bool is_true) {\n    struct TCP_Control_Block *tcb = socket->tcb;\n    tcb->is_small_window = is_true;\n}\n\nbool\nbanner_is_heartbleed(const struct stack_handle_t *socket) {\n    struct TCP_ConnectionTable *tcpcon = socket->tcpcon;\n    return tcpcon->banner1->is_heartbleed != 0;\n}\n\n/***************************************************************************\n * Parse the information we get from the server we are scanning. Typical\n * examples are SSH banners, FTP banners, or the response from HTTP\n * requests\n ***************************************************************************/\nsize_t\nbanner_parse(\n             struct stack_handle_t *socket,\n    const unsigned char *payload,\n    size_t payload_length\n    )\n{\n    struct TCP_ConnectionTable *tcpcon = socket->tcpcon;\n    struct TCP_Control_Block *tcb = socket->tcb;\n    assert(tcb->banout.max_length);\n    \n    banner1_parse(\n                                    tcpcon->banner1,\n                                    &tcb->banner1_state,\n                                    payload,\n                                    payload_length,\n                                    &tcb->banout,\n                                    socket);\n    return payload_length;\n}\n\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_next_IP_port(struct TCP_ConnectionTable *tcpcon,\n              ipaddress *ip_me,\n              unsigned *port_me) {\n    const struct stack_src_t *src = tcpcon->stack->src;\n    unsigned index;\n\n    /* Get another source port, because we can't use the existing\n     * one for new connection */\n    index = *port_me - src->port.first + 1;\n    *port_me = src->port.first + index;\n    if (*port_me >= src->port.last) {\n        *port_me = src->port.first;\n\n        /* We've wrapped the ports, so therefore choose another source\n         * IP address as well. */\n        switch (ip_me->version) {\n            case 4:\n                index = ip_me->ipv4 - src->ipv4.first + 1;\n                ip_me->ipv4 = src->ipv4.first + index;\n                if (ip_me->ipv4 >= src->ipv4.last)\n                    ip_me->ipv4 = src->ipv4.first;\n                break;\n            case 6: {\n                /* TODO: this code is untested, yolo */\n                ipv6address_t diff;\n\n                diff = ipv6address_subtract(ip_me->ipv6, src->ipv6.first);\n                diff = ipv6address_add_uint64(diff, 1);\n                ip_me->ipv6 = ipv6address_add(src->ipv6.first, diff);\n                if (ipv6address_is_lessthan(src->ipv6.last, ip_me->ipv6))\n                    ip_me->ipv6 = src->ipv6.first;\n                break;\n            }\n            default:\n                break;\n        }\n    }\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_do_reconnect(struct TCP_ConnectionTable *tcpcon,\n              const struct TCP_Control_Block *old_tcb,\n              const struct ProtocolParserStream *stream,\n              unsigned secs, unsigned usecs,\n              unsigned established) {\n    struct TCP_Control_Block *new_tcb;\n\n    ipaddress ip_them = old_tcb->ip_them;\n    unsigned port_them = old_tcb->port_them;\n    ipaddress ip_me = old_tcb->ip_me;\n    unsigned port_me = old_tcb->port_me;\n    unsigned seqno;\n\n\n    /*\n     * First, get another port number and potentially ip address\n     */\n    {\n        ipaddress prev_ip = ip_me;\n        unsigned prev_port = port_me;\n        _next_IP_port(tcpcon, &ip_me, &port_me);\n\n        if (ipaddress_is_equal(ip_me, prev_ip) && port_me == prev_port)\n            ERRMSG(\"There must be multiple source ports/addresses for reconnection\\n\");\n\n    }\n\n    /*\n     * Calculate the SYN cookie, the same algorithm as for when spewing\n     * SYN packets. However, since we'll probably be using a different\n     * port or IP address, it'll be different in practice.\n     */\n    seqno = (unsigned)syn_cookie(ip_them, port_them,\n                                 ip_me, port_me,\n                                 tcpcon->entropy);\n\n    /*\n     * Now create a new TCB for this new connection\n     */\n    new_tcb = tcpcon_create_tcb(\n                    tcpcon,\n                    ip_me, ip_them,\n                    port_me, port_them,\n                    seqno+1, 0,\n                    255,\n                    stream,\n                    secs, usecs);\n    new_tcb->app_state = established;\n}\n\nstatic void\n_tcb_seg_close(void *in_tcpcon,\n              void *in_tcb,\n              unsigned secs, unsigned usecs) {\n    struct TCP_ConnectionTable *tcpcon = (struct TCP_ConnectionTable *)in_tcpcon;\n    struct TCP_Control_Block *tcb = (struct TCP_Control_Block *)in_tcb;\n\n    stack_incoming_tcp(tcpcon, tcb,\n                  TCP_WHAT_CLOSE,\n                  0, 0, \n                  secs, usecs,\n                  tcb->seqno_them, tcb->ackno_them);\n}\n\n/***************************************************************************\n ***************************************************************************/\nint\ntcpapi_set_timeout(struct stack_handle_t *socket,\n                        unsigned secs,\n                        unsigned usecs\n                        ) {\n    struct TCP_ConnectionTable *tcpcon = socket->tcpcon;\n    struct TCP_Control_Block *tcb = socket->tcb;\n\n    if (socket == NULL)\n        return SOCKERR_EBADF;\n\n    timeouts_add(tcpcon->timeouts,\n             tcb->timeout,\n             offsetof(struct TCP_Control_Block, timeout),\n             TICKS_FROM_TV(socket->secs+secs, socket->usecs + usecs)\n             );\n    return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint\ntcpapi_recv(struct stack_handle_t *socket) {\n    struct TCP_Control_Block *tcb;\n\n    if (socket == 0 || socket->tcb == 0)\n        return SOCKERR_EBADF;\n    tcb = socket->tcb;\n\n    switch (tcb->tcpstate) {\n        default:\n        case STATE_ESTABLISHED_SEND:\n            _tcb_change_state_to(socket->tcb, STATE_ESTABLISHED_RECV);\n            break;\n        case STATE_FIN_WAIT1_RECV:\n            _tcb_change_state_to(socket->tcb, STATE_FIN_WAIT1_RECV);\n            break;\n        case STATE_FIN_WAIT1_SEND:\n            _tcb_change_state_to(socket->tcb, STATE_FIN_WAIT1_RECV);\n            break;\n    }\n    return 0;\n}\n\nint\ntcpapi_send(struct stack_handle_t *socket,\n            const void *buf, size_t length,\n            enum TCP__flags flags) {\n    struct TCP_Control_Block *tcb;\n\n    if (socket == 0 || socket->tcb == 0)\n        return SOCKERR_EBADF;\n\n    tcb = socket->tcb;\n    switch (tcb->tcpstate) {\n        case STATE_ESTABLISHED_RECV:\n            _tcb_change_state_to(tcb, STATE_ESTABLISHED_SEND);\n            /*follow through*/\n        case STATE_ESTABLISHED_SEND:\n            _tcb_seg_send(socket->tcpcon, tcb, buf, length, flags);\n            return 0;\n        default:\n            LOG(1, \"TCP app attempted SEND in wrong state\\n\");\n            return 1;\n    }\n}\n\nint\ntcpapi_reconnect(struct stack_handle_t *old_socket,\n               struct ProtocolParserStream *new_stream,\n               unsigned new_app_state) {\n    if (old_socket == 0 || old_socket->tcb == 0)\n        return SOCKERR_EBADF;\n\n    _do_reconnect(old_socket->tcpcon,\n                  old_socket->tcb,\n                  new_stream,\n                  old_socket->secs, old_socket->usecs,\n                  new_app_state);\n    return 0;\n}\n\nunsigned\ntcpapi_change_app_state(struct stack_handle_t *socket, unsigned new_app_state) {\n    struct TCP_Control_Block *tcb;\n\n    if (socket == 0 || socket->tcb == 0)\n        return SOCKERR_EBADF;\n\n    tcb = socket->tcb;\n\n    //printf(\"%u --> %u\\n\", tcb->app_state, new_app_state);\n\n    tcb->app_state = new_app_state;\n    return new_app_state;\n}\n\n\nint\ntcpapi_close(struct stack_handle_t *socket) {\n    if (socket == NULL || socket->tcb == NULL)\n        return SOCKERR_EBADF;\n    _tcb_seg_close(socket->tcpcon,\n                   socket->tcb,\n                   socket->secs,\n                   socket->usecs);\n    return 0;\n}\n\n\n\nstatic bool\n_tcb_they_have_acked_my_fin(struct TCP_Control_Block *tcb) {\n    if (tcb->segments && tcb->segments->is_fin && tcb->segments->length == 0) {\n        if (tcb->ackno_them >= tcb->segments->seqno + 1)\n            return true;\n        return false;\n    } else\n        return false;\n}\n\n\nstatic void\n_tcb_send_ack(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb) {\n        tcpcon_send_packet(tcpcon, tcb, 0x10, 0, 0);\n}\n\n\n\nstatic int\n_tcb_seg_recv(struct TCP_ConnectionTable *tcpcon,\n                  struct TCP_Control_Block *tcb,\n                  const unsigned char *payload, size_t payload_length,\n                  unsigned seqno_them,\n                  unsigned secs, unsigned usecs,\n                  bool is_fin)\n{\n    /* Special case when packet contains only a FIN */\n    if (payload_length == 0 && is_fin && (tcb->seqno_them - seqno_them) == 0) {\n        tcb->is_their_fin = 1;\n        tcb->seqno_them += 1;\n        tcb->ackno_me += 1;\n        tcpcon_send_packet(tcpcon, tcb, 0x10/*ACK*/, 0, 0);\n        return 1;\n    }\n\n\n    if ((tcb->seqno_them - seqno_them) > payload_length)  {\n        LOGSEND(tcb, \"peer(ACK) [acknowledge payload 1]\");\n        tcpcon_send_packet(tcpcon, tcb, 0x10 /*ACK*/, 0, 0);\n        return 1;\n    }\n\n    while (seqno_them != tcb->seqno_them && payload_length) {\n        seqno_them++;\n        payload_length--;\n        payload++;\n    }\n\n    if (tcb->is_their_fin) {\n        /* payload cannot be received after a FIN */\n        return 1;\n    }\n\n    if (payload_length == 0) {\n        tcpcon_send_packet(tcpcon, tcb, 0x10/*ACK*/, 0, 0);\n        return 1;\n    }\n\n    LOGtcb(tcb, 2, \"received %u bytes\\n\", payload_length);\n\n    tcb->seqno_them += payload_length + is_fin;\n    tcb->ackno_me += payload_length + is_fin;\n\n    application_notify(tcpcon, tcb, APP_RECV_PAYLOAD,\n                       payload, payload_length, secs, usecs);\n\n\n\n    if (is_fin)\n        tcb->is_their_fin = true;\n\n    /* Send ack for the data */\n    _tcb_send_ack(tcpcon, tcb);\n\n    return 0;\n}\n\n/*****************************************************************************\n * Handles incoming events, like timeouts and packets, that cause a change\n * in the TCP control block \"state\".\n *\n * This is the part of the code that implements the famous TCP state-machine\n * you see drawn everywhere, where they have states like \"TIME_WAIT\". Only\n * we don't really have those states.\n *****************************************************************************/\nenum TCB_result\nstack_incoming_tcp(struct TCP_ConnectionTable *tcpcon,\n              struct TCP_Control_Block *tcb,\n              enum TCP_What what, const unsigned char *payload, size_t payload_length,\n              unsigned secs, unsigned usecs,\n              unsigned seqno_them, unsigned ackno_them)\n{\n\n    /* FILTER\n     * Reject out-of-order payloads \n     */\n    if (payload_length) {\n        /* Wrapping technique: If there is a gap between this\n         * packet and the last one, then it means there is a missing\n         * packet somewhere. In that case, this calculation will\n         * wrap and `payload_offset` will be some huge number in the future.\n         * If there is no gap, then this will be zero.\n         * If there's overlap between this packet and the previous, `payload_offset`\n         * will be a small number less than the `length` of this packet.\n         * If it's a retransmission, the numbers will be the same\n         */\n        int payload_offset = seqno_them - tcb->seqno_them;\n        if (payload_offset < 0) {\n            /* This is a retrnasmission that we've already acknowledged */\n            if (payload_offset <= 0 - (int)payload_length) {\n                /* Both begin and end are old, so simply discard it */\n                return TCB__okay;\n            } else {\n                /* Otherwise shorten the payload */\n                payload_length += payload_offset;\n                payload -= payload_offset;\n                seqno_them -= payload_offset;\n                assert(payload_length < 2000);\n            }\n        } else if (payload_offset > 0) {\n            /* This is an out-of-order fragment in the future. an important design\n             * of this light-weight stack is that we don't support this, and\n             * force the other side to retransmit such packets */\n            return TCB__okay;\n        }\n    }\n    \n    /* FILTER:\n     * Reject out-of-order FINs.\n     * Handle duplicate FINs here\n     */\n    if (what == TCP_WHAT_FIN) {\n        if (seqno_them == tcb->seqno_them - 1) {\n            /* Duplicate FIN, respond with ACK */\n            LOGtcb(tcb, 1, \"duplicate FIN\\n\");\n            _tcb_send_ack(tcpcon, tcb);\n            return TCB__okay;\n        } else if (seqno_them != tcb->seqno_them) {\n            /* out of order FIN, so drop it */\n            LOGtcb(tcb, 1, \"out-of-order FIN\\n\");\n            return TCB__okay;\n        }\n    }\n\n    LOGtcb(tcb, 1, \"##%s##\\n\", what_to_string(what));\n\n    /* Make sure no connection lasts longer than ~30 seconds */\n    if (what == TCP_WHAT_TIMEOUT) {\n        if (tcb->when_created + tcpcon->timeout_connection < secs) {\n            LOGip(8, tcb->ip_them, tcb->port_them,\n                \"%s                \\n\",\n                \"CONNECTION TIMEOUT---\");\n            LOGSEND(tcb, \"peer(RST)\");\n            tcpcon_send_packet(tcpcon, tcb, 0x04 /*RST*/, 0, 0);\n            tcpcon_destroy_tcb(tcpcon, tcb, Reason_Timeout);\n            return TCB__destroyed;\n        }\n    }\n    \n    if (what == TCP_WHAT_RST) {\n        LOGSEND(tcb, \"tcb(destroy)\");\n        tcpcon_destroy_tcb(tcpcon, tcb, Reason_RST);\n        return TCB__destroyed;\n    }\n    \n\n    \n    /*\n     *\n     *\n     *\n     *\n     *\n     *\n     */\n    switch (tcb->tcpstate) {\n            /* TODO: validate any SYNACK is real before sending it here\n             * to the state-machine, by validating that it's acking\n             * something */\n        case STATE_SYN_SENT:\n            switch (what) {\n                case TCP_WHAT_TIMEOUT:\n                    /* We've sent a SYN, but didn't get SYN-ACK, so\n                        * send another */\n                    tcb->syns_sent++;\n\n                    /* Send a SYN */\n                    tcpcon_send_packet(tcpcon, tcb, 0x02 /*SYN*/, 0, 0);\n                    break;\n                case TCP_WHAT_SYNACK:\n                    tcb->seqno_them = seqno_them;\n                    tcb->seqno_them_first = seqno_them - 1;\n                    tcb->seqno_me = ackno_them;\n                    tcb->seqno_me_first = ackno_them - 1;\n\n                    LOGtcb(tcb, 1, \"%s connection established\\n\",\n                           what_to_string(what));\n\n                    /* Send \"ACK\" to acknowlege their \"SYN-ACK\" */\n                    _tcb_send_ack(tcpcon, tcb);\n                    _tcb_change_state_to(tcb, STATE_ESTABLISHED_RECV);\n                    application_notify(tcpcon, tcb, APP_CONNECTED, 0, 0, secs, usecs);\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n\n                    break;\n            }\n            break;\n\n\n        case STATE_ESTABLISHED_SEND:\n            switch (what) {\n                case TCP_WHAT_CLOSE:\n                    _tcb_seg_send(tcpcon, tcb, 0, 0, TCP__close_fin);\n                    _tcb_change_state_to(tcb, STATE_FIN_WAIT1_SEND);\n                    break;\n                case TCP_WHAT_FIN:\n                    if (seqno_them == tcb->seqno_them) {\n                        /* I have ACKed all their data, so therefore process this */\n                        _tcb_seg_recv(tcpcon, tcb, 0, 0, seqno_them, secs, usecs, true);\n                        _tcb_change_state_to(tcb, STATE_FIN_WAIT1_SEND);\n                        _tcb_send_ack(tcpcon, tcb);\n                    } else {\n                        /* I haven't received all their data, so ignore it until I do */\n                        _tcb_send_ack(tcpcon, tcb);\n                    }\n                    break;\n                case TCP_WHAT_ACK:\n                    _tcp_seg_acknowledge(tcb, ackno_them);\n\n                    if (tcb->segments == NULL || tcb->segments->length == 0) {\n                        /* We've finished sending everything, so switch our application state\n                         * back to sending */\n                        _tcb_change_state_to(tcb, STATE_ESTABLISHED_RECV);\n\n                        /* All the payload has been sent. Notify the application of this, so that they\n                         * can send more if the want, or switch to listening. */\n                        application_notify(tcpcon, tcb, APP_SEND_SENT, 0, 0, secs, usecs);\n\n                    }\n                    break;\n                case TCP_WHAT_TIMEOUT:\n                    /* They haven't acknowledged everything yet, so resend the last segment */\n                    _tcb_seg_resend(tcpcon, tcb);\n                    break;\n                case TCP_WHAT_DATA:\n                    /* We don't receive data while in the sending state. We force them\n                     * to keep re-sending it until we are prepared to receive it. This\n                     * saves us from having to buffer it in this stack.\n                     */\n                    break;\n                case TCP_WHAT_SYNACK:\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n\n        case STATE_ESTABLISHED_RECV:\n            switch (what) {\n                case TCP_WHAT_CLOSE:\n                    _tcb_seg_send(tcpcon, tcb, 0, 0, TCP__close_fin);\n                    _tcb_change_state_to(tcb, STATE_FIN_WAIT1_RECV);\n                    break;\n                case TCP_WHAT_FIN:\n                    if (seqno_them == tcb->seqno_them) {\n                        /* I have ACKed all their data, so therefore process this */\n                        _tcb_seg_recv(tcpcon, tcb, 0, 0, seqno_them, secs, usecs, true);\n                        _tcb_change_state_to(tcb, STATE_CLOSE_WAIT);\n                        //_tcb_send_ack(tcpcon, tcb);\n                        application_notify(tcpcon, tcb, APP_CLOSE,\n                                0, payload_length, secs, usecs);\n\n                    } else {\n                        /* I haven't received all their data, so ignore it until I do */\n                        _tcb_send_ack(tcpcon, tcb);\n                    }\n                    break;\n                case TCP_WHAT_ACK:\n                    _tcp_seg_acknowledge(tcb, ackno_them);\n                    break;\n                case TCP_WHAT_TIMEOUT:\n                    application_notify(tcpcon, tcb, APP_RECV_TIMEOUT, 0, 0, secs, usecs);\n                    break;\n                case TCP_WHAT_DATA:\n                    _tcb_seg_recv(tcpcon, tcb, payload, payload_length, seqno_them, secs, usecs, false);\n                    break;\n                case TCP_WHAT_SYNACK:\n                    /* This happens when a delayed SYN-ACK arrives from the target.\n                     * I see these fairly often from host 178.159.37.125.\n                     * We are going to make them silent for now, but eventually, keep\n                     * statistics about this sort of thing. */\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n\n        /*\n         SYN-RCVD + FIN = FIN-WAIT-1\n         ESTAB + FIN = FIN-WAIT-1\n             +---------+\n             |  FIN    |\n             | WAIT-1  |\n             +---------+\n         FIN-WAIT-1 + FIN --> CLOSING\n         FIN-WAIT-1 + ACK-of-FIN --> FIN-WAIT-2\n        */\n        case STATE_FIN_WAIT1_SEND:\n            switch (what) {\n                case TCP_WHAT_FIN:\n                    /* Ignore their FIN while in the SENDing state. */\n                    break;\n                case TCP_WHAT_ACK:\n                    /* Apply the ack */\n                    if (_tcp_seg_acknowledge(tcb, ackno_them)) {\n\n                        /* Same a in ESTABLISHED_SEND, once they've acknowledged\n                         * all reception BEFORE THE FIN, then change the state */\n                        if (tcb->segments == NULL || tcb->segments->length == 0) {\n                            /* All the payload has been sent. Notify the application of this, so that they\n                             * can send more if the want, or switch to listening. */\n                            _tcb_change_state_to(tcb, STATE_FIN_WAIT1_RECV);\n                            application_notify(tcpcon, tcb, APP_SEND_SENT, 0, 0, secs, usecs);\n                        }\n                    }\n                    break;\n                case TCP_WHAT_TIMEOUT:\n                    _tcb_seg_resend(tcpcon, tcb); /* also resends FINs */\n                    break;\n                case TCP_WHAT_DATA:\n                    /* Ignore any data received while in the SEND state */\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n        case STATE_FIN_WAIT1_RECV:\n            switch (what) {\n                case TCP_WHAT_FIN:\n                    _tcb_seg_recv(tcpcon, tcb, 0, 0, seqno_them, secs, usecs, true);\n                    _tcb_change_state_to(tcb, STATE_CLOSING);\n                    _tcb_send_ack(tcpcon, tcb);\n                    application_notify(tcpcon, tcb, APP_CLOSE, 0, 0, secs, usecs);\n                    break;\n                case TCP_WHAT_ACK:\n                    /* Apply the ack */\n                    if (_tcp_seg_acknowledge(tcb, ackno_them)) {\n                        if (_tcb_they_have_acked_my_fin(tcb)) {\n                            _tcb_change_state_to(tcb, STATE_FIN_WAIT2);\n                            application_notify(tcpcon, tcb, APP_CLOSE, 0, 0, secs, usecs);\n                        }\n                    }\n                    break;\n                case TCP_WHAT_TIMEOUT:\n                    _tcb_seg_resend(tcpcon, tcb); /* also recv FIN */\n                    break;\n                case TCP_WHAT_DATA:\n                    _tcb_seg_recv(tcpcon, tcb, payload, payload_length, seqno_them, secs, usecs, false);\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n\n\n        case STATE_CLOSING:\n            switch (what) {\n                case TCP_WHAT_TIMEOUT:\n                    tcpcon_destroy_tcb(tcpcon, tcb, Reason_Timeout);\n                    return TCB__destroyed;\n                case TCP_WHAT_ACK:\n                    _tcp_seg_acknowledge(tcb, ackno_them);\n                    if (_tcb_they_have_acked_my_fin(tcb)) {\n                        tcpcon_destroy_tcb(tcpcon, tcb, Reason_FIN);\n                        return TCB__destroyed;\n                    }\n                    break;\n                case TCP_WHAT_FIN:\n                    /* I've already acknowledged their FIN, but hey, do it again */\n                    _tcb_send_ack(tcpcon, tcb);\n                    break;\n                case TCP_WHAT_CLOSE:\n                    /* The application this machine has issued a second `tcpapi_close()` request.\n                     * This represents a bug in the application process. One place where I see this\n                     * when scanning 193.109.9.122:992.\n                     * FIXME TODO */\n                    ; /* make this silent for now */\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n\n\n        case STATE_FIN_WAIT2:\n        case STATE_TIME_WAIT:\n            switch (what) {\n                case TCP_WHAT_TIMEOUT:\n                    /* giving up */\n                    if (tcb->tcpstate == STATE_TIME_WAIT) {\n                        tcpcon_destroy_tcb(tcpcon, tcb, Reason_Timeout);\n                        return TCB__destroyed;\n                    }\n                    break;\n                case TCP_WHAT_ACK:\n                    break;\n                case TCP_WHAT_FIN:\n                    /* Processing incoming FIN as an empty paylaod */\n                    _tcb_seg_recv(tcpcon, tcb, 0, 0, seqno_them, secs, usecs, true);\n\n                    _tcb_change_state_to(tcb, STATE_TIME_WAIT);\n\n                    timeouts_add(   tcpcon->timeouts,\n                                 tcb->timeout,\n                                 offsetof(struct TCP_Control_Block, timeout),\n                                 TICKS_FROM_TV(secs+5,usecs)\n                                 );\n                    break;\n                case TCP_WHAT_SYNACK:\n                case TCP_WHAT_RST:\n                case TCP_WHAT_DATA:\n                    break;\n                case TCP_WHAT_CLOSE:\n                    /* FIXME: to reach this state, we've already done a close.\n                     * FIXME: but this happens twice, because only have\n                     * FIXME: a single close function. */\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n        case STATE_CLOSE_WAIT:\n            /* Waiting for app to call `close()` */\n            switch (what) {\n                case TCP_WHAT_CLOSE:\n                    _tcb_seg_send(tcpcon, tcb, 0, 0, TCP__close_fin);\n                    _tcb_change_state_to(tcb, STATE_LAST_ACK);\n                    break;\n                case TCP_WHAT_TIMEOUT:\n                    /* Remind the app that it's waiting for it to be closed */\n                    application_notify(tcpcon, tcb, APP_CLOSE,\n                            0, payload_length, secs, usecs);\n                    break;\n                default:\n                    ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\",\n                            state_to_string(tcb->tcpstate), what_to_string(what));\n                    break;\n            }\n            break;\n        case STATE_LAST_ACK:\n            switch (what) {\n            case TCP_WHAT_TIMEOUT:\n                /* They haven't acknowledged everything yet, so resend the last segment */\n                _tcb_seg_resend(tcpcon, tcb);\n                break;\n            case TCP_WHAT_ACK:\n                if (_tcp_seg_acknowledge(tcb, ackno_them)) {\n                    tcpcon_destroy_tcb(tcpcon, tcb, Reason_Shutdown);\n                    return TCB__destroyed;\n                }\n                break;\n            default:\n                ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n                break;\n            }\n            break;\n            break;\n        default:\n            ERRMSGip(tcb->ip_them, tcb->port_them, \"%s:%s **** UNHANDLED EVENT ****\\n\", \n                        state_to_string(tcb->tcpstate), what_to_string(what));\n            break;\n    }\n    return TCB__okay;\n}\n\n"
  },
  {
    "path": "src/stack-tcp-core.h",
    "content": "#ifndef PROTO_TCP_H\n#define PROTO_TCP_H\n#include \"massip-addr.h\"\n#include \"stack-queue.h\"\n#include \"output.h\"\n#include \"util-bool.h\"\n\nstruct Adapter;\nstruct TCP_Control_Block;\nstruct TemplatePacket;\nstruct TCP_ConnectionTable;\nstruct lua_State;\nstruct ProtocolParserStream;\n\n#define TCP_SEQNO(px,i) (px[i+4]<<24|px[i+5]<<16|px[i+6]<<8|px[i+7])\n#define TCP_ACKNO(px,i) (px[i+8]<<24|px[i+9]<<16|px[i+10]<<8|px[i+11])\n#define TCP_FLAGS(px,i) (px[(i)+13])\n#define TCP_IS_SYNACK(px,i) ((TCP_FLAGS(px,i) & 0x12) == 0x12)\n#define TCP_IS_ACK(px,i) ((TCP_FLAGS(px,i) & 0x10) == 0x10)\n#define TCP_IS_RST(px,i) ((TCP_FLAGS(px,i) & 0x4) == 0x4)\n#define TCP_IS_FIN(px,i) ((TCP_FLAGS(px,i) & 0x1) == 0x1)\n\n\n/**\n * [KLUDGE] The 'tcpcon' module doesn't have access to the main configuration,\n * so specific configuration options have to be sent to it using this\n * function.\n */\nvoid\ntcpcon_set_parameter(struct TCP_ConnectionTable *tcpcon,\n                        const char *name,\n                        size_t value_length,\n                        const void *value);\nenum http_field_t {\n    http_field_replace,\n    http_field_add,\n    http_field_remove,\n    http_field_method,\n    http_field_url,\n    http_field_version,\n};\n\nvoid\ntcpcon_set_http_header(struct TCP_ConnectionTable *tcpcon,\n                        const char *name,\n                        size_t value_length,\n                        const void *value,\n                        enum http_field_t what);\n\nvoid scripting_init_tcp(struct TCP_ConnectionTable *tcpcon, struct lua_State *L);\n\n/**\n * Create a TCP connection table (to store TCP control blocks) with\n * the desired initial size.\n *\n * @param entry_count\n *      A hint about the desired initial size. This should be about twice\n *      the number of outstanding connections, so you should base this number\n *      on your transmit rate (the faster the transmit rate, the more\n *      outstanding connections you'll have). This function will automatically\n *      round this number up to the nearest power of 2, or round it down\n *      if it causes malloc() to not be able to allocate enough memory.\n * @param entropy\n *      Seed for syn-cookie randomization\n */\nstruct TCP_ConnectionTable *\ntcpcon_create_table(    size_t entry_count,\n                        struct stack_t *stack,\n                        struct TemplatePacket *pkt_template,\n                        OUTPUT_REPORT_BANNER report_banner,\n                        struct Output *out,\n                        unsigned timeout,\n                        uint64_t entropy\n                        );\n\nvoid tcpcon_set_banner_flags(struct TCP_ConnectionTable *tcpcon,\n    unsigned is_capture_cert,\n    unsigned is_capture_servername,\n    unsigned is_capture_html,\n    unsigned is_capture_heartbleed,\n\tunsigned is_capture_ticketbleed);\n\n/**\n * Gracefully destroy a TCP connection table. This is the last chance for any\n * partial banners (like HTTP server version) to be sent to the output. At the\n * end of a scan, you'll see a bunch of banners all at once due to this call.\n *\n * @param tcpcon\n *      A TCP connection table created with a matching call to\n *      'tcpcon_create_table()'.\n */\nvoid\ntcpcon_destroy_table(struct TCP_ConnectionTable *tcpcon);\n\n\nvoid\ntcpcon_timeouts(struct TCP_ConnectionTable *tcpcon, unsigned secs, unsigned usecs);\n\nenum TCP_What {\n    TCP_WHAT_TIMEOUT,\n    TCP_WHAT_SYNACK,\n    TCP_WHAT_RST,\n    TCP_WHAT_FIN,\n    TCP_WHAT_ACK,\n    TCP_WHAT_DATA,\n    TCP_WHAT_CLOSE\n};\n\nenum TCB_result {\n    TCB__okay,\n    TCB__destroyed\n};\n\nenum TCB_result\nstack_incoming_tcp(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *entry,\n    enum TCP_What what, \n    const unsigned char *payload, size_t payload_length,\n    unsigned secs, unsigned usecs,\n    unsigned seqno_them, unsigned ackno_them);\n\n\n/**\n * Lookup a connection record based on IP/ports.\n */\nstruct TCP_Control_Block *\ntcpcon_lookup_tcb(\n    struct TCP_ConnectionTable *tcpcon,\n    ipaddress ip_src, ipaddress ip_dst,\n    unsigned port_src, unsigned port_dst);\n\n/**\n * Create a new TCB (TCP control block. It's created only in two places,\n * either because we've initiated an outbound TCP connection, or we've\n * received incoming SYN-ACK from a probe.\n */\nstruct TCP_Control_Block *\ntcpcon_create_tcb(\n    struct TCP_ConnectionTable *tcpcon,\n    ipaddress ip_src, ipaddress ip_dst,\n    unsigned port_src, unsigned port_dst,\n    unsigned my_seqno, unsigned their_seqno,\n    unsigned ttl,\n    const struct ProtocolParserStream *stream,\n    unsigned secs, unsigned usecs);\n\n\nvoid\ntcpcon_send_RST(\n                struct TCP_ConnectionTable *tcpcon,\n                ipaddress ip_me, ipaddress ip_them,\n                unsigned port_me, unsigned port_them,\n                uint32_t seqno_them, uint32_t ackno_them);\n\n/**\n * Send a reset packet back, even if we don't have a TCP connection\n * table\n */\nvoid\ntcp_send_RST(\n    struct TemplatePacket *templ,\n    struct stack_t *stack,\n    ipaddress ip_them, ipaddress ip_me,\n    unsigned port_them, unsigned port_me,\n    unsigned seqno_them, unsigned seqno_me\n);\n\n#endif\n"
  },
  {
    "path": "src/stub-lua.c",
    "content": "#define LUAAPI\n#include \"stub-lua.h\"\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4133 4113 4047)\n#endif\n\n#if defined(WIN32)\n#define WIN32_LEAN_AND_MEAN\n#include <Windows.h>\n#else\n#include <dlfcn.h>\n#endif\n\n#if defined(__GNUC__)\n/* Disable MinGW warnings for Windows */\n#pragma GCC diagnostic ignored \"-Wincompatible-pointer-types\"\n#endif\n\n\nint stublua_init(void)\n{\n    void *lib = NULL;\n    \n    {\n#if defined(__APPLE__)\n        static const char *possible_names[] = {\n\n            \"liblua.5.3.5.dylib\",\n            \"liblua.5.3.dylib\",\n            \"liblua5.3.dylib\",\n            \"liblua.dylib\",\n            0\n        };\n#elif defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)\n        static const char *possible_names[] = {\n            \"lua53.dll\",\n            \"lua.dll\",\n            0\n        };\n#else\n        static const char *possible_names[] = {\n            \"liblua5.3.so\",\n            \"liblua5.3.so.0\",\n            \"liblua5.3.so.0.0.0\",\n            0\n        };\n#endif\n        unsigned i;\n        for (i=0; possible_names[i]; i++) {\n#if defined(WIN32)\n            lib = LoadLibraryA(possible_names[i]);\n#else\n            lib = dlopen(possible_names[i], RTLD_LAZY);\n#endif\n            if (lib) {\n                break;\n            } else {\n                ;\n            }\n        }\n        \n        if (lib == NULL) {\n            fprintf(stderr, \"liblua: failed to load Lua shared library\\n\");\n            fprintf(stderr, \"    HINT: you must install Lua library\\n\");\n        }\n    }\n\n#if defined(WIN32)\n#define DOLINK(name) \\\n    name = (void (*)())GetProcAddress(lib, #name); \\\n    if (name == NULL) fprintf(stderr, \"liblua: %s: failed\\n\", #name);\n#else\n#define DOLINK(name) \\\n    name = dlsym(lib, #name); \\\n    if (name == NULL) fprintf(stderr, \"liblua: %s: failed\\n\", #name);\n#endif\n    \n    DOLINK(lua_version);\n    \n    \n    DOLINK(lua_close)\n    DOLINK(lua_getfield)\n    DOLINK(lua_getglobal)\n    DOLINK(lua_geti)\n    DOLINK(lua_gettop)\n    DOLINK(lua_isnumber);\n    DOLINK(lua_isstring);\n    DOLINK(lua_iscfunction);\n    DOLINK(lua_isinteger);\n    DOLINK(lua_isuserdata);\n    DOLINK(lua_newthread)\n    DOLINK(lua_newuserdata)\n    DOLINK(lua_pcallk)\n    DOLINK(lua_pushcclosure)\n    DOLINK(lua_pushinteger)\n    DOLINK(lua_pushlstring)\n    DOLINK(lua_pushnumber)\n    DOLINK(lua_pushstring)\n    DOLINK(lua_pushvalue)\n    DOLINK(lua_resume)\n    DOLINK(lua_setfield)\n    DOLINK(lua_setglobal)\n    DOLINK(lua_seti)\n    DOLINK(lua_settop)\n    DOLINK(lua_toboolean)\n    DOLINK(lua_tointegerx)\n    DOLINK(lua_tolstring)\n    DOLINK(lua_tonumberx)\n    DOLINK(lua_type)\n    DOLINK(lua_typename)\n    DOLINK(lua_version)\n    DOLINK(lua_xmove)\n    DOLINK(lua_yieldk)\n    \n    DOLINK(luaL_checkinteger)\n    DOLINK(luaL_checklstring)\n    DOLINK(luaL_checkudata)\n    DOLINK(luaL_len)\n    DOLINK(luaL_loadbufferx)\n    DOLINK(luaL_loadfilex)\n    DOLINK(luaL_loadstring)\n    DOLINK(luaL_newmetatable)\n    DOLINK(luaL_newstate)\n    DOLINK(luaL_openlibs)\n    DOLINK(luaL_ref)\n    DOLINK(luaL_setfuncs)\n    DOLINK(luaL_setmetatable)\n    DOLINK(luaL_unref)\n    \n    return 0;\n}\n"
  },
  {
    "path": "src/stub-lua.h",
    "content": "/*\n    Stub declarations, for loading Lua dynamically at runtime using\n    openlib() or LoadLibrary().\n */\n\n#ifndef STUB_LUA_H\n#define STUB_LUA_H\n#include <stdio.h>\n#include <stddef.h>\n#include <stdint.h>\n\n/**\n * Called to load the Lua dynamic library, suh as lua53.dll or lua5.3.so.0,\n * and link all the function pointers. This must be called before calling any\n * Lua functions, or the program will crash.\n */\nint stublua_init(void);\n\nstruct lua_State;\ntypedef struct lua_State lua_State;\ntypedef long long lua_Integer;\ntypedef double lua_Number;\ntypedef unsigned long long lua_Unsigned;\ntypedef ptrdiff_t lua_KContext;\ntypedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);\ntypedef int (*lua_CFunction) (lua_State *L);\ntypedef struct luaL_Reg {\n    const char *name;\n    lua_CFunction func;\n} luaL_Reg;\n\n#define LUA_MULTRET    (-1)\n#define LUAI_MAXSTACK        1000000\n#define LUA_REGISTRYINDEX    (-LUAI_MAXSTACK - 1000)\n\n#define LUA_OK          0\n#define LUA_YIELD       1\n#define LUA_ERRRUN      2\n#define LUA_ERRSYNTAX   3\n#define LUA_ERRMEM      4\n#define LUA_ERRGCMM     5\n#define LUA_ERRERR      6\n\n#define LUA_TNONE           (-1)\n#define LUA_TNIL            0\n#define LUA_TBOOLEAN        1\n#define LUA_TLIGHTUSERDATA  2\n#define LUA_TNUMBER         3\n#define LUA_TSTRING         4\n#define LUA_TTABLE          5\n#define LUA_TFUNCTION       6\n#define LUA_TUSERDATA       7\n#define LUA_TTHREAD         8\n#define LUA_NUMTAGS         9\n\n\n#define lua_isfunction(L,n)         (lua_type(L, (n)) == LUA_TFUNCTION)\n#define lua_istable(L,n)            (lua_type(L, (n)) == LUA_TTABLE)\n#define lua_islightuserdata(L,n)    (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)\n#define lua_isnil(L,n)              (lua_type(L, (n)) == LUA_TNIL)\n#define lua_isboolean(L,n)          (lua_type(L, (n)) == LUA_TBOOLEAN)\n#define lua_isthread(L,n)           (lua_type(L, (n)) == LUA_TTHREAD)\n#define lua_isnone(L,n)             (lua_type(L, (n)) == LUA_TNONE)\n#define lua_isnoneornil(L, n)       (lua_type(L, (n)) <= 0)\n#define lua_pcall(L,n,r,f)          lua_pcallk(L, (n), (r), (f), 0, NULL)\n#define lua_pop(L,n)                lua_settop(L, -(n)-1)\n#define lua_pushcfunction(L,f)      lua_pushcclosure(L, (f), 0)\n#define lua_register(L,n,f)         (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))\n#define lua_tonumber(L,i)           lua_tonumberx(L,(i),NULL)\n#define lua_tointeger(L,i)          lua_tointegerx(L,(i),NULL)\n#define lua_tostring(L,i)           lua_tolstring(L, (i), NULL)\n#define lua_upvalueindex(i)         (LUA_REGISTRYINDEX - (i))\n#define lua_yield(L,n)              lua_yieldk(L, (n), 0, NULL)\n\n#define luaL_checkstring(L,n)       (luaL_checklstring(L, (n), NULL))\n#define luaL_dofile(L, fn)          (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))\n#define luaL_dostring(L, s)         (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))\n#define luaL_getmetatable(L,n)      (lua_getfield(L, LUA_REGISTRYINDEX, (n)))\n#define luaL_loadbuffer(L,s,sz,n)   luaL_loadbufferx(L,s,sz,n,NULL)\n#define luaL_loadfile(L,f)          luaL_loadfilex(L,f,NULL)\n#define luaL_opt(L,f,n,d)           (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))\n#define luaL_typename(L,i)          lua_typename(L, lua_type(L,(i)))\n\n#ifndef LUAAPI\n#define LUAAPI extern\n#endif\n\nLUAAPI void        (*lua_close)(lua_State *L);\nLUAAPI int         (*lua_getfield)(lua_State *L, int idx, const char *k);\nLUAAPI int         (*lua_getglobal)(lua_State *L, const char *name);\nLUAAPI int         (*lua_geti)(lua_State *L, int idx, lua_Integer n);\nLUAAPI int         (*lua_gettop)(lua_State *L);\nLUAAPI int         (*lua_isnumber)(lua_State *L, int idx);\nLUAAPI int         (*lua_isstring)(lua_State *L, int idx);\nLUAAPI int         (*lua_iscfunction)(lua_State *L, int idx);\nLUAAPI int         (*lua_isinteger)(lua_State *L, int idx);\nLUAAPI int         (*lua_isuserdata)(lua_State *L, int idx);\nLUAAPI lua_State * (*lua_newthread)(lua_State *L);\nLUAAPI void *      (*lua_newuserdata)(lua_State *L, size_t size);\nLUAAPI int         (*lua_pcallk)(lua_State *L, int nargs, int nresults, int errfunc,lua_KContext ctx,lua_KFunction k);\nLUAAPI void        (*lua_pushcclosure)(lua_State *L,lua_CFunction fn, int n);\nLUAAPI void        (*lua_pushinteger)(lua_State *L,lua_Integer n);\nLUAAPI const char *(*lua_pushlstring)(lua_State *L, const char *s, size_t len);\nLUAAPI void        (*lua_pushnumber)(lua_State *L,lua_Number n);\nLUAAPI const char *(*lua_pushstring)(lua_State *L, const char *s);\nLUAAPI void        (*lua_pushvalue )(lua_State *L, int idx);\nLUAAPI int         (*lua_resume)(lua_State *L,lua_State *from, int nargs);\nLUAAPI void        (*lua_setfield)(lua_State *L, int idx, const char *k);\nLUAAPI void        (*lua_setglobal)(lua_State *L, const char *name);\nLUAAPI void        (*lua_seti)(lua_State *L, int idx, lua_Integer n);\nLUAAPI void        (*lua_settop)(lua_State *L, int idx);\nLUAAPI int         (*lua_toboolean)(lua_State *L, int idx);\nLUAAPI lua_Integer (*lua_tointegerx)(lua_State *L, int idx, int *pisnum);\nLUAAPI const char *(*lua_tolstring)(lua_State *L, int idx, size_t *len);\nLUAAPI lua_Number  (*lua_tonumberx)(lua_State *L, int idx, int *pisnum);\nLUAAPI int         (*lua_type)(lua_State *L, int idx);\nLUAAPI const char *(*lua_typename)(lua_State *L, int t);\nLUAAPI const lua_Number *(*lua_version)(lua_State *L);\nLUAAPI void        (*lua_xmove)(lua_State *from,lua_State *to, int n);\nLUAAPI int         (*lua_yieldk)(lua_State *L, int nresults,lua_KContext ctx,lua_KFunction k);\n\nLUAAPI lua_Integer (*luaL_checkinteger)(lua_State *L, int arg);\nLUAAPI const char *(*luaL_checklstring)(lua_State *L, int arg, size_t *len);\nLUAAPI void *      (*luaL_checkudata)(lua_State *L, int ud, const char *tname);\nLUAAPI lua_Integer (*luaL_len)(lua_State *L, int idx);\nLUAAPI int         (*luaL_loadbufferx)(lua_State *L, const char *buff, size_t size, const char *name, const char *mode);\nLUAAPI int         (*luaL_loadfilex)(lua_State *L, const char *filename, const char *mode);\nLUAAPI int         (*luaL_loadstring)(lua_State *L, const char *s);\nLUAAPI int         (*luaL_newmetatable)(lua_State *L, const char *tname);\nLUAAPI lua_State * (*luaL_newstate)(void);\nLUAAPI void        (*luaL_openlibs)(lua_State *L);\nLUAAPI int         (*luaL_ref)(lua_State *L, int t);\nLUAAPI void        (*luaL_setfuncs)(lua_State *L, const luaL_Reg *l, int nup);\nLUAAPI void        (*luaL_setmetatable)(lua_State *L, const char *tname);\nLUAAPI void        (*luaL_unref)(lua_State *L, int t, int ref);\n\n#endif\n\n"
  },
  {
    "path": "src/stub-pcap-dlt.h",
    "content": "#ifndef STUB_PCAP_DLT_H\n#define STUB_PCAP_DLT_H\n\ntypedef enum {\n\t/* Packets are prefixed by an integer indicating\n\t * the protocol type in host-byte-order (4-bytes)\n\t * followed by the raw IPv4 or IPv6 header */\n\tPCAP_DLT_NULL = 0,\n\n\t/* Ethernet */\n\tPCAP_DLT_ETHERNET = 1,\n\n\t/* Packets are 'raw' on the network. The first byte\n\t * will be the first byte of the IPv4/IPv6 header */\n\tPCAP_DLT_RAW = 12,\n} pcap_dlt_t;\n\n#endif\n\n"
  },
  {
    "path": "src/stub-pcap.c",
    "content": "/* Copyright (c) 2007 by Errata Security, All Rights Reserved\n * Copyright (c) 2017 by Robert David Graham\n * Programmer(s): Robert David Graham [rdg]\n */\n/*\n\tLIBPCAP INTERFACE\n \n This VERY MESSY code is a hack to load the 'libpcap' library \n at runtime rather than compile time.\n \n This reason for this mess is that it gets rid of a dependency\n when compiling this project. Otherwise, developers would have\n to download the 'libpcap-dev' dependency in order to build\n this project.\n \n Almost every platform these days (OpenBSD, FreeBSD, macOS,\n Debian, RedHat) comes with a \"libpcap.so\" library already\n installed by default with a known BINARY interface. Thus,\n we can include the data structures definitions directly\n in this project, then load the library dynamically.\n \n For those systems without libpcap.so already installed, the\n user can either install those on the system, or compile\n this project in \"STATIC\" mode, which will link to the \n static libpcap.a library.\n \n*/\n#include \"util-logger.h\"\n\n#if defined(_MSC_VER)\n#pragma warning(disable:4115 4201)\n#pragma warning(disable:4100) /* unreferenced formal parameter */\n//#include <winerror.h>\n#endif\n\n#include \"stub-pcap.h\"\n\n\n#ifdef WIN32\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#else\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n\n#ifndef UNUSEDPARM\n#ifdef __GNUC__\n#define UNUSEDPARM(x)\n#else\n#define UNUSEDPARM(x) x=(x)\n#endif\n#endif\n\nstruct pcap_if {\n    struct pcap_if *next;\n    char *name;\t\t/* name to hand to \"pcap_open_live()\" */\n    char *description;\t/* textual description of interface, or NULL */\n    void  *addresses;\n    unsigned flags;\t/* PCAP_IF_ interface flags */\n};\n\nstatic void seterr(char *errbuf, const char *msg)\n{\n    size_t length = strlen(msg);\n    \n    if (length > PCAP_ERRBUF_SIZE-1)\n    length = PCAP_ERRBUF_SIZE-1;\n    memcpy(errbuf, msg, length);\n    errbuf[length] = '\\0';\n}\n\nstatic void null_PCAP_CLOSE(void *hPcap)\n{\n#ifdef STATICPCAP\n    pcap_close(hPcap);\n    return;\n#endif\n    UNUSEDPARM(hPcap);\n}\n\n#ifdef STATICPCAP\nstatic pcap_t *(*null_PCAP_CREATE)(const char *source, char *errbuf);\nstatic int (*null_PCAP_SET_SNAPLEN)(pcap_t *p, int snaplen);\nstatic int (*null_PCAP_SET_PROMISC)(pcap_t *p, int promisc);\nstatic int (*null_PCAP_SET_TIMEOUT)(pcap_t *p, int to_ms);\nstatic int (*null_PCAP_SET_IMMEDIATE_MODE)(pcap_t *p, int immediate_mode);\nstatic int (*null_PCAP_SET_BUFFER_SIZE)(pcap_t *p, int buffer_size);\nstatic int (*null_PCAP_SET_RFMON)(pcap_t *p, int rfmon);\nstatic int (*null_PCAP_CAN_SET_RFMON)(pcap_t *p);\nstatic int (*null_PCAP_ACTIVATE)(pcap_t *p);\n#else\nstatic pcap_t *null_PCAP_CREATE(const char *source, char *errbuf) {return 0;}\nstatic int null_PCAP_SET_SNAPLEN(pcap_t *p, int snaplen) {return 0;}\nstatic int null_PCAP_SET_PROMISC(pcap_t *p, int promisc) {return 0;}\nstatic int null_PCAP_SET_TIMEOUT(pcap_t *p, int to_ms) {return 0;}\nstatic int null_PCAP_SET_IMMEDIATE_MODE(pcap_t *p, int immediate_mode)  {return 0;}\nstatic int null_PCAP_SET_BUFFER_SIZE(pcap_t *p, int buffer_size) {return 0;}\nstatic int null_PCAP_SET_RFMON(pcap_t *p, int rfmon) {return 0;}\nstatic int null_PCAP_CAN_SET_RFMON(pcap_t *p) {return 0;}\nstatic int null_PCAP_ACTIVATE(pcap_t *p) {return 0;}\n#endif\n\nstatic unsigned null_PCAP_DATALINK(void *hPcap)\n{\n#ifdef STATICPCAP\n    return pcap_datalink(hPcap);\n#endif\n    UNUSEDPARM(hPcap);\n    return 0;\n}\n\n\nstatic unsigned null_PCAP_DISPATCH(void *hPcap, unsigned how_many_packets, PCAP_HANDLE_PACKET handler, void *handle_data)\n{\n#ifdef STATICPCAP\n    return pcap_dispatch(hPcap, how_many_packets, handler, handle_data);\n#endif\n    UNUSEDPARM(hPcap);UNUSEDPARM(how_many_packets);UNUSEDPARM(handler);UNUSEDPARM(handle_data);\n    return 0;\n}\n\n\nstatic int null_PCAP_FINDALLDEVS(pcap_if_t **alldevs, char *errbuf)\n{\n#ifdef STATICPCAP\n    return pcap_findalldevs(alldevs, errbuf);\n#endif\n    *alldevs = 0;\n    seterr(errbuf, \"libpcap not loaded\");\n    return -1;\n}\n\n\nstatic void null_PCAP_FREEALLDEVS(pcap_if_t *alldevs)\n{\n#ifdef STATICPCAP\n    return pcap_freealldevs(alldevs);\n#endif\n    UNUSEDPARM(alldevs);\n    return;\n}\n\n\nstatic char *null_PCAP_LOOKUPDEV(char *errbuf)\n{\n#ifdef STATICPCAP\n    return pcap_lookupdev(errbuf);\n#endif\n    seterr(errbuf, \"libpcap not loaded\");\n    return \"\";\n}\n\n\nstatic void * null_PCAP_OPEN_LIVE(const char *devicename, unsigned snap_length, unsigned is_promiscuous, unsigned read_timeout, char *errbuf)\n{\n#ifdef STATICPCAP\n    return pcap_open_live(devicename, snap_length, is_promiscuous, read_timeout, errbuf);\n#endif\n    seterr(errbuf, \"libpcap not loaded\");\n    UNUSEDPARM(devicename);UNUSEDPARM(snap_length);UNUSEDPARM(is_promiscuous);UNUSEDPARM(read_timeout);\n    return NULL;\n}\n\nstatic int null_PCAP_MAJOR_VERSION(void *p)\n{\n#ifdef STATICPCAP\n    return pcap_major_version(p);\n#endif\n    UNUSEDPARM(p);\n    return 0;\n}\n\n\nstatic int null_PCAP_MINOR_VERSION(void *p)\n{\n#ifdef STATICPCAP\n    return pcap_minor_version(p);\n#endif\n    UNUSEDPARM(p);\n    return 0;\n}\n\nstatic const char *null_PCAP_LIB_VERSION(void)\n{\n#ifdef STATICPCAP\n    return pcap_lib_version();\n#endif\n    \n    return \"stub/0.0\";\n}\n\n\n\n\n\nstruct PcapFunctions PCAP = {\n    0,0,0,0,0,\n    null_PCAP_CLOSE,\n};\n\n\nstatic void *my_null(int x, ...)\n{\n\tUNUSEDPARM(x);\n    printf(\"%.*s\", 0, \"a\"); /* Remove warnings about no effects */\n    return 0;\n}\nstatic pcap_t *null_PCAP_OPEN_OFFLINE(const char *fname, char *errbuf)\n{\n#ifdef STATICPCAP\n    return pcap_open_offline(fname, errbuf);\n#endif\n    return my_null(2, fname, errbuf);\n}\nstatic int null_PCAP_SENDPACKET(pcap_t *p, const unsigned char *buf, int size)\n{\n#ifdef STATICPCAP\n    return pcap_sendpacket(p, buf, size);\n#endif\n    my_null(3, p, buf, size);\n\treturn 0;\n}\n\nstatic const unsigned char *null_PCAP_NEXT(pcap_t *p, struct pcap_pkthdr *h)\n{\n#ifdef STATICPCAP\n    return pcap_next(p, h);\n#endif\n    my_null(3, p, h);\n    return 0;\n}\nstatic int null_PCAP_SETDIRECTION(pcap_t *p, pcap_direction_t d)\n{\n#ifdef STATICPCAP\n    return pcap_setdirection(p, d);\n#endif\n\tmy_null(2, p, d);\n    return 0;\n}\nstatic const char *null_PCAP_DATALINK_VAL_TO_NAME(int dlt)\n{\n#ifdef STATICPCAP\n    return pcap_datalink_val_to_name(dlt);\n#endif\n\tmy_null(1, dlt);\n    return 0;\n}\nstatic void null_PCAP_PERROR(pcap_t *p, char *prefix)\n{\n#ifdef STATICPCAP\n    pcap_perror(p, prefix);\n    return;\n#endif\n\tUNUSEDPARM(p);\n\tfprintf(stderr, \"%s\\n\", prefix);\n    perror(\"pcap\");\n}\nstatic const char*null_PCAP_GETERR(pcap_t *p)\n{\n#ifdef STATICPCAP\n    return pcap_geterr(p);\n#endif\n\tUNUSEDPARM(p);\n\treturn \"(unknown)\";\n}\nstatic const char *null_PCAP_DEV_NAME(const pcap_if_t *dev)\n{\n    return dev->name;\n}\nstatic const char *null_PCAP_DEV_DESCRIPTION(const pcap_if_t *dev)\n{\n    return dev->description;\n}\nstatic const pcap_if_t *null_PCAP_DEV_NEXT(const pcap_if_t *dev)\n{\n    return dev->next;\n}\n\n/*\n * Some Windows-specific functions to improve speed\n */\n#if defined(WIN32)\nstatic pcap_send_queue *null_PCAP_SENDQUEUE_ALLOC(size_t size)\n{\n\tUNUSEDPARM(size);\n\treturn 0;\n}\nstatic unsigned null_PCAP_SENDQUEUE_TRANSMIT(pcap_t *p, pcap_send_queue *queue, int sync)\n{\n\tmy_null(3, p, queue, sync);\n\treturn 0;\n}\nstatic void null_PCAP_SENDQUEUE_DESTROY(pcap_send_queue *queue) \n{\n\tmy_null(1, queue);\n\tUNUSEDPARM(queue);\n}\nstatic int null_PCAP_SENDQUEUE_QUEUE(pcap_send_queue *queue,\n    const struct pcap_pkthdr *pkt_header,\n    const unsigned char *pkt_data)\n{\n\tmy_null(4, queue, pkt_header, pkt_data);\n\treturn 0;\n}\n#endif /*WIN32*/\n\n\n/**\n * Runtime-load the libpcap shared-object or the winpcap DLL. We\n * load at runtime rather than loadtime to allow this program to\n * be used to process offline content, and to provide more helpful\n * messages to people who don't realize they need to install PCAP.\n */\nint pcap_init(void)\n{\n    struct PcapFunctions *pl = &PCAP;\n#ifdef WIN32\n    void * hPacket;\n    void * hLibpcap;\n    \n    pl->is_available = 0;\n    pl->is_printing_debug = 1;\n    \n    /* Look for the Packet.dll */\n    hPacket = LoadLibraryA(\"NPcap\\\\Packet.dll\");\n    if (hPacket == NULL)\n        hPacket = LoadLibraryA(\"Packet.dll\");\n    if (hPacket == NULL) {\n        if (pl->is_printing_debug)\n        switch (GetLastError()) {\n            case ERROR_MOD_NOT_FOUND:\n                fprintf(stderr, \"%s: not found\\n\", \"Packet.dll\");\n                fprintf(stderr, \"  HINT: you must install either WinPcap or Npcap\\n\");\n                return -1;\n            default:\n                fprintf(stderr, \"%s: couldn't load %d\\n\", \"Packet.dll\", (int)GetLastError());\n                return -1;\n        }\n    }\n    \n    /* Look for the winpcap.dll */\n    hLibpcap = LoadLibraryA(\"Npcap\\\\wpcap.dll\");\n    if (hLibpcap == NULL)\n        hLibpcap = LoadLibraryA(\"wpcap.dll\");\n    if (hLibpcap == NULL) {\n        if (pl->is_printing_debug)\n            fprintf(stderr, \"%s: couldn't load %d\\n\", \"wpcap.dll\", (int)GetLastError());\n        return -1;\n    }\n    \n    \n#define DOLINK(PCAP_DATALINK, datalink) \\\npl->datalink = (PCAP_DATALINK)GetProcAddress(hLibpcap, \"pcap_\"#datalink); \\\nif (pl->datalink == NULL) pl->func_err=1, pl->datalink = null_##PCAP_DATALINK;\n#endif\n    \n    \n#ifndef WIN32\n#ifndef STATICPCAP\n    void *hLibpcap;\n    \n    pl->is_available = 0;\n    pl->is_printing_debug = 1;\n    \n    {\n        static const char *possible_names[] = {\n            \"libpcap.so\",\n            \"libpcap.A.dylib\",\n            \"libpcap.dylib\",\n            \"libpcap.so.1\",\n            \"libpcap.so.0.9.5\",\n            \"libpcap.so.0.9.4\",\n            \"libpcap.so.0.8\",\n            0\n        };\n        unsigned i;\n        for (i=0; possible_names[i]; i++) {\n            hLibpcap = dlopen(possible_names[i], RTLD_LAZY);\n            if (hLibpcap) {\n                LOG(1, \"[+] pcap: found library: %s\\n\", possible_names[i]);\n                break;\n            } else {\n                LOG(1, \"[-] pcap: failed to load: %s\\n\", possible_names[i]);\n            }\n        }\n     \n        if (hLibpcap == NULL) {\n            LOG(0, \"[-] FAIL: failed to load libpcap shared library\\n\");\n            LOG(0, \"    [hint]: you must install libpcap or WinPcap\\n\");\n        }\n    }\n    \n#define DOLINK(PCAP_DATALINK, datalink) \\\npl->datalink = (PCAP_DATALINK)dlsym(hLibpcap, \"pcap_\"#datalink); \\\n    if (pl->datalink == NULL) LOG(1, \"pcap: pcap_%s: failed\\n\", #datalink); \\\n    if (pl->datalink == NULL) pl->func_err=1, pl->datalink = null_##PCAP_DATALINK;\n#else\n#define DOLINK(PCAP_DATALINK, datalink) \\\npl->func_err=0, pl->datalink = null_##PCAP_DATALINK;\n#endif\n#endif\n    \n    DOLINK(PCAP_CLOSE\t\t\t, close);\n    DOLINK(PCAP_DATALINK\t\t, datalink);\n    DOLINK(PCAP_DISPATCH\t\t, dispatch);\n    DOLINK(PCAP_FINDALLDEVS\t\t, findalldevs);\n    DOLINK(PCAP_FREEALLDEVS\t\t, freealldevs);\n    DOLINK(PCAP_LIB_VERSION\t\t, lib_version);\n    DOLINK(PCAP_LOOKUPDEV\t\t, lookupdev);\n    DOLINK(PCAP_MAJOR_VERSION\t, major_version);\n    DOLINK(PCAP_MINOR_VERSION\t, minor_version);\n    DOLINK(PCAP_OPEN_LIVE\t\t, open_live);\n    \n    DOLINK(PCAP_OPEN_OFFLINE    , open_offline);\n    DOLINK(PCAP_SENDPACKET      , sendpacket);\n    DOLINK(PCAP_NEXT            , next);\n    DOLINK(PCAP_SETDIRECTION    , setdirection);\n    DOLINK(PCAP_DATALINK_VAL_TO_NAME , datalink_val_to_name);\n    DOLINK(PCAP_PERROR          , perror);\n    DOLINK(PCAP_GETERR          , geterr);\n\n\n    /* pseudo functions that don't exist in the libpcap interface */\n    pl->dev_name = null_PCAP_DEV_NAME;\n    pl->dev_description = null_PCAP_DEV_DESCRIPTION;\n    pl->dev_next = null_PCAP_DEV_NEXT;\n\n    /* windows-only functions that might improve speed */\n#if defined(WIN32)\n\tDOLINK(PCAP_SENDQUEUE_ALLOC\t\t, sendqueue_alloc);\n\tDOLINK(PCAP_SENDQUEUE_TRANSMIT\t, sendqueue_transmit);\n\tDOLINK(PCAP_SENDQUEUE_DESTROY\t, sendqueue_destroy);\n\tDOLINK(PCAP_SENDQUEUE_QUEUE\t\t, sendqueue_queue);\n#endif\n\n    DOLINK(PCAP_CREATE              , create);\n    DOLINK(PCAP_SET_SNAPLEN         , set_snaplen);\n    DOLINK(PCAP_SET_PROMISC         , set_promisc);\n    DOLINK(PCAP_SET_TIMEOUT         , set_timeout);\n    DOLINK(PCAP_SET_IMMEDIATE_MODE  , set_immediate_mode);\n    DOLINK(PCAP_SET_BUFFER_SIZE     , set_buffer_size);\n    DOLINK(PCAP_SET_RFMON           , set_rfmon);\n    DOLINK(PCAP_CAN_SET_RFMON       , can_set_rfmon);\n    DOLINK(PCAP_ACTIVATE            , activate);\n\n    \n    if (!pl->func_err)\n        pl->is_available = 1;\n    else\n        pl->is_available = 0;\n    \n    return 0;\n}\n\n"
  },
  {
    "path": "src/stub-pcap.h",
    "content": "/*\n    Dynamically load libpcap at runtime\n \n This library optionally loads the 'libpcap' library at runtime, rather\n than statically linked at compile time. The advantage of this is that\n the user can build this project with no dependencies -- although they\n may require this dependency in order to run the program.\n \n As of 2017, libpcap shared libraries are standard on major Linux\n distributions (Debian, Readhat), FreeBSD, OpenBSD, and macOS. On\n Windows, \"winpcap\" must be downloaded. \n*/\n#ifndef STUB_PCAP_H\n#define STUB_PCAP_H\n#include <stdio.h>\n\n\n\n/* Including the right \".h\" file to define \"timeval\" is difficult, so instead\n * so instead we are simply going to define our own structure. This should\n * match the binary definition within the operating system\n */\n#if __NetBSD__\n#include <sys/time.h>\n#define pcap_timeval timeval\n#elif __OpenBSD__\n#include <net/bpf.h>\n#define pcap_timeval bpf_timeval\n#else\nstruct pcap_timeval {\n        long    tv_sec;         /* seconds */\n        long    tv_usec;        /* and microseconds */\n};\n#endif\n\n/* Forward reference of opaque 'pcap_t' structure */\nstruct pcap;\ntypedef struct pcap pcap_t;\n\n/* Forward reference of opaque 'pcap_if_t' structure */\nstruct pcap_if;\ntypedef struct pcap_if pcap_if_t;\n\n/* How many bytes to reserve for error messages. This is the number specified\n * in libpcap, smaller numbers can crash */\nenum {\n    PCAP_ERRBUF_SIZE=256,\n};\n\n/* used in pcap_setdirection() */\ntypedef enum {\n    PCAP_D_INOUT    = 0,\n    PCAP_D_IN       = 1,\n    PCAP_D_OUT      = 2,\n} pcap_direction_t;\n\nenum {\n    PCAP_ERROR                          =  -1,\n    PCAP_ERROR_BREAK                    =  -2,\n    PCAP_ERROR_NOT_ACTIVATED            =  -3,\n    PCAP_ERROR_ACTIVATED                =  -4,\n    PCAP_ERROR_NO_SUCH_DEVICE           =  -5,\n    PCAP_ERROR_RFMON_NOTSUP             =  -6,\n    PCAP_ERROR_NOT_RFMON                =  -7,\n    PCAP_ERROR_PERM_DENIED              =  -8,\n    PCAP_ERROR_IFACE_NOT_UP             =  -9,\n    PCAP_ERROR_CANTSET_TSTAMP_TYPE      = -10,\n    PCAP_ERROR_PROMISC_PERM_DENIED      = -11,\n    PCAP_ERROR_TSTAMP_PRECISION_NOTSUP  = -12, \n\n    /* warnings, not errors */\n    PCAP_WARNING                        =   1,\n    PCAP_WARNING_PROMISC_NOTSUP         =   2,\n    PCAP_WARNING_TSTAMP_TYPE_NOTSUP     =   3,\n};\n\n/* The packet header for capturing packets. Apple macOS inexplicably adds\n * an extra comment-field onto the end of this, so the definition needs\n * to be careful to match the real definition */\nstruct pcap_pkthdr {\n    struct pcap_timeval ts;\n    unsigned caplen;\n    unsigned len;\n#ifdef __APPLE__\n    char comment[256];\n#endif\n};\n\n\n/*\n * This block is for function declarations. Consult the libpcap\n * documentation for what these functions really mean\n */\ntypedef void        (*PCAP_HANDLE_PACKET)(unsigned char *v_seap, const struct pcap_pkthdr *framehdr, const unsigned char *buf);\ntypedef void        (*PCAP_CLOSE)(void *hPcap);\ntypedef unsigned    (*PCAP_DATALINK)(void *hPcap);\ntypedef unsigned    (*PCAP_DISPATCH)(void *hPcap, unsigned how_many_packets, PCAP_HANDLE_PACKET handler, void *handle_data);\ntypedef int         (*PCAP_FINDALLDEVS)(pcap_if_t **alldevs, char *errbuf);\ntypedef const char *(*PCAP_LIB_VERSION)(void);\ntypedef char *      (*PCAP_LOOKUPDEV)(char *errbuf);\ntypedef int         (*PCAP_MAJOR_VERSION)(void *p);\ntypedef int         (*PCAP_MINOR_VERSION)(void *p);\ntypedef void *      (*PCAP_OPEN_LIVE)(const char *devicename, unsigned snap_length, unsigned is_promiscuous, unsigned read_timeout, char *errbuf);\ntypedef void        (*PCAP_FREEALLDEVS)(pcap_if_t *alldevs);\ntypedef pcap_t *    (*PCAP_OPEN_OFFLINE)(const char *fname, char *errbuf);\ntypedef int         (*PCAP_SENDPACKET)(pcap_t *p, const unsigned char *buf, int size);\ntypedef const unsigned char *(*PCAP_NEXT)(pcap_t *p, struct pcap_pkthdr *h);\ntypedef int         (*PCAP_SETDIRECTION)(pcap_t *, pcap_direction_t);\ntypedef const char *(*PCAP_DATALINK_VAL_TO_NAME)(int dlt);\ntypedef void        (*PCAP_PERROR)(pcap_t *p, char *prefix);\ntypedef const char *(*PCAP_GETERR)(pcap_t *p);\ntypedef const char *(*PCAP_DEV_NAME)(const pcap_if_t *dev);\ntypedef const char *(*PCAP_DEV_DESCRIPTION)(const pcap_if_t *dev);\ntypedef const pcap_if_t *(*PCAP_DEV_NEXT)(const pcap_if_t *dev);\n\n/*\n pcap_open() replaced with a series of calls to:\n  p = pcap_create(device, errbuf);\n  pcap_set_snaplen(p, snaplen);\n  pcap_set_promisc(p, promisc);\n  pcap_set_timeout(p, to_ms);\n  pcap_activate(p);\n */\ntypedef pcap_t *(*PCAP_CREATE)(const char *source, char *errbuf);\ntypedef int (*PCAP_SET_SNAPLEN)(pcap_t *p, int snaplen);\ntypedef int (*PCAP_SET_PROMISC)(pcap_t *p, int promisc);\ntypedef int (*PCAP_SET_TIMEOUT)(pcap_t *p, int to_ms);\ntypedef int (*PCAP_SET_IMMEDIATE_MODE)(pcap_t *p, int immediate_mode);\ntypedef int (*PCAP_SET_BUFFER_SIZE)(pcap_t *p, int buffer_size);\ntypedef int (*PCAP_SET_RFMON)(pcap_t *p, int rfmon);\ntypedef int (*PCAP_CAN_SET_RFMON)(pcap_t *p);\ntypedef int (*PCAP_ACTIVATE)(pcap_t *p);\n\n\n\n/*\n * PORTABILITY: Windows supports the \"sendq\" feature, and is really slow\n * without this feature. It's not needed on Linux, so we just create\n * equivalent functions that do nothing\n */\nstruct pcap_send_queue;\ntypedef struct pcap_send_queue pcap_send_queue;\n\ntypedef pcap_send_queue *(*PCAP_SENDQUEUE_ALLOC)(size_t size);\ntypedef unsigned (*PCAP_SENDQUEUE_TRANSMIT)(pcap_t *p, pcap_send_queue *queue, int sync);\ntypedef void (*PCAP_SENDQUEUE_DESTROY)(pcap_send_queue *queue);\ntypedef int (*PCAP_SENDQUEUE_QUEUE)(pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const unsigned char *pkt_data);\n\n\n\n\n\nstruct PcapFunctions {\n    unsigned func_err:1;\n    unsigned is_available:1;\n    unsigned is_printing_debug:1;\n    unsigned status;\n    unsigned errcode;\n    \n    PCAP_CLOSE              close;\n    PCAP_DATALINK           datalink;\n    PCAP_DISPATCH           dispatch;\n    PCAP_FINDALLDEVS        findalldevs;\n    PCAP_FREEALLDEVS        freealldevs;\n    PCAP_LOOKUPDEV          lookupdev;\n    PCAP_LIB_VERSION        lib_version;\n    PCAP_MAJOR_VERSION      major_version;\n    PCAP_MINOR_VERSION      minor_version;\n    PCAP_OPEN_LIVE          open_live;\n    \n    \n    PCAP_OPEN_OFFLINE       open_offline;\n    PCAP_SENDPACKET         sendpacket;\n    PCAP_NEXT               next;\n    PCAP_SETDIRECTION       setdirection;\n    PCAP_DATALINK_VAL_TO_NAME datalink_val_to_name;\n    PCAP_PERROR             perror;\n    PCAP_GETERR             geterr;\n    \n    /* Accessor functions for opaque data structure, don't really\n     * exist in libpcap */\n    PCAP_DEV_NAME           dev_name;\n    PCAP_DEV_DESCRIPTION    dev_description;\n    PCAP_DEV_NEXT           dev_next;\n\n    /* Windows-only functions */\n\tPCAP_SENDQUEUE_ALLOC\tsendqueue_alloc;\n\tPCAP_SENDQUEUE_TRANSMIT\tsendqueue_transmit;\n\tPCAP_SENDQUEUE_DESTROY\tsendqueue_destroy;\n\tPCAP_SENDQUEUE_QUEUE\tsendqueue_queue;\n\n    PCAP_CREATE              create;\n    PCAP_SET_SNAPLEN         set_snaplen;\n    PCAP_SET_PROMISC         set_promisc;\n    PCAP_SET_TIMEOUT         set_timeout;\n    PCAP_SET_IMMEDIATE_MODE  set_immediate_mode;\n    PCAP_SET_BUFFER_SIZE     set_buffer_size;\n    PCAP_SET_RFMON           set_rfmon;\n    PCAP_CAN_SET_RFMON       can_set_rfmon;\n    PCAP_ACTIVATE            activate;\n\n};\n\n/**\n * This is global structure containing all the libpcap function pointers.\n * use in the form \"PCAP.functionname()\" rather than \"pcap_functioname()\".\n */\nextern struct PcapFunctions PCAP;\n\n/**\n * Dynamically loads the shared library (libpcap.so, libpcap.dynlib,\n * or libpcap.dll. Call this during program startup like main() in order\n * to load the libraries. Not thread safe, so call from the startup\n * thread, but not within threads.\n * @return\n *  0 on success or\n *  -1 on failure\n */\nint pcap_init(void);\n\n\n#endif\n"
  },
  {
    "path": "src/stub-pfring.c",
    "content": "/*\n    PF_RING compatibility layer\n\n    In order to avoid special build hassle, this code links to PF_RING at\n    runtime instead compile-time. That means you can compile this code\n    BEFORE installing and building PF_RING.\n\n*/\n#include \"stub-pfring.h\"\n#include \"util-safefunc.h\"\n#include \"util-logger.h\"\n\nstruct PFRING PFRING;\n\n#if defined(__linux__)\n#include <dlfcn.h>\n#endif\n\n/***************************************************************************\n * This checks whether the \"pf_ring\" driver is installed.\n ***************************************************************************/\nint\nPFRING_is_installed(void);\n\nint\nPFRING_is_installed(void)\n{\n#if defined(__linux__)\n    FILE *fp;\n    char line[256];\n    int found = 0;\n\n    fp = fopen(\"/proc/modules\", \"rb\");\n    if (fp == NULL)\n        return 0;\n\n    while (fgets(line, sizeof(line), fp)) {\n        if (memcmp(line, \"pf_ring \", 8) == 0) {\n            found = 1;\n            LOG(2, \"pfring: found 'pf_ring' driver\\n\");\n        }\n        if (memcmp(line, \"ixgbe \", 6) == 0) {\n            LOG(2, \"pfring: found 'ixgbe' driver\\n\");\n        }\n        if (memcmp(line, \"e1000e \", 8) == 0) {\n            LOG(2, \"pfring: found 'e1000e' driver\\n\");\n        }\n    }\n    fclose(fp);\n    return found;\n#else\n    return 0;\n#endif\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nPFRING_init(void)\n{\n#if defined(__linux__)\n    void *h;\n    int err = 0;\n    LOG(6, \"pfring: initializing subsystem\\n\");\n    LOG(6, \"pfring: looking for 'libpfring.so'\\n\");\n    h = dlopen(\"libpfring.so\", RTLD_LAZY);\n    if (h == NULL) {\n        LOG(2, \"pfring: error: dlopen('libpfring.so'): %s\\n\", strerror(errno));\n        return 0;\n    } else\n        LOG(2, \"pfring: found 'libpfring.so'!\\n\");\n\n#define LOADSYM(name) if ((PFRING.name = dlsym(h, \"pfring_\"#name)) == 0) {LOG(2, \"pfring_%s: not found in 'libpfring.so': %s\\n\", #name, strerror(errno));err=1;}\n    LOADSYM(open);\n    LOADSYM(close);\n    LOADSYM(enable_ring);\n    LOADSYM(send);\n    LOADSYM(recv);\n    LOADSYM(poll);\n    LOADSYM(version);\n    LOADSYM(set_direction);\n    LOADSYM(set_application_name);\n    //LOADSYM(get_bound_device);\n\n    if (err) {\n        memset(&PFRING, 0, sizeof(PFRING));\n        LOG(2, \"pfring: failed to load\\n\");\n    } else {\n        LOG(2, \"pfring: successfully loaded PF_RING API\\n\");\n\n        if (!PFRING_is_installed()) {\n            LOG(0, \"pfring: ERROR: 'pf_ring' driver module not found!!!!!\\n\");\n        } else\n            LOG(2, \"pfring: found 'pf_ring' driver module\\n\");\n    }\n\n#endif\n    return 0;\n}\n\n\n\n\n\n"
  },
  {
    "path": "src/stub-pfring.h",
    "content": "#ifndef RAWSOCK_PFRING_H\n#define RAWSOCK_PFRING_H\n#include <stdint.h>\n#include <time.h>\n\n/*\n * Various PF_RING defines\n */\nstruct __pfring;\ntypedef struct __pfring pfring;\n\ntypedef enum {\n  rx_and_tx_direction = 0,\n  rx_only_direction,\n  tx_only_direction\n} packet_direction;\nstruct pfring_pkthdr {\n  struct xtimeval {\n        long    tv_sec;\n        long    tv_usec;\n  } ts;\n  unsigned caplen;\n  unsigned len;\n  /* only filled in if PF_RING_LONG_HEADER set */\n  unsigned char extended_hdr[512];\n};\n#define PF_RING_ERROR_GENERIC              -1\n#define PF_RING_ERROR_INVALID_ARGUMENT     -2\n#define PF_RING_ERROR_NO_PKT_AVAILABLE     -3\n#define PF_RING_ERROR_NO_TX_SLOT_AVAILABLE -4\n#define PF_RING_ERROR_WRONG_CONFIGURATION  -5\n#define PF_RING_ERROR_END_OF_DEMO_MODE     -6\n#define PF_RING_ERROR_NOT_SUPPORTED        -7\n#define PF_RING_ERROR_INVALID_LIB_VERSION  -8\n#define PF_RING_ERROR_UNKNOWN_ADAPTER      -9\n#define PF_RING_ERROR_NOT_ENOUGH_MEMORY   -10\n#define PF_RING_ERROR_INVALID_STATUS      -11\n#define PF_RING_DNA_SYMMETRIC_RSS    1 << 0\n#define PF_RING_REENTRANT            1 << 1\n#define PF_RING_LONG_HEADER          1 << 2\n#define PF_RING_PROMISC              1 << 3\n#define PF_RING_TIMESTAMP            1 << 4\n#define PF_RING_HW_TIMESTAMP         1 << 5\n#define PF_RING_RX_PACKET_BOUNCE     1 << 6\n#define PF_RING_DNA_FIXED_RSS_Q_0    1 << 7\n#define PF_RING_STRIP_HW_TIMESTAMP   1 << 8\n#define PF_RING_DO_NOT_PARSE         1 << 9  /* parsing already disabled in zero-copy */\n#define PF_RING_DO_NOT_TIMESTAMP     1 << 10 /* sw timestamp already disabled in zero-copy */\n\n/*\n * function prototypes\n */\ntypedef pfring*(*PFRING_OPEN)(\n                    const char *device_name,\n                    unsigned caplen,\n                    unsigned flags);\ntypedef void (*PFRING_CLOSE)(pfring *ring);\ntypedef int (*PFRING_ENABLE_RING)(pfring *ring);\ntypedef int (*PFRING_SEND)( pfring *ring,\n                    const unsigned char *buffer,\n                    unsigned buffer_length,\n                    unsigned char flush_packet);\ntypedef int (*PFRING_RECV)(    pfring *ring,\n                    unsigned char** buffer,\n                    unsigned buffer_length,\n                    struct pfring_pkthdr *hdr,\n                    unsigned char wait_for_incoming_packet);\ntypedef int (*PFRING_POLL)(pfring *ring, unsigned wait_duration);\ntypedef int (*PFRING_VERSION)(pfring *ring, unsigned *version);\ntypedef int (*PFRING_SET_DIRECTION)(pfring *ring, int direction);\ntypedef int (*PFRING_SET_APPLICATION_NAME)(pfring *ring, char *name);\ntypedef int (*PFRING_GET_BOUND_DEVICE)(pfring *ring, unsigned char mac_address[6]);\n\n/*\n * scoped object\n */\nextern struct PFRING {\n    PFRING_OPEN                     open;\n    PFRING_CLOSE                    close;\n    PFRING_ENABLE_RING              enable_ring;\n    PFRING_SEND                     send;\n    PFRING_RECV                     recv;\n    PFRING_POLL                     poll;\n    PFRING_VERSION                  version;\n    PFRING_SET_DIRECTION            set_direction;\n    PFRING_SET_APPLICATION_NAME     set_application_name;\n    PFRING_GET_BOUND_DEVICE         get_bound_device;\n} PFRING;\n\n/*\n * call this to load the library\n */\nint PFRING_init(void);\n\n#endif\n"
  },
  {
    "path": "src/syn-cookie.c",
    "content": "#include \"syn-cookie.h\"\n#include \"pixie-timer.h\"\n#include \"util-safefunc.h\"\n#include \"crypto-siphash24.h\"\n#include <assert.h>\n#include <time.h>\n#include <stdarg.h>\n\n#if defined(_MSC_VER)\n#include <intrin.h>\n#endif\n\n/***************************************************************************\n * Go gather some entropy (aka. randmoness) to seed hashing with.\n *\n * NOTE: Mostly it's here to amuse cryptographers with its lulz.\n ***************************************************************************/\nuint64_t\nget_entropy(void)\n{\n    uint64_t entropy[2] = {0,0};\n    unsigned i;\n\n    /*\n     * Gather some random bits\n     */\n    for (i=0; i<64; i++) {\n        FILE *fp;\n        entropy[0] += pixie_nanotime();\n#if defined(_MSC_VER)\n        entropy[0] ^= __rdtsc();\n#endif\n        time(0);\n        fp = fopen(\"/\", \"r\");\n        entropy[1] <<= 1;\n        entropy[1] |= entropy[0]>>63;\n        entropy[0] <<= 1;\n        if (fp) {\n            fclose(fp);\n        }\n    }\n\n    entropy[0] ^= time(0);\n\n    /* Always try to open this file, even on platforms like Windows\n     * where it's not going to exist. */\n    {\n        FILE *fp;\n\n        fp = fopen(\"/dev/urandom\", \"r\");\n        if (fp) {\n            size_t x;\n            uint64_t urand = 0;\n            x = fread(&urand, 1, sizeof(urand), fp);\n            entropy[0] ^= urand;\n            entropy[0] ^= x;\n            x = fread(&urand, 1, sizeof(urand), fp);\n            entropy[1] ^= urand;\n            entropy[1] ^= x;\n            fclose(fp);\n        }\n        entropy[0] ^= pixie_nanotime();\n    }\n\n    return entropy[0] ^ entropy[1];\n}\n\n#if 0\n/***************************************************************************\n * This implements the \"murmur\" hash function.\n ***************************************************************************/\nstatic unsigned\nmurmur(uint64_t entropy, ...)\n{\n    /* reference:\n     * http://en.wikipedia.org/wiki/MurmurHash\n     */\n    static const unsigned c1 = 0xcc9e2d51;\n    static const unsigned c2 = 0x1b873593;\n    unsigned r1 = 15;\n    unsigned r2 = 13;\n    unsigned m = 5;\n    unsigned n = 0xe6546b64;\n    va_list key;\n    unsigned len;\n\n    unsigned hash = (unsigned)entropy;\n\n    va_start(key, entropy);\n\n    for (len=0; len<2; len++) {\n        unsigned k = va_arg(key, unsigned);\n        k = k * c1;\n        k = (k << r1) | (k >> (32-r1));\n        k = k * c2;\n\n        hash = hash ^ k;\n        hash = (hash << r2) | (hash >> (32-r2));\n        hash = hash * m + n;\n    }\n\n    hash = hash ^ (len*4);\n\n    hash = hash ^ (hash >> 16);\n    hash = hash * 0x85ebca6b;\n    hash = hash ^ (hash >> 13);\n    hash = hash * 0xc2b2ae35;\n    hash = hash ^ (hash >> 16);\n\n    return hash;\n}\n#endif\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nsyn_cookie( ipaddress ip_them, unsigned port_them,\n            ipaddress ip_me, unsigned port_me,\n            uint64_t entropy)\n{\n    switch (ip_them.version) {\n    case 4:\n        return syn_cookie_ipv4(ip_them.ipv4, port_them, ip_me.ipv4, port_me, entropy);\n    case 6:\n        return syn_cookie_ipv6(ip_them.ipv6, port_them, ip_me.ipv6, port_me, entropy);\n    default:\n        assert(!\"unknown ip version\");\n        return 0;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nsyn_cookie_ipv4( unsigned ip_them, unsigned port_them,\n            unsigned ip_me, unsigned port_me,\n            uint64_t entropy)\n{\n    unsigned data[4];\n    uint64_t x[2];\n\n    x[0] = entropy;\n    x[1] = entropy;\n\n    data[0] = ip_them;\n    data[1] = port_them;\n    data[2] = ip_me;\n    data[3] = port_me;\n    return siphash24(data, sizeof(data), x);\n}\n\n/***************************************************************************\n ***************************************************************************/\nuint64_t\nsyn_cookie_ipv6( ipv6address ip_them, unsigned port_them,\n            ipv6address ip_me, unsigned port_me,\n            uint64_t entropy)\n{\n    uint64_t data[5];\n    uint64_t x[2];\n\n    x[0] = entropy;\n    x[1] = entropy;\n\n    data[0] = ip_them.hi;\n    data[1] = ip_them.lo;\n    data[2] = ip_me.hi;\n    data[3] = ip_me.lo;\n    data[4] = port_them<<16ULL | port_me;\n    return siphash24(data, sizeof(data), x);\n}\n"
  },
  {
    "path": "src/syn-cookie.h",
    "content": "#ifndef SYN_COOKIE_H\n#define SYN_COOKIE_H\n#include <stdint.h>\n#include \"massip-addr.h\"\n\n/**\n * Create a hash of the src/dst IP/port combination. This allows us to match\n * incoming responses with their original requests\n */\nuint64_t\nsyn_cookie_ipv4( unsigned ip_dst, unsigned port_dst,\n            unsigned ip_src, unsigned port_src,\n            uint64_t entropy);\n\nuint64_t\nsyn_cookie( ipaddress ip_dst, unsigned port_dst,\n            ipaddress ip_src, unsigned port_src,\n            uint64_t entropy);\n\nuint64_t\nsyn_cookie_ipv6( ipv6address ip_dst, unsigned port_dst,\n            ipv6address ip_src, unsigned port_src,\n            uint64_t entropy);\n\n\n/**\n * Called on startup to set a secret key\n */\nuint64_t get_entropy(void);\n\n\n#endif\n"
  },
  {
    "path": "src/templ-nmap-payloads.c",
    "content": "#include \"templ-nmap-payloads.h\"\n#include \"massip-port.h\"\n#include \"massip-rangesv4.h\"\n#include <string.h>\n#include <ctype.h>\n#include <stdlib.h>\n\n\n/***************************************************************************\n * remove leading/trailing whitespace\n ***************************************************************************/\nstatic void\ntrim(char *line, size_t sizeof_line)\n{\n    if (sizeof_line > strlen(line))\n        sizeof_line = strlen(line);\n\n    while (isspace(*line & 0xFF))\n        memmove(line, line+1, sizeof_line--);\n    while (isspace(line[sizeof_line-1] & 0xFF))\n        line[--sizeof_line] = '\\0';\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nis_comment(const char *line)\n{\n    if (line[0] == '#' || line[0] == '/' || line[0] == ';')\n        return 1;\n    else\n        return 0;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic char *\nget_next_line(FILE *fp, unsigned *line_number, char *line, size_t sizeof_line)\n{\n    if (line[0] != '\\0')\n        return line;\n\n    for (;;) {\n        char *p;\n\n        p = fgets(line, (unsigned)sizeof_line, fp);\n        if (p == NULL) {\n            line[0] = '\\0';\n            return NULL;\n        }\n        (*line_number)++;\n\n        trim(line, sizeof_line);\n        if (is_comment(line))\n            continue;\n        if (line[0] == '\\0')\n            continue;\n\n        return line;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nappend_byte(unsigned char *buf, size_t *buf_length, size_t buf_max, unsigned c)\n{\n    if (*buf_length < buf_max)\n        buf[(*buf_length)++] = (unsigned char)c;\n\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\nisodigit(int c)\n{\n    if ('0' <= c && c <= '7')\n        return 1;\n    else\n        return 0;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nhexval(unsigned c)\n{\n    if ('0' <= c && c <= '9')\n        return c - '0';\n    if ('a' <= c && c <= 'f')\n        return c - 'a' + 10;\n    if ('A' <= c && c <= 'F')\n        return c - 'A' + 10;\n    return 0;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic const char *\nparse_c_string(unsigned char *buf, size_t *buf_length,\n               size_t buf_max, const char *line)\n{\n    size_t offset;\n\n    if (*line != '\\\"')\n        return line;\n    else\n        offset = 1;\n\n    while (line[offset] && line[offset] != '\\\"') {\n        if (line[offset] == '\\\\') {\n            offset++;\n            switch (line[offset]) {\n                case '0': case '1': case '2': case '3': case '4':\n                case '5': case '6': case '7': case '8': case '9':\n                {\n                    unsigned val = 0;\n\n                    if (isodigit(line[offset]))\n                        val = val * 8 + hexval(line[offset++]);\n                    if (isodigit(line[offset]))\n                        val = val * 8 + hexval(line[offset++]);\n                    if (isodigit(line[offset]))\n                        val = val * 8 + hexval(line[offset++]);\n                    append_byte(buf, buf_length, buf_max, val);\n                    continue;\n                }\n                    break;\n                case 'x':\n                    offset++;\n                {\n                    unsigned val = 0;\n\n                    if (isxdigit(line[offset]))\n                        val = val * 16 + hexval(line[offset++]);\n                    if (isxdigit(line[offset]))\n                        val = val * 16 + hexval(line[offset++]);\n                    append_byte(buf, buf_length, buf_max, val);\n                    continue;\n                }\n                    break;\n\n                case 'a':\n                    append_byte(buf, buf_length, buf_max, '\\a');\n                    break;\n                case 'b':\n                    append_byte(buf, buf_length, buf_max, '\\b');\n                    break;\n                case 'f':\n                    append_byte(buf, buf_length, buf_max, '\\f');\n                    break;\n                case 'n':\n                    append_byte(buf, buf_length, buf_max, '\\n');\n                    break;\n                case 'r':\n                    append_byte(buf, buf_length, buf_max, '\\r');\n                    break;\n                case 't':\n                    append_byte(buf, buf_length, buf_max, '\\t');\n                    break;\n                case 'v':\n                    append_byte(buf, buf_length, buf_max, '\\v');\n                    break;\n                default:\n                case '\\\\':\n                    append_byte(buf, buf_length, buf_max, line[offset]);\n                    break;\n            }\n        } else\n            append_byte(buf, buf_length, buf_max, line[offset]);\n\n        offset++;\n    }\n\n    if (line[offset] == '\\\"')\n        offset++;\n\n    return line + offset;\n\n}\n\n\n/***************************************************************************\n * Called during processing of the \"--nmap-payloads <filename>\" directive.\n ***************************************************************************/\nvoid\nread_nmap_payloads(FILE *fp, const char *filename,\n                      struct PayloadsUDP *payloads,\n                      payloads_datagram_add_cb add_payload\n                      )\n{\n    char line[16384];\n    unsigned line_number = 0;\n\n\n    line[0] = '\\0';\n\n    for (;;) {\n        unsigned is_error = 0;\n        const char *p;\n        struct RangeList ports[1] = {{0}};\n        unsigned source_port = 0x10000;\n        unsigned char buf[1500] = {0};\n        size_t buf_length = 0;\n\n        memset(ports, 0, sizeof(ports[0]));\n\n        /* [UDP] */\n        if (!get_next_line(fp, &line_number, line, sizeof(line)))\n            break;\n\n        if (memcmp(line, \"udp\", 3) != 0) {\n            fprintf(stderr, \"%s:%u: syntax error, expected \\\"udp\\\".\\n\",\n                    filename, line_number);\n            goto end;\n        } else\n            memmove(line, line+3, strlen(line));\n        trim(line, sizeof(line));\n\n\n        /* [ports] */\n        if (!get_next_line(fp, &line_number, line, sizeof(line)))\n            break;\n        p = rangelist_parse_ports(ports, line, &is_error, 0);\n        if (is_error) {\n            fprintf(stderr, \"%s:%u: syntax error, expected ports\\n\",\n                    filename, line_number);\n            goto end;\n        }\n        memmove(line, p, strlen(p)+1);\n        trim(line, sizeof(line));\n\n        /* [C string] */\n        for (;;) {\n            trim(line, sizeof(line));\n            if (!get_next_line(fp, &line_number, line, sizeof(line)))\n                break;\n            if (line[0] != '\\\"')\n                break;\n\n            p = parse_c_string(buf, &buf_length, sizeof(buf), line);\n            memmove(line, p, strlen(p)+1);\n            trim(line, sizeof(line));\n        }\n\n        /* [source] */\n        if (memcmp(line, \"source\", 6) == 0) {\n            memmove(line, line+6, strlen(line+5));\n            trim(line, sizeof(line));\n            if (!isdigit(line[0])) {\n                fprintf(stderr, \"%s:%u: expected source port\\n\",\n                        filename, line_number);\n                goto end;\n            }\n            source_port = (unsigned)strtoul(line, 0, 0);\n            line[0] = '\\0';\n        }\n\n        /*\n         * Now we've completely parsed the record, so add it to our\n         * list of payloads\n         */\n        if (buf_length)\n            add_payload(payloads, buf, buf_length, ports, source_port);\n\n        rangelist_remove_all(ports);\n    }\n\nend:\n    ;//fclose(fp);\n}\n\n/****************************************************************************\n ****************************************************************************/\nint\ntempl_nmap_selftest(void)\n{\n    unsigned char buf[1024];\n    size_t buf_length;\n\n    buf_length = 0;\n    parse_c_string(buf, &buf_length, sizeof(buf), \"\\\"\\\\t\\\\n\\\\r\\\\x1f\\\\123\\\"\");\n    if (memcmp(buf, \"\\t\\n\\r\\x1f\\123\", 5) != 0)\n        return 1;\n    return 0;\n\n    /*\n     \"OPTIONS sip:carol@chicago.com SIP/2.0\\r\\n\"\n     \"Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877\\r\\n\"\n     \"Max-Forwards: 70\\r\\n\"\n     \"To: <sip:carol@chicago.com>\\r\\n\"\n     \"From: Alice <sip:alice@atlanta.com>;tag=1928301774\\r\\n\"\n     \"Call-ID: a84b4c76e66710\\r\\n\"\n     \"CSeq: 63104 OPTIONS\\r\\n\"\n     \"Contact: <sip:alice@pc33.atlanta.com>\\r\\n\"\n     \"Accept: application/sdp\\r\\n\"\n     \"Content-Length: 0\\r\\n\"\n     */\n\n}\n\n"
  },
  {
    "path": "src/templ-nmap-payloads.h",
    "content": "/*\n    Parses the \"nmap-payloads\" file.\n */\n#ifndef TEMPL_NMAP_PAYLOADS_H\n#define TEMPL_NMAP_PAYLOADS_H\n#include <stdio.h>\nstruct PayloadsUDP;\nstruct RangeList;\n\ntypedef unsigned\n(*payloads_datagram_add_cb)(struct PayloadsUDP *payloads,\n                      const unsigned char *buf, size_t length,\n                      struct RangeList *ports, unsigned source_port\n                    );\n\nvoid\nread_nmap_payloads(FILE *fp, const char *filename,\n                      struct PayloadsUDP *payloads,\n                      payloads_datagram_add_cb add_payload\n                      );\n\nint\ntempl_nmap_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/templ-opts.h",
    "content": "#ifndef TEMPL_OPTS_H\n#define TEMPL_OPTS_H\n#include \"massip-addr.h\"\n\n#ifdef _MSC_VER\n#pragma warning(disable:4214)\n#endif\n\n/**\n * This tells us whether we should add, remove, or leave default\n * a field in the packet headers.\n * FIXME: not all of these are supported\n */\ntypedef enum {Default, Add, Remove} addremove_t;\n\nstruct TemplateOptions {\n    struct {\n        addremove_t is_badsum:4; /* intentionally bad checksum */\n        addremove_t is_tsecho:4; /* enable timestamp echo */\n        addremove_t is_tsreply:4; /* enable timestamp echo */\n        addremove_t is_flags:4;\n        addremove_t is_ackno:4;\n        addremove_t is_seqno:4;\n        addremove_t is_win:4;\n        addremove_t is_mss:4;\n        addremove_t is_sackok:4;\n        addremove_t is_wscale:4;\n        unsigned flags;\n        unsigned ackno;\n        unsigned seqno;\n        unsigned win;\n        unsigned mss;\n        unsigned sackok;\n        unsigned wscale;\n        unsigned tsecho;\n        unsigned tsreply;\n    } tcp;\n\n    struct {\n        addremove_t is_badsum:4; /* intentionally bad checksum */\n    } udp;\n\n    struct {\n        addremove_t is_sender_mac:4;\n        addremove_t is_sender_ip:4;\n        addremove_t is_target_mac:4;\n        addremove_t is_target_ip:4;\n        macaddress_t sender_mac;\n        ipaddress sender_ip;\n        macaddress_t target_mac;\n        ipaddress target_ip;\n    } arp;\n    \n    struct {\n        addremove_t is_badsum:4; /* intentionally bad checksum */\n        addremove_t is_tos:4;\n        addremove_t is_ipid:4;\n        addremove_t is_df:4;\n        addremove_t is_mf:4;\n        addremove_t is_ttl:4;\n\n        unsigned tos;\n        unsigned ipid;\n        unsigned ttl;\n\n    } ipv4;\n};\n\n#endif\n\n"
  },
  {
    "path": "src/templ-payloads.c",
    "content": "/*\n Reads in UDP payload templates.\n\n This supports two formats. The first format is the \"nmap-payloads\" file\n included with the nmap port scanner.\n\n The second is the \"libpcap\" format that reads in real packets,\n extracting just the payloads, associated them with the destination\n UDP port.\n\n */\n#include \"templ-payloads.h\"\n#include \"massip-port.h\"\n#include \"rawsock-pcapfile.h\"   /* for reading payloads from pcap files */\n#include \"proto-preprocess.h\"   /* parse packets */\n#include \"util-logger.h\"\n#include \"proto-zeroaccess.h\"   /* botnet p2p protocol */\n#include \"proto-snmp.h\"\n#include \"proto-memcached.h\"\n#include \"proto-coap.h\"         /* constrained app proto for IoT udp/5683*/\n#include \"proto-ntp.h\"\n#include \"proto-dns.h\"\n#include \"proto-isakmp.h\"\n#include \"util-malloc.h\"\n#include \"massip.h\"\n#include \"templ-nmap-payloads.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n#include <stdlib.h>\n\nstruct PayloadUDP_Item {\n    unsigned port;\n    unsigned source_port; /* not used yet */\n    unsigned length;\n    unsigned xsum;\n    unsigned rarity;\n    SET_COOKIE set_cookie;\n    unsigned char buf[1];\n};\nstruct PayloadUDP_Default {\n    unsigned port;\n    unsigned source_port;\n    unsigned length;\n    unsigned xsum;\n    SET_COOKIE set_cookie;\n    char *buf;\n\n};\n\nstruct PayloadsUDP {\n    unsigned count;\n    size_t max;\n    struct PayloadUDP_Item **list;\n};\n\n\nstruct PayloadUDP_Default hard_coded_oproto_payloads[] = {\n    /* ECHO protocol - echoes back whatever we send */\n    {47, 65536, 4, 0, 0, \"\\0\\0\\0\\0\"},\n    {0,0,0,0,0}\n};\n\n\nstruct PayloadUDP_Default hard_coded_udp_payloads[] = {\n    /* ECHO protocol - echoes back whatever we send */\n    {7, 65536, 12, 0, 0, \"masscan-test 0x00000000\"},\n\n    /* QOTD - quote of the day (amplifier) */\n    {17, 65536, 12, 0, 0, \"masscan-test\"},\n    \n    /* chargen - character generator (amplifier) */\n    {19, 65536, 12, 0, 0, \"masscan-test\"},\n    \n    {53, 65536, 0x1f, 0, dns_set_cookie,\n        /* 00 */\"\\x50\\xb6\"  /* transaction id */\n        /* 02 */\"\\x01\\x20\"  /* query */\n        /* 04 */\"\\x00\\x01\"  /* query = 1 */\n        /* 06 */\"\\x00\\x00\\x00\\x00\\x00\\x00\"\n        /* 0c */\"\\x07\" \"version\"  \"\\x04\" \"bind\" \"\\x00\"\n        /* 1b */\"\\x00\\x10\" /* TXT */\n        /* 1d */\"\\x00\\x03\" /* CHAOS */\n        /* 1f */\n    },\n\n    {69, 65536, 24, 0, 0,\n        \"\\x00\\x01\"          /* opcode = read */\n        \"masscan-test\" \"\\0\" /* filename = \"masscan-test\" */\n        \"netascii\" \"\\0\"     /* type = \"netascii\" */\n    },\n    /* portmapper */\n    {111, 65536, 40, 0, dns_set_cookie,\n        \"\\x00\\x00\\x00\\x00\" /* xid - first two bytes set by dns_set_cookie() */\n        \"\\x00\\x00\\x00\\x00\" /* RPC opcode = CALL*/\n        \"\\x00\\x00\\x00\\x02\" /* RPC version = 2 */\n        \"\\x00\\x01\\x86\\xa0\" /* RPC program = NFS */\n        \"\\x00\\x00\\x00\\x02\" /* portmapper version = 2 */\n        \"\\x00\\x00\\x00\\x00\" /* portmapper procedure = 0 (NULL, ping) */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* credentials = none*/\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* verifier = none   */\n    },\n\n    {123, 65536, 48, 0, ntp_set_cookie,\n        \"\\x17\\x00\\x03\\x2a\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n    },\n    {137, 65536, 50, 0, dns_set_cookie,\n        \"\\xab\\x12\" /* transaction id */\n        \"\\x00\\x00\" /* query */\n        \"\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\" /* one question */\n        \"\\x20\" /*name length*/\n        \"CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n        \"\\x00\"\n        \"\\x00\\x21\" /* type = nbt */\n        \"\\x00\\x01\" /* class = iternet*/\n    },\n\n    /* NetBIOS-SMB BROWSER protocol */\n    {138, 65536, 174, 0, 0,\n        \"\\x11\" /* broadcast datagram */\n        \"\\x0a\" /* flags */\n        \"\\xc1\\x00\" /* datagram id */\n        \"\\x0a\\x01\\x01\\xd5\" /* source IP */\n        \"\\x00\\x8a\" /* source port */\n        \"\\x00\\xa0\" /* length */\n        \"\\x00\\x00\" /* packet offset */\n        \"\\x20\" /* namelength = 32 bytes*/\n        \"ENEBFDFDEDEBEOCNFEEFFDFECACACAAA\" /* \"MASSCAN-TEST<00>\" */\n        \"\\x00\"\n        \"\\x20\"\n        \"FHEPFCELEHFCEPFFFACACACACACACABN\" /* \"WORKGROUP<1D>*/\n        \"\\x00\"\n        \"\\xff\\x53\\x4d\\x42\\x25\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n\n        \"\\x11\\x00\\x00\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xe8\\x03\\x00\"\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x06\\x00\\x56\\x00\\x03\\x00\\x01\\x00\\x01\"\n        \"\\x00\\x02\\x00\\x17\\x00\\x5c\\x4d\\x41\\x49\\x4c\\x53\\x4c\\x4f\\x54\\x5c\\x42\"\n        \"\\x52\\x4f\\x57\\x53\\x45\\x00\"\n\n        \"\\x09\\x04\\x01\\x00\\x00\\x00\"\n    },\n\n    {161, 65536, 59, 0, snmp_set_cookie,\n        \"\\x30\" \"\\x39\"\n        \"\\x02\\x01\\x00\"                    /* version */\n        \"\\x04\\x06\" \"public\"               /* community = public */\n        \"\\xa0\" \"\\x2c\"                     /* type = GET */\n        \"\\x02\\x04\\x00\\x00\\x00\\x00\"      /* transaction id = ???? */\n        \"\\x02\\x01\\x00\"                  /* error = 0 */\n        \"\\x02\\x01\\x00\"                  /* error index = 0 */\n        \"\\x30\\x1e\"\n        \"\\x30\\x0d\"\n        \"\\x06\\x09\\x2b\\x06\\x01\\x80\\x02\\x01\\x01\\x01\\x00\" /*sysName*/\n        \"\\x05\\x00\"          /*^^^^_____IDS LULZ HAH HA HAH*/\n        \"\\x30\\x0d\"\n        \"\\x06\\x09\\x2b\\x06\\x01\\x80\\x02\\x01\\x01\\x05\\x00\" /*sysDesc*/\n        \"\\x05\\x00\"},        /*^^^^_____IDS LULZ HAH HA HAH*/\n\n    {443, 65536, 115, 0, 0,\n        \"\\x16\" /* opcode = handshake */\n        \"\\xfe\\xff\" /* version = dTLS v1.0 */\n        \"\\x00\\x00\" /* epoch = 0 */\n        \"\\x00\\x00\\x00\\x00\\x00\\x07\" /* sequence number = 7 */\n        \"\\x00\\x66\" /* length 104 */\n\n        \"\\x01\" /* opcode = client hello */\n        \"\\x00\\x00\\x5a\" /* length 90 */\n        \"\\x00\\x00\" /* sequence number = 0 */\n        \"\\x00\\x00\\x00\" /* fragment offset = 0 */\n        \"\\x00\\x00\\x5a\" /* framgent length = 90 */\n        \"\\xfe\\xfd\" /* version = dTLS v1.2 */\n        \"\\x1d\\xb1\\xe3\\x52\\x2e\\x89\\x94\\xb7\\x15\\x33\\x2f\\x30\\xff\\xff\\xcf\\x76\"\n        \"\\x27\\x77\\xab\\x04\\xe4\\x86\\x6f\\x21\\x18\\x0e\\xf8\\xdd\\x70\\xcc\\xab\\x9e\"\n        \"\\x00\" /* session id length = 0 */\n        \"\\x00\" /* cookie length = 0 */\n        \"\\x00\\x04\" /* cipher suites length = 4 */\n        \"\\xc0\\x30\" /* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 */\n        \"\\x00\\xff\"\n        \"\\x01\" /* compression methods length = 1*/\n        \"\\x00\" /* NULL compression */\n        \"\\x00\\x2c\" /* extensions length = 44 */\n        \"\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\"\n        \"\\x00\\x0a\\x00\\x0c\\x00\\x0a\\x00\\x1d\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\"\n        \"\\x00\\x23\\x00\\x00\"\n        \"\\x00\\x16\\x00\\x00\"\n        \"\\x00\\x17\\x00\\x00\"\n        \"\\x00\\x0d\\x00\\x04\\x00\\x02\\x05\\x01\"\n    },\n\n    {520, 65536, 24, 0, 0,\n        \"\\x01\"  /* opcode = request */\n        \"\\x01\"  /* version = 1 */\n        \"\\x00\\x00\" /* padding */\n        \"\\x00\\x02\" /* address familly = IPv4 */\n        \"\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x10\" /* metric = 16 */\n\n    },\n\n    /* RADIUS  */\n    {1645, 65536, 20, 0, 0,\n        \"\\x01\" /* opcode = access request */\n        \"\\x00\" /* packet id = 0 */\n        \"\\x00\\x14\" /* length = 20 */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n    },\n    {1812, 65536, 20, 0, 0,\n        \"\\x01\" /* opcode = access request */\n        \"\\x00\" /* packet id = 0 */\n        \"\\x00\\x14\" /* length = 20 */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n    },\n    {1646, 65536, 20, 0, 0,\n        \"\\x04\" /* opcode = access request */\n        \"\\x00\" /* packet id = 0 */\n        \"\\x00\\x14\" /* length = 20 */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n    },\n    {1813, 65536, 20, 0, 0,\n        \"\\x04\" /* opcode = access request */\n        \"\\x00\" /* packet id = 0 */\n        \"\\x00\\x14\" /* length = 20 */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n    },\n\n    /* L2TP */\n    {1701, 65536, 60, 0, 0,\n        \"\\xc8\\x02\" /* flags */\n        \"\\x00\\x3c\" /* length = 60 */\n        \"\\x00\\x00\" /* tunnel id = 0 */\n        \"\\x00\\x00\" /* session id = 0 */\n        \"\\x00\\x00\" /* Nsent = 0 */\n        \"\\x00\\x00\" /* Nrecvd = 0 */\n        \"\\x80\\x08\\x00\\x00\\x00\\x00\\x00\\x01\" /* control message */\n        \"\\x80\\x08\\x00\\x00\\x00\\x02\\x01\\x00\" /* protocol version */\n        \"\\x80\\x0e\\x00\\x00\\x00\\x07\" \"masscan1\" /* hostname */\n        \"\\x80\\x0a\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x03\" /* framing capabilities */\n        \"\\x80\\x08\\x00\\x00\\x00\\x09\\x00\\x00\" /* assigned tunnel */\n    },\n\n    /* UPnP SSDP - Univeral Plug-n-Play Simple Service Discovery Protocol */\n    {1900, 65536, 0xFFFFFFFF, 0, 0,\n        \"M-SEARCH * HTTP/1.1\\r\\n\"\n        \"HOST: 239.255.255.250:1900\\r\\n\"\n        \"MAN: \\\"ssdp:discover\\\"\\r\\n\"\n        \"MX: 1\\r\\n\"\n        \"ST: ssdp:all\\r\\n\"\n        \"USER-AGENT: unix/1.0 UPnP/1.1 masscan/1.x\\r\\n\"},\n\n    /* NFS - kludge: use the DNS cookie, setting first 2 bytes instead of 4 */\n    {2049, 65536, 40, 0, dns_set_cookie,\n        \"\\x00\\x00\\x00\\x00\" /* xid - first two bytes set by dns_set_cookie() */\n        \"\\x00\\x00\\x00\\x00\" /* RPC opcode = CALL*/\n        \"\\x00\\x00\\x00\\x02\" /* RPC version = 2 */\n        \"\\x00\\x01\\x86\\xa3\" /* RPC program = NFS */\n        \"\\x00\\x00\\x00\\x02\" /* NFS version = 2 */\n        \"\\x00\\x00\\x00\\x00\" /* NFS procedure = 0 (NULL, ping) */\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* credentials = none*/\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* verifier = none   */\n    },\n    {5060, 65536, 0xFFFFFFFF, 0, 0,\n        \"OPTIONS sip:carol@chicago.com SIP/2.0\\r\\n\"\n        \"Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877\\r\\n\"\n        \"Max-Forwards: 70\\r\\n\"\n        \"To: <sip:carol@chicago.com>\\r\\n\"\n        \"From: Alice <sip:alice@atlanta.com>;tag=1928301774\\r\\n\"\n        \"Call-ID: a84b4c76e66710\\r\\n\"\n        \"CSeq: 63104 OPTIONS\\r\\n\"\n        \"Contact: <sip:alice@pc33.atlanta.com>\\r\\n\"\n        \"Accept: application/sdp\\r\\n\"\n        \"Content-Length: 0\\r\\n\"\n    },\n    \n    /* CoAP (contrained app proto for IoT) GET /.well-known/core request */\n    {5683, 65536, 21, 0, coap_udp_set_cookie,\n        \"\\x40\"      /* ver=1 type=con */\n        \"\\x01\"      /* code=GET */\n        \"\\x01\\xce\"  /* message id (changed by set-cookie) */\n        \"\\xbb\" /* \".well-known */\n        \"\\x2e\\x77\\x65\\x6c\\x6c\\x2d\\x6b\\x6e\\x6f\\x77\\x6e\"\n        \"\\x04\" /* \"core\" */\n        \"\\x63\\x6f\\x72\\x65\"\n\n    },\n\n    /* memcached \"stats\" request. This looks for memcached systems that can\n     * be used for DDoS amplifiers */\n    {11211, 65536, 15, 0, memcached_udp_set_cookie,\n        \"\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00stats\\r\\n\"\n    },\n\n    //16464,16465,16470, 16471\n    {16464, 65536, zeroaccess_getL_length, 0, 0,\n        (char *)zeroaccess_getL},\n    {16465, 65536, zeroaccess_getL_length, 0, 0,\n        (char *)zeroaccess_getL},\n    {16470, 65536, zeroaccess_getL_length, 0, 0,\n        (char *)zeroaccess_getL},\n    {16471, 65536, zeroaccess_getL_length, 0, 0,\n        (char *)zeroaccess_getL},\n\n    /* Quake 3 (amplifier)\n     * http://blog.alejandronolla.com/2013/06/24/amplification-ddos-attack-with-quake3-servers-an-analysis-1-slash-2/\n     */\n    {27960, 65536, 0xFFFFFFFF, 0, 0,\n        \"\\xFF\\xFF\\xFF\\xFF\\x67\\x65\\x74\\x73\\x74\\x61\\x74\\x75\\x73\\x10\"},\n\n    /* ISAKMP */\n    {500, 500, 352, 0, isakmp_set_cookie,\n     /* ISAKMP */\n     \"\\x00\\x11\\x22\\x33\\x44\\x55\\x66\\x77\"/* init_cookie, overwritten on send() */\n     \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" /* resp_cookie*/\n     \"\\x01\" /* next_payload: SA */\n     \"\\x10\" /* version */\n     \"\\x02\" /* exch_type: identity prot. */\n     \"\\x00\" /* flags */\n     \"\\x00\\x00\\x00\\x00\" /* id */\n     \"\\x00\\x00\\x01\\x60\" /* length: 352 */\n     /* ISAKMP_SA */\n     \"\\x00\" /* next_payload: None */\n     \"\\x00\" /* reserved */\n     \"\\x01\\x44\" /* length: 324 */\n     \"\\x00\\x00\\x00\\x01\" /* DOI: IPSEC */\n     \"\\x00\\x00\\x00\\x01\" /* situation: identity */\n     /* Proposal */\n     \"\\x00\" /* next_payload: None */\n     \"\\x00\" /* reserved */\n     \"\\x01\\x38\" /* length: 312 */\n     \"\\x01\" /* proposal: 1 */\n     \"\\x01\" /* protocol: ISAKMP */\n     \"\\x00\" /* SPIsize: 0 */\n     \"\\x0d\" /* trans_count: 13 */\n     \"\" /* SPI */\n     /* Tranforms */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x20\" /* length: 32 */\n     \"\\x00\" /* num */\n     \"\\x01\" /* id: KEY_IKE */\n     \"\\x00\\x00\" /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\x00\\x01\\x80\\x04\\x00\\x02\"\n     \"\\x80\\x0b\\x00\\x01\\x80\\x0c\\x00\\x01\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'),\n        ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'),\n        ('LifeDuration', 1) */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x20\" /* length: 32 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x01\\x80\\x02\\x00\\x01\\x80\\x03\\x00\\x01\\x80\\x04\\x00\\x02\"\n     \"\\x80\\x0b\\x00\\x01\\x80\\x0c\\x00\\x01\"\n     /* ('Encryption', 'DES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'),\n        ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'),\n        ('LifeDuration', 1) */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x20\" /* length: 32 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x07\\x80\\x02\\x00\\x04\\x80\\x03\\x00\\x01\\x80\\x04\\x00\\x0e\"\n     \"\\x80\\x0b\\x00\\x01\\x80\\x0c\\x00\\x01\"\n     /* ('Encryption', 'AES-CBC'), ('Hash', 'SHA2-256'),\n        ('Authentication', 'PSK'), ('GroupDesc', '2048MODPgr'),\n        ('LifeType', 'Seconds'), ('LifeDuration', 1) */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\x00\\x02\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'DSS') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\x00\\x03\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'RSA Sig') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\x00\\x04\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'RSA Encryption') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\x00\\x08\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'ECDSA Sig') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfa\\xdd\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'HybridInitRSA') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfa\\xdf\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'HybridInitDSS') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfd\\xe9\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'XAUTHInitPreShared') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfd\\xeb\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'XAUTHInitDSS') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfd\\xed\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'XAUTHInitRSA') */\n     \"\\x03\" /* next_payload: Transform */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x14\" /* length: 20 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */\n     \"\\x80\\x01\\x00\\x05\\x80\\x02\\x00\\x02\\x80\\x03\\xfd\\xef\"\n     /* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),\n        ('Authentication', 'XAUTHInitRSAEncryption') */\n     \"\\x00\" /* next_payload: None */\n     \"\\x00\" /* reserved */\n     \"\\x00\\x08\" /* length: 8 */\n     \"\\x00\" /* num */\n     \"\\x01\"  /* id: KEY_IKE */\n     \"\\x00\\x00\"  /* reserved */},\n\n    {0,0,0,0,0}\n};\n\n\n/***************************************************************************\n * Calculate the partial checksum of the payload. This allows us to simply\n * add this to the checksum when transmitting instead of recalculating\n * everything.\n ***************************************************************************/\nstatic unsigned\npartial_checksum(const unsigned char *px, size_t icmp_length)\n{\n    uint64_t xsum = 0;\n    unsigned i;\n\n    for (i=0; i<icmp_length; i += 2) {\n        xsum += px[i]<<8 | px[i + 1];\n    }\n\n    xsum -= (icmp_length & 1) * px[i - 1]; /* yea I know going off end of packet is bad so sue me */\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return (unsigned)xsum;\n}\n\n/***************************************************************************\n * If we have the port, return the best payload for that port.\n ***************************************************************************/\nint\npayloads_udp_lookup(\n                    const struct PayloadsUDP *payloads,\n                    unsigned port,\n                    const unsigned char **px,\n                    unsigned *length,\n                    unsigned *source_port,\n                    uint64_t *xsum,\n                    SET_COOKIE *set_cookie)\n{\n    unsigned i;\n    if (payloads == 0)\n        return 0;\n\n    port &= 0xFFFF;\n\n    /* This is just a linear search, done once at startup, to search\n     * through all the payloads for the best match. */\n    for (i=0; i<payloads->count; i++) {\n        if (payloads->list[i]->port == port) {\n            *px = payloads->list[i]->buf;\n            *length = payloads->list[i]->length;\n            *source_port = payloads->list[i]->source_port;\n            *xsum = payloads->list[i]->xsum;\n            *set_cookie = payloads->list[i]->set_cookie;\n            return 1;\n        }\n    }\n    return 0;\n}\n\n\n/***************************************************************************\n * cleanup on program shutdown\n ***************************************************************************/\nvoid\npayloads_udp_destroy(struct PayloadsUDP *payloads)\n{\n    unsigned i;\n    if (payloads == NULL)\n        return;\n\n    for (i=0; i<payloads->count; i++)\n        free(payloads->list[i]);\n\n    if (payloads->list)\n        free(payloads->list);\n\n    free(payloads);\n}\n\n/***************************************************************************\n * We read lots of UDP payloads from the files. However, we probably\n * aren't using most, or even any, of them. Therefore, we use this\n * function to remove the ones we won't be using. This makes lookups\n * faster, ideally looking up only zero or one rather than twenty.\n ***************************************************************************/\nvoid\npayloads_udp_trim(struct PayloadsUDP *payloads, const struct MassIP *targets)\n{\n    unsigned i;\n    struct PayloadUDP_Item **list2;\n    unsigned count2 = 0;\n\n    /* Create a new list */\n    list2 = REALLOCARRAY(0, payloads->max, sizeof(list2[0]));\n\n    /* Add to the new list any used ports */\n    for (i=0; i<payloads->count; i++) {\n        unsigned found;\n\n        found = massip_has_port(targets, payloads->list[i]->port + Templ_UDP);\n        if (found) {\n            list2[count2++] = payloads->list[i];\n        } else {\n            free(payloads->list[i]);\n        }\n        //payloads->list[i] = 0;\n    }\n\n    /* Replace the old list */\n    free(payloads->list);\n    payloads->list = list2;\n    payloads->count = count2;\n}\n\nvoid\npayloads_oproto_trim(struct PayloadsUDP *payloads, const struct MassIP *targets)\n{\n    unsigned i;\n    struct PayloadUDP_Item **list2;\n    unsigned count2 = 0;\n    \n    /* Create a new list */\n    list2 = REALLOCARRAY(0, payloads->max, sizeof(list2[0]));\n    \n    /* Add to the new list any used ports */\n    for (i=0; i<payloads->count; i++) {\n        unsigned found;\n        \n        found = massip_has_port(targets, payloads->list[i]->port + Templ_Oproto_first);\n        if (found) {\n            list2[count2++] = payloads->list[i];\n        } else {\n            free(payloads->list[i]);\n        }\n    }\n    \n    /* Replace the old list */\n    free(payloads->list);\n    payloads->list = list2;\n    payloads->count = count2;\n}\n\n\n/***************************************************************************\n * Adds a payloads template for the indicated datagram protocol, which\n * is UDP or Oproto (\"other IP protocol\").\n ***************************************************************************/\nstatic unsigned\npayloads_datagram_add(struct PayloadsUDP *payloads,\n                      const unsigned char *buf, size_t length,\n                      struct RangeList *ports, unsigned source_port,\n                      SET_COOKIE set_cookie)\n{\n    unsigned count = 1;\n    struct PayloadUDP_Item *p;\n    uint64_t port_count = rangelist_count(ports);\n    uint64_t i;\n\n    for (i=0; i<port_count; i++) {\n        /* grow the list if we need to */\n        if (payloads->count + 1 > payloads->max) {\n            size_t new_max = payloads->max*2 + 1;\n            payloads->list = REALLOCARRAY(payloads->list, new_max, sizeof(payloads->list[0]));\n            payloads->max = new_max;\n        }\n\n        /* allocate space for this record */\n        p = MALLOC(sizeof(p[0]) + length);\n        p->port = rangelist_pick(ports, i);\n        p->source_port = source_port;\n        p->length = (unsigned)length;\n        memcpy(p->buf, buf, length);\n        p->xsum = partial_checksum(buf, length);\n        p->set_cookie = set_cookie;\n\n        /* insert in sorted order */\n        {\n            unsigned j;\n\n            for (j=0; j<payloads->count; j++) {\n                if (p->port <= payloads->list[j]->port)\n                    break;\n            }\n\n            if (j < payloads->count) {\n                if (p->port == payloads->list[j]->port) {\n                    free(payloads->list[j]);\n                    count = 0; /* don't increment count */\n                } else\n                    memmove(payloads->list + j + 1,\n                            payloads->list + j,\n                            (payloads->count-j) * sizeof(payloads->list[0]));\n            }\n            payloads->list[j] = p;\n\n            payloads->count += count;\n            count = 1;\n        }\n    }\n    return count; /* zero or one */\n}\n\nstatic unsigned\npayloads_datagram_add_nocookie(struct PayloadsUDP *payloads,\n                               const unsigned char *buf, size_t length,\n                               struct RangeList *ports, unsigned source_port\n                               ) {\n    return payloads_datagram_add(payloads,\n                                 buf, length,\n                                 ports, source_port,\n                                 0);\n\n}\n\n\n/***************************************************************************\n * Called during processing of the \"--pcap-payloads <filename>\" directive.\n * This is the well-known 'pcap' file format. This code strips off the\n * headers of the packets then preserves just the payload portion\n * and port number.\n ***************************************************************************/\nvoid\npayloads_read_pcap(const char *filename,\n                   struct PayloadsUDP *payloads,\n                   struct PayloadsUDP *oproto_payloads)\n{\n    struct PcapFile *pcap;\n    unsigned count = 0;\n\n    LOG(2, \"payloads:'%s': opening packet capture\\n\", filename);\n\n    /* open packet-capture */\n    pcap = pcapfile_openread(filename);\n    if (pcap == NULL) {\n        fprintf(stderr, \"payloads: can't read from file '%s'\\n\", filename);\n        return;\n    }\n\n    /* for all packets in the capture file\n     *  - read in packet\n     *  - parse packet\n     *  - save payload\n     */\n    for (;;) {\n        unsigned x;\n        unsigned captured_length;\n        unsigned char buf[65536];\n        struct PreprocessedInfo parsed;\n        struct RangeList ports[1] = {{0}};\n        struct Range range[1] = {{0}};\n\n        /*\n         * Read the next packet from the capture file\n         */\n        {\n            unsigned time_secs;\n            unsigned time_usecs;\n            unsigned original_length;\n\n            x = pcapfile_readframe(pcap,\n                                   &time_secs, &time_usecs,\n                                   &original_length, &captured_length,\n                                   buf, (unsigned)sizeof(buf));\n        }\n        if (!x)\n            break;\n\n        /*\n         * Parse the packet up to its headers\n         */\n        x = preprocess_frame(buf, captured_length, 1, &parsed);\n        if (!x)\n            continue; /* corrupt packet */\n\n        /*\n         * Make sure it has UDP\n         */\n        switch (parsed.found) {\n            case FOUND_DNS:\n            case FOUND_UDP:\n                /*\n                 * Kludge: mark the port in the format the API wants\n                 */\n                ports->list = range;\n                ports->count = 1;\n                ports->max = 1;\n                range->begin = parsed.port_dst;\n                range->end = range->begin;\n                \n                /*\n                 * Now we've completely parsed the record, so add it to our\n                 * list of payloads\n                 */\n                count += payloads_datagram_add(   payloads,\n                                               buf + parsed.app_offset,\n                                               parsed.app_length,\n                                               ports,\n                                               0x10000,\n                                               0);\n                break;\n            case FOUND_OPROTO:\n                /*\n                 * Kludge: mark the port in the format the API wants\n                 */\n                ports->list = range;\n                ports->count = 1;\n                ports->max = 1;\n                range->begin = parsed.ip_protocol;\n                range->end = range->begin;\n                \n                /*\n                 * Now we've completely parsed the record, so add it to our\n                 * list of payloads\n                 */\n                count += payloads_datagram_add(oproto_payloads,\n                                               buf + parsed.transport_offset,\n                                               parsed.transport_length,\n                                               ports,\n                                               0x10000,\n                                               0);\n                break;\n            default:\n                continue;\n        }\n\n    }\n\n    LOG(2, \"payloads:'%s': imported %u unique payloads\\n\", filename, count);\n    LOG(2, \"payloads:'%s': closed packet capture\\n\", filename);\n    pcapfile_close(pcap);\n}\n\n/***************************************************************************\n * Called from the \"conf\" subsystem in order read in the file\n * \"nmap-payloads\". We call the function 'read_nmap_payloads()\" defined\n * in a different file that focuses on parsing that file format.\n ***************************************************************************/\nvoid\npayloads_udp_readfile(FILE *fp, const char *filename,\n                      struct PayloadsUDP *payloads) {\n    read_nmap_payloads(fp, filename, payloads, payloads_datagram_add_nocookie);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstruct PayloadsUDP *\npayloads_udp_create(void)\n{\n    unsigned i;\n    struct PayloadsUDP *payloads;\n    struct PayloadUDP_Default *hard_coded = hard_coded_udp_payloads;\n    \n    payloads = CALLOC(1, sizeof(*payloads));\n    \n    /*\n     * For popular parts, include some hard-coded default UDP payloads\n     */\n    for (i=0; hard_coded[i].length; i++) {\n        //struct Range range;\n        struct RangeList list = {0};\n        unsigned length;\n\n        /* Kludge: create a pseudo-rangelist to hold the one port */\n        /*list.list = &range;\n         list.count = 1;\n         range.begin = hard_coded[i].port;\n         range.end = range.begin;*/\n        rangelist_add_range(&list, hard_coded[i].port, hard_coded[i].port);\n\n        length = hard_coded[i].length;\n        if (length == 0xFFFFFFFF)\n            length = (unsigned)strlen(hard_coded[i].buf);\n\n        /* Add this to our real payloads. This will get overwritten\n         * if the user adds their own with the same port */\n        payloads_datagram_add(payloads,\n                              (const unsigned char*)hard_coded[i].buf,\n                              length,\n                              &list,\n                              hard_coded[i].source_port,\n                              hard_coded[i].set_cookie);\n\n        rangelist_remove_all(&list);\n    }\n    return payloads;\n}\n\n/***************************************************************************\n * (same code as for UDP)\n ***************************************************************************/\nstruct PayloadsUDP *\npayloads_oproto_create(void)\n{\n    unsigned i;\n    struct PayloadsUDP *payloads;\n    struct PayloadUDP_Default *hard_coded = hard_coded_oproto_payloads;\n    \n    payloads = CALLOC(1, sizeof(*payloads));\n    \n    /*\n     * Some hard-coded ones, like GRE\n     */\n    for (i=0; hard_coded[i].length; i++) {\n        //struct Range range;\n        struct RangeList list = {0};\n        unsigned length;\n        \n        /* Kludge: create a pseudo-rangelist to hold the one port */\n        rangelist_add_range(&list, hard_coded[i].port, hard_coded[i].port);\n        \n        length = hard_coded[i].length;\n        if (length == 0xFFFFFFFF)\n            length = (unsigned)strlen(hard_coded[i].buf);\n        \n        /* Add this to our real payloads. This will get overwritten\n         * if the user adds their own with the same port */\n        payloads_datagram_add(payloads,\n                              (const unsigned char*)hard_coded[i].buf,\n                              length,\n                              &list,\n                              hard_coded[i].source_port,\n                              hard_coded[i].set_cookie);\n        \n        rangelist_remove_all(&list);\n    }\n    return payloads;\n}\n\n\nint\ntempl_payloads_selftest(void) {\n    return templ_nmap_selftest();\n}\n"
  },
  {
    "path": "src/templ-payloads.h",
    "content": "#ifndef TEMPL_PAYLOADS_H\n#define TEMPL_PAYLOADS_H\n#include <stdio.h>\n#include <stdint.h>\nstruct MassIP;\n\n/**\n * Regression test this module.\n * @return\n *      0 on success, or positive integer on failure.\n */\nint\ntempl_payloads_selftest(void);\n\n/**\n * Create this module. Must be matched with the 'destroy()' function on exit\n */\nstruct PayloadsUDP *\npayloads_udp_create(void);\n\nstruct PayloadsUDP *\npayloads_oproto_create(void);\n\n/**\n * Free the resources of an object created with a matching call to\n * 'payloads_create()'\n */\nvoid\npayloads_udp_destroy(struct PayloadsUDP *payloads);\n\nvoid\npayloads_oproto_destroy(struct PayloadsUDP *payloads);\n\n/**\n * Read payloads from an \"nmap-payloads\" formatted file. The caller is\n * responsible for opening/closing the file, but should passing the\n * filename so that we can print helpful error messages.\n */\nvoid\npayloads_udp_readfile(FILE *fp, const char *filename,\n                   struct PayloadsUDP *payloads);\n\n/**\n * Read payloads from a libpcap formatted file.\n */\nvoid\npayloads_read_pcap(const char *filename, struct PayloadsUDP *payloads, struct PayloadsUDP *oproto_payloads);\n\n/**\n * Called to remove any payloads that aren't be used in the scan. This makes\n * lookups faster when generating packets.\n */\nvoid\npayloads_udp_trim(struct PayloadsUDP *payloads, const struct MassIP *targets);\n\nvoid\npayloads_oproto_trim(struct PayloadsUDP *payloads, const struct MassIP *targets);\n\n\n/**\n * The port scanner creates a \"cookie\" for every packet that it sends, which\n * will be a 64-bit value, whose low-order bits will be trimmed to fit whatever\n * size is available. For TCP, this becomes the 32-bit seqno of the SYN packet.\n * For UDP protocols, however, each application layer protocol will be\n * different. For example, SNMP can use a 32-bit transaction ID, whereas DNS\n * can use only a 16-bit transaction ID.\n */\ntypedef unsigned (*SET_COOKIE)(unsigned char *px, size_t length,\n                               uint64_t seqno);\n\n\n/**\n * Given a UDP port number, return the payload we have that is associated\n * with that port number.\n * @param payloads\n *      A table full over payloads.\n * @param port\n *      The input port number.\n * @param px\n *      The returned payload bytes.\n * @param length\n *      The returned count of payload bytes.\n * @param source_port\n *      The returned port that should be used when sending packets.\n * @param xsum\n *      The returned partial checksum of the payload bytes, so that it\n *      doesn't need to be recalculated for every packet.\n * @param set_cookie\n *      The returned function that will set the \"cookie\" field in the\n *      packet for each transmission\n */\nint\npayloads_udp_lookup(\n                const struct PayloadsUDP *payloads,\n                unsigned port,\n                const unsigned char **px,\n                unsigned *length,\n                unsigned *source_port,\n                uint64_t *xsum,\n                SET_COOKIE *set_cookie);\n\nint\npayloads_oproto_lookup(\n                    const struct PayloadsUDP *payloads,\n                    unsigned port,\n                    const unsigned char **px,\n                    unsigned *length,\n                    unsigned *source_port,\n                    uint64_t *xsum,\n                    SET_COOKIE *set_cookie);\n\n\n\n#endif\n"
  },
  {
    "path": "src/templ-pkt.c",
    "content": "/*\n\n    Construct a TCP packet based upon a template.\n\n    The (eventual) idea of this module is to make this scanner extensible\n    by providing an arbitrary packet template. Thus, the of this module\n    is to take an existing packet template, parse it, then make\n    appropriate changes.\n*/\n#include \"templ-pkt.h\"\n#include \"templ-tcp-hdr.h\"\n#include \"templ-opts.h\"\n#include \"massip-port.h\"\n#include \"proto-preprocess.h\"\n#include \"proto-sctp.h\"\n#include \"util-safefunc.h\"\n#include \"pixie-timer.h\"\n#include \"util-logger.h\"\n#include \"templ-payloads.h\"\n#include \"syn-cookie.h\"\n#include \"unusedparm.h\"\n#include \"vulncheck.h\"\n#include \"util-checksum.h\"\n#include \"util-malloc.h\"\n#include \"stub-pcap-dlt.h\" /* data link types, like NULL, RAW, or ETHERNET */\n#include <assert.h>\n#include <string.h>\n#include <stdlib.h>\n\nstatic unsigned char default_tcp_template[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x2c\"      /* total length = 40 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x06\"      /* TTL=255, proto=TCP */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\0\\0\"          /* source port */\n    \"\\0\\0\"          /* destination port */\n    \"\\0\\0\\0\\0\"      /* sequence number */\n    \"\\0\\0\\0\\0\"      /* ACK number */\n    \"\\x60\"          /* header length */\n    \"\\x02\"          /* SYN */\n    \"\\x04\\x01\"      /* window fixed to 1024 */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\x00\\x00\"      /* urgent pointer */\n      \"\\x02\\x04\\x05\\xb4\"  /* opt [mss 1460] h/t @IvreRocks */\n;\n\nstatic unsigned char default_udp_template[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x1c\"      /* total length = 28 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x11\"      /* TTL=255, proto=UDP */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\xfe\\xdc\"      /* source port */\n    \"\\x00\\x00\"      /* destination port */\n    \"\\x00\\x08\"      /* length */\n    \"\\x00\\x00\"      /* checksum */\n;\n\nstatic unsigned char default_sctp_template[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x34\"      /* total length = 52 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x84\"      /* TTL=255, proto = SCTP */\n    \"\\x00\\x00\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\x00\\x00\"          /* source port */\n    \"\\x00\\x00\"          /* destination port */\n    \"\\x00\\x00\\x00\\x00\"  /* verification tag */\n    \"\\x58\\xe4\\x5d\\x36\"  /* checksum */\n    \"\\x01\"              /* type = init */\n    \"\\x00\"              /* flags = none */\n    \"\\x00\\x14\"          /* length = 20 */\n    \"\\x9e\\x8d\\x52\\x25\"  /* initiate tag */\n    \"\\x00\\x00\\x80\\x00\"  /* receiver window credit */\n    \"\\x00\\x0a\"          /* outbound streams = 10 */\n    \"\\x08\\x00\"          /* inbound streams = 2048 */\n    \"\\x46\\x1a\\xdf\\x3d\"  /* initial TSN */\n;\n\n\nstatic unsigned char default_icmp_ping_template[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x4c\"      /* total length = 76 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x01\"      /* TTL=255, proto=ICMP */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\x08\\x00\"      /* Ping Request */\n    \"\\x00\\x00\"      /* checksum */\n\n    \"\\x00\\x00\\x00\\x00\" /* ID, seqno */\n\n    \"\\x08\\x09\\x0a\\x0b\" /* payload */\n    \"\\x0c\\x0d\\x0e\\x0f\"\n    \"\\x10\\x11\\x12\\x13\"\n    \"\\x14\\x15\\x16\\x17\"\n    \"\\x18\\x19\\x1a\\x1b\"\n    \"\\x1c\\x1d\\x1e\\x1f\"\n    \"\\x20\\x21\\x22\\x23\"\n    \"\\x24\\x25\\x26\\x27\"\n    \"\\x28\\x29\\x2a\\x2b\"\n    \"\\x2c\\x2d\\x2e\\x2f\"\n    \"\\x30\\x31\\x32\\x33\"\n    \"\\x34\\x35\\x36\\x37\"\n;\n\nstatic unsigned char default_icmp_timestamp_template[] =\n\"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n\"\\x08\\x00\"      /* Ethernet type: IPv4 */\n\"\\x45\"          /* IP type */\n\"\\x00\"\n\"\\x00\\x28\"      /* total length = 84 bytes */\n\"\\x00\\x00\"      /* identification */\n\"\\x00\\x00\"      /* fragmentation flags */\n\"\\xFF\\x01\"      /* TTL=255, proto=UDP */\n\"\\xFF\\xFF\"      /* checksum */\n\"\\0\\0\\0\\0\"      /* source address */\n\"\\0\\0\\0\\0\"      /* destination address */\n\n\"\\x0d\\x00\"  /* timestamp request */\n\"\\x00\\x00\"  /* checksum */\n\"\\x00\\x00\"  /* identifier */\n\"\\x00\\x00\"  /* sequence number */\n\"\\x00\\x00\\x00\\x00\"\n\"\\x00\\x00\\x00\\x00\"\n\"\\x00\\x00\\x00\\x00\"\n;\n\n\nstatic unsigned char default_arp_template[] =\n    \"\\xff\\xff\\xff\\xff\\xff\\xff\"  /* Ethernet: destination */\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\"  /* Ethernet: source */\n    \"\\x08\\x06\"      /* Ethernet type: ARP */\n    \"\\x00\\x01\" /* hardware = Ethernet */\n    \"\\x08\\x00\" /* protocol = IPv4 */\n    \"\\x06\\x04\" /* MAC length = 6, IPv4 length = 4 */\n    \"\\x00\\x01\" /* opcode = request */\n\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\"\n    \"\\x00\\x00\\x00\\x00\"\n\n    \"\\x00\\x00\\x00\\x00\\x00\\x00\"\n    \"\\x00\\x00\\x00\\x00\"\n;\n\n\n/***************************************************************************\n * Checksum the IP header. This is a \"partial\" checksum, so we\n * don't reverse the bits ~.\n ***************************************************************************/\nstatic unsigned\nip_header_checksum(const unsigned char *px, unsigned offset, unsigned max_offset)\n{\n    unsigned header_length = (px[offset]&0xF) * 4;\n    unsigned xsum = 0;\n    unsigned i;\n\n    /* restrict check only over packet */\n    if (max_offset > offset + header_length)\n        max_offset = offset + header_length;\n\n    /* add all the two-byte words together */\n    xsum = 0;\n    for (i = offset; i < max_offset; i += 2) {\n        xsum += px[i]<<8 | px[i+1];\n    }\n\n    /* if more than 16 bits in result, reduce to 16 bits */\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return xsum;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcp_checksum2(const unsigned char *px, unsigned offset_ip,\n              unsigned offset_tcp, size_t tcp_length)\n{\n    uint64_t xsum = 0;\n    unsigned i;\n\n    /* pseudo checksum */\n    xsum = 6;\n    xsum += tcp_length;\n    xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];\n    xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];\n    xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];\n    xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];\n\n    /* TCP checksum */\n    for (i=0; i<tcp_length; i += 2) {\n        xsum += px[offset_tcp + i]<<8 | px[offset_tcp + i + 1];\n    }\n\n    xsum -= (tcp_length & 1) * px[offset_tcp + i - 1]; /* yea I know going off end of packet is bad so sue me */\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return (unsigned)xsum;\n}\n\n/***************************************************************************\n ***************************************************************************/\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcp_ipv4_checksum(struct TemplatePacket *tmpl)\n{\n    const unsigned char *px = tmpl->ipv4.packet;\n    unsigned offset_ip = tmpl->ipv4.offset_ip;\n    unsigned offset_app = tmpl->ipv4.offset_app;\n    unsigned offset_tcp = tmpl->ipv4.offset_tcp;\n    unsigned xsum = 0;\n    unsigned i;\n\n\n\n    /* pseudo checksum */\n    xsum = 6;\n    xsum += offset_app - offset_tcp;\n    xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];\n    xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];\n    xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];\n    xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];\n\n    /* TCP checksum */\n    for (i=offset_tcp; i<offset_app; i += 2) {\n        xsum += px[i]<<8 | px[i+1];\n    }\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return xsum;\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nunsigned\nudp_checksum2(const unsigned char *px, unsigned offset_ip,\n              unsigned offset_tcp, size_t tcp_length)\n{\n    uint64_t xsum = 0;\n    unsigned i;\n\n    /* pseudo checksum */\n    xsum = 17;\n    xsum += tcp_length;\n    xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];\n    xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];\n    xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];\n    xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];\n\n    /* TCP checksum */\n    for (i=0; i<tcp_length; i += 2) {\n        xsum += px[offset_tcp + i]<<8 | px[offset_tcp + i + 1];\n    }\n\n    xsum -= (tcp_length & 1) * px[offset_tcp + i - 1]; /* yea I know going off end of packet is bad so sue me */\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return (unsigned)xsum;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nudp_ipv4_checksum(struct TemplatePacket *tmpl)\n{\n    return udp_checksum2(\n                         tmpl->ipv4.packet,\n                         tmpl->ipv4.offset_ip,\n                         tmpl->ipv4.offset_tcp,\n                         tmpl->ipv4.length - tmpl->ipv4.offset_tcp);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nicmp_checksum2(const unsigned char *px,\n              unsigned offset_icmp, size_t icmp_length)\n{\n    uint64_t xsum = 0;\n    unsigned i;\n\n    for (i=0; i<icmp_length; i += 2) {\n        xsum += px[offset_icmp + i]<<8 | px[offset_icmp + i + 1];\n    }\n\n    xsum -= (icmp_length & 1) * px[offset_icmp + i - 1]; /* yea I know going off end of packet is bad so sue me */\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n    xsum = (xsum & 0xFFFF) + (xsum >> 16);\n\n    return (unsigned)xsum;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\nicmp_ipv4_checksum(struct TemplatePacket *tmpl)\n{\n    return icmp_checksum2(\n                         tmpl->ipv4.packet,\n                         tmpl->ipv4.offset_tcp,\n                         tmpl->ipv4.length - tmpl->ipv4.offset_tcp);\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstruct TemplateSet templ_copy(const struct TemplateSet *templset)\n{\n    struct TemplateSet result;\n    unsigned i;\n\n    memcpy(&result, templset, sizeof(result));\n\n    for (i=0; i<templset->count; i++) {\n        const struct TemplatePacket *p1 = &templset->pkts[i];\n        struct TemplatePacket *p2 = &result.pkts[i];\n        p2->ipv4.packet = MALLOC(2048+p2->ipv4.length);\n        memcpy(p2->ipv4.packet, p1->ipv4.packet, p2->ipv4.length);\n        p2->ipv6.packet = MALLOC(2048+p2->ipv6.length);\n        memcpy(p2->ipv6.packet, p1->ipv6.packet, p2->ipv6.length);\n    }\n\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\ntcp_set_window(unsigned char *px, size_t px_length, unsigned window)\n{\n    struct PreprocessedInfo parsed;\n    unsigned x;\n    size_t offset;\n    unsigned xsum;\n\n    /* Parse the frame looking for the TCP header */\n    x = preprocess_frame(px, (unsigned)px_length, 1 /*enet*/, &parsed);\n    if (!x || parsed.found == FOUND_NOTHING)\n        return;\n    if (parsed.ip_protocol != 6)\n        return;\n    offset = parsed.transport_offset;\n    if (offset + 20 > px_length)\n        return;\n\n\n    /* set the new window */\n#if 0\n    xsum = px[offset + 16] << 8 | px[offset + 17];\n    xsum = (~xsum)&0xFFFF;\n    xsum += window & 0xFFFF;\n    xsum -= px[offset + 14] << 8 | px[offset + 15];\n    xsum = ((xsum)&0xFFFF) + (xsum >> 16);\n    xsum = ((xsum)&0xFFFF) + (xsum >> 16);\n    xsum = ((xsum)&0xFFFF) + (xsum >> 16);\n    xsum = (~xsum)&0xFFFF;\n#endif\n\n    px[offset + 14] = (unsigned char)(window>>8);\n    px[offset + 15] = (unsigned char)(window>>0);\n    px[offset + 16] = (unsigned char)(0);\n    px[offset + 17] = (unsigned char)(0);\n\n\n    xsum = ~tcp_checksum2(px, parsed.ip_offset, parsed.transport_offset,\n                            parsed.transport_length);\n\n    px[offset + 16] = (unsigned char)(xsum>>8);\n    px[offset + 17] = (unsigned char)(xsum>>0);\n}\n\n/***************************************************************************\n ***************************************************************************/\nsize_t\ntcp_create_packet(\n        struct TemplatePacket *tmpl,\n        ipaddress ip_them, unsigned port_them,\n        ipaddress ip_me, unsigned port_me,\n        unsigned seqno, unsigned ackno,\n        unsigned flags,\n        const unsigned char *payload, size_t payload_length,\n        unsigned char *px, size_t px_length)\n{\n    uint64_t xsum;\n  \n    if (ip_them.version == 4) {\n        unsigned ip_id = ip_them.ipv4 ^ port_them ^ seqno;\n        unsigned offset_ip = tmpl->ipv4.offset_ip;\n        unsigned offset_tcp = tmpl->ipv4. offset_tcp;\n        unsigned offset_payload = offset_tcp + ((tmpl->ipv4.packet[offset_tcp+12]&0xF0)>>2);\n        size_t new_length = offset_payload + payload_length;\n        size_t ip_len = (offset_payload - offset_ip) + payload_length;\n        unsigned old_len;\n\n        if (new_length > px_length) {\n            fprintf(stderr, \"tcp: err generating packet: too much payload\\n\");\n            return 0;\n        }\n\n        memcpy(px + 0,              tmpl->ipv4.packet,   tmpl->ipv4.length);\n        memcpy(px + offset_payload, payload,        payload_length);\n        old_len = px[offset_ip+2]<<8 | px[offset_ip+3];\n\n        /*\n         * Fill in the empty fields in the IP header and then re-calculate\n         * the checksum.\n         */\n        px[offset_ip+2] = (unsigned char)(ip_len>> 8);\n        px[offset_ip+3] = (unsigned char)(ip_len & 0xFF);\n        px[offset_ip+4] = (unsigned char)(ip_id >> 8);\n        px[offset_ip+5] = (unsigned char)(ip_id & 0xFF);\n        px[offset_ip+12] = (unsigned char)((ip_me.ipv4 >> 24) & 0xFF);\n        px[offset_ip+13] = (unsigned char)((ip_me.ipv4 >> 16) & 0xFF);\n        px[offset_ip+14] = (unsigned char)((ip_me.ipv4 >>  8) & 0xFF);\n        px[offset_ip+15] = (unsigned char)((ip_me.ipv4 >>  0) & 0xFF);\n        px[offset_ip+16] = (unsigned char)((ip_them.ipv4 >> 24) & 0xFF);\n        px[offset_ip+17] = (unsigned char)((ip_them.ipv4 >> 16) & 0xFF);\n        px[offset_ip+18] = (unsigned char)((ip_them.ipv4 >>  8) & 0xFF);\n        px[offset_ip+19] = (unsigned char)((ip_them.ipv4 >>  0) & 0xFF);\n\n        xsum = tmpl->ipv4.checksum_ip;\n        xsum += (ip_id&0xFFFF);\n        xsum += ip_me.ipv4;\n        xsum += ip_them.ipv4;\n        xsum += ip_len - old_len;\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = ~xsum;\n\n        px[offset_ip+10] = (unsigned char)(xsum >> 8);\n        px[offset_ip+11] = (unsigned char)(xsum & 0xFF);\n\n        /*\n         * now do the same for TCP\n         */\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n\n        px[offset_tcp+ 8] = (unsigned char)(ackno >> 24);\n        px[offset_tcp+ 9] = (unsigned char)(ackno >> 16);\n        px[offset_tcp+10] = (unsigned char)(ackno >>  8);\n        px[offset_tcp+11] = (unsigned char)(ackno >>  0);\n\n        px[offset_tcp+13] = (unsigned char)flags;\n\n        px[offset_tcp+14] = (unsigned char)(1200>>8);\n        px[offset_tcp+15] = (unsigned char)(1200 & 0xFF);\n\n        px[offset_tcp+16] = (unsigned char)(0 >>  8);\n        px[offset_tcp+17] = (unsigned char)(0 >>  0);\n\n        xsum = tcp_checksum2(px, tmpl->ipv4.offset_ip, tmpl->ipv4.offset_tcp,\n                             new_length - tmpl->ipv4.offset_tcp);\n        xsum = ~xsum;\n\n        px[offset_tcp+16] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+17] = (unsigned char)(xsum >>  0);\n\n        if (new_length < 60) {\n            memset(px+new_length, 0, 60-new_length);\n            new_length = 60;\n        }\n        return new_length;\n    } else {\n        unsigned offset_ip = tmpl->ipv6.offset_ip;\n        unsigned offset_tcp = tmpl->ipv6.offset_tcp;\n        unsigned offset_app = tmpl->ipv6.offset_app;\n\n        /* Make sure the new packet won't exceed buffer size */\n        if (offset_app + payload_length > px_length) {\n            fprintf(stderr, \"tcp: err generating packet: too much payload\\n\");\n            return 0;\n        }\n\n        /* Copy over everything up to the new application-layer-payload */\n        memcpy(px, tmpl->ipv6.packet, tmpl->ipv6.offset_app);\n\n        /* Replace the template's application-layer-payload with the new app-payload */\n        memcpy(px + tmpl->ipv6.offset_app, payload, payload_length);\n\n        /* Fixup the \"payload length\" field in the IPv6 header. This is everything\n         * after the IPv6 header. There may be additional headers between the IPv6\n         * and TCP headers, so the calculation isn't simply the length of the TCP portion */\n        {\n            size_t len = tmpl->ipv6.offset_app + payload_length - tmpl->ipv6.offset_ip - 40;\n            px[offset_ip + 4] = (unsigned char)(len>>8) & 0xFF;\n            px[offset_ip + 5] = (unsigned char)(len>>0) & 0xFF;\n        }\n\n        /* Copy over the IP addresses */\n        px[offset_ip+ 8] = (unsigned char)((ip_me.ipv6.hi >> 56ULL) & 0xFF);\n        px[offset_ip+ 9] = (unsigned char)((ip_me.ipv6.hi >> 48ULL) & 0xFF);\n        px[offset_ip+10] = (unsigned char)((ip_me.ipv6.hi >> 40ULL) & 0xFF);\n        px[offset_ip+11] = (unsigned char)((ip_me.ipv6.hi >> 32ULL) & 0xFF);\n        px[offset_ip+12] = (unsigned char)((ip_me.ipv6.hi >> 24ULL) & 0xFF);\n        px[offset_ip+13] = (unsigned char)((ip_me.ipv6.hi >> 16ULL) & 0xFF);\n        px[offset_ip+14] = (unsigned char)((ip_me.ipv6.hi >>  8ULL) & 0xFF);\n        px[offset_ip+15] = (unsigned char)((ip_me.ipv6.hi >>  0ULL) & 0xFF);\n\n        px[offset_ip+16] = (unsigned char)((ip_me.ipv6.lo >> 56ULL) & 0xFF);\n        px[offset_ip+17] = (unsigned char)((ip_me.ipv6.lo >> 48ULL) & 0xFF);\n        px[offset_ip+18] = (unsigned char)((ip_me.ipv6.lo >> 40ULL) & 0xFF);\n        px[offset_ip+19] = (unsigned char)((ip_me.ipv6.lo >> 32ULL) & 0xFF);\n        px[offset_ip+20] = (unsigned char)((ip_me.ipv6.lo >> 24ULL) & 0xFF);\n        px[offset_ip+21] = (unsigned char)((ip_me.ipv6.lo >> 16ULL) & 0xFF);\n        px[offset_ip+22] = (unsigned char)((ip_me.ipv6.lo >>  8ULL) & 0xFF);\n        px[offset_ip+23] = (unsigned char)((ip_me.ipv6.lo >>  0ULL) & 0xFF);\n\n        px[offset_ip+24] = (unsigned char)((ip_them.ipv6.hi >> 56ULL) & 0xFF);\n        px[offset_ip+25] = (unsigned char)((ip_them.ipv6.hi >> 48ULL) & 0xFF);\n        px[offset_ip+26] = (unsigned char)((ip_them.ipv6.hi >> 40ULL) & 0xFF);\n        px[offset_ip+27] = (unsigned char)((ip_them.ipv6.hi >> 32ULL) & 0xFF);\n        px[offset_ip+28] = (unsigned char)((ip_them.ipv6.hi >> 24ULL) & 0xFF);\n        px[offset_ip+29] = (unsigned char)((ip_them.ipv6.hi >> 16ULL) & 0xFF);\n        px[offset_ip+30] = (unsigned char)((ip_them.ipv6.hi >>  8ULL) & 0xFF);\n        px[offset_ip+31] = (unsigned char)((ip_them.ipv6.hi >>  0ULL) & 0xFF);\n\n        px[offset_ip+32] = (unsigned char)((ip_them.ipv6.lo >> 56ULL) & 0xFF);\n        px[offset_ip+33] = (unsigned char)((ip_them.ipv6.lo >> 48ULL) & 0xFF);\n        px[offset_ip+34] = (unsigned char)((ip_them.ipv6.lo >> 40ULL) & 0xFF);\n        px[offset_ip+35] = (unsigned char)((ip_them.ipv6.lo >> 32ULL) & 0xFF);\n        px[offset_ip+36] = (unsigned char)((ip_them.ipv6.lo >> 24ULL) & 0xFF);\n        px[offset_ip+37] = (unsigned char)((ip_them.ipv6.lo >> 16ULL) & 0xFF);\n        px[offset_ip+38] = (unsigned char)((ip_them.ipv6.lo >>  8ULL) & 0xFF);\n        px[offset_ip+39] = (unsigned char)((ip_them.ipv6.lo >>  0ULL) & 0xFF);\n\n\n        /*\n         * now do the same for TCP\n         */\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n\n        px[offset_tcp+ 8] = (unsigned char)(ackno >> 24);\n        px[offset_tcp+ 9] = (unsigned char)(ackno >> 16);\n        px[offset_tcp+10] = (unsigned char)(ackno >>  8);\n        px[offset_tcp+11] = (unsigned char)(ackno >>  0);\n\n        px[offset_tcp+13] = (unsigned char)flags;\n\n        px[offset_tcp+14] = (unsigned char)(1200>>8);\n        px[offset_tcp+15] = (unsigned char)(1200 & 0xFF);\n\n        px[offset_tcp+16] = (unsigned char)(0 >>  8);\n        px[offset_tcp+17] = (unsigned char)(0 >>  0);\n\n        xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 6, (offset_app - offset_tcp) + payload_length, px + offset_tcp);\n        px[offset_tcp+16] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+17] = (unsigned char)(xsum >>  0);\n\n        px[offset_tcp+16] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+17] = (unsigned char)(xsum >>  0);\n\n        return offset_app + payload_length;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nudp_payload_fixup(struct TemplatePacket *tmpl, unsigned port, unsigned seqno)\n{\n    const unsigned char *px2 = 0;\n    unsigned length2 = 0;\n    unsigned source_port2 = 0x1000;\n    uint64_t xsum2 = 0;\n    //unsigned char *px = tmpl->packet;\n    SET_COOKIE set_cookie = 0;\n\n    UNUSEDPARM(seqno);\n\n    payloads_udp_lookup(tmpl->payloads,\n                    port,\n                    &px2,\n                    &length2,\n                    &source_port2,\n                    &xsum2,\n                    &set_cookie);\n\n    /* Copy over the payloads */\n    memcpy( tmpl->ipv4.packet + tmpl->ipv4.offset_app,\n            px2,\n            length2);\n    memcpy( tmpl->ipv6.packet + tmpl->ipv6.offset_app,\n            px2,\n            length2);\n\n    /* Change the cookie values */\n    if (set_cookie) {\n        set_cookie(\n                        tmpl->ipv4.packet + tmpl->ipv4.offset_app,\n                        length2,\n                        seqno);\n        set_cookie(\n                        tmpl->ipv6.packet + tmpl->ipv6.offset_app,\n                        length2,\n                        seqno);\n    }\n\n    tmpl->ipv4.length = tmpl->ipv4.offset_app + length2;\n    tmpl->ipv6.length = tmpl->ipv6.offset_app + length2;\n}\n\nvoid\ntemplate_set_target_ipv6(\n    struct TemplateSet *tmplset,\n    ipv6address ip_them, unsigned port_them,\n    ipv6address ip_me, unsigned port_me,\n    unsigned seqno,\n    unsigned char *px, size_t sizeof_px, size_t *r_length\n    )\n{\n    unsigned offset_ip;\n    unsigned offset_tcp;\n    uint64_t xsum;\n    struct TemplatePacket *tmpl = NULL;\n    uint64_t entropy = tmplset->entropy;\n    unsigned payload_length;\n\n    *r_length = sizeof_px;\n\n    /*\n     * Find out which packet template to use. This is because we can\n     * simultaneously scan for both TCP and UDP (and others). We've\n     * just overloaded the \"port\" field to signal which protocol we\n     * are using\n     */\n    if (port_them < Templ_TCP + 65536)\n        tmpl = &tmplset->pkts[Proto_TCP];\n    else if (port_them < Templ_UDP + 65536) {\n        tmpl = &tmplset->pkts[Proto_UDP];\n        port_them &= 0xFFFF;\n        udp_payload_fixup(tmpl, port_them, seqno);\n    } else if (port_them < Templ_SCTP + 65536) {\n        tmpl = &tmplset->pkts[Proto_SCTP];\n        port_them &= 0xFFFF;\n    } else if (port_them == Templ_ICMP_echo) {\n        tmpl = &tmplset->pkts[Proto_ICMP_ping];\n    } else if (port_them == Templ_ICMP_timestamp) {\n        tmpl = &tmplset->pkts[Proto_ICMP_timestamp];\n    } else if (port_them == Templ_ARP) {\n        tmpl = &tmplset->pkts[Proto_ARP];\n        if (*r_length > tmpl->ipv6.length)\n            *r_length = tmpl->ipv6.length;\n        memcpy(px, tmpl->ipv6.packet, *r_length);\n        return;\n    } else if (port_them == Templ_VulnCheck) {\n        tmpl = &tmplset->pkts[Proto_VulnCheck];\n        port_them &= 0xFFFF;\n    } else {\n        return;\n    }\n\n    /* Create some shorter local variables to work with */\n    if (*r_length > tmpl->ipv6.length)\n        *r_length = tmpl->ipv6.length;\n    memcpy(px, tmpl->ipv6.packet, *r_length);\n    offset_ip = tmpl->ipv6.offset_ip;\n    offset_tcp = tmpl->ipv6.offset_tcp;\n    //ip_id = ip_them ^ port_them ^ seqno;\n\n/*\n\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |Version| Traffic Class |           Flow Label                  |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |         Payload Length        |  Next Header  |   Hop Limit   |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                                                               |\n   +                                                               +\n   |                                                               |\n   +                         Source Address                        +\n   |                                                               |\n   +                                                               +\n   |                                                               |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                                                               |\n   +                                                               +\n   |                                                               |\n   +                      Destination Address                      +\n   |                                                               |\n   +                                                               +\n   |                                                               |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n*/\n    /*\n     * Fill in the empty fields in the IP header and then re-calculate\n     * the checksum.\n     */\n    payload_length = tmpl->ipv6.length - tmpl->ipv6.offset_ip - 40;\n    px[offset_ip+4] = (unsigned char)(payload_length>>8);\n    px[offset_ip+5] = (unsigned char)(payload_length>>0);\n    px[offset_ip+ 8] = (unsigned char)((ip_me.hi >> 56ULL) & 0xFF);\n    px[offset_ip+ 9] = (unsigned char)((ip_me.hi >> 48ULL) & 0xFF);\n    px[offset_ip+10] = (unsigned char)((ip_me.hi >> 40ULL) & 0xFF);\n    px[offset_ip+11] = (unsigned char)((ip_me.hi >> 32ULL) & 0xFF);\n    px[offset_ip+12] = (unsigned char)((ip_me.hi >> 24ULL) & 0xFF);\n    px[offset_ip+13] = (unsigned char)((ip_me.hi >> 16ULL) & 0xFF);\n    px[offset_ip+14] = (unsigned char)((ip_me.hi >>  8ULL) & 0xFF);\n    px[offset_ip+15] = (unsigned char)((ip_me.hi >>  0ULL) & 0xFF);\n\n    px[offset_ip+16] = (unsigned char)((ip_me.lo >> 56ULL) & 0xFF);\n    px[offset_ip+17] = (unsigned char)((ip_me.lo >> 48ULL) & 0xFF);\n    px[offset_ip+18] = (unsigned char)((ip_me.lo >> 40ULL) & 0xFF);\n    px[offset_ip+19] = (unsigned char)((ip_me.lo >> 32ULL) & 0xFF);\n    px[offset_ip+20] = (unsigned char)((ip_me.lo >> 24ULL) & 0xFF);\n    px[offset_ip+21] = (unsigned char)((ip_me.lo >> 16ULL) & 0xFF);\n    px[offset_ip+22] = (unsigned char)((ip_me.lo >>  8ULL) & 0xFF);\n    px[offset_ip+23] = (unsigned char)((ip_me.lo >>  0ULL) & 0xFF);\n\n    px[offset_ip+24] = (unsigned char)((ip_them.hi >> 56ULL) & 0xFF);\n    px[offset_ip+25] = (unsigned char)((ip_them.hi >> 48ULL) & 0xFF);\n    px[offset_ip+26] = (unsigned char)((ip_them.hi >> 40ULL) & 0xFF);\n    px[offset_ip+27] = (unsigned char)((ip_them.hi >> 32ULL) & 0xFF);\n    px[offset_ip+28] = (unsigned char)((ip_them.hi >> 24ULL) & 0xFF);\n    px[offset_ip+29] = (unsigned char)((ip_them.hi >> 16ULL) & 0xFF);\n    px[offset_ip+30] = (unsigned char)((ip_them.hi >>  8ULL) & 0xFF);\n    px[offset_ip+31] = (unsigned char)((ip_them.hi >>  0ULL) & 0xFF);\n\n    px[offset_ip+32] = (unsigned char)((ip_them.lo >> 56ULL) & 0xFF);\n    px[offset_ip+33] = (unsigned char)((ip_them.lo >> 48ULL) & 0xFF);\n    px[offset_ip+34] = (unsigned char)((ip_them.lo >> 40ULL) & 0xFF);\n    px[offset_ip+35] = (unsigned char)((ip_them.lo >> 32ULL) & 0xFF);\n    px[offset_ip+36] = (unsigned char)((ip_them.lo >> 24ULL) & 0xFF);\n    px[offset_ip+37] = (unsigned char)((ip_them.lo >> 16ULL) & 0xFF);\n    px[offset_ip+38] = (unsigned char)((ip_them.lo >>  8ULL) & 0xFF);\n    px[offset_ip+39] = (unsigned char)((ip_them.lo >>  0ULL) & 0xFF);\n\n    /*\n     * Now do the checksum for the higher layer protocols\n     */\n    switch (tmpl->proto) {\n    case Proto_TCP:\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n\n        xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 6,  tmpl->ipv6.length - offset_tcp, px + offset_tcp);\n        px[offset_tcp+16] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+17] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_UDP:\n            /* TODO: IPv6 */\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)((tmpl->ipv6.length - tmpl->ipv6.offset_app + 8)>>8);\n        px[offset_tcp+ 5] = (unsigned char)((tmpl->ipv6.length - tmpl->ipv6.offset_app + 8)&0xFF);\n\n        px[offset_tcp+6] = (unsigned char)(0);\n        px[offset_tcp+7] = (unsigned char)(0);\n        xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 17,  tmpl->ipv6.length - offset_tcp, px + offset_tcp);\n        px[offset_tcp+6] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+7] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_SCTP:\n            /* TODO: IPv6 */\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n\n        px[offset_tcp+16] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+17] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+18] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+19] = (unsigned char)(seqno >>  0);\n\n        xsum = sctp_checksum(px + offset_tcp, tmpl->ipv6.length - offset_tcp);\n        px[offset_tcp+ 8] = (unsigned char)(xsum >>  24);\n        px[offset_tcp+ 9] = (unsigned char)(xsum >>  16);\n        px[offset_tcp+10] = (unsigned char)(xsum >>   8);\n        px[offset_tcp+11] = (unsigned char)(xsum >>   0);\n        break;\n    case Proto_ICMP_ping:\n    case Proto_ICMP_timestamp:\n            /* TODO: IPv6 */\n            seqno = (unsigned)syn_cookie_ipv6(ip_them, port_them, ip_me, 0, entropy);\n            px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n            px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n            px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n            px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n            xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 58,  tmpl->ipv6.length - offset_tcp, px + offset_tcp);\n            px[offset_tcp+2] = (unsigned char)(xsum >>  8);\n            px[offset_tcp+3] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_VulnCheck:\n            /* TODO: IPv6 */\n            /*tmplset->vulncheck->set_target(tmpl,\n                                     ip_them, port_them,\n                                     ip_me, port_me,\n                                     seqno,\n                                     px, sizeof_px, r_length);*/\n            break;\n    case Proto_ARP:\n            /* TODO: IPv6 */\n        /* don't do any checksumming */\n        break;\n    case Proto_Oproto:\n            /* TODO: IPv6 */\n        /* TODO: probably need to add checksums for certain protocols */\n        break;\n    case Proto_Count:\n        break;\n    }\n}\n\n\n/***************************************************************************\n * This is the function that formats the transmitted packets for probing\n * machines. It takes a template for the protocol (usually a TCP SYN\n * packet), then sets the destination IP address and port numbers.\n ***************************************************************************/\nvoid\ntemplate_set_target_ipv4(\n    struct TemplateSet *tmplset,\n    ipv4address ip_them, unsigned port_them,\n    ipv4address ip_me, unsigned port_me,\n    unsigned seqno,\n    unsigned char *px, size_t sizeof_px, size_t *r_length\n    )\n{\n    unsigned offset_ip;\n    unsigned offset_tcp;\n    uint64_t xsum;\n    unsigned ip_id;\n    struct TemplatePacket *tmpl = NULL;\n    unsigned xsum2;\n    uint64_t entropy = tmplset->entropy;\n    \n    *r_length = sizeof_px;\n\n    /*\n     * Find out which packet template to use. This is because we can\n     * simultaneously scan for both TCP and UDP (and others). We've\n     * just overloaded the \"port\" field to signal which protocol we\n     * are using\n     */\n    if (port_them < Templ_TCP + 65536)\n        tmpl = &tmplset->pkts[Proto_TCP];\n    else if (port_them < Templ_UDP + 65536) {\n        tmpl = &tmplset->pkts[Proto_UDP];\n        port_them &= 0xFFFF;\n        udp_payload_fixup(tmpl, port_them, seqno);\n    } else if (port_them < Templ_SCTP + 65536) {\n        tmpl = &tmplset->pkts[Proto_SCTP];\n        port_them &= 0xFFFF;\n    } else if (port_them == Templ_ICMP_echo) {\n        tmpl = &tmplset->pkts[Proto_ICMP_ping];\n    } else if (port_them == Templ_ICMP_timestamp) {\n        tmpl = &tmplset->pkts[Proto_ICMP_timestamp];\n    } else if (port_them == Templ_ARP) {\n        tmpl = &tmplset->pkts[Proto_ARP];\n        if (*r_length > tmpl->ipv4.length)\n            *r_length = tmpl->ipv4.length;\n        memcpy(px, tmpl->ipv4.packet, *r_length);\n        px = px + tmpl->ipv4.offset_ip;\n        px[14] = (unsigned char)((ip_me >> 24) & 0xFF);\n        px[15] = (unsigned char)((ip_me >> 16) & 0xFF);\n        px[16] = (unsigned char)((ip_me >>  8) & 0xFF);\n        px[17] = (unsigned char)((ip_me >>  0) & 0xFF);\n        px[24] = (unsigned char)((ip_them >> 24) & 0xFF);\n        px[25] = (unsigned char)((ip_them >> 16) & 0xFF);\n        px[26] = (unsigned char)((ip_them >>  8) & 0xFF);\n        px[27] = (unsigned char)((ip_them >>  0) & 0xFF);\n        return;\n    } else if (port_them == Templ_VulnCheck) {\n        tmpl = &tmplset->pkts[Proto_VulnCheck];\n        port_them &= 0xFFFF;\n    } else {\n        return;\n    }\n\n    /* Create some shorter local variables to work with */\n    if (*r_length > tmpl->ipv4.length)\n        *r_length = tmpl->ipv4.length;\n    memcpy(px, tmpl->ipv4.packet, *r_length);\n    offset_ip = tmpl->ipv4.offset_ip;\n    offset_tcp = tmpl->ipv4.offset_tcp;\n    ip_id = ip_them ^ port_them ^ seqno;\n\n    /*\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |Version|  IHL  |Type of Service|          Total Length         |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |         Identification        |Flags|      Fragment Offset    |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |  Time to Live |    Protocol   |         Header Checksum       |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                       Source Address                          |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                    Destination Address                        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                    Options                    |    Padding    |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n*/\n\n    /*\n     * Fill in the empty fields in the IP header and then re-calculate\n     * the checksum.\n     */\n    {\n        unsigned total_length = tmpl->ipv4.length - tmpl->ipv4.offset_ip;\n        px[offset_ip+2] = (unsigned char)(total_length>>8);\n        px[offset_ip+3] = (unsigned char)(total_length>>0);\n    }\n    px[offset_ip+4] = (unsigned char)(ip_id >> 8);\n    px[offset_ip+5] = (unsigned char)(ip_id & 0xFF);\n    px[offset_ip+12] = (unsigned char)((ip_me >> 24) & 0xFF);\n    px[offset_ip+13] = (unsigned char)((ip_me >> 16) & 0xFF);\n    px[offset_ip+14] = (unsigned char)((ip_me >>  8) & 0xFF);\n    px[offset_ip+15] = (unsigned char)((ip_me >>  0) & 0xFF);\n    px[offset_ip+16] = (unsigned char)((ip_them >> 24) & 0xFF);\n    px[offset_ip+17] = (unsigned char)((ip_them >> 16) & 0xFF);\n    px[offset_ip+18] = (unsigned char)((ip_them >>  8) & 0xFF);\n    px[offset_ip+19] = (unsigned char)((ip_them >>  0) & 0xFF);\n\n\n    px[offset_ip+10] = (unsigned char)(0);\n    px[offset_ip+11] = (unsigned char)(0);\n\n    xsum2 = (unsigned)~ip_header_checksum(px, offset_ip, tmpl->ipv4.length);\n\n    px[offset_ip+10] = (unsigned char)(xsum2 >> 8);\n    px[offset_ip+11] = (unsigned char)(xsum2 & 0xFF);\n\n\n    /*\n     * Now do the checksum for the higher layer protocols\n     */\n    xsum = 0;\n    switch (tmpl->proto) {\n    case Proto_TCP:\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n\n        xsum += (uint64_t)tmpl->ipv4.checksum_tcp\n                + (uint64_t)ip_me\n                + (uint64_t)ip_them\n                + (uint64_t)port_me\n                + (uint64_t)port_them\n                + (uint64_t)seqno;\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = ~xsum;\n\n        px[offset_tcp+16] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+17] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_UDP:\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n        px[offset_tcp+ 4] = (unsigned char)((tmpl->ipv4.length - tmpl->ipv4.offset_app + 8)>>8);\n        px[offset_tcp+ 5] = (unsigned char)((tmpl->ipv4.length - tmpl->ipv4.offset_app + 8)&0xFF);\n\n        px[offset_tcp+6] = (unsigned char)(0);\n        px[offset_tcp+7] = (unsigned char)(0);\n        xsum = udp_checksum2(px, offset_ip, offset_tcp, tmpl->ipv4.length - offset_tcp);\n        /*xsum += (uint64_t)tmpl->checksum_tcp\n                + (uint64_t)ip_me\n                + (uint64_t)ip_them\n                + (uint64_t)port_me\n                + (uint64_t)port_them\n                + (uint64_t)2*(tmpl->length - tmpl->offset_app);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        xsum = (xsum >> 16) + (xsum & 0xFFFF);\n        printf(\"%04x\\n\", xsum);*/\n        xsum = ~xsum;\n        px[offset_tcp+6] = (unsigned char)(xsum >>  8);\n        px[offset_tcp+7] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_SCTP:\n        px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n        px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n        px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n        px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n\n        px[offset_tcp+16] = (unsigned char)(seqno >> 24);\n        px[offset_tcp+17] = (unsigned char)(seqno >> 16);\n        px[offset_tcp+18] = (unsigned char)(seqno >>  8);\n        px[offset_tcp+19] = (unsigned char)(seqno >>  0);\n\n        xsum = sctp_checksum(px + offset_tcp, tmpl->ipv4.length - offset_tcp);\n        px[offset_tcp+ 8] = (unsigned char)(xsum >>  24);\n        px[offset_tcp+ 9] = (unsigned char)(xsum >>  16);\n        px[offset_tcp+10] = (unsigned char)(xsum >>   8);\n        px[offset_tcp+11] = (unsigned char)(xsum >>   0);\n        break;\n    case Proto_ICMP_ping:\n    case Proto_ICMP_timestamp:\n            seqno = (unsigned)syn_cookie_ipv4(ip_them, port_them, ip_me, 0, entropy);\n            px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);\n            px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);\n            px[offset_tcp+ 6] = (unsigned char)(seqno >>  8);\n            px[offset_tcp+ 7] = (unsigned char)(seqno >>  0);\n            xsum = (uint64_t)tmpl->ipv4.checksum_tcp\n                    + (uint64_t)seqno;\n            xsum = (xsum >> 16) + (xsum & 0xFFFF);\n            xsum = (xsum >> 16) + (xsum & 0xFFFF);\n            xsum = (xsum >> 16) + (xsum & 0xFFFF);\n            xsum = ~xsum;\n            px[offset_tcp+2] = (unsigned char)(xsum >>  8);\n            px[offset_tcp+3] = (unsigned char)(xsum >>  0);\n        break;\n    case Proto_VulnCheck:\n            tmplset->vulncheck->set_target(tmpl,\n                                     ip_them, port_them,\n                                     ip_me, port_me,\n                                     seqno,\n                                     px, sizeof_px, r_length);\n            break;\n    case Proto_ARP:\n        /* don't do any checksumming */\n        break;\n    case Proto_Oproto:\n        /* TODO: probably need to add checksums for certain protocols */\n        break;\n    case Proto_Count:\n        break;\n    }\n}\n\n#if defined(WIN32) || defined(_WIN32)\n#define AF_INET6 23\n#else\n#include <sys/socket.h>\n#endif\n\n/***************************************************************************\n * Creates an IPv6 packet from an IPv4 template, by simply replacing\n * the IPv4 header with the IPv6 header.\n ***************************************************************************/\nstatic void\n_template_init_ipv6(struct TemplatePacket *tmpl, macaddress_t router_mac_ipv6, unsigned data_link_type)\n{\n    struct PreprocessedInfo parsed;\n    unsigned x;\n    unsigned payload_length;\n    unsigned offset_ip;\n    unsigned offset_tcp;\n    unsigned offset_tcp6;\n    unsigned char *buf;\n\n    /* Zero out everything and start from scratch */\n    if (tmpl->ipv6.packet) {\n        free(tmpl->ipv6.packet);\n        memset(&tmpl->ipv6, 0, sizeof(tmpl->ipv6));\n    }\n\n    /* Parse the existing IPv4 packet */\n    x = preprocess_frame(tmpl->ipv4.packet, tmpl->ipv4.length, data_link_type, &parsed);\n    if (!x || parsed.found == FOUND_NOTHING) {\n        LOG(0, \"ERROR: bad packet template\\n\");\n        exit(1);\n    }\n\n    /* The \"payload\" in this case is everything past the IP header,\n     * so TCP or UDP headers are inside the IP payload */\n    payload_length = tmpl->ipv4.length - tmpl->ipv4.offset_tcp;\n    offset_ip = tmpl->ipv4.offset_ip;\n    offset_tcp = tmpl->ipv4.offset_tcp;\n\n    /* Create a copy of the IPv4 packet */\n    buf = MALLOC(tmpl->ipv4.length + 40);\n    memcpy(buf, tmpl->ipv4.packet, tmpl->ipv4.length);\n    tmpl->ipv6.packet = buf;\n\n\n    /* destination = end of IPv6 header\n     * source = end of IPv4 header\n     * contents = everything after IPv4/IPv6 header */\n    offset_tcp6 = offset_ip + 40;\n    memmove(buf + offset_tcp6,\n            buf + offset_tcp,       \n            payload_length\n            );\n\n    /* fill the IPv6 header with zeroes */\n    memset(buf + offset_ip, 0, 40);\n    tmpl->ipv6.length = offset_ip + 40 + payload_length;\n    \n    switch (data_link_type) {\n        case PCAP_DLT_NULL: /* Null VPN tunnel */\n            /* FIXME: insert platform dependent value here */\n            *(int*)buf = AF_INET6;\n            break;\n\tcase PCAP_DLT_RAW: /* Raw (nothing before IP header) */\n\t    break;\n        case PCAP_DLT_ETHERNET: /* Ethernet */\n            /* Reset the destination MAC address to be the IPv6 router\n             * instead of the IPv4 router, which sometimes are different */\n            memcpy(buf + 0, router_mac_ipv6.addr, 6);\n            \n            /* Reset the Ethertype field to 0x86dd (meaning IPv6) */\n            buf[12] = 0x86;\n            buf[13] = 0xdd;\n            break;\n    }\n    \n\n    /* IP.version = 6 */\n    buf[offset_ip + 0] = 0x60; \n\n    /* Set payload length field. In IPv4, this field included the header,\n     * but in IPv6, it's everything after the header. In other words,\n     * the size of an IPv6 packet is 40+payload_length, whereas in IPv4\n     * it was total_length. */\n    buf[offset_ip + 4] = (unsigned char)(payload_length >> 8);\n    buf[offset_ip + 5] = (unsigned char)(payload_length >> 0);\n\n    /* Set the \"next header\" field.\n     * TODO: need to fix ICMP */\n    buf[offset_ip + 6] = (unsigned char)parsed.ip_protocol;\n    if (parsed.ip_protocol == 1) {\n        buf[offset_ip + 6] = 58; /* ICMPv6 */\n        if (payload_length > 0 && buf[offset_tcp6 + 0] == 8) {\n            /* PING -> PINGv6 */\n            buf[offset_tcp6 + 0] = 128;\n        }\n    }\n\n    /* Hop limit starts out as 255 */\n    buf[offset_ip + 7] = 0xFF;\n\n    /* Parse our newly construct IPv6 packet */\n    x = preprocess_frame(buf, tmpl->ipv6.length, data_link_type, &parsed);\n    if (!x || parsed.found == FOUND_NOTHING) {\n        LOG(0, \"[-] FAILED: bad packet template\\n\");\n        exit(1);\n    }\n    tmpl->ipv6.offset_ip = parsed.ip_offset;\n    tmpl->ipv6.offset_tcp = parsed.transport_offset;\n    tmpl->ipv6.offset_app = parsed.app_offset;\n\n\n}\n\n/***************************************************************************\n * Here we take a packet template, parse it, then make it easier to work\n * with.\n ***************************************************************************/\nstatic void\n_template_init(\n    struct TemplatePacket *tmpl,\n    macaddress_t source_mac,\n    macaddress_t router_mac_ipv4,\n    macaddress_t router_mac_ipv6,\n    const void *packet_bytes,\n    size_t packet_size,\n    unsigned data_link_type\n    )\n{\n    unsigned char *px;\n    struct PreprocessedInfo parsed;\n    unsigned x;\n    \n    /*\n     * Create the new template structure:\n     * - zero it out\n     * - make copy of the old packet to serve as new template\n     */\n    memset(tmpl, 0, sizeof(*tmpl));\n    tmpl->ipv4.length = (unsigned)packet_size;\n\n    tmpl->ipv4.packet = MALLOC(2048 + packet_size);\n    memcpy(tmpl->ipv4.packet, packet_bytes, tmpl->ipv4.length);\n    px = tmpl->ipv4.packet;\n\n    /*\n     * Parse the existing packet template. We support TCP, UDP, ICMP,\n     * and ARP packets.\n     */\n    x = preprocess_frame(px, tmpl->ipv4.length, 1 /*enet*/, &parsed);\n    if (!x || parsed.found == FOUND_NOTHING) {\n        LOG(0, \"ERROR: bad packet template\\n\");\n        exit(1);\n    }\n    tmpl->ipv4.offset_ip = parsed.ip_offset;\n    tmpl->ipv4.offset_tcp = parsed.transport_offset;\n    tmpl->ipv4.offset_app = parsed.app_offset;\n    if (parsed.found == FOUND_ARP) {\n        tmpl->ipv4.length = parsed.ip_offset + 28;\n    } else\n        tmpl->ipv4.length = parsed.ip_offset + parsed.ip_length;\n\n    /*\n     * Overwrite the MAC and IP addresses\n     */\n    memcpy(px+0, router_mac_ipv4.addr, 6);\n    memcpy(px+6, source_mac.addr, 6);\n    memset((void*)parsed._ip_src, 0, 4);\n    memset((void*)parsed._ip_dst, 0, 4);\n\n\n    /*\n     * ARP\n     *\n     * If this is an ARP template (for doing arpscans), then just set our\n     * configured source IP and MAC addresses.\n     */\n    if (parsed.found == FOUND_ARP) {\n        memcpy((char*)parsed._ip_src - 6, source_mac.addr, 6);\n        tmpl->proto = Proto_ARP;\n        return;\n    }\n\n    /*\n     * IPv4\n     *\n     * Calculate the partial checksum. We zero out the fields that will be\n     * added later the packet, then calculate the checksum as if they were\n     * zero. This makes recalculation of the checksum easier when we transmit\n     */\n    memset(px + tmpl->ipv4.offset_ip + 4, 0, 2);  /* IP ID field */\n    memset(px + tmpl->ipv4.offset_ip + 10, 0, 2); /* checksum */\n    memset(px + tmpl->ipv4.offset_ip + 12, 0, 8); /* addresses */\n    tmpl->ipv4.checksum_ip = ip_header_checksum( tmpl->ipv4.packet,\n                                            tmpl->ipv4.offset_ip,\n                                            tmpl->ipv4.length);\n\n    /*\n     * Higher layer protocols: zero out dest/checksum fields, then calculate\n     * a partial checksum\n     */\n    switch (parsed.ip_protocol) {\n    case 1: /* ICMP */\n            tmpl->ipv4.offset_app = tmpl->ipv4.length;\n            tmpl->ipv4.checksum_tcp = icmp_ipv4_checksum(tmpl);\n            switch (px[tmpl->ipv4.offset_tcp]) {\n                case 8:\n                    tmpl->proto = Proto_ICMP_ping;\n                    break;\n                case 13:\n                    tmpl->proto = Proto_ICMP_timestamp;\n                    break;\n            }\n            break;\n        break;\n    case 6: /* TCP */\n        /* zero out fields that'll be overwritten */\n        memset(px + tmpl->ipv4.offset_tcp + 0, 0, 8); /* destination port and seqno */\n        memset(px + tmpl->ipv4.offset_tcp + 16, 0, 2); /* checksum */\n        tmpl->ipv4.checksum_tcp = tcp_ipv4_checksum(tmpl);\n        tmpl->proto = Proto_TCP;\n        break;\n    case 17: /* UDP */\n        memset(px + tmpl->ipv4.offset_tcp + 6, 0, 2); /* checksum */\n        tmpl->ipv4.checksum_tcp = udp_ipv4_checksum(tmpl);\n        tmpl->proto = Proto_UDP;\n        break;\n    case 132: /* SCTP */\n        tmpl->ipv4.checksum_tcp = sctp_checksum(\n                                    tmpl->ipv4.packet + tmpl->ipv4.offset_tcp,\n                                    tmpl->ipv4.length - tmpl->ipv4.offset_tcp);\n        tmpl->proto = Proto_SCTP;\n        break;\n    }\n\n    /*\n     * DATALINK KLUDGE\n     *\n     * Adjust the data link header in case of Raw IP packets. This isn't\n     * the correct way to do this, but I'm too lazy to refactor code\n     * for the right way, so we'll do it this way now.\n     */\n    if (data_link_type == PCAP_DLT_NULL /* Null VPN tunnel */) {\n        int linkproto = 2; /* AF_INET */\n        tmpl->ipv4.length -= tmpl->ipv4.offset_ip - sizeof(int);\n        tmpl->ipv4.offset_tcp -= tmpl->ipv4.offset_ip - sizeof(int);\n        tmpl->ipv4.offset_app -= tmpl->ipv4.offset_ip - sizeof(int);\n        memmove(tmpl->ipv4.packet + sizeof(int),\n                tmpl->ipv4.packet + tmpl->ipv4.offset_ip,\n                tmpl->ipv4.length);\n        tmpl->ipv4.offset_ip = 4;\n        memcpy(tmpl->ipv4.packet, &linkproto, sizeof(int));\n    } else if (data_link_type == PCAP_DLT_RAW /* Raw IP */) {\n        tmpl->ipv4.length -= tmpl->ipv4.offset_ip;\n        tmpl->ipv4.offset_tcp -= tmpl->ipv4.offset_ip;\n        tmpl->ipv4.offset_app -= tmpl->ipv4.offset_ip;\n        memmove(tmpl->ipv4.packet,\n                tmpl->ipv4.packet + tmpl->ipv4.offset_ip,\n                tmpl->ipv4.length);\n        tmpl->ipv4.offset_ip = 0;\n    } else if (data_link_type == PCAP_DLT_ETHERNET) {\n\t/* the default, do nothing */\n    } else {\n\tLOG(0, \"[-] FAILED: bad packet template, unknown data link type\\n\");\n        LOG(0, \"    [hint] masscan doesn't know how to format packets for this interface\\n\");\n\texit(1);\n    }\n\n    /* Now create an IPv6 template based upon the IPv4 template */\n    _template_init_ipv6(tmpl, router_mac_ipv6, data_link_type);\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid\ntemplate_packet_init(\n    struct TemplateSet *templset,\n    macaddress_t source_mac,\n    macaddress_t router_mac_ipv4,\n    macaddress_t router_mac_ipv6,\n    struct PayloadsUDP *udp_payloads,\n    struct PayloadsUDP *oproto_payloads,\n    int data_link,\n    uint64_t entropy,\n    const struct TemplateOptions *templ_opts)\n{\n    unsigned char *buf;\n    size_t length;\n    templset->count = 0;\n    templset->entropy = entropy;\n\n\n    /* [SCTP] */\n    _template_init(&templset->pkts[Proto_SCTP],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   default_sctp_template,\n                   sizeof(default_sctp_template)-1,\n                   data_link);\n    templset->count++;\n\n    /* [TCP] */\n    length = sizeof(default_tcp_template) - 1;\n    buf = MALLOC(length);\n    memcpy(buf, default_tcp_template, length);\n    templ_tcp_apply_options(&buf, &length, templ_opts);\n    _template_init(&templset->pkts[Proto_TCP],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   buf,\n                   length,\n                   data_link);\n    templset->count++;\n    free(buf);\n\n    /* [UDP] */\n    _template_init(&templset->pkts[Proto_UDP],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   default_udp_template,\n                   sizeof(default_udp_template)-1,\n                   data_link);\n    templset->pkts[Proto_UDP].payloads = udp_payloads;\n    templset->count++;\n    \n    /* [UDP oproto] */\n    _template_init(&templset->pkts[Proto_Oproto],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   default_udp_template,\n                   sizeof(default_udp_template)-1,\n                   data_link);\n    templset->pkts[Proto_Oproto].payloads = oproto_payloads;\n    templset->count++;\n    \n\n    /* [ICMP ping] */\n    _template_init(&templset->pkts[Proto_ICMP_ping],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   default_icmp_ping_template,\n                   sizeof(default_icmp_ping_template)-1,\n                   data_link);\n    templset->count++;\n\n    /* [ICMP timestamp] */\n    _template_init(&templset->pkts[Proto_ICMP_timestamp],\n                   source_mac, router_mac_ipv4, router_mac_ipv6,\n                   default_icmp_timestamp_template,\n                   sizeof(default_icmp_timestamp_template)-1,\n                   data_link);\n    templset->count++;\n\n    /* [ARP] */\n    _template_init( &templset->pkts[Proto_ARP],\n                    source_mac, router_mac_ipv4, router_mac_ipv6,\n                    default_arp_template,\n                    sizeof(default_arp_template)-1,\n                    data_link);\n    templset->count++;\n\n    /* [VulnCheck] */\n    if (templset->vulncheck) {\n        _template_init( &templset->pkts[Proto_VulnCheck],\n                       source_mac, router_mac_ipv4, router_mac_ipv6,\n                       templset->vulncheck->packet,\n                       templset->vulncheck->packet_length,\n                       data_link);\n        templset->count++;\n    }\n}\n\n\n\n\n/***************************************************************************\n * Overwrites the TTL of the packet\n ***************************************************************************/\nvoid\ntemplate_set_ttl(struct TemplateSet *tmplset, unsigned ttl)\n{\n    unsigned i;\n\n    for (i=0; i<tmplset->count; i++) {\n        struct TemplatePacket *tmpl = &tmplset->pkts[i];\n        unsigned char *px = tmpl->ipv4.packet;\n        unsigned offset = tmpl->ipv4.offset_ip;\n\n        px[offset+8] = (unsigned char)(ttl);\n        tmpl->ipv4.checksum_ip = ip_header_checksum(    tmpl->ipv4.packet,\n                                                    tmpl->ipv4.offset_ip,\n                                                    tmpl->ipv4.length);\n    }\n}\n\nvoid\ntemplate_set_vlan(struct TemplateSet *tmplset, unsigned vlan)\n{\n    unsigned i;\n    \n    for (i=0; i<tmplset->count; i++) {\n        struct TemplatePacket *tmpl = &tmplset->pkts[i];\n        unsigned char *px;\n\n        if (tmpl->ipv4.length < 14)\n            continue;\n        \n        px = MALLOC(tmpl->ipv4.length + 4);\n        memcpy(px, tmpl->ipv4.packet, 12);\n        memcpy(px+16, tmpl->ipv4.packet+12, tmpl->ipv4.length - 12);\n        \n        px[12] = 0x81;\n        px[13] = 0x00;\n        px[14] = (unsigned char)(vlan>>8);\n        px[15] = (unsigned char)(vlan>>0);\n        \n        tmpl->ipv4.packet = px;\n        tmpl->ipv4.length += 4;\n        \n        tmpl->ipv4.offset_ip += 4;\n        tmpl->ipv4.offset_tcp += 4;\n        tmpl->ipv4.offset_app += 4;\n    }\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nint\ntemplate_selftest(void)\n{\n    struct TemplateSet tmplset[1];\n    int failures = 0;\n    struct TemplateOptions templ_opts = {{0}};\n\n    /* Test the module that edits TCP headers */\n    if (templ_tcp_selftest()) {\n        fprintf(stderr, \"[-] templ-tcp-hdr: selftest failed\\n\");\n        return 1;\n    }\n\n\n    memset(tmplset, 0, sizeof(tmplset[0]));\n    template_packet_init(\n            tmplset,\n            macaddress_from_bytes(\"\\x00\\x11\\x22\\x33\\x44\\x55\"),\n            macaddress_from_bytes(\"\\x66\\x55\\x44\\x33\\x22\\x11\"),\n            macaddress_from_bytes(\"\\x66\\x55\\x44\\x33\\x22\\x11\"),\n            0,  /* UDP payloads = empty */\n            0,  /* Oproto payloads = empty */\n            1,  /* Ethernet */\n            0,  /* no entropy */\n            &templ_opts\n            );\n    failures += tmplset->pkts[Proto_TCP].proto  != Proto_TCP;\n    failures += tmplset->pkts[Proto_UDP].proto  != Proto_UDP;\n    //failures += tmplset->pkts[Proto_SCTP].proto != Proto_SCTP;\n    failures += tmplset->pkts[Proto_ICMP_ping].proto != Proto_ICMP_ping;\n    //failures += tmplset->pkts[Proto_ICMP_timestamp].proto != Proto_ICMP_timestamp;\n    //failures += tmplset->pkts[Proto_ARP].proto  != Proto_ARP;\n\n    if (failures)\n        fprintf(stderr, \"template: failed\\n\");\n    return failures;\n}\n\n"
  },
  {
    "path": "src/templ-pkt.h",
    "content": "#ifndef TCP_PACKET_H\n#define TCP_PACKET_H\n#include <stdio.h>\n#include <stdint.h>\n#include \"massip-addr.h\"\nstruct PayloadsUDP;\nstruct MassVulnCheck;\nstruct TemplateOptions;\n\n/**\n * Does a regression test of this module.\n * @return\n *      1 on failure\n *      0 on success\n */\nint template_selftest(void);\n\nenum TemplateProtocol {\n    Proto_TCP,\n    Proto_UDP,\n    Proto_SCTP,\n    Proto_ICMP_ping,\n    Proto_ICMP_timestamp,\n    Proto_ARP,\n    Proto_Oproto,\n    Proto_VulnCheck,\n    //Proto_IP,\n    //Proto_Custom,\n    Proto_Count\n};\n\nstruct TemplatePayload {\n    unsigned length;\n    unsigned checksum;\n    unsigned char buf[1500];\n};\n\nunsigned\nudp_checksum2(const unsigned char *px, unsigned offset_ip,\n              unsigned offset_tcp, size_t tcp_length);\n\n/**\n * Describes a packet template. The scan packets we transmit are based on a\n * a template containing most of the data, and we fill in just the necessary\n * bits, like the destination IP address and port\n */\nstruct TemplatePacket {\n    struct {\n        unsigned length;\n        unsigned offset_ip;\n        unsigned offset_tcp;\n        unsigned offset_app;\n        unsigned char *packet;\n        unsigned checksum_ip;\n        unsigned checksum_tcp;\n        unsigned ip_id;\n    } ipv4;\n    struct {\n        unsigned length;\n        unsigned offset_ip;\n        unsigned offset_tcp;\n        unsigned offset_app;\n        unsigned char *packet;\n        unsigned checksum_ip;\n        unsigned checksum_tcp;\n        unsigned ip_id;\n    } ipv6;\n    enum TemplateProtocol proto;\n    struct PayloadsUDP *payloads;\n};\n\n/**\n * We can run multiple types of scans (TCP, UDP, vulns, etc.) at the same\n * time. Therefore, instead of one packet prototype for all scans, we have\n * a set of prototypes/templates.\n */\nstruct TemplateSet\n{\n    unsigned count;\n    struct MassVulnCheck *vulncheck;\n    uint64_t entropy;\n    struct TemplatePacket pkts[Proto_Count];\n};\n\nstruct TemplateSet templ_copy(const struct TemplateSet *templ);\n\n\n\n/**\n * Initialize the \"template\" packets. As we spew out probes, we simply make\n * minor adjustments to the template, such as changing the target IP\n * address or port number\n *\n * @param templset\n *      The template we are creating.\n * @param source_ip\n *      Our own IP address that we send packets from. The caller will have\n *      retrieved this automatically from the network interface/adapter, or\n *      the user will have set this with --source-ip parameter.\n * @param source_mac\n *      Our own MAC address. Gotten automatically from the network adapter,\n *      or on the commandline with --source-mac parameter\n * @param router_mac\n *      The MAC address of the local router/gateway, which will be placed in\n *      the Ethernet destination address field. This is gotten by ARPing\n *      the local router, or by --router-mac configuration parameter.\n * @param data_link\n *      The OSI layer 2 protocol, as defined in <pcap.h> standard.\n *       1 = Ethernet\n *      12 = Raw IP (no data link)\n */\nvoid\ntemplate_packet_init(\n    struct TemplateSet *templset,\n    macaddress_t source_mac,\n    macaddress_t router_mac_ipv4,\n    macaddress_t router_mac_ipv6,\n    struct PayloadsUDP *udp_payloads,\n    struct PayloadsUDP *oproto_payloads,\n    int data_link,\n    uint64_t entropy,\n    const struct TemplateOptions *templ_opts);\n\n/**\n * Sets the target/destination IP address of the packet, the destination port\n * number, and other bits of interest about the packet, such as a unique\n * sequence number. The template can contain things like IP or TCP options\n * with specific values. The program contains several built-in templates,\n * but they can also be read from a file.\n *\n * @param templset\n *      A template created by \"template_packet_init()\" and further modified\n *      by various configuration parameters.\n * @param ip\n *      The target/destination IPv4 address.\n * @param port\n *      The TCP port number, or port number from another protocol that will\n *      be shifted into the appropriate range. We actually build six base\n *      templates, one for each of these six protocols.\n *      [     0.. 65535] = TCP port number\n *      [ 65536..131071] = UDP port number\n *      [131072..196607] = SCTP port number\n *      [     196608   ] = ICMP\n *      [     196609   ] = ARP\n *      [     196610   ] = IP\n *      [      more    ] = custom\n * @param seqno\n *      On TCP, this will be the desired sequence number, which the caller\n *      will create from SYN-cookies. Other protocols may use this in a\n *      different manner. For example, if the UDP port is 161, then\n *      this will be the transaction ID of the SNMP request template.\n */\nvoid\ntemplate_set_target_ipv4(\n    struct TemplateSet *templset,\n    ipv4address ip_them, unsigned port_them,\n    ipv4address ip_me, unsigned port_me,\n    unsigned seqno,\n    unsigned char *px, size_t sizeof_px, size_t *r_length);\n\nvoid\ntemplate_set_target_ipv6(\n    struct TemplateSet *templset,\n    ipv6address ip_them, unsigned port_them,\n    ipv6address ip_me, unsigned port_me,\n    unsigned seqno,\n    unsigned char *px, size_t sizeof_px, size_t *r_length);\n\n\n/**\n * Create a TCP packet containing a payload, based on the original\n * template used for the SYN\n */\nsize_t\ntcp_create_packet(\n        struct TemplatePacket *pkt,\n        ipaddress ip_them, unsigned port_them,\n        ipaddress ip_me, unsigned port_me,\n        unsigned seqno, unsigned ackno,\n        unsigned flags,\n        const unsigned char *payload, size_t payload_length,\n        unsigned char *px, size_t px_length);\n\n/**\n * Set's the TCP \"window\" field. The purpose is to cause the recipient\n * to fragment data on the response, thus evading IDS that triggers on\n * out going packets\n */\nvoid\ntcp_set_window(unsigned char *px, size_t px_length, unsigned window);\n\n\nvoid template_set_ttl(struct TemplateSet *tmplset, unsigned ttl);\nvoid template_set_vlan(struct TemplateSet *tmplset, unsigned vlan);\n\n#endif\n"
  },
  {
    "path": "src/templ-tcp-hdr.c",
    "content": "/*\n This module edits an existing TCP packet, adding and removing\n options, setting the values of certain fields.\n\n From RFC793:\n\n 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |          Source Port          |       Destination Port        |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |                        Sequence Number                        |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |                    Acknowledgment Number                      |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |  Data |           |U|A|P|R|S|F|                               |\n | Offset| Reserved  |R|C|S|S|Y|I|            Window             |\n |       |           |G|K|H|T|N|N|                               |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |           Checksum            |         Urgent Pointer        |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |                    Options                    |    Padding    |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |                             data                              |\n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n TCP Window Scale Option (WSopt):\n Kind: 3 Length: 3 bytes\n +---------+---------+---------+\n | Kind=3  |Length=3 |shift.cnt|\n +---------+---------+---------+\n\n TCP Timestamps Option (TSopt):\n Kind: 8\n Length: 10 bytes\n +-------+-------+---------------------+---------------------+\n |Kind=8 |  10   |   TS Value (TSval)  |TS Echo Reply (TSecr)|\n +-------+-------+---------------------+---------------------+\n 1       1              4                     4\n\n TCP Sack-Permitted Option:\n Kind: 4\n +---------+---------+\n | Kind=4  | Length=2|\n +---------+---------+\n\n\n TCP SACK Option:\n Kind: 5\n Length: Variable\n\n +--------+--------+\n | Kind=5 | Length |\n +--------+--------+--------+--------+\n |      Left Edge of 1st Block       |\n +--------+--------+--------+--------+\n |      Right Edge of 1st Block      |\n +--------+--------+--------+--------+\n |                                   |\n /            . . .                  /\n |                                   |\n +--------+--------+--------+--------+\n |      Left Edge of nth Block       |\n +--------+--------+--------+--------+\n |      Right Edge of nth Block      |\n +--------+--------+--------+--------+\n\n */\n#include \"templ-tcp-hdr.h\"\n#include \"templ-opts.h\"\n#include \"util-logger.h\"\n#include \"proto-preprocess.h\"\n#include <string.h>\n#include <stdlib.h>\n#include <ctype.h>\n\nstruct tcp_opt_t {\n    const unsigned char *buf;\n    size_t length;\n    unsigned kind;\n    bool is_found;\n};\n\nstruct tcp_hdr_t {\n    size_t begin;\n    size_t max;\n    size_t ip_offset;\n    unsigned char ip_version;\n    bool is_found;\n};\n\n/**\n * Do a memmove() of a chunk of memory within a buffer with bounds checking.\n */\nstatic void\nsafe_memmove(unsigned char *buf, size_t length, size_t to, size_t from, size_t chunklength) {\n    if (chunklength + to > length) {\n        fprintf(stderr, \"+\"); fflush(stderr);\n        chunklength = length - to;\n    }\n    if (chunklength + from > length) {\n        fprintf(stderr, \"-\"); fflush(stderr);\n        chunklength = length - from;\n    }\n    memmove(buf + to, buf + from, chunklength);\n}\n\n/**\n * Do a memset() of a chunk of memory within a buffer with bounds checking\n */\nstatic void\nsafe_memset(unsigned char *buf, size_t length, size_t offset, int c, size_t chunklength) {\n    if (chunklength + offset > length) {\n        chunklength = length - offset;\n        fprintf(stderr, \"*\"); fflush(stderr);\n    }\n    memset(buf + offset, c, chunklength);\n}\n\n/***************************************************************************\n * A typical hexdump function, but dumps specifically the <options-list>\n * section of a TCP header. An added feature is that it marks the byte\n * at \"offset\". This makes debugging easier, so I can see the <options-list>\n * as I'm stepping through code. You'll see this commented-out throughout\n * the code.\n ***************************************************************************/\nstatic void\n_HEXDUMP(const void *v, struct tcp_hdr_t hdr, size_t offset, const char *name)\n{\n    const unsigned char *p = ((const unsigned char *)v) + hdr.begin + 20;\n    size_t i;\n    size_t len = hdr.max - hdr.begin + 8 - 20;\n\n    printf(\"%s:\\n\", name);\n    offset -= hdr.begin + 20;\n\n    for (i=0; i<len; i += 16) {\n        size_t j;\n\n        for (j=i; j<i+16 && j<len; j++) {\n            char c = ' ';\n            if (j == offset)\n                c = '>';\n            if (j + 1 == offset)\n                c = '<';\n            printf(\"%02x%c\", p[j], c);\n        }\n        for (;j<i+16; j++)\n            printf(\"   \");\n        printf(\"  \");\n        for (j=i; j<i+16 && j<len; j++) {\n            char c = p[j];\n\n            if (j == offset)\n                c = '#';\n\n            if (isprint(c&0xff) && !isspace(c&0xff))\n                printf(\"%c\", c);\n            else\n                printf(\".\");\n        }\n        printf(\"\\n\");\n    }\n}\n\n\n\n/***************************************************************************\n * A quick macro to calculate the TCP header length, given a buffer\n * and an offset to the start of the TCP header.\n ***************************************************************************/\nstatic unsigned inline\n_tcp_header_length(const unsigned char *buf, size_t offset) {\n    return (buf[offset + 12] >> 4) * 4;\n}\n\n/***************************************************************************\n * Does a consistency check of the whole packet, including IP header,\n * TCP header, and the options in the <options-list> field. This is used\n * in the self-test feature after test cases, to make sure the packet\n * hasn't bee corrupted.\n ***************************************************************************/\nstatic int\n_consistancy_check(const unsigned char *buf, size_t length,\n                   const void *payload, size_t payload_length) {\n    struct PreprocessedInfo parsed;\n    unsigned is_success;\n\n    /* Parse the packet */\n    is_success = preprocess_frame(buf,\n                                  (unsigned)length,\n                                  1 /*enet*/,\n                                  &parsed);\n    if (!is_success || parsed.found != FOUND_TCP) {\n        fprintf(stderr, \"[-] check: TCP header not found\\n\");\n        goto fail;\n    }\n\n    /* Check the lengths */\n    switch (parsed.ip_version) {\n        case 4:\n            if (parsed.ip_length + 14 != length) {\n                fprintf(stderr, \"[-] check: IP length bad\\n\");\n                goto fail;\n            }\n            break;\n        case 6:\n            break;\n        default:\n            fprintf(stderr, \"[-] check: IPv?\\n\");\n            goto fail;\n    }\n\n    /* Validate TCP header options */\n    {\n        size_t offset = parsed.transport_offset;\n        size_t max = offset + _tcp_header_length(buf, offset);\n\n        /* Get the start of the <options> section of the header. This is defined\n         * as 20 bytes into the TCP header. */\n        offset += 20;\n\n        /* Enumerate any existing options one-by-one.  */\n        while (offset < max) {\n            unsigned kind;\n            unsigned len;\n\n            /* Get the option type (aka. \"kind\") */\n            kind = buf[offset++];\n\n            if (kind == 0x00) {\n                /* EOL - end of options list\n                 * According to the spec, processing should stop here, even if\n                 * there are additional options after this point. */\n                break;\n            } else if (kind == 0x01) {\n                /* NOP - No-operation\n                 * This is a single byte option, used to pad other options to\n                 * even 4 byte boundaries. Padding is optional. */\n                continue;\n            }\n\n            /* If we've reached the end of */\n            if (offset > max)\n                goto fail;\n            if (offset == max)\n                break;\n            len = buf[offset++];\n\n            /* Check for corruption, the lenth field is inclusive, so should\n             * equal at least two. It's maximum length should be bfore the end\n             * of the packet */\n            if (len < 2 || len > (max-offset+2)) {\n                goto fail;\n            }\n\n            offset += len - 2;\n        }\n    }\n\n    /* Check the payload */\n    if (parsed.app_length != payload_length)\n        goto fail;\n    if (memcmp(buf + parsed.app_offset, payload, payload_length) != 0)\n        goto fail;\n\n    return 0;\nfail:\n    return 1;\n}\n\n/***************************************************************************\n * Find the TCP header in the packet. We can't be sure what's in the\n * current template because it could've been provided by the user, so\n * we instead parse it as if we've received it from the network wire.\n ***************************************************************************/\nstatic struct tcp_hdr_t\n_find_tcp_header(const unsigned char *buf, size_t length) {\n    struct tcp_hdr_t hdr = {0};\n    struct PreprocessedInfo parsed;\n    unsigned is_success;\n\n    /*\n     * Parse the packet, telling us where the TCP header is. This works\n     * for both IPv4 and IPv6, we care only about the TCP header portion.\n     */\n    is_success = preprocess_frame(buf, /* the packet, including Ethernet hdr */\n                                  (unsigned)length,\n                                  1 /*enet*/,\n                                  &parsed);\n    if (!is_success || parsed.found != FOUND_TCP) {\n        /* We were unable to parse a well-formatted TCP packet. This\n         * might've been UDP or something. */\n        goto fail;\n    }\n\n    hdr.begin = parsed.transport_offset;\n    hdr.max = hdr.begin + _tcp_header_length(buf, hdr.begin);\n    hdr.ip_offset = parsed.ip_offset;\n    hdr.ip_version = (unsigned char)parsed.ip_version;\n    hdr.is_found = true;\n    return hdr;\n\nfail:\n    hdr.is_found = false;\n    return hdr;\n}\n\n/***************************************************************************\n * A quick macro at the start of for(;;) loops that enumerate all the\n * options in the <option-list>\n ***************************************************************************/\nstatic inline size_t\n_opt_begin(struct tcp_hdr_t hdr) {\n    return hdr.begin + 20; /* start of <options> field */\n}\n\n/***************************************************************************\n * A quick macro in the for(;;) loop that enumerates all the options\n * in the <option-list>. It has three possibilities based on the KIND:\n * 0x00 - we've reached the end of the options-list\n * 0x01 - padding NOP byte, which we skipo\n * 0x?? - some option, the following byte is the length. We skip\n *        that `len` bytes.\n ***************************************************************************/\nstatic inline size_t\n_opt_next(struct tcp_hdr_t hdr, size_t offset, const unsigned char *buf) {\n    unsigned kind = buf[offset];\n    if (kind == 0x00) {\n        return hdr.max;\n    } else if (kind == 0x01) {\n        return offset + 1;\n    } else if (offset + 2 > hdr.max) {\n        return hdr.max; /* corruption */\n    } else {\n        unsigned len = buf[offset+1];\n        if (len < 2 || offset + len > hdr.max)\n            return hdr.max; /* corruption */\n        else\n            return offset + len;\n    }\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\n_HEXDUMPopt(const unsigned char *buf, size_t length, const char *name) {\n    struct tcp_hdr_t hdr;\n\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found) {\n        fprintf(stderr, \"[-] templ.tcp.hdr: failure\\n\");\n    }\n    _HEXDUMP(buf, hdr, _opt_begin(hdr), name);\n}\n\n/***************************************************************************\n * Search throgh the <option-list> until we find the specified option,\n * 'kind', or reach the end of the list. An impossible 'kind', like 0x100,\n * will force finding the end of the list before padding starts.\n ***************************************************************************/\nstatic size_t\n_find_opt(const unsigned char *buf, struct tcp_hdr_t hdr, unsigned in_kind,\n          unsigned *nop_count) {\n    size_t offset;\n\n    /* This field is optional, if used, set it to zero */\n    if (nop_count)\n        *nop_count = 0;\n\n    /* enumerate all <options> looking for a match */\n    for (offset = _opt_begin(hdr);\n         offset < hdr.max;\n         offset = _opt_next(hdr, offset, buf)) {\n        unsigned kind;\n\n        /* get the option type/kind */\n        kind = buf[offset];\n\n        /* Stop search if we hit an EOL marker */\n        if (kind == 0x00)\n            break;\n\n        /* Stop search when we find our option */\n        if (kind == in_kind)\n            break;\n\n        /* Count the number of NOPs leading up to where we end */\n        if (nop_count) {\n            if (kind == 0x01)\n                (*nop_count)++;\n            else\n                (*nop_count) = 0;\n        }\n    }\n    return offset;\n}\n\n/***************************************************************************\n * Search the TCP header's <options> field for the specified kind/type.\n * Typical kinds of options are MSS, window scale, SACK, timestamp.\n ***************************************************************************/\nstatic struct tcp_opt_t\ntcp_find_opt(const unsigned char *buf, size_t length, unsigned in_kind) {\n    struct tcp_opt_t result = {0};\n    struct tcp_hdr_t hdr;\n    size_t offset;\n\n    /* Get the TCP header in the packet */\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found)\n        goto fail;\n\n    /* Search for a matchin <option> */\n    offset = _find_opt(buf, hdr, in_kind, 0);\n    if (offset >= hdr.max || buf[offset] != in_kind)\n        goto fail;\n\n    /* We've found it! If we've passed all the checks above, we have\n     * a well formatted field, so just return it. */\n    result.kind = in_kind;\n    result.buf = buf + offset + 2;\n    result.length = buf[offset+1] - 2;\n    if (offset + result.length >= hdr.max)\n        goto fail;\n    result.is_found = true;\n    return result;\n\nfail:\n    result.is_found = false;\n    return result;\n}\n\n/***************************************************************************\n * Adjusts the IP \"total length\" and TCP \"header length\" fields to match\n * recent additions/removals of options in the <option-list>\n ***************************************************************************/\nstatic void\n_adjust_length(unsigned char *buf, size_t length, int adjustment, struct tcp_hdr_t hdr) {\n    size_t ip_offset = hdr.ip_offset;\n\n    /* The adjustment should already have been aligned on an even 4 byte\n     * boundary */\n    if ((adjustment & 0x3) != 0) {\n        fprintf(stderr, \"[-] templ.tcp: impossible alignment error\\n\");\n        return;\n    }\n\n    /* Adjust the IP header length */\n    switch (hdr.ip_version) {\n        case 4: {\n            unsigned total_length;\n            total_length = buf[ip_offset+2] << 8 | buf[ip_offset+3] << 0;\n            total_length += adjustment;\n            buf[ip_offset+2] = (unsigned char)(total_length>>8);\n            buf[ip_offset+3] = (unsigned char)(total_length>>0);\n            total_length = buf[ip_offset+2] << 8 |buf[ip_offset+3] << 0;\n            if (total_length + 14 != length) {\n                fprintf(stderr, \"[-] IP length mismatch\\n\");\n            }\n            break;\n        }\n        case 6: {\n            unsigned payload_length;\n            payload_length = buf[ip_offset+4] << 8 | buf[ip_offset+5] << 0;\n            payload_length += adjustment;\n            buf[ip_offset+4] = (unsigned char)(payload_length>>8);\n            buf[ip_offset+5] = (unsigned char)(payload_length>>0);\n            break;\n        }\n    }\n\n    /* Adjust the TCP header length */\n    {\n        size_t hdr_length;\n        size_t offset = hdr.begin + 12;\n\n        hdr_length = (buf[offset] >> 4) * 4;\n\n        hdr_length += adjustment;\n\n        if (hdr_length % 4 != 0) {\n            fprintf(stderr, \"[-] templ.tcp corruptoin\\n\");\n        }\n\n        buf[offset] = (unsigned char)((buf[offset] & 0x0F) | ((hdr_length/4) << 4));\n\n        hdr_length = (buf[offset] >> 4) * 4;\n        if (hdr.begin + hdr_length > length) {\n            fprintf(stderr, \"[-] templ.tcp corruptoin\\n\");\n        }\n    }\n}\n\n/***************************************************************************\n * After adding/removing an option, the <option-list> may no longer be\n * aligned on an even 4-byte boundary as required. This function\n * adds padding as necessary to align to the boundary.\n ***************************************************************************/\nstatic void\n_add_padding(unsigned char **inout_buf, size_t *inout_length, size_t offset, unsigned pad_count) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n\n    length += pad_count;\n    buf = realloc(buf, length);\n\n    /* open space between headers and payload */\n    safe_memmove(buf, length,\n                offset + pad_count,\n                offset,\n                (length - pad_count) - offset);\n\n    /* set padding to zero */\n    safe_memset(buf, length,\n                offset, 0, pad_count);\n\n    /* Set the out parameters */\n    *inout_buf = buf;\n    *inout_length = length;\n}\n\n/***************************************************************************\n * Afte changes, there my be more padding bytes than necessary. This\n * reduces the number to 3 or less. Also, it changes any trailing NOPs\n * to EOL bytes, since there are no more options after that point.\n ***************************************************************************/\nstatic bool\n_normalize_padding(unsigned char **inout_buf, size_t *inout_length) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n    struct tcp_hdr_t hdr;\n    size_t offset;\n    unsigned nop_count = 0;\n\n    /* find TCP header */\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found)\n        goto fail;\n\n\n    /* find the start of the padding field  */\n    offset = _find_opt(buf, hdr, 0x100, &nop_count);\n    if (offset >= hdr.max && nop_count == 0)\n        goto success; /* no padding needing to be removed */\n\n    /* If NOPs immediately before EOL, include them too */\n    offset -= nop_count;\n\n    {\n        size_t remove_count = hdr.max - offset;\n\n        /* the amount removed must be aligned on 4-byte boundary */\n        while (remove_count % 4)\n            remove_count--;\n\n        /* If we have nothing left to remove, then exit.\n         * THIS IS THE NORMAL CASE -- most of the time, we have no\n         * extra padding to remove. */\n        if (remove_count == 0)\n            goto fail; /* likely, normal*/\n\n        //_HEXDUMP(buf, hdr, offset, \"before padding removal\");\n\n        safe_memmove(buf, length,\n                        offset,\n                        offset + remove_count,\n                        length - (offset + remove_count));\n        hdr.max -= remove_count;\n        length -= remove_count;\n\n        /* normalize all the bytes to zero, in case they aren't already */\n        safe_memset(buf, length, offset, 0, hdr.max - offset);\n\n        //_HEXDUMP(buf, hdr, offset, \"after padding removal\");\n\n        /* fix the IP and TCP length fields */\n        _adjust_length(buf, length, 0 - (int)remove_count, hdr);\n    }\n\nsuccess:\n    *inout_buf = buf;\n    *inout_length = length;\n    return true; /* success */\nfail:\n    *inout_buf = buf;\n    *inout_length = length;\n    return false; /* failure */\n\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic bool\ntcp_remove_opt(\n        unsigned char **inout_buf, size_t *inout_length, unsigned in_kind\n               ) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n    struct tcp_hdr_t hdr;\n    size_t offset;\n    unsigned nop_count = 0;\n\n    /* find the TCP header */\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found)\n        goto fail;\n\n    /* enumerate all the <options> looking for a match  */\n    offset = _find_opt(buf, hdr, in_kind, &nop_count);\n    if (offset + 2 >= hdr.max)\n        goto success; /* not found, no matching option type/kind */\n\n\n    {\n        unsigned opt_len = buf[offset+1];\n        unsigned remove_length = opt_len;\n\n        if (offset + opt_len > hdr.max)\n            goto fail;\n\n        /* Remove any trailing NOPs */\n        while (offset + remove_length < hdr.max\n               && buf[offset + remove_length] == 1)\n            remove_length++;\n\n        /* Remove any leading NOPs */\n        offset -= nop_count;\n        remove_length += nop_count;\n\n        /* Remove the bytes from the current packet buffer.\n         * Before this will be the ...IP/TCP headers plus maybe some options.\n         * After this will be maybe some options, padding, then the TCP payload\n         * */\n\n        //_HEXDUMP(buf, hdr, offset, \"before removal\");\n\n        safe_memmove(buf, length,\n                        offset,\n                        offset + remove_length,\n                        length - (offset + remove_length));\n        hdr.max -= remove_length;\n        length -= remove_length;\n\n        //_HEXDUMP(buf, hdr, offset, \"after removal\");\n\n\n        /* Now we may need to add back padding  */\n        if (remove_length % 4) {\n            unsigned add_length = (remove_length % 4);\n            _add_padding(&buf, &length, hdr.max, add_length);\n            remove_length -= add_length;\n            hdr.max += add_length;\n        }\n\n        //_HEXDUMP(buf, hdr, offset, \"padding added\");\n\n        /* fix the IP and TCP length fields */\n        _adjust_length(buf, length, 0 - remove_length, hdr);\n\n        /* In case we've padded the packet with four 0x00, get rid\n         * of them */\n        _normalize_padding(&buf, &length);\n    }\n\nsuccess:\n    *inout_buf = buf;\n    *inout_length = length;\n    return true;\n\nfail:\n    *inout_buf = buf;\n    *inout_length = length;\n    return false;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic int\n_insert_field(unsigned char **inout_buf,\n              size_t *inout_length,\n              size_t offset_begin,\n              size_t offset_end,\n              const unsigned char *new_data,\n              size_t new_length\n              ) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n    int adjust = 0;\n\n    /* can theoreitcally be negative, but that's ok */\n    adjust = (int)new_length - ((int)offset_end - (int)offset_begin);\n    if (adjust > 0) {\n        length += adjust;\n        buf = realloc(buf, length);\n        safe_memmove(buf, length,\n                        offset_begin + new_length,\n                        offset_end,\n                        (length - adjust) - offset_end);\n    }\n    if (adjust < 0) {\n        safe_memmove(buf, length,\n                        offset_begin + new_length,\n                        offset_end,\n                        length - offset_end);\n        length += adjust;\n        buf = realloc(buf, length);\n    }\n\n    /**/\n    memcpy(buf + offset_begin,\n           new_data,\n           new_length);\n\n    *inout_buf = buf;\n    *inout_length = length;\n\n    return adjust;\n}\n\n/** Calculate the total number of padding bytes, both NOPs in the middle\n * and EOLs at the end. We call this when there's not enough space for\n * another option, and we want to remove all the padding. */\n#if 0\nstatic unsigned\n_calc_padding(const unsigned char *buf, struct tcp_hdr_t hdr) {\n    size_t offset;\n    unsigned result = 0;\n\n    /* enumerate through all <option> fields */\n    for (offset = _opt_begin(hdr);\n         offset < hdr.max;\n         offset = _opt_next(hdr, offset, buf)) {\n        unsigned kind;\n\n        /* Get the kind: 0=EOL, 1=NOP, 2=MSS, 3=Wscale, etc. */\n        kind = buf[offset];\n\n        /* If EOL, we end here, and all the remainder bytes are counted\n         * as padding. */\n        if (kind == 0) {\n            result += (hdr.max - offset);\n            break;\n        }\n\n        /* If a NOP, then this is a padding byte */\n        if (kind == 1)\n            result++;\n    }\n\n    return result;\n}\n#endif\n\n/***************************************************************************\n * Remove all the padding bytes, and return an offset to the beginning\n * of the rest of the option field.\n ***************************************************************************/\nstatic size_t\n_squeeze_padding(unsigned char *buf, size_t length, struct tcp_hdr_t hdr, unsigned in_kind) {\n    size_t offset;\n    unsigned nop_count = 0;\n\n    for (offset = _opt_begin(hdr);\n         offset < hdr.max;\n         offset = _opt_next(hdr, offset, buf)) {\n        unsigned kind;\n        unsigned len;\n\n        //_HEXDUMP(buf, hdr, offset, \"squeeze\");\n\n        /* Get the kind: 0=EOL, 1=NOP, 2=MSS, 3=Wscale, etc. */\n        kind = buf[offset];\n\n        /* If a NOP padding, simply count it until we reach something\n         * more interesting */\n        if (kind == 0x01) {\n            nop_count++;\n            continue;\n        }\n\n        /* If end of option list, any remaining padding bytes are added */\n        if (kind == 0x00) {\n            /* normalize the padding at the end */\n            offset -= nop_count;\n            safe_memset(buf, length, offset, 0, hdr.max - offset);\n\n            //_HEXDUMP(buf, hdr, offset, \"null\");\n\n            return offset;\n        }\n\n        /* If we match an existing field, all those bytes become padding */\n        if (kind == in_kind) {\n            len = buf[offset+1];\n            safe_memset(buf, length, offset, 0x01, len);\n            nop_count++;\n\n            //_HEXDUMP(buf, hdr, offset, \"VVVVV\");\n\n            continue;\n        }\n\n        if (nop_count == 0)\n            continue; /*no squeezing needed */\n\n        /* move this field backward overwriting NOPs */\n        len = buf[offset+1];\n        safe_memmove(buf, length,\n                        offset - nop_count,\n                        offset,\n                        len);\n\n        //_HEXDUMP(buf, hdr, offset - nop_count, \"<<<<\");\n\n        /* now write NOPs where this field used to be */\n        safe_memset(buf, length, \n                    offset + len - nop_count, 0x01, nop_count);\n\n        //_HEXDUMP(buf, hdr, offset + len - nop_count, \"!!!!!\");\n\n        /* reset the <offset> to the end of this relocated field */\n        offset -= nop_count;\n        nop_count = 0;\n    }\n\n    /* if we reach the end, then there were only NOPs at the end and no\n     * EOL byte, so simply zero them out */\n    safe_memset(buf, length, \n                offset - nop_count, 0x00, nop_count);\n    offset -= nop_count;\n\n    //_HEXDUMP(buf, hdr, offset, \"\");\n\n    return offset;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic bool\ntcp_add_opt(unsigned char **inout_buf,\n            size_t *inout_length,\n            unsigned opt_kind,\n            unsigned opt_length,\n            const unsigned char *opt_data) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n    struct tcp_hdr_t hdr;\n    size_t offset;\n    unsigned nop_count = 0;\n    int adjust = 0;\n\n\n    /* Check for corruption:\n     * The maximum size of a TCP header is 60 bytes (0x0F * 4), and the\n     * rest of the header takes up 20 bytes. The [kind,length] takes up\n     * another 2 bytes. Thus, the max option length is 38 bytes */\n    if (opt_length > 38) {\n        fprintf(stderr, \"[-] templ.tcp.add_opt: opt_len too large\\n\");\n        goto fail;\n    }\n\n\n    /* find TCP header */\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found)\n        goto fail;\n\n    /* enumerate all existing options looking match */\n    offset = _find_opt(buf, hdr, opt_kind, &nop_count);\n\n    {\n        size_t old_begin;\n        size_t old_end;\n        unsigned char new_field[64];\n        size_t new_length;\n\n        /* Create a well-formatted field that will be inserted */\n        new_length = 1 + 1 + opt_length;\n        new_field[0] = (unsigned char)opt_kind;\n        new_field[1] = (unsigned char)new_length;\n        memcpy(new_field + 2, opt_data, opt_length);\n\n        /* Calculate the begin/end of the existing field in the packet */\n        old_begin = offset;\n        if (old_begin >= hdr.max)\n            old_end = hdr.max; /* will insert end of header */\n        else if (buf[offset] == 0x00)\n            old_end = hdr.max; /* will insert start of padding */\n        else if (buf[offset] == opt_kind) { /* will replace old field */\n            size_t len = buf[offset + 1];\n            old_end = offset + len;\n        } else {\n            fprintf(stderr, \"[-] not possible i09670t\\n\");\n            return false;\n        }\n\n        /* If the existing space is too small, try to expand it by\n         * using neighboring (leading, trailing) NOPs */\n        while ((old_end-old_begin) < new_length) {\n            if (nop_count) {\n                nop_count--;\n                old_begin--;\n            } else if (old_end < hdr.max && buf[old_end] == 0x01) {\n                old_end++;\n            } else\n                break;\n        }\n\n        /* If the existing space is too small, and we are at the end,\n         * and there's pading, then try to use the padding */\n        if ((old_end-old_begin) < new_length) {\n            if (old_end < hdr.max) {\n                if (buf[old_end] == 0x00) {\n                    /* normalize padding to all zeroes */\n                    safe_memset(buf, length, old_end, 0, hdr.max - old_end);\n\n                    while ((old_end-old_begin) < new_length) {\n                        if (old_end >= hdr.max)\n                            break;\n                        old_end++;\n                    }\n                }\n            }\n        }\n\n        /* Make sure we have enough space in the header */\n        {\n            static const size_t max_tcp_hdr = (0xF0>>4) * 4; /* 60 */\n            size_t added = new_length - (old_end - old_begin);\n            if (hdr.max + added > hdr.begin + max_tcp_hdr) {\n                //unsigned total_padding = _calc_padding(buf, hdr);\n                old_begin = _squeeze_padding(buf, length, hdr, opt_kind);\n                old_end = hdr.max;\n            }\n        }\n\n\n        /* Now insert the option field into packet. This may change the\n         * sizeof the packet. The amount changed is indicated by 'adjust' */\n        adjust = _insert_field(&buf, &length,\n                               old_begin, old_end,\n                               new_field, new_length);\n        hdr.max += adjust;\n    }\n\n    if (adjust) {\n\n        /* TCP headers have to be aligned to 4 byte boundaries, so we may need\n         * to add padding of 0 at the end of the header to handle this */\n        if (adjust % 4 && adjust > 0) {\n            unsigned add_length = 4 - (adjust % 4);\n            _add_padding(&buf, &length, hdr.max, add_length);\n            hdr.max += add_length;\n            adjust += add_length;\n        } else if (adjust % 4 && adjust < 0) {\n            unsigned add_length = 0 - (adjust % 4);\n\n            //_HEXDUMP(buf, hdr, hdr.max, \"pad before\");\n            _add_padding(&buf, &length, hdr.max, add_length);\n            hdr.max += add_length;\n            adjust += add_length;\n\n            //_HEXDUMP(buf, hdr, hdr.max, \"pad after\");\n        }\n\n        /* fix the IP and TCP length fields */\n        _adjust_length(buf, length, adjust, hdr);\n\n        /* In case we've padded the packet with four 0x00, get rid\n         * of them */\n        _normalize_padding(&buf, &length);\n    }\n\n    *inout_buf = buf;\n    *inout_length = length;\n    return true;\n\nfail:\n    /* no changes were made */\n    *inout_buf = buf;\n    *inout_length = length;\n    return false;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcp_get_mss(const unsigned char *buf, size_t length, bool *is_found) {\n    struct tcp_opt_t opt;\n    unsigned result = 0;\n\n    opt = tcp_find_opt(buf, length, 2 /* MSS */);\n    if (is_found)\n        *is_found = opt.is_found;\n    if (!opt.is_found)\n        return 0xFFFFffff;\n\n    if (opt.length != 2) {\n        /* corrupt */\n        if (is_found)\n            *is_found = false;\n        return 0xFFFFffff;\n    }\n\n    result = opt.buf[0] << 8 | opt.buf[1];\n\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcp_get_wscale(const unsigned char *buf, size_t length, bool *is_found) {\n    struct tcp_opt_t opt;\n    unsigned result = 0;\n\n    opt = tcp_find_opt(buf, length, 3 /* Wscale */);\n    if (is_found)\n        *is_found = opt.is_found;\n    if (!opt.is_found)\n        return 0xFFFFffff;\n\n    if (opt.length != 1) {\n        /* corrupt */\n        if (is_found)\n            *is_found = false;\n        return 0xFFFFffff;\n    }\n\n    result = opt.buf[0];\n\n    return result;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic unsigned\ntcp_get_sackperm(const unsigned char *buf, size_t length, bool *is_found) {\n    struct tcp_opt_t opt;\n\n    opt = tcp_find_opt(buf, length, 3 /* Wscale */);\n    if (is_found)\n        *is_found = opt.is_found;\n    if (!opt.is_found)\n        return 0xFFFFffff;\n\n    if (opt.length != 1) {\n        /* corrupt */\n        if (is_found)\n            *is_found = false;\n        return 0xFFFFffff;\n    }\n\n    return 0;\n}\n\n/***************************************************************************\n * Called at the end of configuration, to change the TCP header template\n * according to configuration. For example, we might add a \"sackperm\" field,\n * or delete an \"mss\" field, or change the value of \"mss\".\n ***************************************************************************/\nvoid\ntempl_tcp_apply_options(unsigned char **inout_buf, size_t *inout_length,\n                  const struct TemplateOptions *templ_opts) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n\n    if (templ_opts == NULL)\n        return;\n\n    /* --tcp-mss <num>\n     * Sets maximum segment size */\n    if (templ_opts->tcp.is_mss == Remove) {\n        tcp_remove_opt(&buf, &length, 2 /* mss */);\n    } else if (templ_opts->tcp.is_mss == Add) {\n        unsigned char field[2];\n        field[0] = (unsigned char)(templ_opts->tcp.mss>>8);\n        field[1] = (unsigned char)(templ_opts->tcp.mss>>0);\n        tcp_add_opt(&buf, &length, 2, 2, field);\n    }\n\n    /* --tcp-sackok\n     * Sets option flag that permits selective acknowledgements */\n    if (templ_opts->tcp.is_sackok == Remove) {\n        tcp_remove_opt(&buf, &length, 4 /* sackok */);\n    } else if (templ_opts->tcp.is_sackok == Add) {\n        tcp_add_opt(&buf, &length, 4, 0, (const unsigned char*)\"\");\n    }\n\n    /* --tcp-wscale <num>\n     * Sets window scale option  */\n    if (templ_opts->tcp.is_wscale == Remove) {\n        tcp_remove_opt(&buf, &length, 3 /* wscale */);\n    } else if (templ_opts->tcp.is_wscale == Add) {\n        unsigned char field[1];\n        field[0] = (unsigned char)templ_opts->tcp.wscale;\n        tcp_add_opt(&buf, &length, 3, 1, field);\n    }\n\n    /* --tcp-ts <num>\n     * Timestamp */\n    if (templ_opts->tcp.is_tsecho == Remove) {\n        tcp_remove_opt(&buf, &length, 8 /* ts */);\n    } else if (templ_opts->tcp.is_tsecho == Add) {\n        unsigned char field[10] = {0};\n        field[0] = (unsigned char)(templ_opts->tcp.tsecho>>24);\n        field[1] = (unsigned char)(templ_opts->tcp.tsecho>>16);\n        field[2] = (unsigned char)(templ_opts->tcp.tsecho>>8);\n        field[2] = (unsigned char)(templ_opts->tcp.tsecho>>0);\n        tcp_add_opt(&buf, &length, 8, 8, field);\n    }\n\n\n    *inout_buf = buf;\n    *inout_length = length;\n}\n\n/***************************************************************************\n * Used during selftests in order to create a known options field as the\n * starting before before changing it somehow, followed by using\n * _compare_options() to test whether the change succeeded.\n ***************************************************************************/\nstatic bool\n_replace_options(unsigned char **inout_buf, size_t *inout_length,\n                        const char *new_options, size_t new_length) {\n    unsigned char *buf = *inout_buf;\n    size_t length = *inout_length;\n    struct tcp_hdr_t hdr;\n    size_t offset;\n    size_t old_length;\n    char newnew_options[40] = {0};\n    int adjust = 0;\n\n    /* Maximum length of the options field is 40 bytes */\n    if (new_length > 40)\n        goto fail;\n\n    /* Pad new options to 4 byte boundary */\n    memcpy(newnew_options, new_options, new_length);\n    while (new_length % 4)\n        new_length++;\n\n    /* find TCP header */\n    hdr = _find_tcp_header(buf, length);\n    if (!hdr.is_found)\n        goto fail;\n\n    /* Find start of options field */\n    offset = _opt_begin(hdr);\n    old_length = hdr.max - offset;\n\n    /* Either increase or decrease the old length appropriately */\n    //_HEXDUMPopt(buf, length, \"resize before\");\n    adjust = (int)(new_length - old_length);\n    if (adjust > 0) {\n        length += adjust;\n        buf = realloc(buf, length);\n        safe_memmove(buf, length,\n                        hdr.max + adjust,\n                        hdr.max,\n                        (length - adjust) - hdr.max);\n    }\n    if (adjust < 0) {\n        safe_memmove(   buf, length,\n                        hdr.max + adjust,\n                        hdr.max,\n                        length - hdr.max);\n        length += adjust;\n        buf = realloc(buf, length);\n    }\n\n    \n    /* Now that we've resized the options field, overright\n     * it with then new field */\n    memcpy(buf + offset, newnew_options, new_length);\n\n    /* fix the IP and TCP length fields */\n    _adjust_length(buf, length, adjust, hdr);\n\n    //_HEXDUMPopt(buf, length, \"resize after\");\n\n\n    *inout_buf = buf;\n    *inout_length = length;\n    return true;\nfail:\n    *inout_buf = buf;\n    *inout_length = length;\n    return false;\n}\n\n/***************************************************************************\n ***************************************************************************/\nenum {\n    TST_NONE,\n    TST_PADDING,\n    TST_ADD,\n    TST_REMOVE,\n};\n\n/***************************************************************************\n * This structure specifies test cases for the sefltest function. Each\n * test has a pre-condition <options-list>, and option to add/remove, and\n * a post-condition <options-list> that should match the result.\n ***************************************************************************/\nstruct mytests_t {\n    struct {\n        const char *options;\n        size_t length;\n    } pre;\n    struct {\n        int opcode;\n        const char *data;\n        size_t length;\n    } test;\n    struct {\n        const char *options;\n        size_t length;\n    } post;\n};\n\n/***************************************************************************\n * The following tests add/remove options to a test packet. The goal of\n * these tests is code-coverage of all the conditions above, testing\n * all the boundary cases. Every code path that produces success is tested,\n * plus many code paths that produce failures.\n ***************************************************************************/\nstatic struct mytests_t\ntests[] = {\n    /* A lot of these tests use 2-byte (\\4\\2) and 3-byte (\\3\\3\\3) options.\n     * The \"\\4\\2\" is \"SACK permitted, kind=4, len=2, with no extra data.\n     * The \"\\3\\3\\3\" is \"Window Scale, kind=3, len=3, data=3.\n     * The \"\\2\\4\\5\\6\" is \"Max Segment Size\", kind=2, len=4, data=0x0506\n     */\n\n    /* Attempt removal of an option that doesn't exist. This is not\n     * a failure, but a success, though nothing is changed*/\n\n    {   {\"\\3\\3\\3\\0\", 4},\n        {TST_REMOVE, \"\\x08\", 1},\n        {\"\\3\\3\\3\\0\", 4}\n    },\n\n\n    /* Test removal of an option. This will also involve removing\n     the now unnecessary padding */\n    {   {\"\\3\\3\\3\\1\\1\\1\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\", 16},\n        {TST_REMOVE, \"\\x08\", 1},\n        {\"\\3\\3\\3\\0\", 4}\n    },\n\n    /* Test when trying to add a big option that won't fit unless we get\n     * rid of all the padding */\n    {   {   \"\\x02\\x04\\x05\\xb4\"\n            \"\\x01\\x03\\x03\\x06\"\n            \"\\x01\\x01\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n            \"\\x04\\x02\\x00\\x00\"\n            \"\\0\\0\\0\\0\",\n            28},\n        {   TST_ADD,\n            \"\\7\\x14\" \"AAAAAAAAAAAAAAAAAAAA\",\n            20\n        },\n        {   \"\\x02\\x04\\x05\\xb4\"\n            \"\\x03\\x03\\x06\"\n            \"\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n            \"\\x04\\x02\"\n            \"\\7\\x14\" \"AAAAAAAAAAAAAAAAAA\"\n            \"\\0\",\n            40\n        }\n    },\n\n    /* same as a bove, but field exists*/\n    {{  \"\\x02\\x04\\x05\\xb4\"\n        \"\\x01\\x03\\x03\\x06\"\n        \"\\x01\\x01\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n        \"\\7\\4\\1\\1\"\n        \"\\x04\\x02\\x00\\x00\",\n        28},\n        {   TST_ADD,\n            \"\\7\\x14\" \"AAAAAAAAAAAAAAAAAAAA\",\n            20\n        },\n        {   \"\\x02\\x04\\x05\\xb4\"\n            \"\\x03\\x03\\x06\"\n            \"\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n            \"\\x04\\x02\"\n            \"\\7\\x14\" \"AAAAAAAAAAAAAAAAAA\"\n            \"\\0\",\n            40\n        }\n    },\n    \n    /* Add a new value to full packet  */\n    {{\"\\3\\3\\3\", 3}, {TST_ADD, \"\\4\\2\", 2}, {\"\\3\\3\\3\\4\\2\\0\\0\\0\", 8}},\n\n    /* Change a 3 byte to 5 byte in middle of packet  */\n    {{\"\\1\\7\\3\\3\\1\\1\\4\\2\", 8}, {TST_ADD, \"\\7\\5\\5\\5\\5\", 5}, {\"\\7\\5\\5\\5\\5\\1\\4\\2\", 8}},\n\n    /* Change 3 to 4 byte at start */\n    {{\"\\7\\3\\3\\1\\2\\4\\5\\6\", 8}, {TST_ADD, \"\\7\\4\\4\\4\", 4}, {\"\\7\\4\\4\\4\\2\\4\\5\\6\", 8}},\n\n    /* Change a 2-byte option */\n    {{\"\\4\\2\", 2}, {TST_ADD, \"\\4\\2\", 2}, {\"\\4\\2\\0\\0\", 4}},\n\n    /* Change a 3-byte option */\n    {{\"\\3\\3\\2\", 3}, {TST_ADD, \"\\3\\3\\3\", 3}, {\"\\3\\3\\3\\0\", 4}},\n\n    /* Change a 4-byte option */\n    {{\"\\2\\4\\1\\1\", 4}, {TST_ADD, \"\\2\\4\\5\\6\", 4}, {\"\\2\\4\\5\\6\", 4}},\n\n    /* Add a 2-byte option to empty packet*/\n    {{\"\", 0}, {TST_ADD, \"\\4\\2\", 2}, {\"\\4\\2\\0\\0\", 4}},\n\n    /* Add a 3-byte option to empty packet*/\n    {{\"\", 0}, {TST_ADD, \"\\3\\3\\3\", 3}, {\"\\3\\3\\3\\0\", 4}},\n\n    /* Add a 4-byte option to empty packet*/\n    {{\"\", 0}, {TST_ADD, \"\\2\\4\\5\\6\", 4}, {\"\\2\\4\\5\\6\", 4}},\n\n    /* Empty packet: padding normalization should make no changes */\n    {{\"\", 0}, {TST_PADDING,0,0}, {\"\", 0}},\n\n    /* Empty packet plus 4 bytes of padding, should be removed */\n    {{\"\\0\", 1}, {TST_PADDING,0,0}, {\"\", 0}},\n\n    /* 8 bytes of padding, should only remove all of them */\n    {{\"\\0\\0\\0\\0\\0\\0\\0\\0\", 8}, {TST_PADDING,0,0}, {\"\", 0}},\n\n    /* some padding is nops, should remove all  */\n    {{\"\\1\\1\\0\\0\\0\\0\\0\\0\", 8}, {TST_PADDING,0,0}, {\"\", 0}},\n\n    /* any trailing NOPs should be converted to EOLs  */\n    {{\"\\3\\3\\3\\1\\0\\0\\0\\0\", 8}, {TST_PADDING,0,0}, {\"\\3\\3\\3\\0\", 4}},\n\n    /* only NOPs should still be removed */\n    {{\"\\3\\3\\3\\1\\1\\1\\1\\1\", 8}, {TST_PADDING,0,0}, {\"\\3\\3\\3\\0\", 4}},\n\n    {{0}}\n};\n\n\n/***************************************************************************\n * This function runs through the tests in the [tests] array above. It\n * first creates a packet accoding to a pre-condition that may have\n * options already. We then call a function to manipulate the packet,\n * such as adding/changing an option. We then verify that that the\n * <option-list> field now matches the post-condition. Along the way,\n * we look for any errors are consistency failures.\n ***************************************************************************/\nstatic int\n_selftests_run(void) {\n    static unsigned char templ[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x48\"      /* total length = 64 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x06\"      /* TTL=255, proto=TCP */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\0\\0\"          /* source port */\n    \"\\0\\0\"          /* destination port */\n    \"\\0\\0\\0\\0\"      /* sequence number */\n    \"\\0\\0\\0\\0\"      /* ACK number */\n    \"\\xB0\"          /* header length */\n    \"\\x02\"          /* SYN */\n    \"\\x04\\x01\"      /* window fixed to 1024 */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\x00\\x00\"      /* urgent pointer */\n\n    \"\\x02\\x04\\x05\\xb4\"\n    \"\\x01\\x03\\x03\\x06\"\n    \"\\x01\\x01\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n    \"\\x04\\x02\\x00\\x00\"\n    \"DeadBeef\"\n    ;\n    size_t i;\n\n    /* execute all tests */\n    for (i=0; tests[i].pre.options; i++) {\n        unsigned char *buf;\n        size_t length = sizeof(templ) - 1;\n        bool success;\n        struct tcp_hdr_t hdr;\n        const unsigned char *field;\n        size_t field_length;\n\n\n        LOG(1, \"[+] templ-tcp-hdr: run #%u\\n\", (unsigned)i);\n\n        /* Each tests creates its own copy of the test packet, which it\n         * will then alter according to the pre-conditions. */\n        buf = malloc(length);\n        memcpy(buf, templ, length);\n\n        /* Set the pre-condition <option-list> field by replacing what\n         * was there with a completely new field */\n        success = _replace_options(&buf, &length,\n                         tests[i].pre.options, tests[i].pre.length);\n        if (!success)\n            goto fail; /* this should never happen */\n        if (_consistancy_check(buf, length, \"DeadBeef\", 8))\n            goto fail; /* this shoiuld never happen*/\n\n\n        //_HEXDUMPopt(buf, length, \"[PRE]\");\n\n        /*\n         * Run the desired test\n         */\n        switch (tests[i].test.opcode) {\n            case TST_PADDING:\n                /* We are testing the \"normalize padding\" function. This\n                 * is called after ever 'add' or 'remove' to make sure that\n                 * the padding at the end is consistent. Mostly, it means\n                 * that when we remove a field, we'll probably have excess\n                 * padding at the end, which needs to be trimmed to the\n                 * minimum amount of padding */\n                success = _normalize_padding(&buf, &length);\n                if (!success)\n                    goto fail;\n                break;\n            case TST_ADD:\n                /* We are testing `tcp_add_opt()` function, which is called\n                 * to either 'add' or 'change' an existing option. */\n                field = (const unsigned char*)tests[i].test.data;\n                field_length = tests[i].test.length;\n                if (field_length < 2)\n                    goto fail;\n                else {\n                    unsigned opt_kind = field[0];\n                    unsigned opt_length = field[1];\n                    const unsigned char *opt_data = field + 2;\n\n                    if (field_length != opt_length)\n                        goto fail;\n\n                    /* skip the KIND and LENGTH fields, justa DATA length */\n                    opt_length -= 2;\n\n                    success = tcp_add_opt(&buf, &length,\n                                          opt_kind,\n                                          opt_length,\n                                          opt_data);\n                    if (!success)\n                        goto fail;\n                }\n                break;\n            case TST_REMOVE:\n                /* We are testing `tcp_add_opt()` function, which is called\n                 * to either 'add' or 'change' an existing option. */\n                field = (const unsigned char*)tests[i].test.data;\n                field_length = tests[i].test.length;\n                if (field_length != 1)\n                    goto fail;\n                else {\n                    unsigned opt_kind = field[0];\n\n                    success = tcp_remove_opt(&buf, &length,\n                                          opt_kind);\n\n                    if (!success)\n                        goto fail;\n                }\n                break;\n            default:\n                return 1; /* fail */\n        }\n\n        //_HEXDUMPopt(buf, length, \"[POST]\");\n\n        if (_consistancy_check(buf, length, \"DeadBeef\", 8))\n            goto fail;\n\n        /*\n         * Make sure output matches expected results\n         */\n        {\n            size_t offset;\n            int err;\n            size_t post_length;\n\n            /* Find the <options-list> field */\n            hdr = _find_tcp_header(buf, length);\n            if (!hdr.is_found)\n                goto fail;\n            offset = _opt_begin(hdr);\n\n            /* Make sure the length matches the expected length */\n            post_length = hdr.max - offset;\n            if (tests[i].post.length != post_length)\n                goto fail;\n\n            /* makre sure the contents of the field match expected */\n            err = memcmp(tests[i].post.options, buf+offset, (hdr.max-offset));\n            if (err) {\n                _HEXDUMPopt(buf, length, \"[-] failed expectations\");\n                goto fail;\n            }\n        }\n\n        free(buf);\n    }\n\n    return 0; /* success */\nfail:\n    fprintf(stderr, \"[-] templ.tcp.selftest failed, test #%u\\n\",\n            (unsigned)i);\n    return 1;\n};\n\n/***************************************************************************\n * These self-tests manipulate a TCP header, adding and removing <option>\n * fields in various scenarios. We expose the `tcp_add_option()` function\n * to the end-user via the command-line, so we have to anticipate that\n * the option they want added is going to be corrupt. For example, the\n * end-user might try to add an option that overflows the <option-list>\n * field, which is rather small (only 40 bytes long).\n ***************************************************************************/\nint\ntempl_tcp_selftest(void) {\n\n    static unsigned char templ[] =\n    \"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n    \"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n    \"\\x08\\x00\"      /* Ethernet type: IPv4 */\n    \"\\x45\"          /* IP type */\n    \"\\x00\"\n    \"\\x00\\x48\"      /* total length = 64 bytes */\n    \"\\x00\\x00\"      /* identification */\n    \"\\x00\\x00\"      /* fragmentation flags */\n    \"\\xFF\\x06\"      /* TTL=255, proto=TCP */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\0\\0\\0\\0\"      /* source address */\n    \"\\0\\0\\0\\0\"      /* destination address */\n\n    \"\\0\\0\"          /* source port */\n    \"\\0\\0\"          /* destination port */\n    \"\\0\\0\\0\\0\"      /* sequence number */\n    \"\\0\\0\\0\\0\"      /* ACK number */\n    \"\\xB0\"          /* header length */\n    \"\\x02\"          /* SYN */\n    \"\\x04\\x01\"      /* window fixed to 1024 */\n    \"\\xFF\\xFF\"      /* checksum */\n    \"\\x00\\x00\"      /* urgent pointer */\n\n    \"\\x02\\x04\\x05\\xb4\"\n    \"\\x01\\x03\\x03\\x06\"\n    \"\\x01\\x01\\x08\\x0a\\x1d\\xe9\\xb2\\x98\\x00\\x00\\x00\\x00\"\n    \"\\x04\\x02\\x00\\x00\"\n    \"DeadBeef\"\n    ;\n    size_t length = sizeof(templ) - 1;\n    unsigned char *buf;\n\n    /* Execute planned selftests */\n    if (_selftests_run())\n        return 1;\n\n    /* We need to make an allocated copy of the buffer, because the\n     * size may change from `realloc()` */\n    buf = malloc(length);\n    memcpy(buf, templ, length);\n\n    /*\n     * Make sure we start wtih an un-corrupted test packet\n     */\n    if (_consistancy_check(buf, length, \"DeadBeef\", 8))\n        goto fail;\n\n    if (1460 != tcp_get_mss(buf, length, 0))\n        goto fail;\n    if (6 != tcp_get_wscale(buf, length, 0))\n        goto fail;\n    if (0 != tcp_get_sackperm(buf, length, 0))\n        goto fail;\n\n    tcp_add_opt(&buf, &length, 2, 2, (const unsigned char*)\"\\x12\\x34\");\n    if (0x1234 != tcp_get_mss(buf, length, 0))\n        goto fail;\n    if (_consistancy_check(buf, length, \"DeadBeef\", 8))\n        goto fail;\n\n    tcp_remove_opt(&buf, &length, 3);\n    if (0x1234 != tcp_get_mss(buf, length, 0))\n        goto fail;\n    if (0xFFFFffff != tcp_get_wscale(buf, length, 0))\n        goto fail;\n    if (_consistancy_check(buf, length, \"DeadBeef\", 8))\n        goto fail;\n\n\n    free(buf);\n    return 0; /* success */\nfail:\n    free(buf);\n    return 1; /* failure */\n}\n"
  },
  {
    "path": "src/templ-tcp-hdr.h",
    "content": "#ifndef TEMPL_TCP_H\n#define TEMPL_TCP_H\n#include \"util-bool.h\" /* <stdbool.h> */\n#include <stdio.h>\nstruct TemplateOptions;\n\n/**\n * Called during configuration, to apply all the various changes the\n * user asked for on the command-line, such as optioms like:\n * --tcp-mss 1460\n * --tcp-sackperm\n * --tcp-wscale 3\n */\nvoid\ntempl_tcp_apply_options(unsigned char **inout_buf, size_t *inout_length,\n                  const struct TemplateOptions *templ_opts);\n\n/**\n * Conduct a selftest of all the functions that manipulate the TCP\n * header template.\n */\nint\ntempl_tcp_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/unusedparm.h",
    "content": "#ifndef UNUSEDPARM\n#if defined(_MSC_VER)\n#define UNUSEDPARM(x) x\n#elif defined(__GNUC__)\n#define UNUSEDPARM(x) (void) x\n#endif\n#endif\n\n"
  },
  {
    "path": "src/util-bool.h",
    "content": "#ifndef UTIL_BOOL_H\n#define UTIL_BOOL_H\n\n#if _MSC_VER && _MSC_VER < 1800\ntypedef enum {false=0, true=1} bool;\n#else\n#include <stdbool.h>\n#endif\n#endif\n\n"
  },
  {
    "path": "src/util-checksum.c",
    "content": "/*\n    Calculates Internet checksums for protocols like TCP/IP.\n\n    Author: Robert David Graham\n    Copyright: 2020\n    License: The MIT License (MIT)\n    Dependencies: none\n*/\n#include \"util-checksum.h\"\n\n/**\n * Calculates the checksum over a buffer.\n * @param checksum\n *      The value of the pseudo-header checksum that this sum will be\n *      added to. This value must be calculated separately. This\n *      is the original value in 2s-complement. In other words,\n *      for TCP, which will be the integer value of the \n *      IP addresses, protocol number, and length field added together.\n * @param buf\n *      The buffer that we are checksumming, such as all the\n *      payload after an IPv4 or IPv6 header.\n */\nstatic unsigned\n_checksum_calculate(const void *vbuf, size_t length)\n{\n    unsigned sum = 0;\n    size_t i;\n    const unsigned char *buf = (const unsigned char *)vbuf;\n    int is_remainder;\n\n    /* If there is an odd number of bytes, then we handle the \n     * last byte in a custom manner. */\n    is_remainder = (length & 1);\n    length &= (~1);\n\n    /* Sum up all the 16-bit words in the packet */\n    for (i=0; i<length; i += 2) {\n        sum += buf[i]<<8 | buf[i+1];\n    }\n\n    /* If there is an odd number of bytes, then add the last\n     * byte to the sum, in big-endian format as if there was\n     * an additional trailing byte of zero. */\n    if (is_remainder)\n        sum += buf[length]<<8;\n\n    /* Return the raw checksum. Note that this hasn't been\n     * truncated to 16-bits yet or had the bits reversed. */\n    return sum;\n}\n\n\n/**\n * After we sum up all the numbers involved, we must \"fold\" the upper\n * 16-bits back into the lower 16-bits. Since something like 0x1FFFF\n * will fold into 0x10000, we need to call a second fold operation\n * (obtaining 0x0001 in this example). In other words, we need to \n * keep folding until the result is 16-bits, but that never takes\n * more than two folds. After this, we need to take the 1s-complement,\n * which means reversing the bits so that 0 becomes 1 and 1 becomes 0.\n */\nstatic unsigned\n_checksum_finish(unsigned sum)\n{\n    sum = (sum >> 16) + (sum & 0xFFFF);\n    sum = (sum >> 16) + (sum & 0xFFFF);\n    return (~sum) & 0xFFFF;\n}\n\n\n\n\n\nunsigned \nchecksum_ipv4(unsigned ip_src, unsigned ip_dst, unsigned ip_proto, size_t payload_length, const void *payload)\n{\n    unsigned sum;\n    const unsigned char *buf = (const unsigned char *)payload;\n\n    /* Calculate the sum of the pseudo-header. Note that all these fields\n     * are assumed to be in host byte-order, not big-endian */\n    sum = (ip_src>>16) & 0xFFFF;\n    sum += (ip_src>> 0) & 0xFFFF;\n    sum += (ip_dst>>16) & 0xFFFF;\n    sum += (ip_dst>> 0) & 0xFFFF;\n    sum += ip_proto;\n    sum += (unsigned)payload_length;\n    sum += _checksum_calculate(buf, payload_length);\n\n    /* Remove the existing checksum field from the calculation. */\n    switch (ip_proto) {\n    case 0: /* IP header -- has no pseudo header */\n        sum = _checksum_calculate(buf, payload_length);\n        sum -= buf[10]<<8 | buf[11]; /* pretend the existing checksum field is zero */\n        break;\n    case 1:\n        sum -= buf[2]<<8 | buf[3];\n        break;\n    case 2: /* IGMP - group message - has no pseudo header */\n        sum = _checksum_calculate(payload, payload_length);\n        sum -= buf[2]<<8 | buf[3];\n        break;\n    case 6:\n        sum -= buf[16]<<8 | buf[17];\n        break;\n    case 17:\n        sum -= buf[6]<<8 | buf[7];\n        break;\n    default:\n        return 0xFFFFFFFF;\n    }\n\n    sum = _checksum_finish(sum);\n    return sum;\n}\n\nunsigned \nchecksum_ipv6(const unsigned char *ip_src, const unsigned char *ip_dst, unsigned ip_proto, size_t payload_length, const void *payload)\n{\n    const unsigned char *buf = (const unsigned char *)payload;\n    unsigned sum;\n\n    /* Calculate the pseudo-header */\n    sum = _checksum_calculate(ip_src, 16);\n    sum += _checksum_calculate(ip_dst, 16);\n    sum += (unsigned)payload_length;\n    sum += ip_proto;\n\n    /* Calculate the remainder of the checksum */\n    sum += _checksum_calculate(payload, payload_length);\n\n    /* Remove the existing checksum field. */\n    switch (ip_proto) {\n    case 0:\n        return 0;\n    case 1:\n    case 58:\n        sum -= buf[2]<<8 | buf[3];\n        break;\n    case 6:\n        sum -= buf[16]<<8 | buf[17];\n        break;\n    case 17:\n        sum -= buf[6]<<8 | buf[7];\n        break;\n    default:\n        return 0xFFFFFFFF;\n    }\n\n    /* fold and invert */\n    sum = _checksum_finish(sum);\n    return sum;\n}\n\n/*\n * Test cases for IPv4\n */\nstatic struct {\n    unsigned checksum;\n    const char *buf;\n    unsigned ip_src;\n    unsigned ip_dst;\n    size_t length;\n    unsigned ip_proto;\n} ipv4packets[] = {\n    {\n        0xee9b,\n        \"\\x11\\x64\\xee\\x9b\\x00\\x00\\x00\\x00\",\n        0x0a141e01, 0xe0000001, 8, 2 /* IGMP - Group Message protocol */\n    }, {\n        0x6042,\n        \"\\xdc\\x13\\x01\\xbb\\x00\\x29\\x60\\x42\"\n        \"\\x5b\\xd6\\x16\\x3a\\xb1\\x78\\x3d\\x5d\\xdd\\x0e\\x5a\\x05\\x35\\x74\\x92\\x91\"\n        \"\\x57\\x4c\\xaa\\xc1\\x85\\x76\\xc0\\x0f\\x8d\\x9e\\x19\\xa5\\xcc\\xa2\\x81\\x65\\xbe\",\n        0x0a141ec9, 0xadc2900a, 41, 17 /* UDP */\n    }, {\n        0x84b2,\n        \"\\x7e\\x70\\x69\\x95\\x1f\\xb9\\x77\\xc6\\xee\\x09\\x7b\\x72\\x50\\x18\\x03\\xfd\" \n        \"\\x84\\xb2\\x00\\x00\"\n        \"\\x17\\x03\\x03\\x00\\x3a\\x6c\\x04\\xe3\\x0e\\x25\\x79\\x8e\\x1c\\x98\\xdd\\x2c\"\n        \"\\x8d\\x41\\x39\\x53\\xfb\\xd0\\xd5\\x3e\\x14\\xf8\\xdf\\xb9\\xb8\\x47\\xe0\\x43\"\n        \"\\xab\\x09\\x24\\x58\\x7c\\x6a\\xab\\x91\\xaf\\x24\\xc0\\x5c\\xc6\\xaf\\x56\\x45\"\n        \"\\xed\\xa3\\xde\\x06\\xa2\\xd1\\x79\\x0a\\x21\\xfe\\x9c\\x2e\\x6e\\x81\\x19\",\n        0x0a141ec9, 0xa2fec14a, 83, 6 /* TCP */\n    }, {0}\n};\n\n/*\n * Test cases for IPv6\n */\nstatic struct {\n    unsigned checksum;\n    const char *buf;\n    const char *ip_src;\n    const char *ip_dst;\n    size_t length;\n    unsigned ip_proto;\n} ipv6packets[] = {\n    {\n        0x09e3,\n        \"\\x02\\x22\\x02\\x23\\x00\\x32\\x09\\xe3\"\n        \"\\x0b\\x15\\x18\\x54\\x00\\x06\\x00\\x0a\\x00\\x17\\x00\\x18\\x00\\x38\\x00\\x1f\"\n        \"\\x00\\x0e\\x00\\x01\\x00\\x0e\\x00\\x02\\x00\\x00\\xab\\x11\\xfd\\xb3\\xae\\xbb\"\n        \"\\xe6\\x57\\x00\\x5c\\x00\\x08\\x00\\x02\\x00\\x00\",\n        \"\\xfe\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x07\\x32\\xff\\xfe\\x42\\x5e\\x35\",\n        \"\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x02\",\n        50, 17 /* UDP */\n    }, {   0xbf3c,\n        \"\\x8f\\x00\\xbf\\x3c\\x00\\x00\\x00\\x04\\x04\\x00\\x00\\x00\\xff\\x02\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\xff\\x03\\x68\\x4c\\x04\\x00\\x00\\x00\"\n        \"\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\xff\\xd4\\xa6\\x80\"\n        \"\\x04\\x00\\x00\\x00\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\"\n        \"\\xff\\x06\\xab\\x72\\x04\\x00\\x00\\x00\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00\"\n        \"\\x00\\x00\\x00\\x01\\xff\\x2f\\x65\\x52\",\n        \"\\xfe\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x1c\\x7b\\x06\\x42\\x4e\\x57\\x19\\xcc\",\n        \"\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x16\",\n        88, 58 /* ICMPv6 */\n    }, {   0x0d0e,\n        \"\\x8d\\x59\\x01\\xbb\\xed\\xb8\\x70\\x8b\\x91\\x6c\\x8d\\x68\\x50\\x10\\x04\\x01\"\n        \"\\x0d\\x0e\\x00\\x00\",\n        \"\\x20\\x02\\x18\\x62\\x5d\\xeb\\x00\\x00\\xac\\xc3\\x59\\xad\\x84\\x6b\\x97\\x80\",\n        \"\\x26\\x02\\xff\\x52\\x00\\x00\\x00\\x6a\\x00\\x00\\x00\\x00\\x1f\\xd2\\x94\\x5a\",\n        20, 6 /* TCP */\n    }, {0}\n};\n\n\n\nint checksum_selftest(void)\n{\n    unsigned sum;\n    size_t i;\n\n    /* Run through some IPv6 examples of TCP, UDP, and ICMP */\n    for (i=0; ipv6packets[i].buf; i++) {\n        sum = checksum_ipv6(\n            (const unsigned char *)ipv6packets[i].ip_src, \n            (const unsigned char *)ipv6packets[i].ip_dst, \n            ipv6packets[i].ip_proto, \n            ipv6packets[i].length, \n            ipv6packets[i].buf);\n        if (sum != ipv6packets[i].checksum)\n            return 1; /* fail */\n    }\n\n\n    /* Run through some IPv4 examples of TCP, UDP, and ICMP */\n    for (i=0; ipv4packets[i].buf; i++) {\n        sum = checksum_ipv4(ipv4packets[i].ip_src, \n            ipv4packets[i].ip_dst, \n            ipv4packets[i].ip_proto, \n            ipv4packets[i].length, \n            ipv4packets[i].buf);\n        if (sum != ipv4packets[i].checksum)\n            return 1; /* fail */\n    }\n\n    return 0; /* success */\n}\n"
  },
  {
    "path": "src/util-checksum.h",
    "content": "/*\n    Calculates Internet checksums for protocols like TCP/IP.\n\n    Author: Robert David Graham\n    Copyright: 2020\n    License: The MIT License (MIT)\n    Dependencies: none\n*/\n#ifndef UTIL_CHECKSUM_H\n#define UTIL_CHECKSUM_H\n#include <stddef.h>\n\n/**\n * Calculate a checksum for IPv4 packets.\n * @param ip_src\n *      The source IPv4 address, represented a standard way,\n *      as a 32-bit integer in host byte order.\n * @param ip_dst\n *      The destination IPv4 address, represented as a 32-bit integer in host byte order.\n * @param ip_proto\n *      A value of 6 for TCP or 17 for UDP.\n * @param payload_length\n *      The length of the IP packet payload, meaning, everything after the IPv4 header.\n *      In other words, it's the \"total length\" field of the IP packet minus the\n *      length of the IP header.\n * @param payload\n *      A pointer to the aforementioned payload (a pointer to the first byte past the\n *      IP header). Note that the calculation skips the checksum field, so the payload\n *      we use is everything but the 2 bytes in the checksum field. Thus, due to the \n *      quirkiness of Internet protocols, the result of this calculation should end\n *      up equally the value of the checksum field.\n * @return\n *      the calculated checksum, which should equal the checksum found in the payload\n */\nunsigned \nchecksum_ipv4(unsigned ip_src, unsigned ip_dst, unsigned ip_proto, size_t payload_length, const void *payload);\n\nunsigned \nchecksum_ipv6(const unsigned char *ip_src, const unsigned char *ip_dst, unsigned ip_proto, size_t payload_length, const void *payload);\n\n\n/**\n * Simple unit tests.\n * @return\n *      1 if failure, 0 if success\n */\nint checksum_selftest(void);\n\n#endif\n"
  },
  {
    "path": "src/util-errormsg.c",
    "content": "#include \"util-errormsg.h\"\n#include \"crypto-siphash24.h\"\n#include \"massip-addr.h\"\n#include <stdarg.h>\n#include <stdio.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4204)\n#endif\n\n\nstatic unsigned long long _entropy;\n\nvoid errmsg_init(unsigned long long in_entropy) {\n    _entropy = in_entropy;\n}\n\nstatic void\n_errmsg(const char *fmt, va_list marker)\n{\n    fprintf(stderr, \"[-] ERR: \");\n    vfprintf(stderr, fmt, marker);\n    fflush(stderr);\n}\n\nstatic void\n_errmsgip(ipaddress ip, unsigned port, const char *fmt, va_list marker)\n{\n    ipaddress_formatted_t fmted = ipaddress_fmt(ip);\n    \n    fprintf(stderr, \"[-] %s:%u: \", fmted.string, port);\n    vfprintf(stderr, fmt, marker);\n    fflush(stderr);\n}\n\n/***************************************************************************\n * Prints the message if the global \"verbosity\" flag exceeds this level.\n ***************************************************************************/\nvoid\nERRMSG(const char *fmt, ...)\n{\n    va_list marker;\n    size_t index;\n    uint64_t key[2] = {_entropy, _entropy};\n    static size_t _table[1024] = {0};\n\n    /* Hash the address of the format string */\n    index = (size_t)siphash24(fmt, sizeof(fmt), key);\n    index %= 1024;\n\n    /* Filter out this error if we've seen it before */\n    if (_table[index] == (size_t)fmt)\n        return;\n    else\n        _table[index] = (size_t)fmt;\n\n   \n    va_start(marker, fmt);\n    _errmsg(fmt, marker);\n    va_end(marker);\n}\n\nvoid\nERRMSGip(ipaddress ip, unsigned port, const char *fmt, ...)\n{\n    va_list marker;\n    size_t index;\n    uint64_t key[2] = {_entropy, _entropy};\n    static size_t _table[1024] = {0};\n\n    /* Hash the address of the format string */\n    index = (size_t)siphash24(fmt, sizeof(fmt), key);\n    index %= 1024;\n\n    /* Filter out this error if we've seen it before */\n    if (_table[index] == (size_t)fmt)\n        return;\n    else\n        _table[index] = (size_t)fmt;\n\n   \n    va_start(marker, fmt);\n    _errmsgip(ip, port, fmt, marker);\n    va_end(marker);\n}\n\n"
  },
  {
    "path": "src/util-errormsg.h",
    "content": "#ifndef UTIL_ERRORMSG_H\n#define UTIL_ERRORMSG_H\n#include \"massip-addr.h\"\n\nvoid errmsg_init(unsigned long long entropy);\n\n/**\n * Prints an error message only once\n */\nvoid\nERRMSG(const char *fmt, ...);\n\nvoid\nERRMSGip(ipaddress ip, unsigned port, const char *fmt, ...);\n\n\n#endif\n"
  },
  {
    "path": "src/util-extract.c",
    "content": "#include \"util-extract.h\"\n\n\nunsigned char\ne_next_byte(struct ebuf_t *ebuf) {\n    if (ebuf->offset + 1 > ebuf->max)\n        return -1;\n    \n    return ebuf->buf[ebuf->offset++];\n}\n\nunsigned short\ne_next_short16(struct ebuf_t *ebuf, int endian) {\n    const unsigned char *buf = ebuf->buf;\n    size_t offset = ebuf->offset;\n    unsigned short result;\n    \n    if (ebuf->offset + 2 > ebuf->max)\n        return -1;\n\n    if (endian == EBUF_BE) {\n        result = buf[offset+0]<<8 | buf[offset+1];\n    } else {\n        result = buf[offset+1]<<8 | buf[offset+0];\n    }\n    ebuf->offset += 2;\n    return result;\n}\nunsigned e_next_int32(struct ebuf_t *ebuf, int endian) {\n    const unsigned char *buf = ebuf->buf;\n    size_t offset = ebuf->offset;\n    unsigned result;\n    \n    if (ebuf->offset + 4 > ebuf->max)\n        return -1;\n\n    if (endian == EBUF_BE) {\n        result = buf[offset+0]<<24 | buf[offset+1] << 16\n                    | buf[offset+2]<<8 | buf[offset+3] << 0;\n    } else {\n        result = buf[offset+3]<<24 | buf[offset+2] << 16\n                    | buf[offset+1]<<8 | buf[offset+0] << 0;\n    }\n    ebuf->offset += 4;\n    return result;\n}\nunsigned long long\ne_next_long64(struct ebuf_t *ebuf, int endian) {\n    const unsigned char *buf = ebuf->buf;\n    size_t offset = ebuf->offset;\n    unsigned long long hi;\n    unsigned long long lo;\n    \n    if (ebuf->offset + 8 > ebuf->max)\n        return -1ll;\n\n    if (endian == EBUF_BE) {\n        hi = buf[offset+0]<<24 | buf[offset+1] << 16\n                    | buf[offset+2]<<8 | buf[offset+3] << 0;\n        lo = buf[offset+4]<<24 | buf[offset+5] << 16\n                    | buf[offset+6]<<8 | buf[offset+7] << 0;\n    } else {\n        lo = buf[offset+3]<<24 | buf[offset+2] << 16\n                    | buf[offset+1]<<8 | buf[offset+0] << 0;\n        hi = buf[offset+7]<<24 | buf[offset+6] << 16\n                    | buf[offset+5]<<8 | buf[offset+4] << 0;\n    }\n    ebuf->offset += 8;\n    return hi<<32ull | lo;\n\n}\n\n\n"
  },
  {
    "path": "src/util-extract.h",
    "content": "#ifndef UTIL_EXTRACT_H\n#define UTIL_EXTRACT_H\n#include <stdio.h>\n\nstruct ebuf_t {\n    const unsigned char *buf;\n    size_t offset;\n    size_t max;\n};\n\nenum {\n    EBUF_BE,\n    EBUG_LE,\n};\n\nunsigned char e_next_byte(struct ebuf_t *ebuf);\nunsigned short e_next_short16(struct ebuf_t *ebuf, int endian);\nunsigned e_next_int32(struct ebuf_t *ebuf, int endian);\nunsigned long long e_next_long64(struct ebuf_t *ebuf, int endian);\n\n\n#endif\n"
  },
  {
    "path": "src/util-logger.c",
    "content": "/*\n    log messages to console, depending on verbose level\n\n    Use -d to get more verbose output. The more -v you add, the\n    more verbose the output becomes.\n\n    Details about the running of the program go to <stderr>.\n    Details about scan results go to <stdout>, so that they can easily\n    be redirected to a file.\n*/\n#include \"util-logger.h\"\n#include \"util-safefunc.h\"\n#include <stdarg.h>\n#include <stdio.h>\n\nstatic int global_debug_level = 0; /* yea! a global variable!! */\nvoid LOG_add_level(int x)\n{\n    global_debug_level += x;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nvLOG(int level, const char *fmt, va_list marker)\n{\n    if (level <= global_debug_level) {\n        vfprintf(stderr, fmt, marker);\n        fflush(stderr);\n    }\n}\n\n\n/***************************************************************************\n * Prints the message if the global \"verbosity\" flag exceeds this level.\n ***************************************************************************/\nvoid\nLOG(int level, const char *fmt, ...)\n{\n    va_list marker;\n\n    va_start(marker, fmt);\n    vLOG(level, fmt, marker);\n    va_end(marker);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nvLOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, va_list marker)\n{\n    char sz_ip[64];\n    ipaddress_formatted_t fmt1 = ipaddress_fmt(ip_them);\n\n    snprintf(sz_ip, sizeof(sz_ip), \"%s\", fmt1.string);\n    fprintf(stderr, \"%u:%s: \", port_me, sz_ip);\n    vfprintf(stderr, fmt, marker);\n    fflush(stderr);\n}\nvoid\nLOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, ...)\n{\n    va_list marker;\n\n    va_start(marker, fmt);\n    vLOGnet(port_me, ip_them, fmt, marker);\n    va_end(marker);\n}\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\nvLOGip(int level, ipaddress ip, unsigned port, const char *fmt, va_list marker)\n{\n    if (level <= global_debug_level) {\n        char sz_ip[64];\n        ipaddress_formatted_t fmt1 = ipaddress_fmt(ip);\n\n        snprintf(sz_ip, sizeof(sz_ip), \"%s:%u: \", fmt1.string, port);\n        fprintf(stderr, \"%s \", sz_ip);\n        vfprintf(stderr, fmt, marker);\n        fflush(stderr);\n    }\n}\nvoid\nLOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...)\n{\n    va_list marker;\n\n    va_start(marker, fmt);\n    vLOGip(level, ip, port, fmt, marker);\n    va_end(marker);\n}\n\n"
  },
  {
    "path": "src/util-logger.h",
    "content": "#ifndef UTIL_LOGGER_H\n#define UTIL_LOGGER_H\n#include \"massip-addr.h\"\n\nvoid LOG(int level, const char *fmt, ...);\nvoid LOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...);\nvoid LOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, ...);\n\n\nvoid LOG_add_level(int level);\n\n#endif\n"
  },
  {
    "path": "src/util-malloc.c",
    "content": "#include \"util-malloc.h\"\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n\n#define MAXNUM ((size_t)1 << (sizeof(size_t)*4))\n\n/***************************************************************************\n ***************************************************************************/\nvoid *\nREALLOCARRAY(void *p, size_t count, size_t size)\n{\n    if (count >= MAXNUM || size >= MAXNUM) {\n        if (size != 0 && count >= SIZE_MAX/size) {\n            fprintf(stderr, \"[-] alloc too large, aborting\\n\");\n            abort();\n        }\n    }\n\n    p = realloc(p, count * size);\n    if (p == NULL && count * size != 0) {\n        fprintf(stderr, \"[-] out of memory, aborting\\n\");\n        abort();\n    }\n    \n    return p;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid *\nCALLOC(size_t count, size_t size)\n{\n    void *p;\n    \n    if (count >= MAXNUM || size >= MAXNUM) {\n        if (size != 0 && count >= SIZE_MAX/size) {\n            fprintf(stderr, \"[-] alloc too large, aborting\\n\");\n            abort();\n        }\n    }\n    \n    p = calloc(count, size);\n    if (p == NULL && count * size != 0) {\n        fprintf(stderr, \"[-] out of memory, aborting\\n\");\n        abort();\n    }\n    \n    return p;\n}\n\n/***************************************************************************\n * Wrap the standard 'malloc()' function.\n * - never returns a NULL pointer, aborts program instead\n * - if size is zero, still returns a valid pointer to one byte\n ***************************************************************************/\nvoid *\nMALLOC(size_t size)\n{\n    void *p;\n    \n    /* If 'size' is zero, then the behavior of 'malloc()' is undefined.\n     * I'm not sure which behavior would be best, to either always abort\n     * or always succeed. I'm choosing \"always succeed\" by bumping the\n     * length by one byte */\n    if (size == 0)\n        size = 1;\n    \n    /* Do the original allocation */\n    p = malloc(size);\n    \n    /* Abort the program if we've run out of memory */\n    if (p == NULL) {\n        fprintf(stderr, \"[-] out of memory, aborting\\n\");\n        abort();\n    }\n    \n    /* At this point, we've either succeeded or aborted the program,\n     * so this value is guaranteed to never be NULL */\n    return p;\n}\n\n/***************************************************************************\n ***************************************************************************/\nvoid *\nREALLOC(void *p, size_t size)\n{\n    p = realloc(p, size);\n    \n    if (p == NULL) {\n        fprintf(stderr, \"[-] out of memory, aborting\\n\");\n        abort();\n    }\n    \n    return p;\n}\n\n/***************************************************************************\n ***************************************************************************/\nchar *\nSTRDUP(const char *str)\n{\n#if defined(WIN32)\n    char *p = _strdup(str);\n#else\n    char *p = strdup(str);\n#endif\n    \n    if (p == NULL && str != NULL) {\n        fprintf(stderr, \"[-] out of memory, aborting\\n\");\n        abort();\n    }\n    \n    return p;\n}\n\n\n"
  },
  {
    "path": "src/util-malloc.h",
    "content": "/*\n    Wrappers around the malloc()/heap functions to `abort()` the program in\n    case of running out of memory.\n \n    Also, defines a REALLOCARRAY() function that checks for integer\n    overflow before trying to allocate memory.\n*/\n#ifndef UTIL_MALLOC_H\n#define UTIL_MALLOC_H\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid *\nREALLOCARRAY(void *p, size_t count, size_t size);\n\nvoid *\nCALLOC(size_t count, size_t size);\n\nvoid *\nMALLOC(size_t size);\n\nvoid *\nREALLOC(void *p, size_t size);\n\nchar *\nSTRDUP(const char *str);\n\n\n\n#endif\n"
  },
  {
    "path": "src/util-safefunc.c",
    "content": "/*\n    safe C library functions\n\n    This upgrades unsafe C functions like \"strcpy()\" to safer equivalents,\n    like \"safe_strcpy()\".\n\n    NOTE: This is for maintaining a policy of \"no unsafe functions\"\n*/\n#include \"util-safefunc.h\"\n#include <errno.h>\n#include <ctype.h>\n#include <errno.h>\n#include <string.h>\n\n/**\n * Case-insensitive memcmp()\n */\n#ifdef __GNUC__\nint\nmemcasecmp(const void *lhs, const void *rhs, size_t length)\n{\n    int i;\n    for (i=0; i<length; i++) {\n        if (tolower(((char*)lhs)[i]) != tolower(((char*)rhs)[i]))\n            return -1;\n    }\n    return 0;\n}\n#endif\n\n/**\n * Safe version of `strcpy()`\n */\nvoid\nsafe_strcpy(char *dst, size_t sizeof_dst, const char *src)\n{\n    size_t i;\n\n    if (sizeof_dst == 0)\n        return;\n\n    if (dst == NULL)\n        return;\n\n    if (src == NULL) {\n        dst[0] = 0;\n        return;\n    }\n\n    for (i=0; src[i]; i++) {\n        if (i >= sizeof_dst) {\n            dst[0] = 0;\n            return;\n        } else\n            dst[i] = src[i];\n    }\n    if (i >= sizeof_dst) {\n        dst[0] = 0;\n        return ;\n    } else\n        dst[i] = src[i];\n\n    return;\n}\n\n\n\nint\nsafe_localtime(struct tm* _tm, const time_t *time)\n{\n    struct tm *x;\n\n    x = localtime(time);\n    if (x == NULL) {\n        memset(_tm, 0, sizeof(*_tm));\n        return -1;\n    }\n    memcpy(_tm, x, sizeof(*_tm));\n\n    return 0;\n}\n\n\nint\nsafe_gmtime(struct tm* _tm, const time_t *time)\n{\n    struct tm *x;\n\n    x = gmtime(time);\n    if (x == NULL) {\n        memset(_tm, 0, sizeof(*_tm));\n        return -1;\n    }\n    memcpy(_tm, x, sizeof(*_tm));\n\n    return 0;\n}\n\n\n"
  },
  {
    "path": "src/util-safefunc.h",
    "content": "/*\n    safe \"string\" functions\n\n    This is for the \"safe\" clib functions, where things like \"strcpy()\" is\n    replaced with a safer version of the function, like \"safe_strcpy()\".\n \n    NOTE: I tried to based these on Microosft's `..._s()` functions proposed\n    in Annex K, but it's become too hard trying to deal with both my own\n    version and existing versions. Therefore, I've changed this code to\n    use names not used by others.\n\n Reference:\n http://msdn.microsoft.com/en-us/library/bb288454.aspx\n*/\n#ifndef UTIL_SAFEFUNC_H\n#define UTIL_SAFEFUNC_H\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <stdint.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4996)\n#endif\n\n#undef strcpy\n#define strcpy      STRCPY_FUNCTION_IS_BAD\n\n/*#undef strncpy\n#define strncpy     STRNCPY_FUNCTION_IS_BAD*/\n\n#undef strcat\n#define strcat      STRCAT_FUNCTION_IS_BAD\n\n#undef strncat\n#define strncat     STRNCAT_FUNCTION_IS_BAD\n\n#undef sprintf\n#define sprintf     SPRINTF_FUNCTION_IS_BAD\n\n#undef vsprintf\n#define vsprintf    VSPRINTF_FUNCTION_IS_BAD\n\n#undef strtok\n#define strtok      STRTOK_FUNCTION_IS_BAD\n\n#undef gets\n#define gets        GETS_FUNCTION_IS_BAD\n\n#undef scanf\n#define scanf       SCANF_FUNCTION_IS_BAD\n\n#undef sscanf\n#define sscanf      SSCANF_FUNCTION_IS_BAD\n\n#undef itoa\n#define itoa        ITOA_FUNCTION_IS_BAD\n\n/**\n * A bounds checking version of strcpy, like `strcpy_s()` on Windows or\n * `strlcpy()` in glibc.\n */\nvoid safe_strcpy(char *dst, size_t sizeof_dst, const char *src);\nint safe_localtime(struct tm* _tm, const time_t *time);\nint safe_gmtime(struct tm* _tm, const time_t *time);\n\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1900)\n/*Visual Studio 2015 and 2017*/\n# include <stdio.h>\n# include <string.h>\n# define strcasecmp     _stricmp\n# define memcasecmp     _memicmp\n# ifndef PRIu64\n#  define PRIu64 \"llu\"\n#  define PRId64 \"lld\"\n#  define PRIx64 \"llx\"\n# endif\n\n#elif defined(_MSC_VER) && (_MSC_VER == 1600)\n/*Visual Studio 2010*/\n# include <stdio.h>\n# include <string.h>\n#pragma warning(disable: 4996)\n#define snprintf _snprintf\n# define strcasecmp     _stricmp\n# define memcasecmp     _memicmp\n# ifndef PRIu64\n#  define PRIu64 \"llu\"\n#  define PRId64 \"lld\"\n#  define PRIx64 \"llx\"\n# endif\n\n\n#elif defined(_MSC_VER) && (_MSC_VER == 1200)\n/* Visual Studio 6.0 */\n# define snprintf      _snprintf\n# define strcasecmp     _stricmp\n# define memcasecmp     _memicmp\n# define vsnprintf     _vsnprintf\n\n#elif defined(__GNUC__) && (__GNUC__ >= 4)\n#include <inttypes.h>\n int memcasecmp(const void *lhs, const void *rhs, size_t length);;\n\n#else\n# warning unknown compiler\n#endif\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/vulncheck-heartbleed.c",
    "content": "#include \"proto-ssl.h\"\n\nstatic const char\nssl_hello_ticketbleed_templatex[] =\n\"\\x16\\x03\\x01\\x01\\x64\\x01\\x00\\x01\\x60\\x03\\x03\\x13\\xd4\\xf7\\xa8\\xac\"\n\"\\xdd\\xc2\\x20\\xc5\\xcc\\xdb\\xa4\\x8d\\xb3\\xf3\\xb5\\xd3\\x45\\x1b\\x53\\x8d\"\n\"\\x18\\x70\\xa2\\xd9\\x97\\xaa\\x63\\xdd\\xff\\xdc\\x68\\x10\\xff\\x6f\\xbf\\xbc\"\n\"\\x1b\\xea\\x36\\x01\\x56\\x76\\x24\\x94\\x2e\\x30\\x34\\x81\\x00\\x1a\\xc0\\x2f\"\n\"\\xc0\\x2b\\xc0\\x11\\xc0\\x07\\xc0\\x13\\xc0\\x09\\xc0\\x14\\xc0\\x0a\\x00\\x05\"\n\"\\x00\\x2f\\x00\\x35\\xc0\\x12\\x00\\x0a\\x01\\x00\\x01\\x0d\\x00\\x00\\x00\\x15\"\n\"\\x00\\x13\\x00\\x00\\x10\\x77\\x77\\x77\\x2e\\x61\\x6e\\x63\\x65\\x73\\x74\\x72\"\n\"\\x79\\x2e\\x63\\x6f\\x6d\\x00\\x05\\x00\\x05\\x01\\x00\\x00\\x00\\x00\\x00\\x0a\"\n\"\\x00\\x08\\x00\\x06\\x00\\x17\\x00\\x18\\x00\\x19\\x00\\x0b\\x00\\x02\\x01\\x00\"\n\"\\x00\\x23\\x00\\xc2\\x58\\x11\\x74\\xac\\xcd\\xf0\\x07\\xee\\x52\\x64\\xcb\\x41\"\n\"\\xed\\x72\\xf7\\x06\\xaa\\xc1\\x1c\\xf1\\xa5\\xf5\\x63\\x42\\x3c\\xea\\x55\\xb7\"\n\"\\xde\\xce\\x8f\\xec\\x00\\x00\\x7e\\x6e\\xed\\xf2\\x28\\x45\\x1f\\xcc\\xc8\\x08\"\n\"\\x08\\x2e\\x23\\x97\\xda\\x33\\x7b\\xaa\\x53\\x86\\x95\\x55\\x58\\xcf\\x27\\xce\"\n\"\\x6a\\x66\\x81\\xb8\\xf8\\x2f\\x13\\xa2\\xc9\\xcc\\x9a\\x93\\x1b\\x87\\x57\\x97\"\n\"\\xe0\\xec\\x64\\x96\\x75\\x01\\x82\\x79\\x17\\xe9\\xb5\\xa4\\x5e\\xba\\xbe\\xfe\"\n\"\\xac\\x86\\x3c\\xa4\\x7c\\xc3\\x66\\x16\\x7e\\x72\\x86\\xc5\\xa9\\x64\\x3f\\x0c\"\n\"\\xd2\\xae\\xa0\\xe6\\xa1\\xc0\\x14\\xdd\\x8c\\x41\\x2c\\xbd\\xa9\\x2a\\xaa\\x1c\"\n\"\\x47\\xa8\\x5f\\x3d\\x26\\xa8\\xd8\\x19\\xa6\\x2b\\x3e\\x1e\\x85\\x75\\x0e\\x73\"\n\"\\x8e\\xb1\\x34\\x15\\x91\\x2e\\xeb\\xb0\\x24\\x45\\xb3\\xc1\\xa3\\x27\\x3d\\xd6\"\n\"\\x21\\x3e\\xad\\xc8\\x25\\x4c\\x75\\x09\\x95\\x3c\\x33\\x3c\\xc4\\x35\\xb8\\xea\"\n\"\\x17\\x3a\\x3b\\x91\\x9d\\x60\\x36\\x70\\x57\\xe5\\x62\\x37\\x27\\xb2\\x1a\\xb5\"\n\"\\xca\\xf6\\x4c\\x8c\\xb0\\x07\\x00\\x0d\\x00\\x0a\\x00\\x08\\x04\\x01\\x04\\x03\"\n\"\\x02\\x01\\x02\\x03\\xff\\x01\\x00\\x01\\x00\";\n\nconst char *\nssl_hello_ticketbleed_template = ssl_hello_ticketbleed_templatex;\n\nstatic const char\nssl_hello_heartbeat_templatex[] =\n\"\\x16\"      /* type = handshake */\n\"\\x03\\x02\"  /* version = 3.2 (TLS/1.1) */\n\"\\x00\\xdc\"  /* length  = 220 */\n\"\\x01\"         /* type = client hello */\n\"\\x00\\x00\\xd8\" /* length = 216 */\n\"\\x03\\x02\"     /* version = 3.2 (TLS/1.1) */\n\"\\x53\\x43\\x5b\\x90\" /* gm time = April 7 */\n/*000F*/ \"\\x9d\"\n/*0010*/ \"\\x9b\\x72\\x0b\\xbc\\x0c\\xbc\\x2b\\x92\\xa8\\x48\\x97\\xcf\\xbd\\x39\\x04\\xcc\"\n/*0020*/ \"\\x16\\x0a\\x85\\x03\\x90\\x9f\\x77\\x04\\x33\\xd4\\xde\"\n\n\"\\x00\"         /* session id length = 0 */\n/* session id */\n\"\\x00\\x66\"     /* cipher suites length = 102 */\n/*002e*/ \"\\xc0\\x14\"\n/*0030*/ \"\\xc0\\x0a\\xc0\\x22\\xc0\\x21\\x00\\x39\\x00\\x38\\x00\\x88\\x00\\x87\\xc0\\x0f\"\n/*0040*/ \"\\xc0\\x05\\x00\\x35\\x00\\x84\\xc0\\x12\\xc0\\x08\\xc0\\x1c\\xc0\\x1b\\x00\\x16\"\n/*0050*/ \"\\x00\\x13\\xc0\\x0d\\xc0\\x03\\x00\\x0a\\xc0\\x13\\xc0\\x09\\xc0\\x1f\\xc0\\x1e\"\n/*0060*/ \"\\x00\\x33\\x00\\x32\\x00\\x9a\\x00\\x99\\x00\\x45\\x00\\x44\\xc0\\x0e\\xc0\\x04\"\n/*0070*/ \"\\x00\\x2f\\x00\\x96\\x00\\x41\\xc0\\x11\\xc0\\x07\\xc0\\x0c\\xc0\\x02\\x00\\x05\"\n/*0080*/ \"\\x00\\x04\\x00\\x15\\x00\\x12\\x00\\x09\\x00\\x14\\x00\\x11\\x00\\x08\\x00\\x06\"\n/*0090*/ \"\\x00\\x03\\x00\\xff\"\n\"\\x01\"         /* compression methods = 1 */\n\"\\x00\"         /* nul compression */\n\"\\x00\\x49\"     /* extensions length */\n\"\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\"\n/*00a0*/ \n\"\\x00\\x0a\\x00\\x34\\x00\\x32\\x00\\x0e\\x00\\x0d\\x00\\x19\\x00\\x0b\\x00\\x0c\"\n/*00b0*/ \"\\x00\\x18\\x00\\x09\\x00\\x0a\\x00\\x16\\x00\\x17\\x00\\x08\\x00\\x06\\x00\\x07\"\n/*00c0*/ \"\\x00\\x14\\x00\\x15\\x00\\x04\\x00\\x05\\x00\\x12\\x00\\x13\\x00\\x01\\x00\\x02\"\n/*00d0*/ \"\\x00\\x03\\x00\\x0f\\x00\\x10\\x00\\x11\"\n\"\\x00\\x23\\x00\\x00\"\n\"\\x00\\x0f\\x00\\x01\\x01\";\n\nconst char *\nssl_hello_heartbeat_template = ssl_hello_heartbeat_templatex;\n\n"
  },
  {
    "path": "src/vulncheck-ntp-monlist.c",
    "content": "#include \"vulncheck.h\"\n#include \"templ-pkt.h\"\n#include \"unusedparm.h\"\n\n\n/*****************************************************************************\n *****************************************************************************/\nstatic void \nset_target(struct TemplatePacket *tmpl,\n                   unsigned ip_them, unsigned port_them,\n                   unsigned ip_me, unsigned port_me,\n                   unsigned seqno,\n                   unsigned char *px, size_t sizeof_px, \n                   size_t *r_length)\n{\n    unsigned offset_tcp = tmpl->ipv4.offset_tcp;\n    unsigned offset_ip = tmpl->ipv4.offset_ip;\n    unsigned offset_app = tmpl->ipv4.offset_app;\n    unsigned tmpl_length= tmpl->ipv4.length;\n    unsigned xsum;\n\n    UNUSEDPARM(r_length);\n    UNUSEDPARM(sizeof_px);\n    UNUSEDPARM(seqno);\n    UNUSEDPARM(ip_me);\n    UNUSEDPARM(ip_them);\n    \n    px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);\n    px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);\n    px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);\n    px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);\n    px[offset_tcp+ 4] = (unsigned char)((tmpl_length - offset_app + 8)>>8);\n    px[offset_tcp+ 5] = (unsigned char)((tmpl_length - offset_app + 8)&0xFF);\n    \n    px[offset_tcp+6] = (unsigned char)(0);\n    px[offset_tcp+7] = (unsigned char)(0);\n    xsum = udp_checksum2(px, offset_ip, offset_tcp, tmpl_length - offset_tcp);\n    xsum = ~xsum;\n    px[offset_tcp+6] = (unsigned char)(xsum >>  8);\n    px[offset_tcp+7] = (unsigned char)(xsum >>  0);\n}\n\n/*****************************************************************************\n *****************************************************************************/\nstatic unsigned char packet_template[] =\n\"\\0\\1\\2\\3\\4\\5\"  /* Ethernet: destination */\n\"\\6\\7\\x8\\x9\\xa\\xb\"  /* Ethernet: source */\n\"\\x08\\x00\"      /* Ethernet type: IPv4 */\n\"\\x45\"          /* IP type */\n\"\\x00\"\n\"\\x00\\x4c\"      /* total length = 28 bytes */\n\"\\x00\\x00\"      /* identification */\n\"\\x00\\x00\"      /* fragmentation flags */\n\"\\xFF\\x11\"      /* TTL=255, proto=UDP */\n\"\\xFF\\xFF\"      /* checksum */\n\"\\0\\0\\0\\0\"      /* source address */\n\"\\0\\0\\0\\0\"      /* destination address */\n\n\"\\xfe\\xdc\"      /* source port */\n\"\\x00\\x00\"      /* destination port */\n\"\\x00\\x38\"      /* length */\n\"\\x00\\x00\"      /* checksum */\n\n\"\\x17\\x00\\x03\\x2a\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n\n;\n\n/*****************************************************************************\n *****************************************************************************/\nstruct MassVulnCheck vuln_ntp_monlist = {\n    \"ntp-monlist\",  /* name of this vuln, matches command-line name */\n    \"U:123\",        /* default ports this vuln check should target */\n    packet_template,\n    sizeof(packet_template)-1,\n    set_target\n    \n};\n"
  },
  {
    "path": "src/vulncheck-sslv3.c",
    "content": "#include \"proto-ssl.h\"\n\n#define TLS_FALLBACK_SCSV       0x5600\n#define inappropriate_fallback  86\n\nstatic const char sslv3_hello[] =\n    \"\\x16\\x03\\x00\\x00\\x43\"\n    \"\\x01\\x00\\x00\\x3f\\x03\\x00\"\n    \"\\x00\\x07\\x06\\x30\" /* gmtime */\n    \"\\x16\"\n    \"\\x79\\xa4\\xc3\\xf0\\xa9\\xbe\\x26\\xf5\\x1c\\x36\\xad\\xff\\x65\\x0b\\x9e\\x2a\"\n    \"\\x8e\\xef\\x58\\x1c\\x16\\x44\\x12\\x35\\x93\\x36\\xb9\"\n    \"\\x00\" /* session id length = 0 */\n    \"\\x00\\x18\" /* cipher suites length = 24 */\n    \"\\x00\\x39\"\n    \"\\x00\\x38\\x00\\x35\\x00\\x33\\x00\\x32\\x00\\x04\\x00\\x05\\x00\\x2f\\x00\\x16\"\n    \"\\x00\\x13\\xfe\\xff\\x00\\x0a\\x01\\x00\";\n\nconst char *\nssl_hello_sslv3_template = sslv3_hello;\n\n"
  },
  {
    "path": "src/vulncheck.c",
    "content": "#include \"vulncheck.h\"\n#include \"util-safefunc.h\"\n\nextern struct MassVulnCheck vuln_ntp_monlist;\n\n\nstruct MassVulnCheck *\nvulncheck_lookup(const char *name)\n{\n    if (strcmp(name, vuln_ntp_monlist.name) == 0)\n        return &vuln_ntp_monlist;\n    return 0;\n}\n\n"
  },
  {
    "path": "src/vulncheck.h",
    "content": "#ifndef VULNCHECK_H\n#define VULNCHECK_H\n#include <stdio.h>\nstruct TemplatePacket;\n\nstruct MassVulnCheck\n{\n    const char *name;\n    \n    /**\n     * A list of default port ranges that should be used in case that none\n     * are specified.\n     */\n    const char *ports;\n    \n    /**\n     * The hello packet template\n     */\n    const unsigned char *packet;\n    \n    /**\n     * The hello packet template length\n     */\n    unsigned packet_length;\n    \n    \n    /**\n     * Called to change the template based upon the target\n     */\n    void (*set_target)(struct TemplatePacket *tmpl,\n                         unsigned ip_them, unsigned port_them,\n                         unsigned ip_me, unsigned port_me,\n                         unsigned seqno,\n                         unsigned char *px, size_t sizeof_px, \n                         size_t *r_length);\n    \n    /**\n     * Called at startup to change the template according to options\n     */\n    void (*init)(struct TemplatePacket *tmpl);\n};\n\n/**\n * Lookup the vuln based on the name\n * @param name\n *      The name of the vuln to check.\n * @return\n *      The desired vuln check if found, NULL if the vuln check doesn't exist\n */\nstruct MassVulnCheck *\nvulncheck_lookup(const char *name);\n\n#endif\n"
  },
  {
    "path": "src/xring.c",
    "content": "#include \"xring.h\"\n#include \"pixie-threads.h\"\n#include \"pixie-timer.h\"\n#include \"util-safefunc.h\"\n#include <stdio.h>\n\n\ntypedef uint64_t Element;\n\n#define XRING_SIZE 16\n\nstruct XRing\n{\n    volatile unsigned long long head;\n    volatile unsigned long long tail;\n    volatile Element ring[XRING_SIZE];\n};\n\n\n\n/***************************************************************************\n ***************************************************************************/\nstatic Element\nxring_remove(struct XRing *xring)\n{\n    volatile Element *ring = xring->ring;\n    Element num;\n\n    if (xring->tail >= xring->head)\n        return 0;\n\n\n    num = ring[xring->tail & (XRING_SIZE-1)];\n    if (num) {\n        ring[xring->tail & (XRING_SIZE-1)] = 0;\n        xring->tail++;\n        return num;\n        /*\n        int x = pixie_locked_CAS64(&ring[xring->tail & (XRING_SIZE-1)], 0, num);\n        if (x) {\n            xring->tail++;\n            return num;\n        } else {\n            goto again;\n        }*/\n    } else {\n        return 0;\n    }\n}\n\nenum {XringSuccess, XringFailure};\n/***************************************************************************\n ***************************************************************************/\nstatic int\nxring_add(struct XRing *xring, Element value)\n{\n    volatile Element *ring = xring->ring;\n    Element num;\n\n    if (value == 0) {\n        return XringFailure;\n    }\n\n    if (xring->head >= xring->tail + XRING_SIZE) {\n        //printf(\"-\");\n        return XringFailure;\n    }\n    num = xring->ring[xring->head & (XRING_SIZE-1)];\n    if (num == 0) {\n        ring[xring->head & (XRING_SIZE-1)] = value;\n        xring->head++;\n        return XringSuccess;\n        /*int x = pixie_locked_CAS64(&ring[xring->head & (XRING_SIZE-1)], value, 0);\n        if (x) {\n            xring->head++;\n            return XringSuccess;\n        } else {\n            return XringFailure;\n        }*/\n    }\n    return XringFailure;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstruct Test\n{\n    struct XRing xring[1];\n    unsigned producer_started;\n    unsigned producer_done;\n    unsigned consumer_done;\n    unsigned long long total_count;\n    volatile int not_active;\n};\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntest_consumer_thread(void *v)\n{\n    struct Test *test = (struct Test *)v;\n    struct XRing *xring = test->xring;\n\n\n    while (!test->not_active) {\n        Element e;\n\n        e = xring_remove(xring);\n        if (e == 0)\n            ;\n        else {\n            test->total_count += e;\n        }\n    }\n\n    while (xring->tail < xring->head) {\n        Element e;\n\n        e = xring_remove(xring);\n        if (e == 0)\n            ;\n        else {\n            test->total_count += e;\n        }\n    }\n\n    test->consumer_done = 1;\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic void\ntest_producer_thread(void *v)\n{\n    struct Test *test = (struct Test *)v;\n    unsigned i = 1000;\n    struct XRing *xring = test->xring;\n\n    pixie_locked_add_u32(&test->producer_started, 1);\n    while (i) {\n        while (xring_add(xring, i) == XringFailure)\n            ;\n        i--;\n    }\n    pixie_locked_add_u32(&test->producer_done, 1);\n}\n\n/***************************************************************************\n ***************************************************************************/\nstatic uint64_t\nrun_test(struct Test *test)\n{\n    unsigned i;\n    const unsigned THREADS = 1;\n\n    memset(test, 0, sizeof(*test));\n\n    /* Generate producer threads */\n    for (i=0; i<THREADS; i++) {\n        pixie_begin_thread(test_producer_thread, 0, test);\n    }\n\n    /* Wait for threads to start */\n    while (test->producer_started < THREADS)\n        pixie_usleep(10);\n    /* Now start consuming */\n    pixie_begin_thread(test_consumer_thread, 0, test);\n\n    /* Wait for producer threads to end */\n    while (test->producer_done < THREADS)\n        pixie_usleep(10);\n\n\n    /* Tell consumer thread to end */\n    test->not_active = 1;\n\n\n    /* Wait for consumer thread to end */\n    while (!test->consumer_done)\n        pixie_usleep(10);\n\n    return test->total_count;\n}\n\n\n/***************************************************************************\n ***************************************************************************/\nint\nxring_selftest(void)\n{\n    unsigned i;\n\n    for (i=0; i<1000; i++) {\n        uint64_t result;\n        struct Test test[1];\n\n        result = run_test(test);\n        if (result != 500500) {\n            printf(\"xring: selftest failed with %\" PRIu64 \"\\n\", result);\n            return 1;\n        } else\n            ;\n    }\n\n    return 0;\n}\n\n\n\n\n"
  },
  {
    "path": "src/xring.h",
    "content": "#ifndef XRING_H\n#define XRING_H\n\n\nint xring_selftest(void);\n\n#endif\n"
  },
  {
    "path": "tmp/.gitignore",
    "content": "*\n!.gitignore\n\n\n"
  },
  {
    "path": "vs10/.gitignore",
    "content": "masscan.opensdf\nmasscan.suo\ntmp/Debug\ntmp/Release\nmasscan.sdf\nmasscan.vcxproj.user\ntmp\nipch\n\n"
  },
  {
    "path": "vs10/masscan.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 11.00\r\n# Visual Studio 2010\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"masscan\", \"masscan.vcxproj\", \"{C88D7583-254F-4BE6-A9B9-89A5BB52E679}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Win32 = Debug|Win32\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tRelease|Win32 = Release|Win32\r\n\t\tRelease|x64 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|Win32.ActiveCfg = Debug|Win32\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|Win32.Build.0 = Debug|Win32\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|Win32.ActiveCfg = Release|Win32\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|Win32.Build.0 = Release|Win32\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|x64.Build.0 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "vs10/masscan.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\src\\crypto-base64.c\" />\r\n    <ClCompile Include=\"..\\src\\crypto-blackrock.c\" />\r\n    <ClCompile Include=\"..\\src\\crypto-blackrock2.c\" />\r\n    <ClCompile Include=\"..\\src\\crypto-lcg.c\" />\r\n    <ClCompile Include=\"..\\src\\crypto-primegen.c\" />\r\n    <ClCompile Include=\"..\\src\\crypto-siphash24.c\" />\r\n    <ClCompile Include=\"..\\src\\event-timeout.c\" />\r\n    <ClCompile Include=\"..\\src\\in-filter.c\" />\r\n    <ClCompile Include=\"..\\src\\in-report.c\" />\r\n    <ClCompile Include=\"..\\src\\main-listscan.c\" />\r\n    <ClCompile Include=\"..\\src\\main-ptrace.c\" />\r\n    <ClCompile Include=\"..\\src\\main-readrange.c\" />\r\n    <ClCompile Include=\"..\\src\\in-binary.c\" />\r\n    <ClCompile Include=\"..\\src\\masscan-app.c\" />\r\n    <ClCompile Include=\"..\\src\\massip-addr.c\" />\r\n    <ClCompile Include=\"..\\src\\massip-parse.c\" />\r\n    <ClCompile Include=\"..\\src\\massip-rangesv4.c\" />\r\n    <ClCompile Include=\"..\\src\\massip-rangesv6.c\" />\r\n    <ClCompile Include=\"..\\src\\massip.c\" />\r\n    <ClCompile Include=\"..\\src\\misc-rstfilter.c\" />\r\n    <ClCompile Include=\"..\\src\\out-binary.c\" />\r\n    <ClCompile Include=\"..\\src\\out-certs.c\" />\r\n    <ClCompile Include=\"..\\src\\out-grepable.c\" />\r\n    <ClCompile Include=\"..\\src\\out-hostonly.c\" />\r\n    <ClCompile Include=\"..\\src\\out-json.c\" />\r\n    <ClCompile Include=\"..\\src\\out-ndjson.c\" />\r\n    <ClCompile Include=\"..\\src\\out-null.c\" />\r\n    <ClCompile Include=\"..\\src\\out-redis.c\" />\r\n    <ClCompile Include=\"..\\src\\out-tcp-services.c\" />\r\n    <ClCompile Include=\"..\\src\\out-text.c\" />\r\n    <ClCompile Include=\"..\\src\\out-unicornscan.c\" />\r\n    <ClCompile Include=\"..\\src\\out-xml.c\" />\r\n    <ClCompile Include=\"..\\src\\pixie-backtrace.c\" />\r\n    <ClCompile Include=\"..\\src\\pixie-file.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-arp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-banner1.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-banout.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-coap.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-dns.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ftp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-http.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-icmp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-imap4.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-isakmp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-mc.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-memcached.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-netbios.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ntlmssp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ntp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-oproto.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-pop3.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-sctp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-smb.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-smtp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-snmp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ssh.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ssl-test.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-ssl.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-tcp-rdp.c\" />\r\n    <ClCompile Include=\"..\\src\\main-conf.c\" />\r\n    <ClCompile Include=\"..\\src\\main-dedup.c\" />\r\n    <ClCompile Include=\"..\\src\\main-initadapter.c\" />\r\n    <ClCompile Include=\"..\\src\\main-status.c\" />\r\n    <ClCompile Include=\"..\\src\\main-throttle.c\" />\r\n    <ClCompile Include=\"..\\src\\main.c\" />\r\n    <ClCompile Include=\"..\\src\\output.c\" />\r\n    <ClCompile Include=\"..\\src\\pixie-threads.c\" />\r\n    <ClCompile Include=\"..\\src\\pixie-timer.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-preprocess.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-tcp-telnet.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-udp.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-versioning.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-vnc.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-x509.c\" />\r\n    <ClCompile Include=\"..\\src\\proto-zeroaccess.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-getif.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-getip.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-getip6.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-getmac.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-getroute.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock-pcapfile.c\" />\r\n    <ClCompile Include=\"..\\src\\rawsock.c\" />\r\n    <ClCompile Include=\"..\\src\\read-service-probes.c\" />\r\n    <ClCompile Include=\"..\\src\\rte-ring.c\" />\r\n    <ClCompile Include=\"..\\src\\scripting-banner.c\" />\r\n    <ClCompile Include=\"..\\src\\scripting-masscan.c\" />\r\n    <ClCompile Include=\"..\\src\\scripting.c\" />\r\n    <ClCompile Include=\"..\\src\\smack1.c\" />\r\n    <ClCompile Include=\"..\\src\\smackqueue.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-arpv4.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-if.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-ndpv6.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-queue.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-src.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-tcp-app.c\" />\r\n    <ClCompile Include=\"..\\src\\stack-tcp-core.c\" />\r\n    <ClCompile Include=\"..\\src\\stub-lua.c\" />\r\n    <ClCompile Include=\"..\\src\\stub-pcap.c\" />\r\n    <ClCompile Include=\"..\\src\\stub-pfring.c\" />\r\n    <ClCompile Include=\"..\\src\\syn-cookie.c\" />\r\n    <ClCompile Include=\"..\\src\\templ-nmap-payloads.c\" />\r\n    <ClCompile Include=\"..\\src\\templ-payloads.c\" />\r\n    <ClCompile Include=\"..\\src\\templ-pkt.c\" />\r\n    <ClCompile Include=\"..\\src\\templ-tcp-hdr.c\" />\r\n    <ClCompile Include=\"..\\src\\util-checksum.c\" />\r\n    <ClCompile Include=\"..\\src\\util-errormsg.c\" />\r\n    <ClCompile Include=\"..\\src\\util-logger.c\" />\r\n    <ClCompile Include=\"..\\src\\util-malloc.c\" />\r\n    <ClCompile Include=\"..\\src\\util-safefunc.c\" />\r\n    <ClCompile Include=\"..\\src\\vulncheck-heartbleed.c\" />\r\n    <ClCompile Include=\"..\\src\\vulncheck-ntp-monlist.c\" />\r\n    <ClCompile Include=\"..\\src\\vulncheck-sslv3.c\" />\r\n    <ClCompile Include=\"..\\src\\vulncheck.c\" />\r\n    <ClCompile Include=\"..\\src\\xring.c\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"..\\src\\crypto-base64.h\" />\r\n    <ClInclude Include=\"..\\src\\crypto-blackrock.h\" />\r\n    <ClInclude Include=\"..\\src\\crypto-lcg.h\" />\r\n    <ClInclude Include=\"..\\src\\crypto-primegen.h\" />\r\n    <ClInclude Include=\"..\\src\\crypto-siphash24.h\" />\r\n    <ClInclude Include=\"..\\src\\in-filter.h\" />\r\n    <ClInclude Include=\"..\\src\\in-report.h\" />\r\n    <ClInclude Include=\"..\\src\\main-globals.h\" />\r\n    <ClInclude Include=\"..\\src\\event-timeout.h\" />\r\n    <ClInclude Include=\"..\\src\\in-binary.h\" />\r\n    <ClInclude Include=\"..\\src\\main-dedup.h\" />\r\n    <ClInclude Include=\"..\\src\\main-ptrace.h\" />\r\n    <ClInclude Include=\"..\\src\\main-readrange.h\" />\r\n    <ClInclude Include=\"..\\src\\main-status.h\" />\r\n    <ClInclude Include=\"..\\src\\main-throttle.h\" />\r\n    <ClInclude Include=\"..\\src\\masscan-app.h\" />\r\n    <ClInclude Include=\"..\\src\\masscan-version.h\" />\r\n    <ClInclude Include=\"..\\src\\masscan.h\" />\r\n    <ClInclude Include=\"..\\src\\massip-addr.h\" />\r\n    <ClInclude Include=\"..\\src\\massip-parse.h\" />\r\n    <ClInclude Include=\"..\\src\\massip-rangesv4.h\" />\r\n    <ClInclude Include=\"..\\src\\massip-rangesv6.h\" />\r\n    <ClInclude Include=\"..\\src\\massip.h\" />\r\n    <ClInclude Include=\"..\\src\\misc-rstfilter.h\" />\r\n    <ClInclude Include=\"..\\src\\out-record.h\" />\r\n    <ClInclude Include=\"..\\src\\out-tcp-services.h\" />\r\n    <ClInclude Include=\"..\\src\\output.h\" />\r\n    <ClInclude Include=\"..\\src\\packet-queue.h\" />\r\n    <ClInclude Include=\"..\\src\\pixie-backtrace.h\" />\r\n    <ClInclude Include=\"..\\src\\pixie-file.h\" />\r\n    <ClInclude Include=\"..\\src\\pixie-sockets.h\" />\r\n    <ClInclude Include=\"..\\src\\pixie-threads.h\" />\r\n    <ClInclude Include=\"..\\src\\pixie-timer.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-arp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-banner1.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-banout.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-coap.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-dns-parse.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-dns.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-ftp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-http.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-icmp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-imap4.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-isakmp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-mc.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-memcached.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-netbios.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-ntlmssp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-ntp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-oproto.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-pop3.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-preprocess.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-sctp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-smb.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-smtp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-snmp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-ssh.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-ssl.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-tcp-rdp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-tcp-telnet.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-udp.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-versioning.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-vnc.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-x509.h\" />\r\n    <ClInclude Include=\"..\\src\\proto-zeroaccess.h\" />\r\n    <ClInclude Include=\"..\\src\\rawsock-adapter.h\" />\r\n    <ClInclude Include=\"..\\src\\rawsock-pcapfile.h\" />\r\n    <ClInclude Include=\"..\\src\\rawsock.h\" />\r\n    <ClInclude Include=\"..\\src\\read-service-probes.h\" />\r\n    <ClInclude Include=\"..\\src\\rte-ring.h\" />\r\n    <ClInclude Include=\"..\\src\\scripting.h\" />\r\n    <ClInclude Include=\"..\\src\\smack.h\" />\r\n    <ClInclude Include=\"..\\src\\smackqueue.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-arpv4.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-ndpv6.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-queue.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-src.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-tcp-api.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-tcp-app.h\" />\r\n    <ClInclude Include=\"..\\src\\stack-tcp-core.h\" />\r\n    <ClInclude Include=\"..\\src\\stub-lua.h\" />\r\n    <ClInclude Include=\"..\\src\\stub-pcap.h\" />\r\n    <ClInclude Include=\"..\\src\\stub-pfring.h\" />\r\n    <ClInclude Include=\"..\\src\\syn-cookie.h\" />\r\n    <ClInclude Include=\"..\\src\\templ-nmap-payloads.h\" />\r\n    <ClInclude Include=\"..\\src\\templ-opts.h\" />\r\n    <ClInclude Include=\"..\\src\\templ-payloads.h\" />\r\n    <ClInclude Include=\"..\\src\\templ-pkt.h\" />\r\n    <ClInclude Include=\"..\\src\\templ-tcp-hdr.h\" />\r\n    <ClInclude Include=\"..\\src\\util-bool.h\" />\r\n    <ClInclude Include=\"..\\src\\util-checksum.h\" />\r\n    <ClInclude Include=\"..\\src\\util-errormsg.h\" />\r\n    <ClInclude Include=\"..\\src\\util-logger.h\" />\r\n    <ClInclude Include=\"..\\src\\util-malloc.h\" />\r\n    <ClInclude Include=\"..\\src\\util-safefunc.h\" />\r\n    <ClInclude Include=\"..\\src\\vulncheck.h\" />\r\n    <ClInclude Include=\"..\\src\\xring.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"..\\doc\\masscan.8.markdown\" />\r\n    <None Include=\"..\\LICENSE\" />\r\n    <None Include=\"..\\Makefile\" />\r\n    <None Include=\"..\\README.md\" />\r\n    <None Include=\"..\\VULNINFO.md\" />\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{C88D7583-254F-4BE6-A9B9-89A5BB52E679}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>masscan</RootNamespace>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <IntDir>$(SolutionDir)\\..\\tmp\\$(Configuration)\\</IntDir>\r\n    <OutDir>$(SolutionDir)\\..\\bin\\</OutDir>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <IntDir>$(SolutionDir)\\..\\tmp\\</IntDir>\r\n    <OutDir>$(SolutionDir)\\..\\bin\\</OutDir>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)\\..\\bin\\</OutDir>\r\n    <IntDir>$(SolutionDir)\\..\\tmp\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)\\..\\bin\\</OutDir>\r\n    <IntDir>$(SolutionDir)\\..\\tmp\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <EnablePREfast>false</EnablePREfast>\r\n      <WholeProgramOptimization>false</WholeProgramOptimization>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <AdditionalLibraryDirectories>lib;</AdditionalLibraryDirectories>\r\n      <Profile>true</Profile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <EnablePREfast>false</EnablePREfast>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <AdditionalLibraryDirectories>lib\\x64;</AdditionalLibraryDirectories>\r\n      <AdditionalDependencies>setargv.obj;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <Profile>true</Profile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>include</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <AdditionalLibraryDirectories>lib</AdditionalLibraryDirectories>\r\n    </Link>\r\n    <BuildLog>\r\n      <Path>$(IntDir)\\$(MSBuildProjectName).log</Path>\r\n    </BuildLog>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>include</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <AdditionalLibraryDirectories>lib\\x64</AdditionalLibraryDirectories>\r\n    </Link>\r\n    <BuildLog>\r\n      <Path>$(IntDir)\\$(MSBuildProjectName).log</Path>\r\n    </BuildLog>\r\n  </ItemDefinitionGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "vs10/masscan.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\proto\">\r\n      <UniqueIdentifier>{fc470d2b-e741-496b-be6e-abf15f4e3573}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\output\">\r\n      <UniqueIdentifier>{3fbe0a31-7af3-4f28-a707-85577ab7be71}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\rawsock\">\r\n      <UniqueIdentifier>{8ca96e86-20f2-45b3-b1c4-ee9d90f5c6d8}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\misc\">\r\n      <UniqueIdentifier>{d429351b-2aea-4e6c-a887-c7fb9d6c38b5}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\pixie\">\r\n      <UniqueIdentifier>{cbd42363-ae71-4e2d-9633-0cb518d5e447}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\crypto\">\r\n      <UniqueIdentifier>{59f7bc00-cf14-4114-8801-1c5e72255c29}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\stubs\">\r\n      <UniqueIdentifier>{a481491e-ed05-4aeb-a49a-d8f071dc1409}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\scripting\">\r\n      <UniqueIdentifier>{ba03c2ec-de65-4581-bef1-8e24f95a8580}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\versioning\">\r\n      <UniqueIdentifier>{09e28aca-e0bd-47a9-b983-5c9f38392d20}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\vulncheck\">\r\n      <UniqueIdentifier>{8ad0f675-466a-4fb9-bac6-6fa0c868aefb}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\massip\">\r\n      <UniqueIdentifier>{1621e340-1943-47fa-b12e-336a46d19b15}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\util\">\r\n      <UniqueIdentifier>{1d9cb2b4-1715-44d0-98e9-745f236c7872}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\stack\">\r\n      <UniqueIdentifier>{26588af1-2234-4000-96fc-72f774f584f8}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\src\\proto-banner1.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-dns.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-http.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-icmp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-preprocess.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-snmp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ssh.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-udp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-netbios.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\templ-payloads.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\templ-pkt.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-binary.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-null.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-text.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-xml.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\output.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-arp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-getif.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-getip.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-getmac.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-getroute.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-pcapfile.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\event-timeout.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-dedup.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-initadapter.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-listscan.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-ptrace.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-throttle.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rte-ring.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\xring.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main.c\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ssl.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\smack1.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\smackqueue.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\syn-cookie.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\in-binary.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-redis.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\masscan-app.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-conf.c\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-zeroaccess.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ssl-test.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-banout.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-x509.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-base64.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\pixie-backtrace.c\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\pixie-file.c\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\pixie-threads.c\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\pixie-timer.c\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-tcp-telnet.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-sctp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-grepable.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ntp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-status.c\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\main-readrange.c\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-blackrock2.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-json.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-certs.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-unicornscan.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ftp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-imap4.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-pop3.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-smtp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-vnc.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\in-filter.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\in-report.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-ndjson.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-memcached.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-smb.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-ntlmssp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-tcp-services.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\scripting.c\">\r\n      <Filter>Source Files\\scripting</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\scripting-banner.c\">\r\n      <Filter>Source Files\\scripting</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\scripting-masscan.c\">\r\n      <Filter>Source Files\\scripting</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stub-lua.c\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stub-pcap.c\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stub-pfring.c\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\vulncheck.c\">\r\n      <Filter>Source Files\\vulncheck</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\vulncheck-heartbleed.c\">\r\n      <Filter>Source Files\\vulncheck</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\vulncheck-ntp-monlist.c\">\r\n      <Filter>Source Files\\vulncheck</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\vulncheck-sslv3.c\">\r\n      <Filter>Source Files\\vulncheck</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\read-service-probes.c\">\r\n      <Filter>Source Files\\versioning</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-coap.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-tcp-rdp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-oproto.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\misc-rstfilter.c\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\rawsock-getip6.c\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\util-checksum.c\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\util-malloc.c\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-src.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-ndpv6.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-queue.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\massip.c\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\massip-parse.c\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\massip-rangesv4.c\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\massip-rangesv6.c\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\massip-addr.c\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\out-hostonly.c\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-arpv4.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-if.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-blackrock.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-lcg.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-primegen.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\crypto-siphash24.c\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-mc.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\templ-nmap-payloads.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\templ-tcp-hdr.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-isakmp.c\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-tcp-core.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\proto-versioning.c\">\r\n      <Filter>Source Files\\versioning</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\stack-tcp-app.c\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\util-logger.c\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\util-errormsg.c\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\src\\util-safefunc.c\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"..\\src\\proto-arp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-udp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-banner1.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-dns.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-http.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-icmp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-preprocess.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-snmp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-ssh.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-netbios.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-dns-parse.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\templ-pkt.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\templ-payloads.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\output.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\out-record.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\rawsock.h\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\rawsock-pcapfile.h\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\xring.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\event-timeout.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-dedup.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-ptrace.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-throttle.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\packet-queue.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\rte-ring.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-ssl.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\masscan.h\">\r\n      <Filter>Source Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\smack.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\smackqueue.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\syn-cookie.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\in-binary.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-globals.h\">\r\n      <Filter>Source Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\masscan-app.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-zeroaccess.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-banout.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-x509.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\crypto-base64.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\pixie-timer.h\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\pixie-backtrace.h\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\pixie-file.h\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\pixie-sockets.h\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\pixie-threads.h\">\r\n      <Filter>Source Files\\pixie</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-tcp-telnet.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-sctp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\masscan-version.h\">\r\n      <Filter>Source Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-ntp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-status.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\main-readrange.h\">\r\n      <Filter>Source Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-ftp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-imap4.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-pop3.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-smtp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-vnc.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\in-filter.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\in-report.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-memcached.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-smb.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-ntlmssp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\out-tcp-services.h\">\r\n      <Filter>Source Files\\output</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\scripting.h\">\r\n      <Filter>Source Files\\scripting</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stub-lua.h\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stub-pcap.h\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stub-pfring.h\">\r\n      <Filter>Source Files\\stubs</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\vulncheck.h\">\r\n      <Filter>Source Files\\vulncheck</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\read-service-probes.h\">\r\n      <Filter>Source Files\\versioning</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-coap.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-bool.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-tcp-rdp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-oproto.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\misc-rstfilter.h\">\r\n      <Filter>Source Files\\misc</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-checksum.h\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-malloc.h\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-src.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-ndpv6.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-queue.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\massip.h\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\massip-parse.h\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\massip-rangesv4.h\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\massip-rangesv6.h\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\massip-addr.h\">\r\n      <Filter>Source Files\\massip</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-arpv4.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\rawsock-adapter.h\">\r\n      <Filter>Source Files\\rawsock</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\crypto-blackrock.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\crypto-lcg.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\crypto-primegen.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\crypto-siphash24.h\">\r\n      <Filter>Source Files\\crypto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-mc.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\templ-nmap-payloads.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\templ-opts.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\templ-tcp-hdr.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-isakmp.h\">\r\n      <Filter>Source Files\\proto</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-tcp-core.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\proto-versioning.h\">\r\n      <Filter>Source Files\\versioning</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-tcp-api.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\stack-tcp-app.h\">\r\n      <Filter>Source Files\\stack</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-logger.h\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-errormsg.h\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\src\\util-safefunc.h\">\r\n      <Filter>Source Files\\util</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"..\\README.md\" />\r\n    <None Include=\"..\\LICENSE\">\r\n      <Filter>Resource Files</Filter>\r\n    </None>\r\n    <None Include=\"..\\Makefile\">\r\n      <Filter>Resource Files</Filter>\r\n    </None>\r\n    <None Include=\"..\\doc\\masscan.8.markdown\">\r\n      <Filter>Resource Files</Filter>\r\n    </None>\r\n    <None Include=\"..\\VULNINFO.md\">\r\n      <Filter>Resource Files</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "xcode4/.gitignore",
    "content": ".DS_Store\r\nbuild\r\n"
  },
  {
    "path": "xcode4/masscan.xcodeproj/.gitignore",
    "content": "project.xcworkspace\r\nxcuserdata\r\n\r\n"
  },
  {
    "path": "xcode4/masscan.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t1107E9B2228DF7BB003384B3 /* proto-tcp-rdp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1107E9B1228DF7BB003384B3 /* proto-tcp-rdp.c */; };\n\t\t110C79B022833AFA003FAC94 /* proto-oproto.c in Sources */ = {isa = PBXBuildFile; fileRef = 110C79AF22833AF9003FAC94 /* proto-oproto.c */; };\n\t\t110ED16820CB0BC200690C91 /* proto-ntlmssp.c in Sources */ = {isa = PBXBuildFile; fileRef = 110ED16720CB0BC200690C91 /* proto-ntlmssp.c */; };\n\t\t11126597197A086B00DC5987 /* out-unicornscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11126596197A086B00DC5987 /* out-unicornscan.c */; };\n\t\t1124DD6B25B4FF1600EEFC2C /* out-hostonly.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6A25B4FF1600EEFC2C /* out-hostonly.c */; };\n\t\t1124DD6F25B4FF3C00EEFC2C /* stack-if.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6C25B4FF3C00EEFC2C /* stack-if.c */; };\n\t\t1124DD7025B4FF3C00EEFC2C /* stack-arpv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6D25B4FF3C00EEFC2C /* stack-arpv4.c */; };\n\t\t112A871A1F9D8DF200D4D240 /* out-ndjson.c in Sources */ = {isa = PBXBuildFile; fileRef = 112A87191F9D8DF200D4D240 /* out-ndjson.c */; };\n\t\t11420DD319A2D47A00DB5BFE /* proto-vnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DD219A2D47A00DB5BFE /* proto-vnc.c */; };\n\t\t11420DD819A8160500DB5BFE /* proto-ftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DD719A8160500DB5BFE /* proto-ftp.c */; };\n\t\t11420DDB19A84A9F00DB5BFE /* proto-smtp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDA19A84A9E00DB5BFE /* proto-smtp.c */; };\n\t\t11420DDE19A8FDE300DB5BFE /* proto-pop3.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDD19A8FDE300DB5BFE /* proto-pop3.c */; };\n\t\t11420DE019A90CB300DB5BFE /* stack-tcp-app.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDF19A90CB300DB5BFE /* stack-tcp-app.c */; };\n\t\t11420DE319A9363B00DB5BFE /* proto-imap4.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DE219A9363A00DB5BFE /* proto-imap4.c */; };\n\t\t11469CA22295D80A00FA76BE /* misc-rstfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11469CA12295D80A00FA76BE /* misc-rstfilter.c */; };\n\t\t1155CF102AF2FE12001B235A /* proto-mc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF0F2AF2FE12001B235A /* proto-mc.c */; };\n\t\t1155CF132AF6EF72001B235A /* templ-nmap-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF112AF6EF72001B235A /* templ-nmap-payloads.c */; };\n\t\t1155CF162AF8311C001B235A /* templ-tcp-hdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF152AF8311C001B235A /* templ-tcp-hdr.c */; };\n\t\t115C0CAB18035BC5004E6CD7 /* proto-netbios.c in Sources */ = {isa = PBXBuildFile; fileRef = 115C0CA518035BC5004E6CD7 /* proto-netbios.c */; };\n\t\t115C0CAC18035BC5004E6CD7 /* proto-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 115C0CA718035BC5004E6CD7 /* proto-ssl.c */; };\n\t\t11623F6A191E0DB00075EEE6 /* out-certs.c in Sources */ = {isa = PBXBuildFile; fileRef = 11623F69191E0DB00075EEE6 /* out-certs.c */; };\n\t\t118B9B3225A00FA900F5FB0B /* massip-rangesv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2B25A00FA800F5FB0B /* massip-rangesv4.c */; };\n\t\t118B9B3325A00FA900F5FB0B /* massip-rangesv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2C25A00FA800F5FB0B /* massip-rangesv6.c */; };\n\t\t118B9B3425A00FA900F5FB0B /* massip-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2F25A00FA900F5FB0B /* massip-parse.c */; };\n\t\t118B9B3525A00FA900F5FB0B /* massip.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B3125A00FA900F5FB0B /* massip.c */; };\n\t\t118D67C42B02D58F00271F7F /* util-errormsg.c in Sources */ = {isa = PBXBuildFile; fileRef = 118D67C22B02CBA000271F7F /* util-errormsg.c */; };\n\t\t118D67C72B02DD6F00271F7F /* stack-queue.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B6297525995AA100D4786F /* stack-queue.c */; };\n\t\t118D67C82B02DD6F00271F7F /* event-timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219317DBCC7E00DDFD32 /* event-timeout.c */; };\n\t\t118D67C92B02DD6F00271F7F /* vulncheck-heartbleed.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363C2107E7ED00CBE1DE /* vulncheck-heartbleed.c */; };\n\t\t118D67CA2B02DD6F00271F7F /* massip-rangesv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2C25A00FA800F5FB0B /* massip-rangesv6.c */; };\n\t\t118D67CB2B02DD6F00271F7F /* util-logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219517DBCC7E00DDFD32 /* util-logger.c */; };\n\t\t118D67CC2B02DD6F00271F7F /* stub-pfring.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FE2141AB3600E82767 /* stub-pfring.c */; };\n\t\t118D67CD2B02DD6F00271F7F /* main-conf.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219717DBCC7E00DDFD32 /* main-conf.c */; };\n\t\t118D67CE2B02DD6F00271F7F /* main-dedup.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219817DBCC7E00DDFD32 /* main-dedup.c */; };\n\t\t118D67CF2B02DD6F00271F7F /* main-initadapter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219A17DBCC7E00DDFD32 /* main-initadapter.c */; };\n\t\t118D67D02B02DD6F00271F7F /* main-status.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219B17DBCC7E00DDFD32 /* main-status.c */; };\n\t\t118D67D12B02DD6F00271F7F /* rawsock-getip6.c in Sources */ = {isa = PBXBuildFile; fileRef = 118E115825859E6F00618314 /* rawsock-getip6.c */; };\n\t\t118D67D22B02DD6F00271F7F /* main-throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219D17DBCC7E00DDFD32 /* main-throttle.c */; };\n\t\t118D67D32B02DD6F00271F7F /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219F17DBCC7E00DDFD32 /* main.c */; };\n\t\t118D67D42B02DD6F00271F7F /* vulncheck-sslv3.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363D2107E7ED00CBE1DE /* vulncheck-sslv3.c */; };\n\t\t118D67D52B02DD6F00271F7F /* out-binary.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A117DBCC7E00DDFD32 /* out-binary.c */; };\n\t\t118D67D62B02DD6F00271F7F /* out-null.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A217DBCC7E00DDFD32 /* out-null.c */; };\n\t\t118D67D72B02DD6F00271F7F /* proto-ntlmssp.c in Sources */ = {isa = PBXBuildFile; fileRef = 110ED16720CB0BC200690C91 /* proto-ntlmssp.c */; };\n\t\t118D67D82B02DD6F00271F7F /* out-text.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A317DBCC7E00DDFD32 /* out-text.c */; };\n\t\t118D67D92B02DD6F00271F7F /* out-xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A417DBCC7E00DDFD32 /* out-xml.c */; };\n\t\t118D67DA2B02DD6F00271F7F /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A517DBCC7E00DDFD32 /* output.c */; };\n\t\t118D67DB2B02DD6F00271F7F /* pixie-threads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A817DBCC7E00DDFD32 /* pixie-threads.c */; };\n\t\t118D67DC2B02DD6F00271F7F /* pixie-timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AA17DBCC7E00DDFD32 /* pixie-timer.c */; };\n\t\t118D67DD2B02DD6F00271F7F /* read-service-probes.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FB21388A3B00E82767 /* read-service-probes.c */; };\n\t\t118D67DE2B02DD6F00271F7F /* proto-arp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AC17DBCC7E00DDFD32 /* proto-arp.c */; };\n\t\t118D67DF2B02DD6F00271F7F /* proto-banner1.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AE17DBCC7E00DDFD32 /* proto-banner1.c */; };\n\t\t118D67E02B02DD6F00271F7F /* stub-pcap.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FF2141AB3600E82767 /* stub-pcap.c */; };\n\t\t118D67E12B02DD6F00271F7F /* proto-tcp-rdp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1107E9B1228DF7BB003384B3 /* proto-tcp-rdp.c */; };\n\t\t118D67E22B02DD6F00271F7F /* proto-preprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B017DBCC7E00DDFD32 /* proto-preprocess.c */; };\n\t\t118D67E32B02DD6F00271F7F /* stack-tcp-core.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B217DBCC7E00DDFD32 /* stack-tcp-core.c */; };\n\t\t118D67E42B02DD6F00271F7F /* crypto-blackrock.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B417DBCC7E00DDFD32 /* crypto-blackrock.c */; };\n\t\t118D67E52B02DD6F00271F7F /* crypto-lcg.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B617DBCC7E00DDFD32 /* crypto-lcg.c */; };\n\t\t118D67E62B02DD6F00271F7F /* crypto-primegen.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B817DBCC7E00DDFD32 /* crypto-primegen.c */; };\n\t\t118D67E72B02DD6F00271F7F /* rawsock-getif.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BD17DBCC7E00DDFD32 /* rawsock-getif.c */; };\n\t\t118D67E82B02DD6F00271F7F /* rawsock-getip.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BE17DBCC7E00DDFD32 /* rawsock-getip.c */; };\n\t\t118D67E92B02DD6F00271F7F /* proto-isakmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C000632AFDA178001EB0EB /* proto-isakmp.c */; };\n\t\t118D67EA2B02DD6F00271F7F /* templ-tcp-hdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF152AF8311C001B235A /* templ-tcp-hdr.c */; };\n\t\t118D67EB2B02DD6F00271F7F /* rawsock-getmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BF17DBCC7E00DDFD32 /* rawsock-getmac.c */; };\n\t\t118D67EC2B02DD6F00271F7F /* util-malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B5897D21C0785B00DD6248 /* util-malloc.c */; };\n\t\t118D67ED2B02DD6F00271F7F /* rawsock-getroute.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C017DBCC7E00DDFD32 /* rawsock-getroute.c */; };\n\t\t118D67EE2B02DD6F00271F7F /* proto-versioning.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36472108DCBB00CBE1DE /* proto-versioning.c */; };\n\t\t118D67EF2B02DD6F00271F7F /* proto-coap.c in Sources */ = {isa = PBXBuildFile; fileRef = 11D0FAFA22763F4900332FA7 /* proto-coap.c */; };\n\t\t118D67F02B02DD6F00271F7F /* in-report.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C936C11EDCE77F0023D32E /* in-report.c */; };\n\t\t118D67F12B02DD6F00271F7F /* rawsock-pcapfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C117DBCC7E00DDFD32 /* rawsock-pcapfile.c */; };\n\t\t118D67F22B02DD6F00271F7F /* rawsock.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C517DBCC7E00DDFD32 /* rawsock.c */; };\n\t\t118D67F32B02DD6F00271F7F /* scripting-banner.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD364A2108E0CB00CBE1DE /* scripting-banner.c */; };\n\t\t118D67F42B02DD6F00271F7F /* rte-ring.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C717DBCC7E00DDFD32 /* rte-ring.c */; };\n\t\t118D67F52B02DD6F00271F7F /* smack1.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CA17DBCC7E00DDFD32 /* smack1.c */; };\n\t\t118D67F62B02DD6F00271F7F /* massip-rangesv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2B25A00FA800F5FB0B /* massip-rangesv4.c */; };\n\t\t118D67F72B02DD6F00271F7F /* smackqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CB17DBCC7E00DDFD32 /* smackqueue.c */; };\n\t\t118D67F82B02DD6F00271F7F /* util-safefunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CD17DBCC7E00DDFD32 /* util-safefunc.c */; };\n\t\t118D67F92B02DD6F00271F7F /* stack-ndpv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B6297625995AA100D4786F /* stack-ndpv6.c */; };\n\t\t118D67FA2B02DD6F00271F7F /* syn-cookie.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CF17DBCC7E00DDFD32 /* syn-cookie.c */; };\n\t\t118D67FB2B02DD6F00271F7F /* stack-arpv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6D25B4FF3C00EEFC2C /* stack-arpv4.c */; };\n\t\t118D67FC2B02DD6F00271F7F /* templ-nmap-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF112AF6EF72001B235A /* templ-nmap-payloads.c */; };\n\t\t118D67FD2B02DD6F00271F7F /* util-errormsg.c in Sources */ = {isa = PBXBuildFile; fileRef = 118D67C22B02CBA000271F7F /* util-errormsg.c */; };\n\t\t118D67FE2B02DD6F00271F7F /* templ-pkt.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D117DBCC7E00DDFD32 /* templ-pkt.c */; };\n\t\t118D67FF2B02DD6F00271F7F /* xring.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D317DBCC7E00DDFD32 /* xring.c */; };\n\t\t118D68002B02DD6F00271F7F /* proto-smb.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DE129520ABC2650041135D /* proto-smb.c */; };\n\t\t118D68012B02DD6F00271F7F /* templ-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */; };\n\t\t118D68022B02DD6F00271F7F /* proto-http.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80E717E0DAD4001BCE3A /* proto-http.c */; };\n\t\t118D68032B02DD6F00271F7F /* proto-icmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80E917E0DAD4001BCE3A /* proto-icmp.c */; };\n\t\t118D68042B02DD6F00271F7F /* proto-ssh.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80EB17E0DAD4001BCE3A /* proto-ssh.c */; };\n\t\t118D68052B02DD6F00271F7F /* main-ptrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80F517E0ED47001BCE3A /* main-ptrace.c */; };\n\t\t118D68062B02DD6F00271F7F /* proto-memcached.c in Sources */ = {isa = PBXBuildFile; fileRef = 119AB2042051FFED008E4DDD /* proto-memcached.c */; };\n\t\t118D68072B02DD6F00271F7F /* scripting-masscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36452107EB8700CBE1DE /* scripting-masscan.c */; };\n\t\t118D68082B02DD6F00271F7F /* massip.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B3125A00FA900F5FB0B /* massip.c */; };\n\t\t118D68092B02DD6F00271F7F /* proto-mc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1155CF0F2AF2FE12001B235A /* proto-mc.c */; };\n\t\t118D680A2B02DD6F00271F7F /* massip-addr.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BE533525A6441100451F95 /* massip-addr.c */; };\n\t\t118D680B2B02DD6F00271F7F /* main-listscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C017E506B400925E7E /* main-listscan.c */; };\n\t\t118D680C2B02DD6F00271F7F /* proto-dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C317E7834000925E7E /* proto-dns.c */; };\n\t\t118D680D2B02DD6F00271F7F /* proto-udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C517E7834000925E7E /* proto-udp.c */; };\n\t\t118D680E2B02DD6F00271F7F /* proto-snmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C917EA092B00925E7E /* proto-snmp.c */; };\n\t\t118D680F2B02DD6F00271F7F /* proto-netbios.c in Sources */ = {isa = PBXBuildFile; fileRef = 115C0CA518035BC5004E6CD7 /* proto-netbios.c */; };\n\t\t118D68102B02DD6F00271F7F /* vulncheck.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363F2107E7ED00CBE1DE /* vulncheck.c */; };\n\t\t118D68112B02DD6F00271F7F /* proto-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 115C0CA718035BC5004E6CD7 /* proto-ssl.c */; };\n\t\t118D68122B02DD6F00271F7F /* in-binary.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868081816F3A7008E00B8 /* in-binary.c */; };\n\t\t118D68132B02DD6F00271F7F /* stack-src.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680B1816F3A7008E00B8 /* stack-src.c */; };\n\t\t118D68142B02DD6F00271F7F /* vulncheck-ntp-monlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36402107E7ED00CBE1DE /* vulncheck-ntp-monlist.c */; };\n\t\t118D68152B02DD6F00271F7F /* misc-rstfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11469CA12295D80A00FA76BE /* misc-rstfilter.c */; };\n\t\t118D68162B02DD6F00271F7F /* masscan-app.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680D1816F3A7008E00B8 /* masscan-app.c */; };\n\t\t118D68172B02DD6F00271F7F /* out-redis.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680F1816F3A7008E00B8 /* out-redis.c */; };\n\t\t118D68182B02DD6F00271F7F /* pixie-file.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868101816F3A7008E00B8 /* pixie-file.c */; };\n\t\t118D68192B02DD6F00271F7F /* crypto-siphash24.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868131816F3A7008E00B8 /* crypto-siphash24.c */; };\n\t\t118D681A2B02DD6F00271F7F /* stack-if.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6C25B4FF3C00EEFC2C /* stack-if.c */; };\n\t\t118D681B2B02DD6F00271F7F /* proto-zeroaccess.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8681C1819A6F7008E00B8 /* proto-zeroaccess.c */; };\n\t\t118D681C2B02DD6F00271F7F /* proto-banout.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED018641DCC00DA5438 /* proto-banout.c */; };\n\t\t118D681D2B02DD6F00271F7F /* proto-ssl-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED218641DCC00DA5438 /* proto-ssl-test.c */; };\n\t\t118D681E2B02DD6F00271F7F /* util-checksum.c in Sources */ = {isa = PBXBuildFile; fileRef = 118E115525859D5300618314 /* util-checksum.c */; };\n\t\t118D681F2B02DD6F00271F7F /* proto-x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED318641DCC00DA5438 /* proto-x509.c */; };\n\t\t118D68202B02DD6F00271F7F /* crypto-base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A773E91881BFC700B135DE /* crypto-base64.c */; };\n\t\t118D68212B02DD6F00271F7F /* pixie-backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 11E76DB21889BC5200061F45 /* pixie-backtrace.c */; };\n\t\t118D68222B02DD6F00271F7F /* proto-sctp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC2F99188CE34A008CB623 /* proto-sctp.c */; };\n\t\t118D68232B02DD6F00271F7F /* out-grepable.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA295F18902CEE0064A759 /* out-grepable.c */; };\n\t\t118D68242B02DD6F00271F7F /* proto-tcp-telnet.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA296018902CEE0064A759 /* proto-tcp-telnet.c */; };\n\t\t118D68252B02DD6F00271F7F /* proto-ntp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA296A189060220064A759 /* proto-ntp.c */; };\n\t\t118D68262B02DD6F00271F7F /* scripting.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363A2107DFEB00CBE1DE /* scripting.c */; };\n\t\t118D68272B02DD6F00271F7F /* crypto-blackrock2.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B05EA418B9649F009C935E /* crypto-blackrock2.c */; };\n\t\t118D68282B02DD6F00271F7F /* out-ndjson.c in Sources */ = {isa = PBXBuildFile; fileRef = 112A87191F9D8DF200D4D240 /* out-ndjson.c */; };\n\t\t118D68292B02DD6F00271F7F /* main-readrange.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B05EA518B9649F009C935E /* main-readrange.c */; };\n\t\t118D682A2B02DD6F00271F7F /* out-json.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A50CAD191C128F006D5802 /* out-json.c */; };\n\t\t118D682B2B02DD6F00271F7F /* out-certs.c in Sources */ = {isa = PBXBuildFile; fileRef = 11623F69191E0DB00075EEE6 /* out-certs.c */; };\n\t\t118D682C2B02DD6F00271F7F /* out-unicornscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11126596197A086B00DC5987 /* out-unicornscan.c */; };\n\t\t118D682D2B02DD6F00271F7F /* proto-vnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DD219A2D47A00DB5BFE /* proto-vnc.c */; };\n\t\t118D682E2B02DD6F00271F7F /* in-filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C936BF1EDCE77F0023D32E /* in-filter.c */; };\n\t\t118D682F2B02DD6F00271F7F /* proto-ftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DD719A8160500DB5BFE /* proto-ftp.c */; };\n\t\t118D68302B02DD6F00271F7F /* proto-oproto.c in Sources */ = {isa = PBXBuildFile; fileRef = 110C79AF22833AF9003FAC94 /* proto-oproto.c */; };\n\t\t118D68312B02DD6F00271F7F /* proto-smtp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDA19A84A9E00DB5BFE /* proto-smtp.c */; };\n\t\t118D68322B02DD6F00271F7F /* out-tcp-services.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363321067BD300CBE1DE /* out-tcp-services.c */; };\n\t\t118D68332B02DD6F00271F7F /* proto-pop3.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDD19A8FDE300DB5BFE /* proto-pop3.c */; };\n\t\t118D68342B02DD6F00271F7F /* stack-tcp-app.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DDF19A90CB300DB5BFE /* stack-tcp-app.c */; };\n\t\t118D68352B02DD6F00271F7F /* proto-imap4.c in Sources */ = {isa = PBXBuildFile; fileRef = 11420DE219A9363A00DB5BFE /* proto-imap4.c */; };\n\t\t118D68362B02DD6F00271F7F /* massip-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 118B9B2F25A00FA900F5FB0B /* massip-parse.c */; };\n\t\t118D68372B02DD6F00271F7F /* out-hostonly.c in Sources */ = {isa = PBXBuildFile; fileRef = 1124DD6A25B4FF1600EEFC2C /* out-hostonly.c */; };\n\t\t118D68382B02DD6F00271F7F /* stub-lua.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36362107DE9700CBE1DE /* stub-lua.c */; };\n\t\t118D68412B06C1F900271F7F /* util-extract.c in Sources */ = {isa = PBXBuildFile; fileRef = 118D683F2B06BB9900271F7F /* util-extract.c */; };\n\t\t118D68422B06C1FA00271F7F /* util-extract.c in Sources */ = {isa = PBXBuildFile; fileRef = 118D683F2B06BB9900271F7F /* util-extract.c */; };\n\t\t118E115725859D5300618314 /* util-checksum.c in Sources */ = {isa = PBXBuildFile; fileRef = 118E115525859D5300618314 /* util-checksum.c */; };\n\t\t118E115925859E6F00618314 /* rawsock-getip6.c in Sources */ = {isa = PBXBuildFile; fileRef = 118E115825859E6F00618314 /* rawsock-getip6.c */; };\n\t\t119968FC21388A3C00E82767 /* read-service-probes.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FB21388A3B00E82767 /* read-service-probes.c */; };\n\t\t119969002141AB3600E82767 /* stub-pfring.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FE2141AB3600E82767 /* stub-pfring.c */; };\n\t\t119969012141AB3600E82767 /* stub-pcap.c in Sources */ = {isa = PBXBuildFile; fileRef = 119968FF2141AB3600E82767 /* stub-pcap.c */; };\n\t\t119AB2062051FFED008E4DDD /* proto-memcached.c in Sources */ = {isa = PBXBuildFile; fileRef = 119AB2042051FFED008E4DDD /* proto-memcached.c */; };\n\t\t11A50CAE191C128F006D5802 /* out-json.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A50CAD191C128F006D5802 /* out-json.c */; };\n\t\t11A773EB1881BFC700B135DE /* crypto-base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A773E91881BFC700B135DE /* crypto-base64.c */; };\n\t\t11A868151816F3A7008E00B8 /* in-binary.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868081816F3A7008E00B8 /* in-binary.c */; };\n\t\t11A868161816F3A7008E00B8 /* stack-src.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680B1816F3A7008E00B8 /* stack-src.c */; };\n\t\t11A868171816F3A7008E00B8 /* masscan-app.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680D1816F3A7008E00B8 /* masscan-app.c */; };\n\t\t11A868181816F3A7008E00B8 /* out-redis.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8680F1816F3A7008E00B8 /* out-redis.c */; };\n\t\t11A868191816F3A7008E00B8 /* pixie-file.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868101816F3A7008E00B8 /* pixie-file.c */; };\n\t\t11A8681A1816F3A7008E00B8 /* crypto-siphash24.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A868131816F3A7008E00B8 /* crypto-siphash24.c */; };\n\t\t11A8681E1819A6F7008E00B8 /* proto-zeroaccess.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A8681C1819A6F7008E00B8 /* proto-zeroaccess.c */; };\n\t\t11A921D517DBCC7E00DDFD32 /* event-timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219317DBCC7E00DDFD32 /* event-timeout.c */; };\n\t\t11A921D617DBCC7E00DDFD32 /* util-logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219517DBCC7E00DDFD32 /* util-logger.c */; };\n\t\t11A921D717DBCC7E00DDFD32 /* main-conf.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219717DBCC7E00DDFD32 /* main-conf.c */; };\n\t\t11A921D817DBCC7E00DDFD32 /* main-dedup.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219817DBCC7E00DDFD32 /* main-dedup.c */; };\n\t\t11A921D917DBCC7E00DDFD32 /* main-initadapter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219A17DBCC7E00DDFD32 /* main-initadapter.c */; };\n\t\t11A921DA17DBCC7E00DDFD32 /* main-status.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219B17DBCC7E00DDFD32 /* main-status.c */; };\n\t\t11A921DB17DBCC7E00DDFD32 /* main-throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219D17DBCC7E00DDFD32 /* main-throttle.c */; };\n\t\t11A921DC17DBCC7E00DDFD32 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A9219F17DBCC7E00DDFD32 /* main.c */; };\n\t\t11A921DD17DBCC7E00DDFD32 /* out-binary.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A117DBCC7E00DDFD32 /* out-binary.c */; };\n\t\t11A921DE17DBCC7E00DDFD32 /* out-null.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A217DBCC7E00DDFD32 /* out-null.c */; };\n\t\t11A921DF17DBCC7E00DDFD32 /* out-text.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A317DBCC7E00DDFD32 /* out-text.c */; };\n\t\t11A921E017DBCC7E00DDFD32 /* out-xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A417DBCC7E00DDFD32 /* out-xml.c */; };\n\t\t11A921E117DBCC7E00DDFD32 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A517DBCC7E00DDFD32 /* output.c */; };\n\t\t11A921E217DBCC7E00DDFD32 /* pixie-threads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921A817DBCC7E00DDFD32 /* pixie-threads.c */; };\n\t\t11A921E317DBCC7E00DDFD32 /* pixie-timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AA17DBCC7E00DDFD32 /* pixie-timer.c */; };\n\t\t11A921E417DBCC7E00DDFD32 /* proto-arp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AC17DBCC7E00DDFD32 /* proto-arp.c */; };\n\t\t11A921E517DBCC7E00DDFD32 /* proto-banner1.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921AE17DBCC7E00DDFD32 /* proto-banner1.c */; };\n\t\t11A921E617DBCC7E00DDFD32 /* proto-preprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B017DBCC7E00DDFD32 /* proto-preprocess.c */; };\n\t\t11A921E717DBCC7E00DDFD32 /* stack-tcp-core.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B217DBCC7E00DDFD32 /* stack-tcp-core.c */; };\n\t\t11A921E817DBCC7E00DDFD32 /* crypto-blackrock.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B417DBCC7E00DDFD32 /* crypto-blackrock.c */; };\n\t\t11A921E917DBCC7E00DDFD32 /* crypto-lcg.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B617DBCC7E00DDFD32 /* crypto-lcg.c */; };\n\t\t11A921EA17DBCC7E00DDFD32 /* crypto-primegen.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921B817DBCC7E00DDFD32 /* crypto-primegen.c */; };\n\t\t11A921ED17DBCC7E00DDFD32 /* rawsock-getif.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BD17DBCC7E00DDFD32 /* rawsock-getif.c */; };\n\t\t11A921EE17DBCC7E00DDFD32 /* rawsock-getip.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BE17DBCC7E00DDFD32 /* rawsock-getip.c */; };\n\t\t11A921EF17DBCC7E00DDFD32 /* rawsock-getmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921BF17DBCC7E00DDFD32 /* rawsock-getmac.c */; };\n\t\t11A921F017DBCC7E00DDFD32 /* rawsock-getroute.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C017DBCC7E00DDFD32 /* rawsock-getroute.c */; };\n\t\t11A921F117DBCC7E00DDFD32 /* rawsock-pcapfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C117DBCC7E00DDFD32 /* rawsock-pcapfile.c */; };\n\t\t11A921F317DBCC7E00DDFD32 /* rawsock.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C517DBCC7E00DDFD32 /* rawsock.c */; };\n\t\t11A921F417DBCC7E00DDFD32 /* rte-ring.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921C717DBCC7E00DDFD32 /* rte-ring.c */; };\n\t\t11A921F517DBCC7E00DDFD32 /* smack1.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CA17DBCC7E00DDFD32 /* smack1.c */; };\n\t\t11A921F617DBCC7E00DDFD32 /* smackqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CB17DBCC7E00DDFD32 /* smackqueue.c */; };\n\t\t11A921F717DBCC7E00DDFD32 /* util-safefunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CD17DBCC7E00DDFD32 /* util-safefunc.c */; };\n\t\t11A921F817DBCC7E00DDFD32 /* syn-cookie.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CF17DBCC7E00DDFD32 /* syn-cookie.c */; };\n\t\t11A921F917DBCC7E00DDFD32 /* templ-pkt.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D117DBCC7E00DDFD32 /* templ-pkt.c */; };\n\t\t11A921FA17DBCC7E00DDFD32 /* xring.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D317DBCC7E00DDFD32 /* xring.c */; };\n\t\t11AC2F9B188CE34A008CB623 /* proto-sctp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC2F99188CE34A008CB623 /* proto-sctp.c */; };\n\t\t11AC80ED17E0DAD4001BCE3A /* proto-http.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80E717E0DAD4001BCE3A /* proto-http.c */; };\n\t\t11AC80EE17E0DAD4001BCE3A /* proto-icmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80E917E0DAD4001BCE3A /* proto-icmp.c */; };\n\t\t11AC80EF17E0DAD4001BCE3A /* proto-ssh.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80EB17E0DAD4001BCE3A /* proto-ssh.c */; };\n\t\t11AC80F617E0ED47001BCE3A /* main-ptrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 11AC80F517E0ED47001BCE3A /* main-ptrace.c */; };\n\t\t11B039C117E506B400925E7E /* main-listscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C017E506B400925E7E /* main-listscan.c */; };\n\t\t11B039C717E7834000925E7E /* proto-dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C317E7834000925E7E /* proto-dns.c */; };\n\t\t11B039C817E7834000925E7E /* proto-udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C517E7834000925E7E /* proto-udp.c */; };\n\t\t11B039CB17EA092B00925E7E /* proto-snmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B039C917EA092B00925E7E /* proto-snmp.c */; };\n\t\t11B05EA618B9649F009C935E /* crypto-blackrock2.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B05EA418B9649F009C935E /* crypto-blackrock2.c */; };\n\t\t11B05EA718B9649F009C935E /* main-readrange.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B05EA518B9649F009C935E /* main-readrange.c */; };\n\t\t11B22ED518641DCC00DA5438 /* proto-banout.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED018641DCC00DA5438 /* proto-banout.c */; };\n\t\t11B22ED618641DCC00DA5438 /* proto-ssl-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED218641DCC00DA5438 /* proto-ssl-test.c */; };\n\t\t11B22ED718641DCC00DA5438 /* proto-x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED318641DCC00DA5438 /* proto-x509.c */; };\n\t\t11B2DD9E17DE4DD8007FC363 /* templ-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */; };\n\t\t11B5897E21C0785C00DD6248 /* util-malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B5897D21C0785B00DD6248 /* util-malloc.c */; };\n\t\t11B6297925995AA100D4786F /* stack-queue.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B6297525995AA100D4786F /* stack-queue.c */; };\n\t\t11B6297A25995AA100D4786F /* stack-ndpv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B6297625995AA100D4786F /* stack-ndpv6.c */; };\n\t\t11BA296218902CEE0064A759 /* out-grepable.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA295F18902CEE0064A759 /* out-grepable.c */; };\n\t\t11BA296318902CEE0064A759 /* proto-tcp-telnet.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA296018902CEE0064A759 /* proto-tcp-telnet.c */; };\n\t\t11BA296B189060220064A759 /* proto-ntp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA296A189060220064A759 /* proto-ntp.c */; };\n\t\t11BE533625A6441100451F95 /* massip-addr.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BE533525A6441100451F95 /* massip-addr.c */; };\n\t\t11C000652AFDA179001EB0EB /* proto-isakmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C000632AFDA178001EB0EB /* proto-isakmp.c */; };\n\t\t11C936C31EDCE77F0023D32E /* in-filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C936BF1EDCE77F0023D32E /* in-filter.c */; };\n\t\t11C936C41EDCE77F0023D32E /* in-report.c in Sources */ = {isa = PBXBuildFile; fileRef = 11C936C11EDCE77F0023D32E /* in-report.c */; };\n\t\t11D0FAFB22763F4900332FA7 /* proto-coap.c in Sources */ = {isa = PBXBuildFile; fileRef = 11D0FAFA22763F4900332FA7 /* proto-coap.c */; };\n\t\t11DD363421067BD400CBE1DE /* out-tcp-services.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363321067BD300CBE1DE /* out-tcp-services.c */; };\n\t\t11DD36382107DE9700CBE1DE /* stub-lua.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36362107DE9700CBE1DE /* stub-lua.c */; };\n\t\t11DD363B2107DFEB00CBE1DE /* scripting.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363A2107DFEB00CBE1DE /* scripting.c */; };\n\t\t11DD36412107E7ED00CBE1DE /* vulncheck-heartbleed.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363C2107E7ED00CBE1DE /* vulncheck-heartbleed.c */; };\n\t\t11DD36422107E7ED00CBE1DE /* vulncheck-sslv3.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363D2107E7ED00CBE1DE /* vulncheck-sslv3.c */; };\n\t\t11DD36432107E7ED00CBE1DE /* vulncheck.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD363F2107E7ED00CBE1DE /* vulncheck.c */; };\n\t\t11DD36442107E7ED00CBE1DE /* vulncheck-ntp-monlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36402107E7ED00CBE1DE /* vulncheck-ntp-monlist.c */; };\n\t\t11DD36462107EB8700CBE1DE /* scripting-masscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36452107EB8700CBE1DE /* scripting-masscan.c */; };\n\t\t11DD36492108DCBB00CBE1DE /* proto-versioning.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD36472108DCBB00CBE1DE /* proto-versioning.c */; };\n\t\t11DD364B2108E0CB00CBE1DE /* scripting-banner.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DD364A2108E0CB00CBE1DE /* scripting-banner.c */; };\n\t\t11DE129620ABC2650041135D /* proto-smb.c in Sources */ = {isa = PBXBuildFile; fileRef = 11DE129520ABC2650041135D /* proto-smb.c */; };\n\t\t11E76DB41889BC5200061F45 /* pixie-backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 11E76DB21889BC5200061F45 /* pixie-backtrace.c */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t118D683A2B02DD6F00271F7F /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = /usr/share/man/man1/;\n\t\t\tdstSubfolderSpec = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 1;\n\t\t};\n\t\t11A9218317DBCB3200DDFD32 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = /usr/share/man/man1/;\n\t\t\tdstSubfolderSpec = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 1;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t1107E9B0228DF7BB003384B3 /* proto-tcp-rdp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-tcp-rdp.h\"; sourceTree = \"<group>\"; };\n\t\t1107E9B1228DF7BB003384B3 /* proto-tcp-rdp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-tcp-rdp.c\"; sourceTree = \"<group>\"; };\n\t\t110C79AE22833AF9003FAC94 /* proto-oproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-oproto.h\"; sourceTree = \"<group>\"; };\n\t\t110C79AF22833AF9003FAC94 /* proto-oproto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-oproto.c\"; sourceTree = \"<group>\"; };\n\t\t110ED16520CA6A8300690C91 /* proto-spnego.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-spnego.h\"; sourceTree = \"<group>\"; };\n\t\t110ED16620CB0BC200690C91 /* proto-ntlmssp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-ntlmssp.h\"; sourceTree = \"<group>\"; };\n\t\t110ED16720CB0BC200690C91 /* proto-ntlmssp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ntlmssp.c\"; sourceTree = \"<group>\"; };\n\t\t11126596197A086B00DC5987 /* out-unicornscan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-unicornscan.c\"; sourceTree = \"<group>\"; };\n\t\t1124DD6A25B4FF1600EEFC2C /* out-hostonly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-hostonly.c\"; sourceTree = \"<group>\"; };\n\t\t1124DD6C25B4FF3C00EEFC2C /* stack-if.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-if.c\"; sourceTree = \"<group>\"; };\n\t\t1124DD6D25B4FF3C00EEFC2C /* stack-arpv4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-arpv4.c\"; sourceTree = \"<group>\"; };\n\t\t1124DD6E25B4FF3C00EEFC2C /* stack-arpv4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-arpv4.h\"; sourceTree = \"<group>\"; };\n\t\t112A87191F9D8DF200D4D240 /* out-ndjson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-ndjson.c\"; sourceTree = \"<group>\"; };\n\t\t113AD3B818208A1900D5E067 /* masscan-status.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"masscan-status.h\"; sourceTree = \"<group>\"; };\n\t\t11420DD219A2D47A00DB5BFE /* proto-vnc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-vnc.c\"; sourceTree = \"<group>\"; };\n\t\t11420DD519A2D48C00DB5BFE /* proto-vnc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-vnc.h\"; sourceTree = \"<group>\"; };\n\t\t11420DD619A815CD00DB5BFE /* proto-ftp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-ftp.h\"; sourceTree = \"<group>\"; };\n\t\t11420DD719A8160500DB5BFE /* proto-ftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ftp.c\"; sourceTree = \"<group>\"; };\n\t\t11420DD919A844B000DB5BFE /* proto-smtp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-smtp.h\"; sourceTree = \"<group>\"; };\n\t\t11420DDA19A84A9E00DB5BFE /* proto-smtp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-smtp.c\"; sourceTree = \"<group>\"; };\n\t\t11420DDC19A8F2D200DB5BFE /* proto-pop3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-pop3.h\"; sourceTree = \"<group>\"; };\n\t\t11420DDD19A8FDE300DB5BFE /* proto-pop3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-pop3.c\"; sourceTree = \"<group>\"; };\n\t\t11420DDF19A90CB300DB5BFE /* stack-tcp-app.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-tcp-app.c\"; sourceTree = \"<group>\"; };\n\t\t11420DE119A9361500DB5BFE /* proto-imap4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-imap4.h\"; sourceTree = \"<group>\"; };\n\t\t11420DE219A9363A00DB5BFE /* proto-imap4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-imap4.c\"; sourceTree = \"<group>\"; };\n\t\t11469CA02295D80A00FA76BE /* misc-rstfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"misc-rstfilter.h\"; sourceTree = \"<group>\"; };\n\t\t11469CA12295D80A00FA76BE /* misc-rstfilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"misc-rstfilter.c\"; sourceTree = \"<group>\"; };\n\t\t1155CF0E2AF2FE12001B235A /* proto-mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-mc.h\"; sourceTree = \"<group>\"; };\n\t\t1155CF0F2AF2FE12001B235A /* proto-mc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-mc.c\"; sourceTree = \"<group>\"; };\n\t\t1155CF112AF6EF72001B235A /* templ-nmap-payloads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"templ-nmap-payloads.c\"; sourceTree = \"<group>\"; };\n\t\t1155CF122AF6EF72001B235A /* templ-nmap-payloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"templ-nmap-payloads.h\"; sourceTree = \"<group>\"; };\n\t\t1155CF142AF8311C001B235A /* templ-tcp-hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"templ-tcp-hdr.h\"; sourceTree = \"<group>\"; };\n\t\t1155CF152AF8311C001B235A /* templ-tcp-hdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"templ-tcp-hdr.c\"; sourceTree = \"<group>\"; };\n\t\t1155CF172AF8509A001B235A /* templ-opts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"templ-opts.h\"; sourceTree = \"<group>\"; };\n\t\t115C0CA318035BC5004E6CD7 /* out-record.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"out-record.h\"; sourceTree = \"<group>\"; };\n\t\t115C0CA418035BC5004E6CD7 /* proto-dns-parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-dns-parse.h\"; sourceTree = \"<group>\"; };\n\t\t115C0CA518035BC5004E6CD7 /* proto-netbios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-netbios.c\"; sourceTree = \"<group>\"; };\n\t\t115C0CA618035BC5004E6CD7 /* proto-netbios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-netbios.h\"; sourceTree = \"<group>\"; };\n\t\t115C0CA718035BC5004E6CD7 /* proto-ssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ssl.c\"; sourceTree = \"<group>\"; };\n\t\t115C0CA818035BC5004E6CD7 /* proto-ssl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-ssl.h\"; sourceTree = \"<group>\"; };\n\t\t115C0CAA18035BC5004E6CD7 /* unusedparm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unusedparm.h; sourceTree = \"<group>\"; };\n\t\t11623F69191E0DB00075EEE6 /* out-certs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-certs.c\"; sourceTree = \"<group>\"; };\n\t\t116806EA1995D421005B0980 /* rawsock-adapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"rawsock-adapter.h\"; sourceTree = \"<group>\"; };\n\t\t118B9B2A25A00FA800F5FB0B /* massip-rangesv4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"massip-rangesv4.h\"; sourceTree = \"<group>\"; };\n\t\t118B9B2B25A00FA800F5FB0B /* massip-rangesv4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"massip-rangesv4.c\"; sourceTree = \"<group>\"; };\n\t\t118B9B2C25A00FA800F5FB0B /* massip-rangesv6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"massip-rangesv6.c\"; sourceTree = \"<group>\"; };\n\t\t118B9B2D25A00FA900F5FB0B /* massip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = massip.h; sourceTree = \"<group>\"; };\n\t\t118B9B2E25A00FA900F5FB0B /* massip-rangesv6.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"massip-rangesv6.h\"; sourceTree = \"<group>\"; };\n\t\t118B9B2F25A00FA900F5FB0B /* massip-parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"massip-parse.c\"; sourceTree = \"<group>\"; };\n\t\t118B9B3025A00FA900F5FB0B /* massip-parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"massip-parse.h\"; sourceTree = \"<group>\"; };\n\t\t118B9B3125A00FA900F5FB0B /* massip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = massip.c; sourceTree = \"<group>\"; };\n\t\t118D67C12B02CBA000271F7F /* util-errormsg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"util-errormsg.h\"; sourceTree = \"<group>\"; };\n\t\t118D67C22B02CBA000271F7F /* util-errormsg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = \"util-errormsg.c\"; sourceTree = \"<group>\"; };\n\t\t118D683E2B02DD6F00271F7F /* masscan copy */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.executable\"; includeInIndex = 0; path = \"masscan copy\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t118D683F2B06BB9900271F7F /* util-extract.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = \"util-extract.c\"; sourceTree = \"<group>\"; };\n\t\t118D68402B06BB9900271F7F /* util-extract.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"util-extract.h\"; sourceTree = \"<group>\"; };\n\t\t118E115325859D2400618314 /* stack-tcp-api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-tcp-api.h\"; sourceTree = \"<group>\"; };\n\t\t118E115425859D5200618314 /* util-bool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"util-bool.h\"; sourceTree = \"<group>\"; };\n\t\t118E115525859D5300618314 /* util-checksum.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"util-checksum.c\"; sourceTree = \"<group>\"; };\n\t\t118E115625859D5300618314 /* util-checksum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"util-checksum.h\"; sourceTree = \"<group>\"; };\n\t\t118E115825859E6F00618314 /* rawsock-getip6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-getip6.c\"; sourceTree = \"<group>\"; };\n\t\t119968FB21388A3B00E82767 /* read-service-probes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"read-service-probes.c\"; sourceTree = \"<group>\"; };\n\t\t119968FD21388A5300E82767 /* read-service-probes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"read-service-probes.h\"; sourceTree = \"<group>\"; };\n\t\t119968FE2141AB3600E82767 /* stub-pfring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stub-pfring.c\"; sourceTree = \"<group>\"; };\n\t\t119968FF2141AB3600E82767 /* stub-pcap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stub-pcap.c\"; sourceTree = \"<group>\"; };\n\t\t119969022141ABAC00E82767 /* stub-pfring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stub-pfring.h\"; sourceTree = \"<group>\"; };\n\t\t119969032141ABAC00E82767 /* stub-pcap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stub-pcap.h\"; sourceTree = \"<group>\"; };\n\t\t119AB2042051FFED008E4DDD /* proto-memcached.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-memcached.c\"; sourceTree = \"<group>\"; };\n\t\t119AB2052051FFED008E4DDD /* proto-memcached.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-memcached.h\"; sourceTree = \"<group>\"; };\n\t\t11A50CAD191C128F006D5802 /* out-json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-json.c\"; sourceTree = \"<group>\"; };\n\t\t11A773E91881BFC700B135DE /* crypto-base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-base64.c\"; sourceTree = \"<group>\"; };\n\t\t11A773EA1881BFC700B135DE /* crypto-base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"crypto-base64.h\"; sourceTree = \"<group>\"; };\n\t\t11A868081816F3A7008E00B8 /* in-binary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"in-binary.c\"; sourceTree = \"<group>\"; };\n\t\t11A868091816F3A7008E00B8 /* in-binary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"in-binary.h\"; sourceTree = \"<group>\"; };\n\t\t11A8680A1816F3A7008E00B8 /* main-globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"main-globals.h\"; sourceTree = \"<group>\"; };\n\t\t11A8680B1816F3A7008E00B8 /* stack-src.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-src.c\"; sourceTree = \"<group>\"; };\n\t\t11A8680C1816F3A7008E00B8 /* stack-src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-src.h\"; sourceTree = \"<group>\"; };\n\t\t11A8680D1816F3A7008E00B8 /* masscan-app.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"masscan-app.c\"; sourceTree = \"<group>\"; };\n\t\t11A8680E1816F3A7008E00B8 /* masscan-app.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"masscan-app.h\"; sourceTree = \"<group>\"; };\n\t\t11A8680F1816F3A7008E00B8 /* out-redis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-redis.c\"; sourceTree = \"<group>\"; };\n\t\t11A868101816F3A7008E00B8 /* pixie-file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"pixie-file.c\"; sourceTree = \"<group>\"; };\n\t\t11A868111816F3A7008E00B8 /* pixie-file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"pixie-file.h\"; sourceTree = \"<group>\"; };\n\t\t11A868121816F3A7008E00B8 /* pixie-sockets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"pixie-sockets.h\"; sourceTree = \"<group>\"; };\n\t\t11A868131816F3A7008E00B8 /* crypto-siphash24.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-siphash24.c\"; sourceTree = \"<group>\"; };\n\t\t11A868141816F3A7008E00B8 /* crypto-siphash24.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"crypto-siphash24.h\"; sourceTree = \"<group>\"; };\n\t\t11A8681C1819A6F7008E00B8 /* proto-zeroaccess.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-zeroaccess.c\"; sourceTree = \"<group>\"; };\n\t\t11A8681D1819A6F7008E00B8 /* proto-zeroaccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-zeroaccess.h\"; sourceTree = \"<group>\"; };\n\t\t11A9218517DBCB3200DDFD32 /* masscan */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.executable\"; includeInIndex = 0; path = masscan; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t11A9219317DBCC7E00DDFD32 /* event-timeout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"event-timeout.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219417DBCC7E00DDFD32 /* event-timeout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"event-timeout.h\"; sourceTree = \"<group>\"; };\n\t\t11A9219517DBCC7E00DDFD32 /* util-logger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"util-logger.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219617DBCC7E00DDFD32 /* util-logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"util-logger.h\"; sourceTree = \"<group>\"; };\n\t\t11A9219717DBCC7E00DDFD32 /* main-conf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-conf.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219817DBCC7E00DDFD32 /* main-dedup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-dedup.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219917DBCC7E00DDFD32 /* main-dedup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"main-dedup.h\"; sourceTree = \"<group>\"; };\n\t\t11A9219A17DBCC7E00DDFD32 /* main-initadapter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-initadapter.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219B17DBCC7E00DDFD32 /* main-status.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-status.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219C17DBCC7E00DDFD32 /* main-status.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"main-status.h\"; sourceTree = \"<group>\"; };\n\t\t11A9219D17DBCC7E00DDFD32 /* main-throttle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-throttle.c\"; sourceTree = \"<group>\"; };\n\t\t11A9219E17DBCC7E00DDFD32 /* main-throttle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"main-throttle.h\"; sourceTree = \"<group>\"; };\n\t\t11A9219F17DBCC7E00DDFD32 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = \"<group>\"; };\n\t\t11A921A017DBCC7E00DDFD32 /* masscan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = masscan.h; sourceTree = \"<group>\"; };\n\t\t11A921A117DBCC7E00DDFD32 /* out-binary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-binary.c\"; sourceTree = \"<group>\"; };\n\t\t11A921A217DBCC7E00DDFD32 /* out-null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-null.c\"; sourceTree = \"<group>\"; };\n\t\t11A921A317DBCC7E00DDFD32 /* out-text.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-text.c\"; sourceTree = \"<group>\"; };\n\t\t11A921A417DBCC7E00DDFD32 /* out-xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-xml.c\"; sourceTree = \"<group>\"; };\n\t\t11A921A517DBCC7E00DDFD32 /* output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = output.c; sourceTree = \"<group>\"; };\n\t\t11A921A617DBCC7E00DDFD32 /* output.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = output.h; sourceTree = \"<group>\"; };\n\t\t11A921A817DBCC7E00DDFD32 /* pixie-threads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"pixie-threads.c\"; sourceTree = \"<group>\"; };\n\t\t11A921A917DBCC7E00DDFD32 /* pixie-threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"pixie-threads.h\"; sourceTree = \"<group>\"; };\n\t\t11A921AA17DBCC7E00DDFD32 /* pixie-timer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"pixie-timer.c\"; sourceTree = \"<group>\"; };\n\t\t11A921AB17DBCC7E00DDFD32 /* pixie-timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"pixie-timer.h\"; sourceTree = \"<group>\"; };\n\t\t11A921AC17DBCC7E00DDFD32 /* proto-arp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-arp.c\"; sourceTree = \"<group>\"; };\n\t\t11A921AD17DBCC7E00DDFD32 /* proto-arp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-arp.h\"; sourceTree = \"<group>\"; };\n\t\t11A921AE17DBCC7E00DDFD32 /* proto-banner1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-banner1.c\"; sourceTree = \"<group>\"; };\n\t\t11A921AF17DBCC7E00DDFD32 /* proto-banner1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-banner1.h\"; sourceTree = \"<group>\"; };\n\t\t11A921B017DBCC7E00DDFD32 /* proto-preprocess.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-preprocess.c\"; sourceTree = \"<group>\"; };\n\t\t11A921B117DBCC7E00DDFD32 /* proto-preprocess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-preprocess.h\"; sourceTree = \"<group>\"; };\n\t\t11A921B217DBCC7E00DDFD32 /* stack-tcp-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-tcp-core.c\"; sourceTree = \"<group>\"; };\n\t\t11A921B317DBCC7E00DDFD32 /* stack-tcp-core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-tcp-core.h\"; sourceTree = \"<group>\"; };\n\t\t11A921B417DBCC7E00DDFD32 /* crypto-blackrock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-blackrock.c\"; sourceTree = \"<group>\"; };\n\t\t11A921B517DBCC7E00DDFD32 /* crypto-blackrock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"crypto-blackrock.h\"; sourceTree = \"<group>\"; };\n\t\t11A921B617DBCC7E00DDFD32 /* crypto-lcg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-lcg.c\"; sourceTree = \"<group>\"; };\n\t\t11A921B717DBCC7E00DDFD32 /* crypto-lcg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"crypto-lcg.h\"; sourceTree = \"<group>\"; };\n\t\t11A921B817DBCC7E00DDFD32 /* crypto-primegen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-primegen.c\"; sourceTree = \"<group>\"; };\n\t\t11A921B917DBCC7E00DDFD32 /* crypto-primegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"crypto-primegen.h\"; sourceTree = \"<group>\"; };\n\t\t11A921BD17DBCC7E00DDFD32 /* rawsock-getif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-getif.c\"; sourceTree = \"<group>\"; };\n\t\t11A921BE17DBCC7E00DDFD32 /* rawsock-getip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-getip.c\"; sourceTree = \"<group>\"; };\n\t\t11A921BF17DBCC7E00DDFD32 /* rawsock-getmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-getmac.c\"; sourceTree = \"<group>\"; };\n\t\t11A921C017DBCC7E00DDFD32 /* rawsock-getroute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-getroute.c\"; sourceTree = \"<group>\"; };\n\t\t11A921C117DBCC7E00DDFD32 /* rawsock-pcapfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rawsock-pcapfile.c\"; sourceTree = \"<group>\"; };\n\t\t11A921C217DBCC7E00DDFD32 /* rawsock-pcapfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"rawsock-pcapfile.h\"; sourceTree = \"<group>\"; };\n\t\t11A921C517DBCC7E00DDFD32 /* rawsock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rawsock.c; sourceTree = \"<group>\"; };\n\t\t11A921C617DBCC7E00DDFD32 /* rawsock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rawsock.h; sourceTree = \"<group>\"; };\n\t\t11A921C717DBCC7E00DDFD32 /* rte-ring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"rte-ring.c\"; sourceTree = \"<group>\"; };\n\t\t11A921C817DBCC7E00DDFD32 /* rte-ring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"rte-ring.h\"; sourceTree = \"<group>\"; };\n\t\t11A921C917DBCC7E00DDFD32 /* smack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smack.h; sourceTree = \"<group>\"; };\n\t\t11A921CA17DBCC7E00DDFD32 /* smack1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smack1.c; sourceTree = \"<group>\"; };\n\t\t11A921CB17DBCC7E00DDFD32 /* smackqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smackqueue.c; sourceTree = \"<group>\"; };\n\t\t11A921CC17DBCC7E00DDFD32 /* smackqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smackqueue.h; sourceTree = \"<group>\"; };\n\t\t11A921CD17DBCC7E00DDFD32 /* util-safefunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"util-safefunc.c\"; sourceTree = \"<group>\"; };\n\t\t11A921CE17DBCC7E00DDFD32 /* util-safefunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"util-safefunc.h\"; sourceTree = \"<group>\"; };\n\t\t11A921CF17DBCC7E00DDFD32 /* syn-cookie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"syn-cookie.c\"; sourceTree = \"<group>\"; };\n\t\t11A921D017DBCC7E00DDFD32 /* syn-cookie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"syn-cookie.h\"; sourceTree = \"<group>\"; };\n\t\t11A921D117DBCC7E00DDFD32 /* templ-pkt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"templ-pkt.c\"; sourceTree = \"<group>\"; };\n\t\t11A921D217DBCC7E00DDFD32 /* templ-pkt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"templ-pkt.h\"; sourceTree = \"<group>\"; };\n\t\t11A921D317DBCC7E00DDFD32 /* xring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xring.c; sourceTree = \"<group>\"; };\n\t\t11A921D417DBCC7E00DDFD32 /* xring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xring.h; sourceTree = \"<group>\"; };\n\t\t11A921FB17DBD17600DDFD32 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = \"<group>\"; };\n\t\t11AC2F99188CE34A008CB623 /* proto-sctp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-sctp.c\"; sourceTree = \"<group>\"; };\n\t\t11AC2F9A188CE34A008CB623 /* proto-sctp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-sctp.h\"; sourceTree = \"<group>\"; };\n\t\t11AC80E717E0DAD4001BCE3A /* proto-http.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-http.c\"; sourceTree = \"<group>\"; };\n\t\t11AC80E817E0DAD4001BCE3A /* proto-http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-http.h\"; sourceTree = \"<group>\"; };\n\t\t11AC80E917E0DAD4001BCE3A /* proto-icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-icmp.c\"; sourceTree = \"<group>\"; };\n\t\t11AC80EA17E0DAD4001BCE3A /* proto-icmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-icmp.h\"; sourceTree = \"<group>\"; };\n\t\t11AC80EB17E0DAD4001BCE3A /* proto-ssh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ssh.c\"; sourceTree = \"<group>\"; };\n\t\t11AC80EC17E0DAD4001BCE3A /* proto-ssh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-ssh.h\"; sourceTree = \"<group>\"; };\n\t\t11AC80F517E0ED47001BCE3A /* main-ptrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-ptrace.c\"; sourceTree = \"<group>\"; };\n\t\t11AC80F817E0EDA7001BCE3A /* main-ptrace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"main-ptrace.h\"; sourceTree = \"<group>\"; };\n\t\t11B039C017E506B400925E7E /* main-listscan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-listscan.c\"; sourceTree = \"<group>\"; };\n\t\t11B039C317E7834000925E7E /* proto-dns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-dns.c\"; sourceTree = \"<group>\"; };\n\t\t11B039C417E7834000925E7E /* proto-dns.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-dns.h\"; sourceTree = \"<group>\"; };\n\t\t11B039C517E7834000925E7E /* proto-udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-udp.c\"; sourceTree = \"<group>\"; };\n\t\t11B039C617E7834000925E7E /* proto-udp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-udp.h\"; sourceTree = \"<group>\"; };\n\t\t11B039C917EA092B00925E7E /* proto-snmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-snmp.c\"; sourceTree = \"<group>\"; };\n\t\t11B039CA17EA092B00925E7E /* proto-snmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-snmp.h\"; sourceTree = \"<group>\"; };\n\t\t11B05EA418B9649F009C935E /* crypto-blackrock2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"crypto-blackrock2.c\"; sourceTree = \"<group>\"; };\n\t\t11B05EA518B9649F009C935E /* main-readrange.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"main-readrange.c\"; sourceTree = \"<group>\"; };\n\t\t11B05EA918B964A9009C935E /* main-readrange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"main-readrange.h\"; sourceTree = \"<group>\"; };\n\t\t11B22ED018641DCC00DA5438 /* proto-banout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-banout.c\"; sourceTree = \"<group>\"; };\n\t\t11B22ED118641DCC00DA5438 /* proto-banout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-banout.h\"; sourceTree = \"<group>\"; };\n\t\t11B22ED218641DCC00DA5438 /* proto-ssl-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ssl-test.c\"; sourceTree = \"<group>\"; };\n\t\t11B22ED318641DCC00DA5438 /* proto-x509.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-x509.c\"; sourceTree = \"<group>\"; };\n\t\t11B22ED418641DCC00DA5438 /* proto-x509.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-x509.h\"; sourceTree = \"<group>\"; };\n\t\t11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"templ-payloads.c\"; sourceTree = \"<group>\"; };\n\t\t11B2DD9D17DE4DD8007FC363 /* templ-payloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"templ-payloads.h\"; sourceTree = \"<group>\"; };\n\t\t11B5897C21C0785B00DD6248 /* util-malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"util-malloc.h\"; sourceTree = \"<group>\"; };\n\t\t11B5897D21C0785B00DD6248 /* util-malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"util-malloc.c\"; sourceTree = \"<group>\"; };\n\t\t11B6297525995AA100D4786F /* stack-queue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-queue.c\"; sourceTree = \"<group>\"; };\n\t\t11B6297625995AA100D4786F /* stack-ndpv6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stack-ndpv6.c\"; sourceTree = \"<group>\"; };\n\t\t11B6297725995AA100D4786F /* stack-queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-queue.h\"; sourceTree = \"<group>\"; };\n\t\t11B6297825995AA100D4786F /* stack-ndpv6.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-ndpv6.h\"; sourceTree = \"<group>\"; };\n\t\t11BA295E18902CEE0064A759 /* masscan-version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"masscan-version.h\"; sourceTree = \"<group>\"; };\n\t\t11BA295F18902CEE0064A759 /* out-grepable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-grepable.c\"; sourceTree = \"<group>\"; };\n\t\t11BA296018902CEE0064A759 /* proto-tcp-telnet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-tcp-telnet.c\"; sourceTree = \"<group>\"; };\n\t\t11BA296118902CEE0064A759 /* proto-tcp-telnet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-tcp-telnet.h\"; sourceTree = \"<group>\"; };\n\t\t11BA296A189060220064A759 /* proto-ntp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-ntp.c\"; sourceTree = \"<group>\"; };\n\t\t11BA296C189060590064A759 /* proto-ntp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"proto-ntp.h\"; sourceTree = \"<group>\"; };\n\t\t11BE532E25A62C4100451F95 /* massip-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"massip-port.h\"; sourceTree = \"<group>\"; };\n\t\t11BE533425A6441100451F95 /* massip-addr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"massip-addr.h\"; sourceTree = \"<group>\"; };\n\t\t11BE533525A6441100451F95 /* massip-addr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"massip-addr.c\"; sourceTree = \"<group>\"; };\n\t\t11C000632AFDA178001EB0EB /* proto-isakmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-isakmp.c\"; sourceTree = \"<group>\"; };\n\t\t11C000642AFDA179001EB0EB /* proto-isakmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-isakmp.h\"; sourceTree = \"<group>\"; };\n\t\t11C000672B01CB16001EB0EB /* stack-tcp-app.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stack-tcp-app.h\"; sourceTree = \"<group>\"; };\n\t\t11C936BF1EDCE77F0023D32E /* in-filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"in-filter.c\"; sourceTree = \"<group>\"; };\n\t\t11C936C01EDCE77F0023D32E /* in-filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"in-filter.h\"; sourceTree = \"<group>\"; };\n\t\t11C936C11EDCE77F0023D32E /* in-report.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"in-report.c\"; sourceTree = \"<group>\"; };\n\t\t11C936C21EDCE77F0023D32E /* in-report.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"in-report.h\"; sourceTree = \"<group>\"; };\n\t\t11D0FAF922763F4900332FA7 /* proto-coap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-coap.h\"; sourceTree = \"<group>\"; };\n\t\t11D0FAFA22763F4900332FA7 /* proto-coap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-coap.c\"; sourceTree = \"<group>\"; };\n\t\t11DD363221067BD300CBE1DE /* out-tcp-services.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"out-tcp-services.h\"; sourceTree = \"<group>\"; };\n\t\t11DD363321067BD300CBE1DE /* out-tcp-services.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"out-tcp-services.c\"; sourceTree = \"<group>\"; };\n\t\t11DD36362107DE9700CBE1DE /* stub-lua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"stub-lua.c\"; sourceTree = \"<group>\"; };\n\t\t11DD36372107DE9700CBE1DE /* stub-lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"stub-lua.h\"; sourceTree = \"<group>\"; };\n\t\t11DD36392107DFEB00CBE1DE /* scripting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scripting.h; sourceTree = \"<group>\"; };\n\t\t11DD363A2107DFEB00CBE1DE /* scripting.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scripting.c; sourceTree = \"<group>\"; };\n\t\t11DD363C2107E7ED00CBE1DE /* vulncheck-heartbleed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"vulncheck-heartbleed.c\"; sourceTree = \"<group>\"; };\n\t\t11DD363D2107E7ED00CBE1DE /* vulncheck-sslv3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"vulncheck-sslv3.c\"; sourceTree = \"<group>\"; };\n\t\t11DD363E2107E7ED00CBE1DE /* vulncheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulncheck.h; sourceTree = \"<group>\"; };\n\t\t11DD363F2107E7ED00CBE1DE /* vulncheck.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vulncheck.c; sourceTree = \"<group>\"; };\n\t\t11DD36402107E7ED00CBE1DE /* vulncheck-ntp-monlist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"vulncheck-ntp-monlist.c\"; sourceTree = \"<group>\"; };\n\t\t11DD36452107EB8700CBE1DE /* scripting-masscan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"scripting-masscan.c\"; sourceTree = \"<group>\"; };\n\t\t11DD36472108DCBB00CBE1DE /* proto-versioning.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-versioning.c\"; sourceTree = \"<group>\"; };\n\t\t11DD36482108DCBB00CBE1DE /* proto-versioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-versioning.h\"; sourceTree = \"<group>\"; };\n\t\t11DD364A2108E0CB00CBE1DE /* scripting-banner.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"scripting-banner.c\"; sourceTree = \"<group>\"; };\n\t\t11DE129420ABC2650041135D /* proto-smb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"proto-smb.h\"; sourceTree = \"<group>\"; };\n\t\t11DE129520ABC2650041135D /* proto-smb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"proto-smb.c\"; sourceTree = \"<group>\"; };\n\t\t11E76DB21889BC5200061F45 /* pixie-backtrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"pixie-backtrace.c\"; sourceTree = \"<group>\"; };\n\t\t11E76DB31889BC5200061F45 /* pixie-backtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"pixie-backtrace.h\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t118D68392B02DD6F00271F7F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t11A9218217DBCB3200DDFD32 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t112A9A0B258A89FC00D1EEBA /* massip */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11BE533525A6441100451F95 /* massip-addr.c */,\n\t\t\t\t11BE533425A6441100451F95 /* massip-addr.h */,\n\t\t\t\t11BE532E25A62C4100451F95 /* massip-port.h */,\n\t\t\t\t118B9B2F25A00FA900F5FB0B /* massip-parse.c */,\n\t\t\t\t118B9B3025A00FA900F5FB0B /* massip-parse.h */,\n\t\t\t\t118B9B2B25A00FA800F5FB0B /* massip-rangesv4.c */,\n\t\t\t\t118B9B2A25A00FA800F5FB0B /* massip-rangesv4.h */,\n\t\t\t\t118B9B2C25A00FA800F5FB0B /* massip-rangesv6.c */,\n\t\t\t\t118B9B2E25A00FA900F5FB0B /* massip-rangesv6.h */,\n\t\t\t\t118B9B3125A00FA900F5FB0B /* massip.c */,\n\t\t\t\t118B9B2D25A00FA900F5FB0B /* massip.h */,\n\t\t\t);\n\t\t\tname = massip;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t114147AC226BD4E1009F9E93 /* stubs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11DD36362107DE9700CBE1DE /* stub-lua.c */,\n\t\t\t\t11DD36372107DE9700CBE1DE /* stub-lua.h */,\n\t\t\t\t119969032141ABAC00E82767 /* stub-pcap.h */,\n\t\t\t\t119969022141ABAC00E82767 /* stub-pfring.h */,\n\t\t\t\t119968FF2141AB3600E82767 /* stub-pcap.c */,\n\t\t\t\t119968FE2141AB3600E82767 /* stub-pfring.c */,\n\t\t\t);\n\t\t\tname = stubs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t118E114E2585931800618314 /* stack */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11C000672B01CB16001EB0EB /* stack-tcp-app.h */,\n\t\t\t\t1124DD6D25B4FF3C00EEFC2C /* stack-arpv4.c */,\n\t\t\t\t1124DD6E25B4FF3C00EEFC2C /* stack-arpv4.h */,\n\t\t\t\t1124DD6C25B4FF3C00EEFC2C /* stack-if.c */,\n\t\t\t\t11B6297625995AA100D4786F /* stack-ndpv6.c */,\n\t\t\t\t11B6297825995AA100D4786F /* stack-ndpv6.h */,\n\t\t\t\t11B6297525995AA100D4786F /* stack-queue.c */,\n\t\t\t\t11B6297725995AA100D4786F /* stack-queue.h */,\n\t\t\t\t11A921B217DBCC7E00DDFD32 /* stack-tcp-core.c */,\n\t\t\t\t11A921B317DBCC7E00DDFD32 /* stack-tcp-core.h */,\n\t\t\t\t118E115325859D2400618314 /* stack-tcp-api.h */,\n\t\t\t\t11420DDF19A90CB300DB5BFE /* stack-tcp-app.c */,\n\t\t\t\t11A8680B1816F3A7008E00B8 /* stack-src.c */,\n\t\t\t\t11A8680C1816F3A7008E00B8 /* stack-src.h */,\n\t\t\t);\n\t\t\tname = stack;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t118E114F25859CFD00618314 /* util */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t118D683F2B06BB9900271F7F /* util-extract.c */,\n\t\t\t\t118D68402B06BB9900271F7F /* util-extract.h */,\n\t\t\t\t11A921CD17DBCC7E00DDFD32 /* util-safefunc.c */,\n\t\t\t\t11A921CE17DBCC7E00DDFD32 /* util-safefunc.h */,\n\t\t\t\t118D67C22B02CBA000271F7F /* util-errormsg.c */,\n\t\t\t\t118D67C12B02CBA000271F7F /* util-errormsg.h */,\n\t\t\t\t115C0CAA18035BC5004E6CD7 /* unusedparm.h */,\n\t\t\t\t11B5897C21C0785B00DD6248 /* util-malloc.h */,\n\t\t\t\t11B5897D21C0785B00DD6248 /* util-malloc.c */,\n\t\t\t\t118E115425859D5200618314 /* util-bool.h */,\n\t\t\t\t118E115525859D5300618314 /* util-checksum.c */,\n\t\t\t\t118E115625859D5300618314 /* util-checksum.h */,\n\t\t\t);\n\t\t\tname = util;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11A9217A17DBCB3200DDFD32 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11A921FB17DBD17600DDFD32 /* README.md */,\n\t\t\t\t11A9219217DBCC7E00DDFD32 /* src */,\n\t\t\t\t11A9218617DBCB3200DDFD32 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11A9218617DBCB3200DDFD32 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11A9218517DBCB3200DDFD32 /* masscan */,\n\t\t\t\t118D683E2B02DD6F00271F7F /* masscan copy */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11A9219217DBCC7E00DDFD32 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t118E114E2585931800618314 /* stack */,\n\t\t\t\t112A9A0B258A89FC00D1EEBA /* massip */,\n\t\t\t\t118E114F25859CFD00618314 /* util */,\n\t\t\t\t114147AC226BD4E1009F9E93 /* stubs */,\n\t\t\t\t11DD36352107DE8200CBE1DE /* scripting */,\n\t\t\t\t11B360CD1F90174B0020F3A3 /* misc */,\n\t\t\t\t11B360C71F90166D0020F3A3 /* rawsock */,\n\t\t\t\t11B360CC1F90170D0020F3A3 /* crypto */,\n\t\t\t\t11B360C81F90169F0020F3A3 /* main */,\n\t\t\t\t11B360C91F9016AD0020F3A3 /* out */,\n\t\t\t\t11B360CB1F9016D80020F3A3 /* pixie */,\n\t\t\t\t11B360CA1F9016C00020F3A3 /* proto */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = ../src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360C71F90166D0020F3A3 /* rawsock */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t118E115825859E6F00618314 /* rawsock-getip6.c */,\n\t\t\t\t11A921C617DBCC7E00DDFD32 /* rawsock.h */,\n\t\t\t\t11A921C517DBCC7E00DDFD32 /* rawsock.c */,\n\t\t\t\t116806EA1995D421005B0980 /* rawsock-adapter.h */,\n\t\t\t\t11A921BD17DBCC7E00DDFD32 /* rawsock-getif.c */,\n\t\t\t\t11A921BE17DBCC7E00DDFD32 /* rawsock-getip.c */,\n\t\t\t\t11A921BF17DBCC7E00DDFD32 /* rawsock-getmac.c */,\n\t\t\t\t11A921C017DBCC7E00DDFD32 /* rawsock-getroute.c */,\n\t\t\t\t11A921C117DBCC7E00DDFD32 /* rawsock-pcapfile.c */,\n\t\t\t\t11A921C217DBCC7E00DDFD32 /* rawsock-pcapfile.h */,\n\t\t\t);\n\t\t\tname = rawsock;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360C81F90169F0020F3A3 /* main */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t119968FD21388A5300E82767 /* read-service-probes.h */,\n\t\t\t\t119968FB21388A3B00E82767 /* read-service-probes.c */,\n\t\t\t\t11A8680D1816F3A7008E00B8 /* masscan-app.c */,\n\t\t\t\t11A8680E1816F3A7008E00B8 /* masscan-app.h */,\n\t\t\t\t113AD3B818208A1900D5E067 /* masscan-status.h */,\n\t\t\t\t11BA295E18902CEE0064A759 /* masscan-version.h */,\n\t\t\t\t11A921A017DBCC7E00DDFD32 /* masscan.h */,\n\t\t\t\t11A9219717DBCC7E00DDFD32 /* main-conf.c */,\n\t\t\t\t11A9219817DBCC7E00DDFD32 /* main-dedup.c */,\n\t\t\t\t11A9219917DBCC7E00DDFD32 /* main-dedup.h */,\n\t\t\t\t11A8680A1816F3A7008E00B8 /* main-globals.h */,\n\t\t\t\t11A9219A17DBCC7E00DDFD32 /* main-initadapter.c */,\n\t\t\t\t11B039C017E506B400925E7E /* main-listscan.c */,\n\t\t\t\t11AC80F517E0ED47001BCE3A /* main-ptrace.c */,\n\t\t\t\t11AC80F817E0EDA7001BCE3A /* main-ptrace.h */,\n\t\t\t\t11B05EA518B9649F009C935E /* main-readrange.c */,\n\t\t\t\t11B05EA918B964A9009C935E /* main-readrange.h */,\n\t\t\t\t11A9219B17DBCC7E00DDFD32 /* main-status.c */,\n\t\t\t\t11A9219C17DBCC7E00DDFD32 /* main-status.h */,\n\t\t\t\t11A9219D17DBCC7E00DDFD32 /* main-throttle.c */,\n\t\t\t\t11A9219E17DBCC7E00DDFD32 /* main-throttle.h */,\n\t\t\t\t11A9219F17DBCC7E00DDFD32 /* main.c */,\n\t\t\t);\n\t\t\tname = main;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360C91F9016AD0020F3A3 /* out */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t1124DD6A25B4FF1600EEFC2C /* out-hostonly.c */,\n\t\t\t\t11DD363321067BD300CBE1DE /* out-tcp-services.c */,\n\t\t\t\t11DD363221067BD300CBE1DE /* out-tcp-services.h */,\n\t\t\t\t112A87191F9D8DF200D4D240 /* out-ndjson.c */,\n\t\t\t\t11623F69191E0DB00075EEE6 /* out-certs.c */,\n\t\t\t\t11A868081816F3A7008E00B8 /* in-binary.c */,\n\t\t\t\t11A868091816F3A7008E00B8 /* in-binary.h */,\n\t\t\t\t11C936BF1EDCE77F0023D32E /* in-filter.c */,\n\t\t\t\t11C936C01EDCE77F0023D32E /* in-filter.h */,\n\t\t\t\t11C936C11EDCE77F0023D32E /* in-report.c */,\n\t\t\t\t11C936C21EDCE77F0023D32E /* in-report.h */,\n\t\t\t\t11126596197A086B00DC5987 /* out-unicornscan.c */,\n\t\t\t\t11A921A117DBCC7E00DDFD32 /* out-binary.c */,\n\t\t\t\t11BA295F18902CEE0064A759 /* out-grepable.c */,\n\t\t\t\t11A50CAD191C128F006D5802 /* out-json.c */,\n\t\t\t\t11A921A217DBCC7E00DDFD32 /* out-null.c */,\n\t\t\t\t115C0CA318035BC5004E6CD7 /* out-record.h */,\n\t\t\t\t11A8680F1816F3A7008E00B8 /* out-redis.c */,\n\t\t\t\t11A921A317DBCC7E00DDFD32 /* out-text.c */,\n\t\t\t\t11A921A417DBCC7E00DDFD32 /* out-xml.c */,\n\t\t\t\t11A921A517DBCC7E00DDFD32 /* output.c */,\n\t\t\t\t11A921A617DBCC7E00DDFD32 /* output.h */,\n\t\t\t);\n\t\t\tname = out;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360CA1F9016C00020F3A3 /* proto */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11DD36482108DCBB00CBE1DE /* proto-versioning.h */,\n\t\t\t\t11DD36472108DCBB00CBE1DE /* proto-versioning.c */,\n\t\t\t\t11A921AC17DBCC7E00DDFD32 /* proto-arp.c */,\n\t\t\t\t11A921AD17DBCC7E00DDFD32 /* proto-arp.h */,\n\t\t\t\t11A921AE17DBCC7E00DDFD32 /* proto-banner1.c */,\n\t\t\t\t11A921AF17DBCC7E00DDFD32 /* proto-banner1.h */,\n\t\t\t\t11B22ED018641DCC00DA5438 /* proto-banout.c */,\n\t\t\t\t11B22ED118641DCC00DA5438 /* proto-banout.h */,\n\t\t\t\t11D0FAFA22763F4900332FA7 /* proto-coap.c */,\n\t\t\t\t11D0FAF922763F4900332FA7 /* proto-coap.h */,\n\t\t\t\t115C0CA418035BC5004E6CD7 /* proto-dns-parse.h */,\n\t\t\t\t11B039C317E7834000925E7E /* proto-dns.c */,\n\t\t\t\t11B039C417E7834000925E7E /* proto-dns.h */,\n\t\t\t\t11420DD719A8160500DB5BFE /* proto-ftp.c */,\n\t\t\t\t11420DD619A815CD00DB5BFE /* proto-ftp.h */,\n\t\t\t\t11AC80E717E0DAD4001BCE3A /* proto-http.c */,\n\t\t\t\t11AC80E817E0DAD4001BCE3A /* proto-http.h */,\n\t\t\t\t11AC80E917E0DAD4001BCE3A /* proto-icmp.c */,\n\t\t\t\t11AC80EA17E0DAD4001BCE3A /* proto-icmp.h */,\n\t\t\t\t11420DE219A9363A00DB5BFE /* proto-imap4.c */,\n\t\t\t\t11420DE119A9361500DB5BFE /* proto-imap4.h */,\n\t\t\t\t11C000632AFDA178001EB0EB /* proto-isakmp.c */,\n\t\t\t\t11C000642AFDA179001EB0EB /* proto-isakmp.h */,\n\t\t\t\t1155CF0F2AF2FE12001B235A /* proto-mc.c */,\n\t\t\t\t1155CF0E2AF2FE12001B235A /* proto-mc.h */,\n\t\t\t\t119AB2042051FFED008E4DDD /* proto-memcached.c */,\n\t\t\t\t119AB2052051FFED008E4DDD /* proto-memcached.h */,\n\t\t\t\t115C0CA518035BC5004E6CD7 /* proto-netbios.c */,\n\t\t\t\t115C0CA618035BC5004E6CD7 /* proto-netbios.h */,\n\t\t\t\t110ED16720CB0BC200690C91 /* proto-ntlmssp.c */,\n\t\t\t\t110ED16620CB0BC200690C91 /* proto-ntlmssp.h */,\n\t\t\t\t11BA296A189060220064A759 /* proto-ntp.c */,\n\t\t\t\t11BA296C189060590064A759 /* proto-ntp.h */,\n\t\t\t\t110C79AF22833AF9003FAC94 /* proto-oproto.c */,\n\t\t\t\t110C79AE22833AF9003FAC94 /* proto-oproto.h */,\n\t\t\t\t11420DDD19A8FDE300DB5BFE /* proto-pop3.c */,\n\t\t\t\t11420DDC19A8F2D200DB5BFE /* proto-pop3.h */,\n\t\t\t\t11A921B017DBCC7E00DDFD32 /* proto-preprocess.c */,\n\t\t\t\t11A921B117DBCC7E00DDFD32 /* proto-preprocess.h */,\n\t\t\t\t11AC2F99188CE34A008CB623 /* proto-sctp.c */,\n\t\t\t\t11AC2F9A188CE34A008CB623 /* proto-sctp.h */,\n\t\t\t\t11DE129520ABC2650041135D /* proto-smb.c */,\n\t\t\t\t11DE129420ABC2650041135D /* proto-smb.h */,\n\t\t\t\t11420DDA19A84A9E00DB5BFE /* proto-smtp.c */,\n\t\t\t\t11420DD919A844B000DB5BFE /* proto-smtp.h */,\n\t\t\t\t11B039C917EA092B00925E7E /* proto-snmp.c */,\n\t\t\t\t11B039CA17EA092B00925E7E /* proto-snmp.h */,\n\t\t\t\t110ED16520CA6A8300690C91 /* proto-spnego.h */,\n\t\t\t\t11AC80EB17E0DAD4001BCE3A /* proto-ssh.c */,\n\t\t\t\t11AC80EC17E0DAD4001BCE3A /* proto-ssh.h */,\n\t\t\t\t11B22ED218641DCC00DA5438 /* proto-ssl-test.c */,\n\t\t\t\t115C0CA718035BC5004E6CD7 /* proto-ssl.c */,\n\t\t\t\t115C0CA818035BC5004E6CD7 /* proto-ssl.h */,\n\t\t\t\t1107E9B1228DF7BB003384B3 /* proto-tcp-rdp.c */,\n\t\t\t\t1107E9B0228DF7BB003384B3 /* proto-tcp-rdp.h */,\n\t\t\t\t11BA296018902CEE0064A759 /* proto-tcp-telnet.c */,\n\t\t\t\t11BA296118902CEE0064A759 /* proto-tcp-telnet.h */,\n\t\t\t\t11B039C517E7834000925E7E /* proto-udp.c */,\n\t\t\t\t11B039C617E7834000925E7E /* proto-udp.h */,\n\t\t\t\t11420DD219A2D47A00DB5BFE /* proto-vnc.c */,\n\t\t\t\t11420DD519A2D48C00DB5BFE /* proto-vnc.h */,\n\t\t\t\t11B22ED318641DCC00DA5438 /* proto-x509.c */,\n\t\t\t\t11B22ED418641DCC00DA5438 /* proto-x509.h */,\n\t\t\t\t11A8681C1819A6F7008E00B8 /* proto-zeroaccess.c */,\n\t\t\t\t11A8681D1819A6F7008E00B8 /* proto-zeroaccess.h */,\n\t\t\t\t1155CF112AF6EF72001B235A /* templ-nmap-payloads.c */,\n\t\t\t\t1155CF122AF6EF72001B235A /* templ-nmap-payloads.h */,\n\t\t\t\t1155CF172AF8509A001B235A /* templ-opts.h */,\n\t\t\t\t11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */,\n\t\t\t\t11B2DD9D17DE4DD8007FC363 /* templ-payloads.h */,\n\t\t\t\t11A921D117DBCC7E00DDFD32 /* templ-pkt.c */,\n\t\t\t\t11A921D217DBCC7E00DDFD32 /* templ-pkt.h */,\n\t\t\t\t1155CF152AF8311C001B235A /* templ-tcp-hdr.c */,\n\t\t\t\t1155CF142AF8311C001B235A /* templ-tcp-hdr.h */,\n\t\t\t);\n\t\t\tname = proto;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360CB1F9016D80020F3A3 /* pixie */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11E76DB21889BC5200061F45 /* pixie-backtrace.c */,\n\t\t\t\t11E76DB31889BC5200061F45 /* pixie-backtrace.h */,\n\t\t\t\t11A868101816F3A7008E00B8 /* pixie-file.c */,\n\t\t\t\t11A868111816F3A7008E00B8 /* pixie-file.h */,\n\t\t\t\t11A868121816F3A7008E00B8 /* pixie-sockets.h */,\n\t\t\t\t11A921A817DBCC7E00DDFD32 /* pixie-threads.c */,\n\t\t\t\t11A921A917DBCC7E00DDFD32 /* pixie-threads.h */,\n\t\t\t\t11A921AA17DBCC7E00DDFD32 /* pixie-timer.c */,\n\t\t\t\t11A921AB17DBCC7E00DDFD32 /* pixie-timer.h */,\n\t\t\t);\n\t\t\tname = pixie;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360CC1F90170D0020F3A3 /* crypto */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11A773E91881BFC700B135DE /* crypto-base64.c */,\n\t\t\t\t11A773EA1881BFC700B135DE /* crypto-base64.h */,\n\t\t\t\t11B05EA418B9649F009C935E /* crypto-blackrock2.c */,\n\t\t\t\t11A921B417DBCC7E00DDFD32 /* crypto-blackrock.c */,\n\t\t\t\t11A921B517DBCC7E00DDFD32 /* crypto-blackrock.h */,\n\t\t\t\t11A921B617DBCC7E00DDFD32 /* crypto-lcg.c */,\n\t\t\t\t11A921B717DBCC7E00DDFD32 /* crypto-lcg.h */,\n\t\t\t\t11A921B817DBCC7E00DDFD32 /* crypto-primegen.c */,\n\t\t\t\t11A921B917DBCC7E00DDFD32 /* crypto-primegen.h */,\n\t\t\t\t11A868131816F3A7008E00B8 /* crypto-siphash24.c */,\n\t\t\t\t11A868141816F3A7008E00B8 /* crypto-siphash24.h */,\n\t\t\t\t11A921CF17DBCC7E00DDFD32 /* syn-cookie.c */,\n\t\t\t\t11A921D017DBCC7E00DDFD32 /* syn-cookie.h */,\n\t\t\t);\n\t\t\tname = crypto;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11B360CD1F90174B0020F3A3 /* misc */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11469CA12295D80A00FA76BE /* misc-rstfilter.c */,\n\t\t\t\t11469CA02295D80A00FA76BE /* misc-rstfilter.h */,\n\t\t\t\t11A921D317DBCC7E00DDFD32 /* xring.c */,\n\t\t\t\t11A921D417DBCC7E00DDFD32 /* xring.h */,\n\t\t\t\t11A921C717DBCC7E00DDFD32 /* rte-ring.c */,\n\t\t\t\t11A921C817DBCC7E00DDFD32 /* rte-ring.h */,\n\t\t\t\t11A921C917DBCC7E00DDFD32 /* smack.h */,\n\t\t\t\t11A921CA17DBCC7E00DDFD32 /* smack1.c */,\n\t\t\t\t11A921CB17DBCC7E00DDFD32 /* smackqueue.c */,\n\t\t\t\t11A921CC17DBCC7E00DDFD32 /* smackqueue.h */,\n\t\t\t\t11A9219317DBCC7E00DDFD32 /* event-timeout.c */,\n\t\t\t\t11A9219417DBCC7E00DDFD32 /* event-timeout.h */,\n\t\t\t\t11A9219517DBCC7E00DDFD32 /* util-logger.c */,\n\t\t\t\t11A9219617DBCC7E00DDFD32 /* util-logger.h */,\n\t\t\t);\n\t\t\tname = misc;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t11DD36352107DE8200CBE1DE /* scripting */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t11DD364A2108E0CB00CBE1DE /* scripting-banner.c */,\n\t\t\t\t11DD36452107EB8700CBE1DE /* scripting-masscan.c */,\n\t\t\t\t11DD363C2107E7ED00CBE1DE /* vulncheck-heartbleed.c */,\n\t\t\t\t11DD36402107E7ED00CBE1DE /* vulncheck-ntp-monlist.c */,\n\t\t\t\t11DD363D2107E7ED00CBE1DE /* vulncheck-sslv3.c */,\n\t\t\t\t11DD363F2107E7ED00CBE1DE /* vulncheck.c */,\n\t\t\t\t11DD363E2107E7ED00CBE1DE /* vulncheck.h */,\n\t\t\t\t11DD363A2107DFEB00CBE1DE /* scripting.c */,\n\t\t\t\t11DD36392107DFEB00CBE1DE /* scripting.h */,\n\t\t\t);\n\t\t\tname = scripting;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t118D67C52B02DD6F00271F7F /* masscan copy */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 118D683B2B02DD6F00271F7F /* Build configuration list for PBXNativeTarget \"masscan copy\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t118D67C62B02DD6F00271F7F /* Sources */,\n\t\t\t\t118D68392B02DD6F00271F7F /* Frameworks */,\n\t\t\t\t118D683A2B02DD6F00271F7F /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"masscan copy\";\n\t\t\tproductName = xcode4;\n\t\t\tproductReference = 118D683E2B02DD6F00271F7F /* masscan copy */;\n\t\t\tproductType = \"com.apple.product-type.tool\";\n\t\t};\n\t\t11A9218417DBCB3200DDFD32 /* masscan */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 11A9218F17DBCB3200DDFD32 /* Build configuration list for PBXNativeTarget \"masscan\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t11A9218117DBCB3200DDFD32 /* Sources */,\n\t\t\t\t11A9218217DBCB3200DDFD32 /* Frameworks */,\n\t\t\t\t11A9218317DBCB3200DDFD32 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = masscan;\n\t\t\tproductName = xcode4;\n\t\t\tproductReference = 11A9218517DBCB3200DDFD32 /* masscan */;\n\t\t\tproductType = \"com.apple.product-type.tool\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t11A9217C17DBCB3200DDFD32 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0430;\n\t\t\t};\n\t\t\tbuildConfigurationList = 11A9217F17DBCB3200DDFD32 /* Build configuration list for PBXProject \"masscan\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tEnglish,\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = 11A9217A17DBCB3200DDFD32;\n\t\t\tproductRefGroup = 11A9218617DBCB3200DDFD32 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t11A9218417DBCB3200DDFD32 /* masscan */,\n\t\t\t\t118D67C52B02DD6F00271F7F /* masscan copy */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t118D67C62B02DD6F00271F7F /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t118D67C72B02DD6F00271F7F /* stack-queue.c in Sources */,\n\t\t\t\t118D67C82B02DD6F00271F7F /* event-timeout.c in Sources */,\n\t\t\t\t118D67C92B02DD6F00271F7F /* vulncheck-heartbleed.c in Sources */,\n\t\t\t\t118D67CA2B02DD6F00271F7F /* massip-rangesv6.c in Sources */,\n\t\t\t\t118D67CB2B02DD6F00271F7F /* util-logger.c in Sources */,\n\t\t\t\t118D67CC2B02DD6F00271F7F /* stub-pfring.c in Sources */,\n\t\t\t\t118D67CD2B02DD6F00271F7F /* main-conf.c in Sources */,\n\t\t\t\t118D67CE2B02DD6F00271F7F /* main-dedup.c in Sources */,\n\t\t\t\t118D67CF2B02DD6F00271F7F /* main-initadapter.c in Sources */,\n\t\t\t\t118D67D02B02DD6F00271F7F /* main-status.c in Sources */,\n\t\t\t\t118D67D12B02DD6F00271F7F /* rawsock-getip6.c in Sources */,\n\t\t\t\t118D67D22B02DD6F00271F7F /* main-throttle.c in Sources */,\n\t\t\t\t118D67D32B02DD6F00271F7F /* main.c in Sources */,\n\t\t\t\t118D67D42B02DD6F00271F7F /* vulncheck-sslv3.c in Sources */,\n\t\t\t\t118D67D52B02DD6F00271F7F /* out-binary.c in Sources */,\n\t\t\t\t118D67D62B02DD6F00271F7F /* out-null.c in Sources */,\n\t\t\t\t118D67D72B02DD6F00271F7F /* proto-ntlmssp.c in Sources */,\n\t\t\t\t118D67D82B02DD6F00271F7F /* out-text.c in Sources */,\n\t\t\t\t118D67D92B02DD6F00271F7F /* out-xml.c in Sources */,\n\t\t\t\t118D67DA2B02DD6F00271F7F /* output.c in Sources */,\n\t\t\t\t118D67DB2B02DD6F00271F7F /* pixie-threads.c in Sources */,\n\t\t\t\t118D67DC2B02DD6F00271F7F /* pixie-timer.c in Sources */,\n\t\t\t\t118D67DD2B02DD6F00271F7F /* read-service-probes.c in Sources */,\n\t\t\t\t118D67DE2B02DD6F00271F7F /* proto-arp.c in Sources */,\n\t\t\t\t118D67DF2B02DD6F00271F7F /* proto-banner1.c in Sources */,\n\t\t\t\t118D67E02B02DD6F00271F7F /* stub-pcap.c in Sources */,\n\t\t\t\t118D67E12B02DD6F00271F7F /* proto-tcp-rdp.c in Sources */,\n\t\t\t\t118D67E22B02DD6F00271F7F /* proto-preprocess.c in Sources */,\n\t\t\t\t118D67E32B02DD6F00271F7F /* stack-tcp-core.c in Sources */,\n\t\t\t\t118D67E42B02DD6F00271F7F /* crypto-blackrock.c in Sources */,\n\t\t\t\t118D67E52B02DD6F00271F7F /* crypto-lcg.c in Sources */,\n\t\t\t\t118D67E62B02DD6F00271F7F /* crypto-primegen.c in Sources */,\n\t\t\t\t118D68422B06C1FA00271F7F /* util-extract.c in Sources */,\n\t\t\t\t118D67E72B02DD6F00271F7F /* rawsock-getif.c in Sources */,\n\t\t\t\t118D67E82B02DD6F00271F7F /* rawsock-getip.c in Sources */,\n\t\t\t\t118D67E92B02DD6F00271F7F /* proto-isakmp.c in Sources */,\n\t\t\t\t118D67EA2B02DD6F00271F7F /* templ-tcp-hdr.c in Sources */,\n\t\t\t\t118D67EB2B02DD6F00271F7F /* rawsock-getmac.c in Sources */,\n\t\t\t\t118D67EC2B02DD6F00271F7F /* util-malloc.c in Sources */,\n\t\t\t\t118D67ED2B02DD6F00271F7F /* rawsock-getroute.c in Sources */,\n\t\t\t\t118D67EE2B02DD6F00271F7F /* proto-versioning.c in Sources */,\n\t\t\t\t118D67EF2B02DD6F00271F7F /* proto-coap.c in Sources */,\n\t\t\t\t118D67F02B02DD6F00271F7F /* in-report.c in Sources */,\n\t\t\t\t118D67F12B02DD6F00271F7F /* rawsock-pcapfile.c in Sources */,\n\t\t\t\t118D67F22B02DD6F00271F7F /* rawsock.c in Sources */,\n\t\t\t\t118D67F32B02DD6F00271F7F /* scripting-banner.c in Sources */,\n\t\t\t\t118D67F42B02DD6F00271F7F /* rte-ring.c in Sources */,\n\t\t\t\t118D67F52B02DD6F00271F7F /* smack1.c in Sources */,\n\t\t\t\t118D67F62B02DD6F00271F7F /* massip-rangesv4.c in Sources */,\n\t\t\t\t118D67F72B02DD6F00271F7F /* smackqueue.c in Sources */,\n\t\t\t\t118D67F82B02DD6F00271F7F /* util-safefunc.c in Sources */,\n\t\t\t\t118D67F92B02DD6F00271F7F /* stack-ndpv6.c in Sources */,\n\t\t\t\t118D67FA2B02DD6F00271F7F /* syn-cookie.c in Sources */,\n\t\t\t\t118D67FB2B02DD6F00271F7F /* stack-arpv4.c in Sources */,\n\t\t\t\t118D67FC2B02DD6F00271F7F /* templ-nmap-payloads.c in Sources */,\n\t\t\t\t118D67FD2B02DD6F00271F7F /* util-errormsg.c in Sources */,\n\t\t\t\t118D67FE2B02DD6F00271F7F /* templ-pkt.c in Sources */,\n\t\t\t\t118D67FF2B02DD6F00271F7F /* xring.c in Sources */,\n\t\t\t\t118D68002B02DD6F00271F7F /* proto-smb.c in Sources */,\n\t\t\t\t118D68012B02DD6F00271F7F /* templ-payloads.c in Sources */,\n\t\t\t\t118D68022B02DD6F00271F7F /* proto-http.c in Sources */,\n\t\t\t\t118D68032B02DD6F00271F7F /* proto-icmp.c in Sources */,\n\t\t\t\t118D68042B02DD6F00271F7F /* proto-ssh.c in Sources */,\n\t\t\t\t118D68052B02DD6F00271F7F /* main-ptrace.c in Sources */,\n\t\t\t\t118D68062B02DD6F00271F7F /* proto-memcached.c in Sources */,\n\t\t\t\t118D68072B02DD6F00271F7F /* scripting-masscan.c in Sources */,\n\t\t\t\t118D68082B02DD6F00271F7F /* massip.c in Sources */,\n\t\t\t\t118D68092B02DD6F00271F7F /* proto-mc.c in Sources */,\n\t\t\t\t118D680A2B02DD6F00271F7F /* massip-addr.c in Sources */,\n\t\t\t\t118D680B2B02DD6F00271F7F /* main-listscan.c in Sources */,\n\t\t\t\t118D680C2B02DD6F00271F7F /* proto-dns.c in Sources */,\n\t\t\t\t118D680D2B02DD6F00271F7F /* proto-udp.c in Sources */,\n\t\t\t\t118D680E2B02DD6F00271F7F /* proto-snmp.c in Sources */,\n\t\t\t\t118D680F2B02DD6F00271F7F /* proto-netbios.c in Sources */,\n\t\t\t\t118D68102B02DD6F00271F7F /* vulncheck.c in Sources */,\n\t\t\t\t118D68112B02DD6F00271F7F /* proto-ssl.c in Sources */,\n\t\t\t\t118D68122B02DD6F00271F7F /* in-binary.c in Sources */,\n\t\t\t\t118D68132B02DD6F00271F7F /* stack-src.c in Sources */,\n\t\t\t\t118D68142B02DD6F00271F7F /* vulncheck-ntp-monlist.c in Sources */,\n\t\t\t\t118D68152B02DD6F00271F7F /* misc-rstfilter.c in Sources */,\n\t\t\t\t118D68162B02DD6F00271F7F /* masscan-app.c in Sources */,\n\t\t\t\t118D68172B02DD6F00271F7F /* out-redis.c in Sources */,\n\t\t\t\t118D68182B02DD6F00271F7F /* pixie-file.c in Sources */,\n\t\t\t\t118D68192B02DD6F00271F7F /* crypto-siphash24.c in Sources */,\n\t\t\t\t118D681A2B02DD6F00271F7F /* stack-if.c in Sources */,\n\t\t\t\t118D681B2B02DD6F00271F7F /* proto-zeroaccess.c in Sources */,\n\t\t\t\t118D681C2B02DD6F00271F7F /* proto-banout.c in Sources */,\n\t\t\t\t118D681D2B02DD6F00271F7F /* proto-ssl-test.c in Sources */,\n\t\t\t\t118D681E2B02DD6F00271F7F /* util-checksum.c in Sources */,\n\t\t\t\t118D681F2B02DD6F00271F7F /* proto-x509.c in Sources */,\n\t\t\t\t118D68202B02DD6F00271F7F /* crypto-base64.c in Sources */,\n\t\t\t\t118D68212B02DD6F00271F7F /* pixie-backtrace.c in Sources */,\n\t\t\t\t118D68222B02DD6F00271F7F /* proto-sctp.c in Sources */,\n\t\t\t\t118D68232B02DD6F00271F7F /* out-grepable.c in Sources */,\n\t\t\t\t118D68242B02DD6F00271F7F /* proto-tcp-telnet.c in Sources */,\n\t\t\t\t118D68252B02DD6F00271F7F /* proto-ntp.c in Sources */,\n\t\t\t\t118D68262B02DD6F00271F7F /* scripting.c in Sources */,\n\t\t\t\t118D68272B02DD6F00271F7F /* crypto-blackrock2.c in Sources */,\n\t\t\t\t118D68282B02DD6F00271F7F /* out-ndjson.c in Sources */,\n\t\t\t\t118D68292B02DD6F00271F7F /* main-readrange.c in Sources */,\n\t\t\t\t118D682A2B02DD6F00271F7F /* out-json.c in Sources */,\n\t\t\t\t118D682B2B02DD6F00271F7F /* out-certs.c in Sources */,\n\t\t\t\t118D682C2B02DD6F00271F7F /* out-unicornscan.c in Sources */,\n\t\t\t\t118D682D2B02DD6F00271F7F /* proto-vnc.c in Sources */,\n\t\t\t\t118D682E2B02DD6F00271F7F /* in-filter.c in Sources */,\n\t\t\t\t118D682F2B02DD6F00271F7F /* proto-ftp.c in Sources */,\n\t\t\t\t118D68302B02DD6F00271F7F /* proto-oproto.c in Sources */,\n\t\t\t\t118D68312B02DD6F00271F7F /* proto-smtp.c in Sources */,\n\t\t\t\t118D68322B02DD6F00271F7F /* out-tcp-services.c in Sources */,\n\t\t\t\t118D68332B02DD6F00271F7F /* proto-pop3.c in Sources */,\n\t\t\t\t118D68342B02DD6F00271F7F /* stack-tcp-app.c in Sources */,\n\t\t\t\t118D68352B02DD6F00271F7F /* proto-imap4.c in Sources */,\n\t\t\t\t118D68362B02DD6F00271F7F /* massip-parse.c in Sources */,\n\t\t\t\t118D68372B02DD6F00271F7F /* out-hostonly.c in Sources */,\n\t\t\t\t118D68382B02DD6F00271F7F /* stub-lua.c in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t11A9218117DBCB3200DDFD32 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t11B6297925995AA100D4786F /* stack-queue.c in Sources */,\n\t\t\t\t11A921D517DBCC7E00DDFD32 /* event-timeout.c in Sources */,\n\t\t\t\t11DD36412107E7ED00CBE1DE /* vulncheck-heartbleed.c in Sources */,\n\t\t\t\t118B9B3325A00FA900F5FB0B /* massip-rangesv6.c in Sources */,\n\t\t\t\t11A921D617DBCC7E00DDFD32 /* util-logger.c in Sources */,\n\t\t\t\t119969002141AB3600E82767 /* stub-pfring.c in Sources */,\n\t\t\t\t11A921D717DBCC7E00DDFD32 /* main-conf.c in Sources */,\n\t\t\t\t11A921D817DBCC7E00DDFD32 /* main-dedup.c in Sources */,\n\t\t\t\t11A921D917DBCC7E00DDFD32 /* main-initadapter.c in Sources */,\n\t\t\t\t11A921DA17DBCC7E00DDFD32 /* main-status.c in Sources */,\n\t\t\t\t118E115925859E6F00618314 /* rawsock-getip6.c in Sources */,\n\t\t\t\t11A921DB17DBCC7E00DDFD32 /* main-throttle.c in Sources */,\n\t\t\t\t11A921DC17DBCC7E00DDFD32 /* main.c in Sources */,\n\t\t\t\t11DD36422107E7ED00CBE1DE /* vulncheck-sslv3.c in Sources */,\n\t\t\t\t11A921DD17DBCC7E00DDFD32 /* out-binary.c in Sources */,\n\t\t\t\t11A921DE17DBCC7E00DDFD32 /* out-null.c in Sources */,\n\t\t\t\t110ED16820CB0BC200690C91 /* proto-ntlmssp.c in Sources */,\n\t\t\t\t11A921DF17DBCC7E00DDFD32 /* out-text.c in Sources */,\n\t\t\t\t11A921E017DBCC7E00DDFD32 /* out-xml.c in Sources */,\n\t\t\t\t11A921E117DBCC7E00DDFD32 /* output.c in Sources */,\n\t\t\t\t11A921E217DBCC7E00DDFD32 /* pixie-threads.c in Sources */,\n\t\t\t\t11A921E317DBCC7E00DDFD32 /* pixie-timer.c in Sources */,\n\t\t\t\t119968FC21388A3C00E82767 /* read-service-probes.c in Sources */,\n\t\t\t\t11A921E417DBCC7E00DDFD32 /* proto-arp.c in Sources */,\n\t\t\t\t11A921E517DBCC7E00DDFD32 /* proto-banner1.c in Sources */,\n\t\t\t\t119969012141AB3600E82767 /* stub-pcap.c in Sources */,\n\t\t\t\t1107E9B2228DF7BB003384B3 /* proto-tcp-rdp.c in Sources */,\n\t\t\t\t11A921E617DBCC7E00DDFD32 /* proto-preprocess.c in Sources */,\n\t\t\t\t11A921E717DBCC7E00DDFD32 /* stack-tcp-core.c in Sources */,\n\t\t\t\t11A921E817DBCC7E00DDFD32 /* crypto-blackrock.c in Sources */,\n\t\t\t\t11A921E917DBCC7E00DDFD32 /* crypto-lcg.c in Sources */,\n\t\t\t\t11A921EA17DBCC7E00DDFD32 /* crypto-primegen.c in Sources */,\n\t\t\t\t118D68412B06C1F900271F7F /* util-extract.c in Sources */,\n\t\t\t\t11A921ED17DBCC7E00DDFD32 /* rawsock-getif.c in Sources */,\n\t\t\t\t11A921EE17DBCC7E00DDFD32 /* rawsock-getip.c in Sources */,\n\t\t\t\t11C000652AFDA179001EB0EB /* proto-isakmp.c in Sources */,\n\t\t\t\t1155CF162AF8311C001B235A /* templ-tcp-hdr.c in Sources */,\n\t\t\t\t11A921EF17DBCC7E00DDFD32 /* rawsock-getmac.c in Sources */,\n\t\t\t\t11B5897E21C0785C00DD6248 /* util-malloc.c in Sources */,\n\t\t\t\t11A921F017DBCC7E00DDFD32 /* rawsock-getroute.c in Sources */,\n\t\t\t\t11DD36492108DCBB00CBE1DE /* proto-versioning.c in Sources */,\n\t\t\t\t11D0FAFB22763F4900332FA7 /* proto-coap.c in Sources */,\n\t\t\t\t11C936C41EDCE77F0023D32E /* in-report.c in Sources */,\n\t\t\t\t11A921F117DBCC7E00DDFD32 /* rawsock-pcapfile.c in Sources */,\n\t\t\t\t11A921F317DBCC7E00DDFD32 /* rawsock.c in Sources */,\n\t\t\t\t11DD364B2108E0CB00CBE1DE /* scripting-banner.c in Sources */,\n\t\t\t\t11A921F417DBCC7E00DDFD32 /* rte-ring.c in Sources */,\n\t\t\t\t11A921F517DBCC7E00DDFD32 /* smack1.c in Sources */,\n\t\t\t\t118B9B3225A00FA900F5FB0B /* massip-rangesv4.c in Sources */,\n\t\t\t\t11A921F617DBCC7E00DDFD32 /* smackqueue.c in Sources */,\n\t\t\t\t11A921F717DBCC7E00DDFD32 /* util-safefunc.c in Sources */,\n\t\t\t\t11B6297A25995AA100D4786F /* stack-ndpv6.c in Sources */,\n\t\t\t\t11A921F817DBCC7E00DDFD32 /* syn-cookie.c in Sources */,\n\t\t\t\t1124DD7025B4FF3C00EEFC2C /* stack-arpv4.c in Sources */,\n\t\t\t\t1155CF132AF6EF72001B235A /* templ-nmap-payloads.c in Sources */,\n\t\t\t\t118D67C42B02D58F00271F7F /* util-errormsg.c in Sources */,\n\t\t\t\t11A921F917DBCC7E00DDFD32 /* templ-pkt.c in Sources */,\n\t\t\t\t11A921FA17DBCC7E00DDFD32 /* xring.c in Sources */,\n\t\t\t\t11DE129620ABC2650041135D /* proto-smb.c in Sources */,\n\t\t\t\t11B2DD9E17DE4DD8007FC363 /* templ-payloads.c in Sources */,\n\t\t\t\t11AC80ED17E0DAD4001BCE3A /* proto-http.c in Sources */,\n\t\t\t\t11AC80EE17E0DAD4001BCE3A /* proto-icmp.c in Sources */,\n\t\t\t\t11AC80EF17E0DAD4001BCE3A /* proto-ssh.c in Sources */,\n\t\t\t\t11AC80F617E0ED47001BCE3A /* main-ptrace.c in Sources */,\n\t\t\t\t119AB2062051FFED008E4DDD /* proto-memcached.c in Sources */,\n\t\t\t\t11DD36462107EB8700CBE1DE /* scripting-masscan.c in Sources */,\n\t\t\t\t118B9B3525A00FA900F5FB0B /* massip.c in Sources */,\n\t\t\t\t1155CF102AF2FE12001B235A /* proto-mc.c in Sources */,\n\t\t\t\t11BE533625A6441100451F95 /* massip-addr.c in Sources */,\n\t\t\t\t11B039C117E506B400925E7E /* main-listscan.c in Sources */,\n\t\t\t\t11B039C717E7834000925E7E /* proto-dns.c in Sources */,\n\t\t\t\t11B039C817E7834000925E7E /* proto-udp.c in Sources */,\n\t\t\t\t11B039CB17EA092B00925E7E /* proto-snmp.c in Sources */,\n\t\t\t\t115C0CAB18035BC5004E6CD7 /* proto-netbios.c in Sources */,\n\t\t\t\t11DD36432107E7ED00CBE1DE /* vulncheck.c in Sources */,\n\t\t\t\t115C0CAC18035BC5004E6CD7 /* proto-ssl.c in Sources */,\n\t\t\t\t11A868151816F3A7008E00B8 /* in-binary.c in Sources */,\n\t\t\t\t11A868161816F3A7008E00B8 /* stack-src.c in Sources */,\n\t\t\t\t11DD36442107E7ED00CBE1DE /* vulncheck-ntp-monlist.c in Sources */,\n\t\t\t\t11469CA22295D80A00FA76BE /* misc-rstfilter.c in Sources */,\n\t\t\t\t11A868171816F3A7008E00B8 /* masscan-app.c in Sources */,\n\t\t\t\t11A868181816F3A7008E00B8 /* out-redis.c in Sources */,\n\t\t\t\t11A868191816F3A7008E00B8 /* pixie-file.c in Sources */,\n\t\t\t\t11A8681A1816F3A7008E00B8 /* crypto-siphash24.c in Sources */,\n\t\t\t\t1124DD6F25B4FF3C00EEFC2C /* stack-if.c in Sources */,\n\t\t\t\t11A8681E1819A6F7008E00B8 /* proto-zeroaccess.c in Sources */,\n\t\t\t\t11B22ED518641DCC00DA5438 /* proto-banout.c in Sources */,\n\t\t\t\t11B22ED618641DCC00DA5438 /* proto-ssl-test.c in Sources */,\n\t\t\t\t118E115725859D5300618314 /* util-checksum.c in Sources */,\n\t\t\t\t11B22ED718641DCC00DA5438 /* proto-x509.c in Sources */,\n\t\t\t\t11A773EB1881BFC700B135DE /* crypto-base64.c in Sources */,\n\t\t\t\t11E76DB41889BC5200061F45 /* pixie-backtrace.c in Sources */,\n\t\t\t\t11AC2F9B188CE34A008CB623 /* proto-sctp.c in Sources */,\n\t\t\t\t11BA296218902CEE0064A759 /* out-grepable.c in Sources */,\n\t\t\t\t11BA296318902CEE0064A759 /* proto-tcp-telnet.c in Sources */,\n\t\t\t\t11BA296B189060220064A759 /* proto-ntp.c in Sources */,\n\t\t\t\t11DD363B2107DFEB00CBE1DE /* scripting.c in Sources */,\n\t\t\t\t11B05EA618B9649F009C935E /* crypto-blackrock2.c in Sources */,\n\t\t\t\t112A871A1F9D8DF200D4D240 /* out-ndjson.c in Sources */,\n\t\t\t\t11B05EA718B9649F009C935E /* main-readrange.c in Sources */,\n\t\t\t\t11A50CAE191C128F006D5802 /* out-json.c in Sources */,\n\t\t\t\t11623F6A191E0DB00075EEE6 /* out-certs.c in Sources */,\n\t\t\t\t11126597197A086B00DC5987 /* out-unicornscan.c in Sources */,\n\t\t\t\t11420DD319A2D47A00DB5BFE /* proto-vnc.c in Sources */,\n\t\t\t\t11C936C31EDCE77F0023D32E /* in-filter.c in Sources */,\n\t\t\t\t11420DD819A8160500DB5BFE /* proto-ftp.c in Sources */,\n\t\t\t\t110C79B022833AFA003FAC94 /* proto-oproto.c in Sources */,\n\t\t\t\t11420DDB19A84A9F00DB5BFE /* proto-smtp.c in Sources */,\n\t\t\t\t11DD363421067BD400CBE1DE /* out-tcp-services.c in Sources */,\n\t\t\t\t11420DDE19A8FDE300DB5BFE /* proto-pop3.c in Sources */,\n\t\t\t\t11420DE019A90CB300DB5BFE /* stack-tcp-app.c in Sources */,\n\t\t\t\t11420DE319A9363B00DB5BFE /* proto-imap4.c in Sources */,\n\t\t\t\t118B9B3425A00FA900F5FB0B /* massip-parse.c in Sources */,\n\t\t\t\t1124DD6B25B4FF1600EEFC2C /* out-hostonly.c in Sources */,\n\t\t\t\t11DD36382107DE9700CBE1DE /* stub-lua.c in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t118D683C2B02DD6F00271F7F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;\n\t\t\t\tCONFIGURATION_BUILD_DIR = ../bin;\n\t\t\t\tCONFIGURATION_TEMP_DIR = ../tmp;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = NO;\n\t\t\t\tOBJROOT = ../tmp;\n\t\t\t\tOTHER_LDFLAGS = \"-lpcap\";\n\t\t\t\t\"OTHER_TEST_FLAGS[sdk=*]\" = \"--selftest\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tRUN_CLANG_STATIC_ANALYZER = YES;\n\t\t\t\tSYMROOT = ../bin;\n\t\t\t\tTEST_AFTER_BUILD = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t118D683D2B02DD6F00271F7F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;\n\t\t\t\tCONFIGURATION_BUILD_DIR = ../bin;\n\t\t\t\tCONFIGURATION_TEMP_DIR = ../tmp;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = NO;\n\t\t\t\tOBJROOT = ../tmp;\n\t\t\t\tOTHER_LDFLAGS = \"-lpcap\";\n\t\t\t\tOTHER_TEST_FLAGS = \"--selftest\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSYMROOT = ../bin;\n\t\t\t\tTEST_AFTER_BUILD = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t11A9218D17DBCB3200DDFD32 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD_64_BIT)\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.6;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t11A9218E17DBCB3200DDFD32 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD_64_BIT)\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.6;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t11A9219017DBCB3200DDFD32 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;\n\t\t\t\tCONFIGURATION_BUILD_DIR = ../bin;\n\t\t\t\tCONFIGURATION_TEMP_DIR = ../tmp;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = NO;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = NO;\n\t\t\t\tOBJROOT = ../tmp;\n\t\t\t\tOTHER_LDFLAGS = \"-lpcap\";\n\t\t\t\t\"OTHER_TEST_FLAGS[sdk=macosx*]\" = \"--selftest\";\n\t\t\t\tPRODUCT_NAME = masscan;\n\t\t\t\tRUN_CLANG_STATIC_ANALYZER = YES;\n\t\t\t\tSYMROOT = ../bin;\n\t\t\t\tTEST_AFTER_BUILD = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t11A9219117DBCB3200DDFD32 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;\n\t\t\t\tCONFIGURATION_BUILD_DIR = ../bin;\n\t\t\t\tCONFIGURATION_TEMP_DIR = ../tmp;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = NO;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = NO;\n\t\t\t\tOBJROOT = ../tmp;\n\t\t\t\tOTHER_LDFLAGS = \"-lpcap\";\n\t\t\t\tOTHER_TEST_FLAGS = \"--selftest\";\n\t\t\t\tPRODUCT_NAME = masscan;\n\t\t\t\tSYMROOT = ../bin;\n\t\t\t\tTEST_AFTER_BUILD = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t118D683B2B02DD6F00271F7F /* Build configuration list for PBXNativeTarget \"masscan copy\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t118D683C2B02DD6F00271F7F /* Debug */,\n\t\t\t\t118D683D2B02DD6F00271F7F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t11A9217F17DBCB3200DDFD32 /* Build configuration list for PBXProject \"masscan\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t11A9218D17DBCB3200DDFD32 /* Debug */,\n\t\t\t\t11A9218E17DBCB3200DDFD32 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t11A9218F17DBCB3200DDFD32 /* Build configuration list for PBXNativeTarget \"masscan\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t11A9219017DBCB3200DDFD32 /* Debug */,\n\t\t\t\t11A9219117DBCB3200DDFD32 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 11A9217C17DBCB3200DDFD32 /* Project object */;\n}\n"
  }
]