Compare commits
	
		
			No commits in common. "master" and "v1.2.2" have entirely different histories.
		
	
	
		
	
		
| @ -1,8 +0,0 @@ | |||||||
| { |  | ||||||
|   "bracketSpacing": true, |  | ||||||
|   "printWidth": 80, |  | ||||||
|   "singleQuote": true, |  | ||||||
|   "tabWidth": 4, |  | ||||||
|   "trailingComma": "none", |  | ||||||
|   "useTabs": true |  | ||||||
| } |  | ||||||
| @ -1,3 +0,0 @@ | |||||||
| v1.2.10 - Tested with dig.js, deployed to production with digd.js |  | ||||||
|     * Parses and packs common record types including: |  | ||||||
|         * A,AAAA,CAA,CNAME,MX,NS,PTR,SOA,SRV,TXT |  | ||||||
							
								
								
									
										375
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										375
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,375 +0,0 @@ | |||||||
| Copyright 2015-2019 AJ ONeal |  | ||||||
| 
 |  | ||||||
| Mozilla Public License Version 2.0 |  | ||||||
| ================================== |  | ||||||
| 
 |  | ||||||
| 1. Definitions |  | ||||||
| -------------- |  | ||||||
| 
 |  | ||||||
| 1.1. "Contributor" |  | ||||||
|     means each individual or legal entity that creates, contributes to |  | ||||||
|     the creation of, or owns Covered Software. |  | ||||||
| 
 |  | ||||||
| 1.2. "Contributor Version" |  | ||||||
|     means the combination of the Contributions of others (if any) used |  | ||||||
|     by a Contributor and that particular Contributor's Contribution. |  | ||||||
| 
 |  | ||||||
| 1.3. "Contribution" |  | ||||||
|     means Covered Software of a particular Contributor. |  | ||||||
| 
 |  | ||||||
| 1.4. "Covered Software" |  | ||||||
|     means Source Code Form to which the initial Contributor has attached |  | ||||||
|     the notice in Exhibit A, the Executable Form of such Source Code |  | ||||||
|     Form, and Modifications of such Source Code Form, in each case |  | ||||||
|     including portions thereof. |  | ||||||
| 
 |  | ||||||
| 1.5. "Incompatible With Secondary Licenses" |  | ||||||
|     means |  | ||||||
| 
 |  | ||||||
|     (a) that the initial Contributor has attached the notice described |  | ||||||
|         in Exhibit B to the Covered Software; or |  | ||||||
| 
 |  | ||||||
|     (b) that the Covered Software was made available under the terms of |  | ||||||
|         version 1.1 or earlier of the License, but not also under the |  | ||||||
|         terms of a Secondary License. |  | ||||||
| 
 |  | ||||||
| 1.6. "Executable Form" |  | ||||||
|     means any form of the work other than Source Code Form. |  | ||||||
| 
 |  | ||||||
| 1.7. "Larger Work" |  | ||||||
|     means a work that combines Covered Software with other material, in |  | ||||||
|     a separate file or files, that is not Covered Software. |  | ||||||
| 
 |  | ||||||
| 1.8. "License" |  | ||||||
|     means this document. |  | ||||||
| 
 |  | ||||||
| 1.9. "Licensable" |  | ||||||
|     means having the right to grant, to the maximum extent possible, |  | ||||||
|     whether at the time of the initial grant or subsequently, any and |  | ||||||
|     all of the rights conveyed by this License. |  | ||||||
| 
 |  | ||||||
| 1.10. "Modifications" |  | ||||||
|     means any of the following: |  | ||||||
| 
 |  | ||||||
|     (a) any file in Source Code Form that results from an addition to, |  | ||||||
|         deletion from, or modification of the contents of Covered |  | ||||||
|         Software; or |  | ||||||
| 
 |  | ||||||
|     (b) any new file in Source Code Form that contains any Covered |  | ||||||
|         Software. |  | ||||||
| 
 |  | ||||||
| 1.11. "Patent Claims" of a Contributor |  | ||||||
|     means any patent claim(s), including without limitation, method, |  | ||||||
|     process, and apparatus claims, in any patent Licensable by such |  | ||||||
|     Contributor that would be infringed, but for the grant of the |  | ||||||
|     License, by the making, using, selling, offering for sale, having |  | ||||||
|     made, import, or transfer of either its Contributions or its |  | ||||||
|     Contributor Version. |  | ||||||
| 
 |  | ||||||
| 1.12. "Secondary License" |  | ||||||
|     means either the GNU General Public License, Version 2.0, the GNU |  | ||||||
|     Lesser General Public License, Version 2.1, the GNU Affero General |  | ||||||
|     Public License, Version 3.0, or any later versions of those |  | ||||||
|     licenses. |  | ||||||
| 
 |  | ||||||
| 1.13. "Source Code Form" |  | ||||||
|     means the form of the work preferred for making modifications. |  | ||||||
| 
 |  | ||||||
| 1.14. "You" (or "Your") |  | ||||||
|     means an individual or a legal entity exercising rights under this |  | ||||||
|     License. For legal entities, "You" includes any entity that |  | ||||||
|     controls, is controlled by, or is under common control with You. For |  | ||||||
|     purposes of this definition, "control" means (a) the power, direct |  | ||||||
|     or indirect, to cause the direction or management of such entity, |  | ||||||
|     whether by contract or otherwise, or (b) ownership of more than |  | ||||||
|     fifty percent (50%) of the outstanding shares or beneficial |  | ||||||
|     ownership of such entity. |  | ||||||
| 
 |  | ||||||
| 2. License Grants and Conditions |  | ||||||
| -------------------------------- |  | ||||||
| 
 |  | ||||||
| 2.1. Grants |  | ||||||
| 
 |  | ||||||
| Each Contributor hereby grants You a world-wide, royalty-free, |  | ||||||
| non-exclusive license: |  | ||||||
| 
 |  | ||||||
| (a) under intellectual property rights (other than patent or trademark) |  | ||||||
|     Licensable by such Contributor to use, reproduce, make available, |  | ||||||
|     modify, display, perform, distribute, and otherwise exploit its |  | ||||||
|     Contributions, either on an unmodified basis, with Modifications, or |  | ||||||
|     as part of a Larger Work; and |  | ||||||
| 
 |  | ||||||
| (b) under Patent Claims of such Contributor to make, use, sell, offer |  | ||||||
|     for sale, have made, import, and otherwise transfer either its |  | ||||||
|     Contributions or its Contributor Version. |  | ||||||
| 
 |  | ||||||
| 2.2. Effective Date |  | ||||||
| 
 |  | ||||||
| The licenses granted in Section 2.1 with respect to any Contribution |  | ||||||
| become effective for each Contribution on the date the Contributor first |  | ||||||
| distributes such Contribution. |  | ||||||
| 
 |  | ||||||
| 2.3. Limitations on Grant Scope |  | ||||||
| 
 |  | ||||||
| The licenses granted in this Section 2 are the only rights granted under |  | ||||||
| this License. No additional rights or licenses will be implied from the |  | ||||||
| distribution or licensing of Covered Software under this License. |  | ||||||
| Notwithstanding Section 2.1(b) above, no patent license is granted by a |  | ||||||
| Contributor: |  | ||||||
| 
 |  | ||||||
| (a) for any code that a Contributor has removed from Covered Software; |  | ||||||
|     or |  | ||||||
| 
 |  | ||||||
| (b) for infringements caused by: (i) Your and any other third party's |  | ||||||
|     modifications of Covered Software, or (ii) the combination of its |  | ||||||
|     Contributions with other software (except as part of its Contributor |  | ||||||
|     Version); or |  | ||||||
| 
 |  | ||||||
| (c) under Patent Claims infringed by Covered Software in the absence of |  | ||||||
|     its Contributions. |  | ||||||
| 
 |  | ||||||
| This License does not grant any rights in the trademarks, service marks, |  | ||||||
| or logos of any Contributor (except as may be necessary to comply with |  | ||||||
| the notice requirements in Section 3.4). |  | ||||||
| 
 |  | ||||||
| 2.4. Subsequent Licenses |  | ||||||
| 
 |  | ||||||
| No Contributor makes additional grants as a result of Your choice to |  | ||||||
| distribute the Covered Software under a subsequent version of this |  | ||||||
| License (see Section 10.2) or under the terms of a Secondary License (if |  | ||||||
| permitted under the terms of Section 3.3). |  | ||||||
| 
 |  | ||||||
| 2.5. Representation |  | ||||||
| 
 |  | ||||||
| Each Contributor represents that the Contributor believes its |  | ||||||
| Contributions are its original creation(s) or it has sufficient rights |  | ||||||
| to grant the rights to its Contributions conveyed by this License. |  | ||||||
| 
 |  | ||||||
| 2.6. Fair Use |  | ||||||
| 
 |  | ||||||
| This License is not intended to limit any rights You have under |  | ||||||
| applicable copyright doctrines of fair use, fair dealing, or other |  | ||||||
| equivalents. |  | ||||||
| 
 |  | ||||||
| 2.7. Conditions |  | ||||||
| 
 |  | ||||||
| Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted |  | ||||||
| in Section 2.1. |  | ||||||
| 
 |  | ||||||
| 3. Responsibilities |  | ||||||
| ------------------- |  | ||||||
| 
 |  | ||||||
| 3.1. Distribution of Source Form |  | ||||||
| 
 |  | ||||||
| All distribution of Covered Software in Source Code Form, including any |  | ||||||
| Modifications that You create or to which You contribute, must be under |  | ||||||
| the terms of this License. You must inform recipients that the Source |  | ||||||
| Code Form of the Covered Software is governed by the terms of this |  | ||||||
| License, and how they can obtain a copy of this License. You may not |  | ||||||
| attempt to alter or restrict the recipients' rights in the Source Code |  | ||||||
| Form. |  | ||||||
| 
 |  | ||||||
| 3.2. Distribution of Executable Form |  | ||||||
| 
 |  | ||||||
| If You distribute Covered Software in Executable Form then: |  | ||||||
| 
 |  | ||||||
| (a) such Covered Software must also be made available in Source Code |  | ||||||
|     Form, as described in Section 3.1, and You must inform recipients of |  | ||||||
|     the Executable Form how they can obtain a copy of such Source Code |  | ||||||
|     Form by reasonable means in a timely manner, at a charge no more |  | ||||||
|     than the cost of distribution to the recipient; and |  | ||||||
| 
 |  | ||||||
| (b) You may distribute such Executable Form under the terms of this |  | ||||||
|     License, or sublicense it under different terms, provided that the |  | ||||||
|     license for the Executable Form does not attempt to limit or alter |  | ||||||
|     the recipients' rights in the Source Code Form under this License. |  | ||||||
| 
 |  | ||||||
| 3.3. Distribution of a Larger Work |  | ||||||
| 
 |  | ||||||
| You may create and distribute a Larger Work under terms of Your choice, |  | ||||||
| provided that You also comply with the requirements of this License for |  | ||||||
| the Covered Software. If the Larger Work is a combination of Covered |  | ||||||
| Software with a work governed by one or more Secondary Licenses, and the |  | ||||||
| Covered Software is not Incompatible With Secondary Licenses, this |  | ||||||
| License permits You to additionally distribute such Covered Software |  | ||||||
| under the terms of such Secondary License(s), so that the recipient of |  | ||||||
| the Larger Work may, at their option, further distribute the Covered |  | ||||||
| Software under the terms of either this License or such Secondary |  | ||||||
| License(s). |  | ||||||
| 
 |  | ||||||
| 3.4. Notices |  | ||||||
| 
 |  | ||||||
| You may not remove or alter the substance of any license notices |  | ||||||
| (including copyright notices, patent notices, disclaimers of warranty, |  | ||||||
| or limitations of liability) contained within the Source Code Form of |  | ||||||
| the Covered Software, except that You may alter any license notices to |  | ||||||
| the extent required to remedy known factual inaccuracies. |  | ||||||
| 
 |  | ||||||
| 3.5. Application of Additional Terms |  | ||||||
| 
 |  | ||||||
| You may choose to offer, and to charge a fee for, warranty, support, |  | ||||||
| indemnity or liability obligations to one or more recipients of Covered |  | ||||||
| Software. However, You may do so only on Your own behalf, and not on |  | ||||||
| behalf of any Contributor. You must make it absolutely clear that any |  | ||||||
| such warranty, support, indemnity, or liability obligation is offered by |  | ||||||
| You alone, and You hereby agree to indemnify every Contributor for any |  | ||||||
| liability incurred by such Contributor as a result of warranty, support, |  | ||||||
| indemnity or liability terms You offer. You may include additional |  | ||||||
| disclaimers of warranty and limitations of liability specific to any |  | ||||||
| jurisdiction. |  | ||||||
| 
 |  | ||||||
| 4. Inability to Comply Due to Statute or Regulation |  | ||||||
| --------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| If it is impossible for You to comply with any of the terms of this |  | ||||||
| License with respect to some or all of the Covered Software due to |  | ||||||
| statute, judicial order, or regulation then You must: (a) comply with |  | ||||||
| the terms of this License to the maximum extent possible; and (b) |  | ||||||
| describe the limitations and the code they affect. Such description must |  | ||||||
| be placed in a text file included with all distributions of the Covered |  | ||||||
| Software under this License. Except to the extent prohibited by statute |  | ||||||
| or regulation, such description must be sufficiently detailed for a |  | ||||||
| recipient of ordinary skill to be able to understand it. |  | ||||||
| 
 |  | ||||||
| 5. Termination |  | ||||||
| -------------- |  | ||||||
| 
 |  | ||||||
| 5.1. The rights granted under this License will terminate automatically |  | ||||||
| if You fail to comply with any of its terms. However, if You become |  | ||||||
| compliant, then the rights granted under this License from a particular |  | ||||||
| Contributor are reinstated (a) provisionally, unless and until such |  | ||||||
| Contributor explicitly and finally terminates Your grants, and (b) on an |  | ||||||
| ongoing basis, if such Contributor fails to notify You of the |  | ||||||
| non-compliance by some reasonable means prior to 60 days after You have |  | ||||||
| come back into compliance. Moreover, Your grants from a particular |  | ||||||
| Contributor are reinstated on an ongoing basis if such Contributor |  | ||||||
| notifies You of the non-compliance by some reasonable means, this is the |  | ||||||
| first time You have received notice of non-compliance with this License |  | ||||||
| from such Contributor, and You become compliant prior to 30 days after |  | ||||||
| Your receipt of the notice. |  | ||||||
| 
 |  | ||||||
| 5.2. If You initiate litigation against any entity by asserting a patent |  | ||||||
| infringement claim (excluding declaratory judgment actions, |  | ||||||
| counter-claims, and cross-claims) alleging that a Contributor Version |  | ||||||
| directly or indirectly infringes any patent, then the rights granted to |  | ||||||
| You by any and all Contributors for the Covered Software under Section |  | ||||||
| 2.1 of this License shall terminate. |  | ||||||
| 
 |  | ||||||
| 5.3. In the event of termination under Sections 5.1 or 5.2 above, all |  | ||||||
| end user license agreements (excluding distributors and resellers) which |  | ||||||
| have been validly granted by You or Your distributors under this License |  | ||||||
| prior to termination shall survive termination. |  | ||||||
| 
 |  | ||||||
| ************************************************************************ |  | ||||||
| *                                                                      * |  | ||||||
| *  6. Disclaimer of Warranty                                           * |  | ||||||
| *  -------------------------                                           * |  | ||||||
| *                                                                      * |  | ||||||
| *  Covered Software is provided under this License on an "as is"       * |  | ||||||
| *  basis, without warranty of any kind, either expressed, implied, or  * |  | ||||||
| *  statutory, including, without limitation, warranties that the       * |  | ||||||
| *  Covered Software is free of defects, merchantable, fit for a        * |  | ||||||
| *  particular purpose or non-infringing. The entire risk as to the     * |  | ||||||
| *  quality and performance of the Covered Software is with You.        * |  | ||||||
| *  Should any Covered Software prove defective in any respect, You     * |  | ||||||
| *  (not any Contributor) assume the cost of any necessary servicing,   * |  | ||||||
| *  repair, or correction. This disclaimer of warranty constitutes an   * |  | ||||||
| *  essential part of this License. No use of any Covered Software is   * |  | ||||||
| *  authorized under this License except under this disclaimer.         * |  | ||||||
| *                                                                      * |  | ||||||
| ************************************************************************ |  | ||||||
| 
 |  | ||||||
| ************************************************************************ |  | ||||||
| *                                                                      * |  | ||||||
| *  7. Limitation of Liability                                          * |  | ||||||
| *  --------------------------                                          * |  | ||||||
| *                                                                      * |  | ||||||
| *  Under no circumstances and under no legal theory, whether tort      * |  | ||||||
| *  (including negligence), contract, or otherwise, shall any           * |  | ||||||
| *  Contributor, or anyone who distributes Covered Software as          * |  | ||||||
| *  permitted above, be liable to You for any direct, indirect,         * |  | ||||||
| *  special, incidental, or consequential damages of any character      * |  | ||||||
| *  including, without limitation, damages for lost profits, loss of    * |  | ||||||
| *  goodwill, work stoppage, computer failure or malfunction, or any    * |  | ||||||
| *  and all other commercial damages or losses, even if such party      * |  | ||||||
| *  shall have been informed of the possibility of such damages. This   * |  | ||||||
| *  limitation of liability shall not apply to liability for death or   * |  | ||||||
| *  personal injury resulting from such party's negligence to the       * |  | ||||||
| *  extent applicable law prohibits such limitation. Some               * |  | ||||||
| *  jurisdictions do not allow the exclusion or limitation of           * |  | ||||||
| *  incidental or consequential damages, so this exclusion and          * |  | ||||||
| *  limitation may not apply to You.                                    * |  | ||||||
| *                                                                      * |  | ||||||
| ************************************************************************ |  | ||||||
| 
 |  | ||||||
| 8. Litigation |  | ||||||
| ------------- |  | ||||||
| 
 |  | ||||||
| Any litigation relating to this License may be brought only in the |  | ||||||
| courts of a jurisdiction where the defendant maintains its principal |  | ||||||
| place of business and such litigation shall be governed by laws of that |  | ||||||
| jurisdiction, without reference to its conflict-of-law provisions. |  | ||||||
| Nothing in this Section shall prevent a party's ability to bring |  | ||||||
| cross-claims or counter-claims. |  | ||||||
| 
 |  | ||||||
| 9. Miscellaneous |  | ||||||
| ---------------- |  | ||||||
| 
 |  | ||||||
| This License represents the complete agreement concerning the subject |  | ||||||
| matter hereof. If any provision of this License is held to be |  | ||||||
| unenforceable, such provision shall be reformed only to the extent |  | ||||||
| necessary to make it enforceable. Any law or regulation which provides |  | ||||||
| that the language of a contract shall be construed against the drafter |  | ||||||
| shall not be used to construe this License against a Contributor. |  | ||||||
| 
 |  | ||||||
| 10. Versions of the License |  | ||||||
| --------------------------- |  | ||||||
| 
 |  | ||||||
| 10.1. New Versions |  | ||||||
| 
 |  | ||||||
| Mozilla Foundation is the license steward. Except as provided in Section |  | ||||||
| 10.3, no one other than the license steward has the right to modify or |  | ||||||
| publish new versions of this License. Each version will be given a |  | ||||||
| distinguishing version number. |  | ||||||
| 
 |  | ||||||
| 10.2. Effect of New Versions |  | ||||||
| 
 |  | ||||||
| You may distribute the Covered Software under the terms of the version |  | ||||||
| of the License under which You originally received the Covered Software, |  | ||||||
| or under the terms of any subsequent version published by the license |  | ||||||
| steward. |  | ||||||
| 
 |  | ||||||
| 10.3. Modified Versions |  | ||||||
| 
 |  | ||||||
| If you create software not governed by this License, and you want to |  | ||||||
| create a new license for such software, you may create and use a |  | ||||||
| modified version of this License if you rename the license and remove |  | ||||||
| any references to the name of the license steward (except to note that |  | ||||||
| such modified license differs from this License). |  | ||||||
| 
 |  | ||||||
| 10.4. Distributing Source Code Form that is Incompatible With Secondary |  | ||||||
| Licenses |  | ||||||
| 
 |  | ||||||
| If You choose to distribute Source Code Form that is Incompatible With |  | ||||||
| Secondary Licenses under the terms of this version of the License, the |  | ||||||
| notice described in Exhibit B of this License must be attached. |  | ||||||
| 
 |  | ||||||
| Exhibit A - Source Code Form License Notice |  | ||||||
| ------------------------------------------- |  | ||||||
| 
 |  | ||||||
|   This Source Code Form is subject to the terms of the Mozilla Public |  | ||||||
|   License, v. 2.0. If a copy of the MPL was not distributed with this |  | ||||||
|   file, You can obtain one at http://mozilla.org/MPL/2.0/. |  | ||||||
| 
 |  | ||||||
| If it is not possible or desirable to put the notice in a particular |  | ||||||
| file, then You may include the notice in a location (such as a LICENSE |  | ||||||
| file in a relevant directory) where a recipient would be likely to look |  | ||||||
| for such a notice. |  | ||||||
| 
 |  | ||||||
| You may add additional accurate notices of copyright ownership. |  | ||||||
| 
 |  | ||||||
| Exhibit B - "Incompatible With Secondary Licenses" Notice |  | ||||||
| --------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
|   This Source Code Form is "Incompatible With Secondary Licenses", as |  | ||||||
|   defined by the Mozilla Public License, v. 2.0. |  | ||||||
							
								
								
									
										439
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										439
									
								
								README.md
									
									
									
									
									
								
							| @ -1,96 +1,78 @@ | |||||||
| # [dns-suite.js](https://git.rootprojects.org/root/dns-suite.js) | dns-suite | ||||||
|  | ======== | ||||||
| 
 | 
 | ||||||
| | Built by [Root](https://rootprojects.org) for [Telebit](https://telebit.io) and [Hub](https://rootprojects.org/hub) | Fast, lightweight, and easy-to-extend **pure JavaScript** (ES5.1) implementation for DNS / mDNS. | ||||||
| 
 | 
 | ||||||
| | **dns-suite.js** | Works great in **Web Browsers** and in node.js! | ||||||
| | [dig.js](https://git.coolaj86.com/coolaj86/dig.js) |  | ||||||
| | [mdig.js](https://git.coolaj86.com/coolaj86/mdig.js) |  | ||||||
| | [digd.js](https://git.coolaj86.com/coolaj86/digd.js) |  | ||||||
| 
 | 
 | ||||||
| Fast, lightweight, and easy-to-extend Vanilla JS (ES5.1) implementation of DNS / mDNS for Node.js and Browsers. | Detailed error checking makes it great for | ||||||
| 
 | 
 | ||||||
| -   [x] Full DNS Support | * capture | ||||||
|     -   [x] Queries | * packing (JSON to DNS/mDNS) | ||||||
|     -   [x] Answers | * parsing (DNS/mDNS to JSON) | ||||||
|     -   [x] Authority | * linting (finding errors in packets) | ||||||
|     -   [x] Additional | * debugging | ||||||
| -   [x] Built for Debugging |  | ||||||
|     -   [x] capture |  | ||||||
|     -   [x] packing (JSON to DNS/mDNS) |  | ||||||
|     -   [x] parsing (DNS/mDNS to JSON) |  | ||||||
|     -   [x] linting (finding errors in packets) |  | ||||||
| 
 | 
 | ||||||
| Uses `DataView`, `Uint8Array`, `Uint16Array`, and `ArrayBuffer` | **No external dependencies** for node.js or modern browsers. Uses `DataView`, `Uint8Array`, `Uint16Array`, and `ArrayBuffer` | ||||||
| 
 | 
 | ||||||
| Similar API to `dns.js` and `native-dns-packet`. | Similar API to `dns.js` and `native-dns-packet`. | ||||||
| 
 | 
 | ||||||
| # Example Query |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| var DNSPacket = require('dns-suite').DNSPacket; |  | ||||||
| 
 |  | ||||||
| var query = { |  | ||||||
| 	header: { |  | ||||||
| 		id: rnd, |  | ||||||
| 		qr: 0, |  | ||||||
| 		opcode: 0, |  | ||||||
| 		aa: 0, |  | ||||||
| 		rd: 1, |  | ||||||
| 		ra: 0, |  | ||||||
| 		rcode: 0 |  | ||||||
| 	}, |  | ||||||
| 	question: [ |  | ||||||
| 		{ |  | ||||||
| 			name: 'google.com', |  | ||||||
| 			typeName: 'A', |  | ||||||
| 			className: 'IN' |  | ||||||
| 		} |  | ||||||
| 	] |  | ||||||
| }; |  | ||||||
| var buffer = DNSPacket.pack(query); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| # Example Response |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| var DNSPacket = require('dns-suite').DNSPacket; |  | ||||||
| DNSPacket.parse(buffer); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ```json | ```json | ||||||
| { | { "header": { | ||||||
| 	"header": { |     "id": 5423 | ||||||
| 		"id": 5423, |   , "qr": 0 | ||||||
| 		"qr": 0, |   , "opcode": 0 | ||||||
| 		"opcode": 0, |   , "aa": 0 | ||||||
| 		"aa": 0, |   , "tc": 0 | ||||||
| 		"tc": 0, |   , "rd": 1 | ||||||
| 		"rd": 1, |   , "ra": 0 | ||||||
| 		"ra": 0, |   , "res1": 0 | ||||||
| 		"res1": 0, |   , "res2": 0 | ||||||
| 		"res2": 0, |   , "res3": 0 | ||||||
| 		"res3": 0, |   , "rcode": 0 | ||||||
| 		"rcode": 0 |   } | ||||||
| 	}, | , "question": [ | ||||||
| 	"question": [ |     { "name": "bowie._sftp-ssh._tcp.local" | ||||||
| 		{ |     , "type": 1 | ||||||
| 			"name": "bowie._sftp-ssh._tcp.local", |     , "typeName": "A" | ||||||
| 			"type": 1, |     , "class": 1 | ||||||
| 			"typeName": "A", |     , "className": "IN" | ||||||
| 			"class": 1, |     , "byteLength": 32 | ||||||
| 			"className": "IN", |     } | ||||||
| 			"byteLength": 32 |   ] | ||||||
| 		} | , "answer": [] | ||||||
| 	], | , "authority": [] | ||||||
| 	"answer": [], | , "additional": [] | ||||||
| 	"authority": [], | , "edns_options": [] | ||||||
| 	"additional": [], | , "byteLength": 44 | ||||||
| 	"edns_options": [], |  | ||||||
| 	"byteLength": 44 |  | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Install | Install with git | ||||||
|  | ------- | ||||||
|  | 
 | ||||||
|  | You can use git to install v1.x like so: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | # latest of v1.x | ||||||
|  | npm install 'git+https://git@git.daplie.com:Daplie/dns-suite#v1' | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | If you want to be more specific to v1.0.x or exactly v1.0.2 you can do so like this: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | # latest of v1.0.x | ||||||
|  | npm install 'git+https://git@git.daplie.com:Daplie/dns-suite#v1.0' | ||||||
|  | 
 | ||||||
|  | # exactly v1.0.2 | ||||||
|  | npm install 'git+https://git@git.daplie.com:Daplie/dns-suite#v1.0.2' | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Install without git | ||||||
|  | ------- | ||||||
|  | 
 | ||||||
|  | Don't have git? Well you can also bow down to the gods of the centralized, monopolized, concentrated, dictatornet | ||||||
|  | (as we like to call it here at Daplie Labs), if that's how you roll: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| npm install --save dns-suite | npm install --save dns-suite | ||||||
| @ -99,13 +81,16 @@ npm install --save dns-suite | |||||||
| **Test**: | **Test**: | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| node ./node_modules/dns-suite/examples/dns-pack.js | pushd node_modules/dns-suite | ||||||
|  | 
 | ||||||
|  | npm test | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Usage | Usage | ||||||
|  | ----- | ||||||
| 
 | 
 | ||||||
| -   CLI | * CLI | ||||||
| -   API | * API | ||||||
| 
 | 
 | ||||||
| ### CLI Usage | ### CLI Usage | ||||||
| 
 | 
 | ||||||
| @ -115,11 +100,9 @@ When installed globally you can use these commands: | |||||||
| dns-parse.js </path/to/packet.dns.bin> [out.json]   # parses a saved DNS packet to JSON | dns-parse.js </path/to/packet.dns.bin> [out.json]   # parses a saved DNS packet to JSON | ||||||
| dns-pack.js </path/to/packet.dns.json> [out.bin]    # packs a JSON DNS packet to binary | dns-pack.js </path/to/packet.dns.json> [out.bin]    # packs a JSON DNS packet to binary | ||||||
| dns-test.js </path/to/packet.dns(.json|.bin)>       # convert a packet back and forth to test reciprocity of the packer and parser | dns-test.js </path/to/packet.dns(.json|.bin)>       # convert a packet back and forth to test reciprocity of the packer and parser | ||||||
|  | mdns-capture.js <prefixname> [startnum]             # listen and save all mDNS packets, numbering by sequence of arrival | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| For **capturing packets** you should use [`dig.js`](https://git.coolaj86.com/coolaj86/dig.js#options) with the `--output` option. |  | ||||||
| It can capture mDNS as well. See <https://git.coolaj86.com/coolaj86/dig.js#options>. |  | ||||||
| 
 |  | ||||||
| You can also access them directly from `node_modules/dns-suite` in a project: | You can also access them directly from `node_modules/dns-suite` in a project: | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| @ -128,12 +111,11 @@ node node_modules/dns-suite/bin/dns-parse.js node_modules/dns-suite/samples/a-0. | |||||||
| 
 | 
 | ||||||
| ### Library API | ### Library API | ||||||
| 
 | 
 | ||||||
| -   `DNSPacket.parse(nodeOrArrayBuffer)` returns json (as shown above) | * `DNSPacket.parse(nodeOrArrayBuffer)` returns json (as shown above) | ||||||
| -   `DNSPacket.pack(packet)` returns ArrayBuffer (browser and node) | * `DNSPacket.pack(packet)` returns ArrayBuffer (browser and node) | ||||||
| -   `DNSPacket.write(packet)` returns NodeBuffer (node only) | * `DNSPacket.write(packet)` returns NodeBuffer (node only) | ||||||
| 
 | 
 | ||||||
| node.js: | node.js: | ||||||
| 
 |  | ||||||
| ```js | ```js | ||||||
| var nodeBuffer = fs.readFileSync('./samples/a-0.mdns.bin'); | var nodeBuffer = fs.readFileSync('./samples/a-0.mdns.bin'); | ||||||
| var arrayBuffer = nodeBuffer.buffer; | var arrayBuffer = nodeBuffer.buffer; | ||||||
| @ -147,11 +129,8 @@ console.log(new Uint8Array(ab)); | |||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Browser: | Browser: | ||||||
| 
 |  | ||||||
| ```js | ```js | ||||||
| var arrayBuffer = new Uint8Array.from([ | var arrayBuffer = new Uint8Array.from([ /* bytes */ ]).buffer; | ||||||
| 	/* bytes */ |  | ||||||
| ]).buffer; |  | ||||||
| 
 | 
 | ||||||
| var packet = DNSPacket.parse(arrayBuffer); | var packet = DNSPacket.parse(arrayBuffer); | ||||||
| var ab = DNSPacket.pack(packet); | var ab = DNSPacket.pack(packet); | ||||||
| @ -160,259 +139,36 @@ console.log(packet); | |||||||
| console.log(new Uint8Array(ab)); | console.log(new Uint8Array(ab)); | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Capturing Packets |  | ||||||
| 
 | 
 | ||||||
| We have a command line tool for that! See [dig.js](https://git.coolaj86.com/coolaj86/dig.js). | Capturing Packets | ||||||
|  | ----- | ||||||
| 
 | 
 | ||||||
| ```bash | We have a command line tool for that! See [dig.js](https://git.daplie.com/Daplie/dig.js). | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
| # Install | # Install | ||||||
| npm install -g 'git+https://git.coolaj86.com/coolaj86/dig.js.git' | npm install -g 'git+https://git@git.daplie.com/Daplie/dig.js.git' | ||||||
| 
 | 
 | ||||||
| # Use with DNS | # Use with DNS | ||||||
| dig.js A coolaj86.com --output . | dig.js A daplie.com --output . | ||||||
| 
 | 
 | ||||||
| # Use with mDNS | # Use with mDNS | ||||||
| dig.js --mdns PTR _services._dns-sd._udp.local --output . | dig.js --mdns PTR _services._dns-sd._udp.local --output . | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| # Resource Record Examples | Contributing and Development | ||||||
|  | ============================ | ||||||
| 
 | 
 | ||||||
| -   SOA | How to add a new parser | ||||||
| -   NS | ----------------------- | ||||||
| -   A |  | ||||||
| -   AAAA |  | ||||||
| -   CNAME |  | ||||||
| -   MX |  | ||||||
| -   TXT |  | ||||||
| -   SRV |  | ||||||
| -   PTR |  | ||||||
| 
 |  | ||||||
| ## SOA |  | ||||||
| 
 |  | ||||||
| I'm pretty sure that the SOA only goes in the `authority` section |  | ||||||
| (except when SOA is queried explicitly) |  | ||||||
| and that it's only given as a response to any empty set |  | ||||||
| (where `RCODE == NXDOMAIN`) |  | ||||||
| to affirm "yes, I am responsible for this domain but, no, I don't have a record for it". |  | ||||||
| 
 |  | ||||||
| If another nameserver has been delegated authority for a particular subdomain |  | ||||||
| a set of `NS` records should be returned instead. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "yahoo.com", |  | ||||||
| 	"type": 6, |  | ||||||
| 	"typeName": "SOA", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 599, |  | ||||||
| 	"primary": "ns1.yahoo.com", |  | ||||||
| 	"admin": "hostmaster.yahoo-inc.com", |  | ||||||
| 	"serial": 2017092539, |  | ||||||
| 	"refresh": 3600, |  | ||||||
| 	"retry": 300, |  | ||||||
| 	"expiration": 1814400, |  | ||||||
| 	"minimum": 600 |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## NS |  | ||||||
| 
 |  | ||||||
| I'm also pretty sure that the NS only goes in the `authority` section |  | ||||||
| (except when NS is queried explicitly) |  | ||||||
| and that it's given as a successful response |  | ||||||
| (`RCODE == SUCCESS`) |  | ||||||
| to any query type |  | ||||||
| (`A` or `AAAA`, `MX`, `TXT`, or `SRV`) |  | ||||||
| where the answer sections is an empty set because the records in |  | ||||||
| question have been delegated to another nameserver. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "google.com", |  | ||||||
| 	"type": 2, |  | ||||||
| 	"typeName": "NS", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 82790, |  | ||||||
| 	"data": "ns3.google.com" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## A |  | ||||||
| 
 |  | ||||||
| The most common type of record. Returns the IPv4 address for a given domain. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "www.linode.com", |  | ||||||
| 	"type": 1, |  | ||||||
| 	"typeName": "A", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 291, |  | ||||||
| 	"address": "72.14.191.202" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## AAAA |  | ||||||
| 
 |  | ||||||
| Returns the IPv6 address for a given domain. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "irc6.geo.oftc.net", |  | ||||||
| 	"type": 28, |  | ||||||
| 	"typeName": "AAAA", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 59, |  | ||||||
| 	"address": "2607:f8f0:610:4000:211:11ff:fe1c:7bec" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## CNAME |  | ||||||
| 
 |  | ||||||
| The CNAME is used to look up the IP address for the given alias. |  | ||||||
| (the alias is often referred to incorrectly as a CNAME but it is, in fact, the alias) |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "www.nodejs.org", |  | ||||||
| 	"type": 5, |  | ||||||
| 	"typeName": "CNAME", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 3600, |  | ||||||
| 	"data": "nodejs.org" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## MX |  | ||||||
| 
 |  | ||||||
| Mail Exchange Records show the alias that should be looked up to know where incoming mail should |  | ||||||
| be sent. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "microsoft.com", |  | ||||||
| 	"type": 15, |  | ||||||
| 	"typeName": "MX", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 197, |  | ||||||
| 	"priority": 10, |  | ||||||
| 	"exchange": "microsoft-com.mail.protection.outlook.com" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## TXT |  | ||||||
| 
 |  | ||||||
| Often used for outgoing mail validations, public keys, lots of arbitrary stuff. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "aol.com", |  | ||||||
| 	"type": 16, |  | ||||||
| 	"typeName": "TXT", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 1926, |  | ||||||
| 	"data": ["v=spf1 ptr:mx.aol.com ?all"] |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## SRV |  | ||||||
| 
 |  | ||||||
| A way to associate a service with a port and other relevant information. |  | ||||||
| Used for federated / dencentralized protocols (like XMPP) and mDNS/DLNA/UPnP/DNS-SD type stuff. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "_xmpp-server._tcp.gmail.com", |  | ||||||
| 	"type": 33, |  | ||||||
| 	"typeName": "SRV", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 900, |  | ||||||
| 	"priority": 5, |  | ||||||
| 	"weight": 0, |  | ||||||
| 	"port": 5269, |  | ||||||
| 	"target": "xmpp-server.l.google.com" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## PTR |  | ||||||
| 
 |  | ||||||
| Used for mDNS/DNS-SD type discoveries and anti-spam reverse lookup verification for mail servers. |  | ||||||
| 
 |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
| 	"name": "_pdl-datastream._tcp.local", |  | ||||||
| 	"type": 12, |  | ||||||
| 	"typeName": "PTR", |  | ||||||
| 	"class": 1, |  | ||||||
| 	"className": "IN", |  | ||||||
| 	"ttl": 255, |  | ||||||
| 	"data": "Canon MF620C Series._pdl-datastream._tcp.local" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## All Properties |  | ||||||
| 
 |  | ||||||
| For simplicity, here's a list of all properties, just for fun: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| { |  | ||||||
|   // All RRs |  | ||||||
|   "name": "example.com", |  | ||||||
|   "type": 1, |  | ||||||
|   "typeName": "A", |  | ||||||
|   "class": 1, |  | ||||||
|   "className": "IN", |  | ||||||
|   "ttl": 600, |  | ||||||
| 
 |  | ||||||
|   // SOA |  | ||||||
|   "primary": "ns1.yahoo.com", |  | ||||||
|   "admin": "hostmaster.yahoo-inc.com", |  | ||||||
|   "serial": 2017092539, |  | ||||||
|   "refresh": 3600, |  | ||||||
|   "retry": 300, |  | ||||||
|   "expiration": 1814400, |  | ||||||
|   "minimum": 600, |  | ||||||
| 
 |  | ||||||
|   // A, AAAA |  | ||||||
|   "address": "72.14.191.202", |  | ||||||
| 
 |  | ||||||
|   // CNAME, NS, PTR |  | ||||||
|   "data": "ns3.google.com", |  | ||||||
| 
 |  | ||||||
|   // TXT |  | ||||||
|   // "data": [ "v=spf1 ptr:mx.aol.com ?all" ], |  | ||||||
| 
 |  | ||||||
|   // MX |  | ||||||
|   "priority": 10, |  | ||||||
|   "exchange": "microsoft-com.mail.protection.outlook.com", |  | ||||||
| 
 |  | ||||||
|   // SRV |  | ||||||
|   "priority": 5, |  | ||||||
|   "weight": 0, |  | ||||||
|   "port": 5269, |  | ||||||
|   "target": "xmpp-server.l.google.com" |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| # Contributing and Development |  | ||||||
| 
 |  | ||||||
| ## How to add a new parser |  | ||||||
| 
 | 
 | ||||||
| Each RR (aka Resource Record or RData) parser is individual. Examples include: | Each RR (aka Resource Record or RData) parser is individual. Examples include: | ||||||
| 
 | 
 | ||||||
| -   A (`parser/type.a.js`) | * A (`parser/type.a.js`) | ||||||
| -   AAAA (`parser/type.aaaa.js`) | * AAAA (`parser/type.aaaa.js`) | ||||||
| -   CNAME (`parser/type.cname.js`) | * CNAME (`parser/type.cname.js`) | ||||||
| -   TXT (`parser/type.txt.js`) | * TXT (`parser/type.txt.js`) | ||||||
| -   SRV (`parser/type.srv.js`) | * SRV (`parser/type.srv.js`) | ||||||
| 
 | 
 | ||||||
| Let's say that To create a parser for a type which we don't currently support, | Let's say that To create a parser for a type which we don't currently support, | ||||||
| just add the appropriate information to `dns.types.js` and create a file for | just add the appropriate information to `dns.types.js` and create a file for | ||||||
| @ -421,7 +177,7 @@ the name of the type in the format `parser/type.<typename>.js`. | |||||||
| For example, if `CNAME` wasn't already supported and I wanted to add support for | For example, if `CNAME` wasn't already supported and I wanted to add support for | ||||||
| it I would follow these steps: | it I would follow these steps: | ||||||
| 
 | 
 | ||||||
| 1. Update `dns.types.js` if it's not there already. | 1) Update `dns.types.js` if it's not there already. | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|   A: 			0x01	//   1 |   A: 			0x01	//   1 | ||||||
| @ -430,7 +186,7 @@ it I would follow these steps: | |||||||
| , SOA: 		0x06  //   6 | , SOA: 		0x06  //   6 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 2. Capture a packet to `test/fixtures/<domain>.<tld>.<type>.bin` | 2) Capture a packet to `test/fixtures/<domain>.<tld>.<type>.bin` | ||||||
| 
 | 
 | ||||||
| This will construct and send a DNS query and save the first result | This will construct and send a DNS query and save the first result | ||||||
| that comes back. | that comes back. | ||||||
| @ -444,11 +200,10 @@ Ideally you should have some idea of what the result file should look | |||||||
| like and should place that in `test/fixtures/<domain>.<tld>.<type>.json` | like and should place that in `test/fixtures/<domain>.<tld>.<type>.json` | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| npm install -g dig.js | node bin/capture-query.js --name www.google.com --type CNAME | ||||||
| dig.js --name www.google.com --type CNAME --output ./samples/ |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 3. Create `parser/type.cname.js` | 3) Create `parser/type.cname.js` | ||||||
| 
 | 
 | ||||||
| Copy `parser/type.TEMPLATE.js` to the type for which you wish to create support | Copy `parser/type.TEMPLATE.js` to the type for which you wish to create support | ||||||
| (`parser/type.cname.js` in this example) and fill in the blanks. | (`parser/type.cname.js` in this example) and fill in the blanks. | ||||||
| @ -466,7 +221,7 @@ exports.DNS_PARSER_TYPE_CNAME = function (ab, packet, record) { | |||||||
| }('undefined' !== typeof window ? window : exports)); | }('undefined' !== typeof window ? window : exports)); | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 4. Document what you've learned in `doc/<type>.txt` | 4) Document what you've learned in `doc/<type>.txt` | ||||||
| 
 | 
 | ||||||
| You may be right or you might be wrong, but you might be right. | You may be right or you might be wrong, but you might be right. | ||||||
| 
 | 
 | ||||||
| @ -476,7 +231,7 @@ record type - tips, tricks, little-known facts, etc. | |||||||
| This may help (or wildly mislead) others if there's a bug in your parser that they need to track down. | This may help (or wildly mislead) others if there's a bug in your parser that they need to track down. | ||||||
| At the very least someone can follow a few links you followed and your thought process. | At the very least someone can follow a few links you followed and your thought process. | ||||||
| 
 | 
 | ||||||
| 5. Check that my changes include these files | 5) Check that my changes include these files | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| ├── README.md | ├── README.md | ||||||
|  | |||||||
							
								
								
									
										219
									
								
								bin/debug.js
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								bin/debug.js
									
									
									
									
									
								
							| @ -1,219 +0,0 @@ | |||||||
| #!/usr/bin/env node
 |  | ||||||
| 
 |  | ||||||
| // node bin/debug.js ../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin
 |  | ||||||
| // node bin/debugd.js ../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin
 |  | ||||||
| // dig @localhost -p 65053 ANY DOEsNteXiST.AJ.OnEal.DAplIE.me
 |  | ||||||
| // dd if=../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin of=blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.trunc.bin bs=1 count=78
 |  | ||||||
| (function () { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| var input = process.argv[2]; |  | ||||||
| var fs = require('fs'); |  | ||||||
| var nb = fs.readFileSync(input, null); |  | ||||||
| 
 |  | ||||||
| var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); |  | ||||||
| var dv = new DataView(ab); |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // read header
 |  | ||||||
| //
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log('//    HEADER    //'); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log(''); |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('byte index 0x00'); |  | ||||||
| console.log(''); |  | ||||||
| 
 |  | ||||||
| console.log('id (int)', dv.getUint16(0)); |  | ||||||
| 
 |  | ||||||
| var flags = dv.getUint16(2, false); |  | ||||||
| console.log('header 0x', flags.toString(16)); |  | ||||||
| var flagsstr = '' |  | ||||||
| 	+ 'qr ' + ((flags & 0x8000) >> 15) + ', ' |  | ||||||
|   + 'opcode ' + ((flags & 0x7800) >> 11) + ', ' |  | ||||||
|   + 'aa ' + ((flags &  0x400) >> 10) + ', ' |  | ||||||
|   + 'tc ' + ((flags &  0x200) >>  9) + ', ' |  | ||||||
|   + 'rd ' + ((flags &  0x100) >>  8) + ', ' |  | ||||||
|   + 'ra ' + ((flags &   0x80) >>  7) + ', ' |  | ||||||
|   + 'res1 ' + ((flags &   0x40) >>  6) + ', ' |  | ||||||
|   + 'res2 ' + ((flags &   0x20) >>  5) + ', ' |  | ||||||
|   + 'res3 ' + ((flags &   0x10) >>  4) + ', ' |  | ||||||
|   + 'rcode ' + ((flags &    0xF)); |  | ||||||
| console.log('(flags: ' + flagsstr); |  | ||||||
| 
 |  | ||||||
| var qdcount = dv.getUint16(4, false);  // query count
 |  | ||||||
| var ancount = dv.getUint16(6, false);  // answer count
 |  | ||||||
| var nscount = dv.getUint16(8, false);  // authority count
 |  | ||||||
| var arcount = dv.getUint16(10, false); // additional count
 |  | ||||||
| var count; |  | ||||||
| 
 |  | ||||||
| console.log('qdcount', qdcount); |  | ||||||
| console.log('ancount', ancount); |  | ||||||
| console.log('nscount', nscount); |  | ||||||
| console.log('arcount', arcount); |  | ||||||
| 
 |  | ||||||
| function unpackQuestionLabels(opts) { |  | ||||||
|   var dv = opts.dv; |  | ||||||
|   //var origTotal = opts.total;
 |  | ||||||
|   var total = opts.total; |  | ||||||
|   var len = opts.len; |  | ||||||
|   var qnames = []; |  | ||||||
|   var labelLen; |  | ||||||
| 
 |  | ||||||
|   while (true) { |  | ||||||
|     if (total >= len) { |  | ||||||
|       opts.trunc = true; |  | ||||||
|       console.warn(''); |  | ||||||
|       console.warn('[WARNING] The label was truncated by byte length of message or rdata.'); |  | ||||||
|       console.warn('[WARNING] Depending on the Resource Record type, that may be a parse error.'); |  | ||||||
|       console.warn(''); |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     labelLen = dv.getUint8(total, false); // additional count
 |  | ||||||
|     total += 1; |  | ||||||
|     if (!labelLen) { |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     if (labelLen >= 0xc0) { |  | ||||||
|       // (11 000000 & whatever) signifies pointer
 |  | ||||||
|       // (00 111111 & whatever) bitmask for potentially large pointer
 |  | ||||||
|       // (00 000001   11111111) largest realistic pointer value (512 byte message size)
 |  | ||||||
|       var pointer = ((labelLen & 0x3f) << 8) | dv.getUint8(total, false); |  | ||||||
|       console.log('Found a pointer to' |  | ||||||
|         + ' 0x' + pointer.toString(16) + ' (' + pointer + ')' |  | ||||||
|         + ' at byte index' |  | ||||||
|         + ' 0x' + leftPad(total.toString(16)) + ' (' + total + ')' |  | ||||||
|         //+ ' which back-references:'
 |  | ||||||
|       ); |  | ||||||
|       /* |  | ||||||
|       console.log('-4', dv.getUint8(pointer - 4, false)); |  | ||||||
|       console.log('-3', dv.getUint8(pointer - 3, false)); |  | ||||||
|       console.log('-2', dv.getUint8(pointer - 2, false)); |  | ||||||
|       console.log('-1', dv.getUint8(pointer - 1, false)); |  | ||||||
|       console.log(' 0', dv.getUint8(pointer + 0, false)); |  | ||||||
|       console.log('+1', dv.getUint8(pointer + 1, false)); |  | ||||||
|       console.log('+2', dv.getUint8(pointer + 2, false)); |  | ||||||
|       console.log('bytes near the pointer itself (not what it points to) are:'); |  | ||||||
|       console.log('-2', dv.getUint8(total - 2, false)); |  | ||||||
|       console.log('-1', dv.getUint8(total - 1, false)); |  | ||||||
|       console.log(' 0', dv.getUint8(total + 0, false)); |  | ||||||
|       console.log('+1', dv.getUint8(total + 1, false)); |  | ||||||
|       console.log('+2', dv.getUint8(total + 2, false)); |  | ||||||
|       console.log('+3', dv.getUint8(total + 3, false)); |  | ||||||
|       console.log('+4', dv.getUint8(total + 4, false)); |  | ||||||
|       */ |  | ||||||
|       //total += 1;
 |  | ||||||
|       opts.cp = true; |  | ||||||
|       qnames.push(unpackQuestionLabels({ dv: dv, total: pointer, len: len }).qname); |  | ||||||
|       total += 1; |  | ||||||
|       break; |  | ||||||
|     } else { |  | ||||||
|       var i; |  | ||||||
|       var label = ''; |  | ||||||
|       console.log('label len', labelLen); |  | ||||||
|       for (i = 0; i < labelLen; i += 1) { |  | ||||||
|         //console.log('total:', total, i);
 |  | ||||||
|         label += String.fromCharCode(dv.getUint8(total + i, false)); |  | ||||||
|       } |  | ||||||
|       total += label.length; |  | ||||||
|       console.log('label:', label); |  | ||||||
|       qnames.push(label); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return { |  | ||||||
|     total: total |  | ||||||
|   , qname: qnames.join('.') |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function unpackQuestion(dv, total, len) { |  | ||||||
| 
 |  | ||||||
|   var result = unpackQuestionLabels({ dv: dv, total: total, len: len }); |  | ||||||
| 
 |  | ||||||
|   // leading length and (potentially) trailing null
 |  | ||||||
|   console.log('QNAME (len ' + (result.total - total) + '):', result.qname, result.cp ? '(pointer)' : ''); |  | ||||||
|   console.log('QTYPE (len 2):', dv.getUint16(result.total, false)); |  | ||||||
|   result.total += 2; |  | ||||||
|   console.log('QCLASS (len 2):', dv.getUint16(result.total, false)); |  | ||||||
|   result.total += 2; |  | ||||||
| 
 |  | ||||||
|   return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var q = { total: 12 }; |  | ||||||
| function mapChar(ch) { return JSON.stringify(String.fromCharCode(ch)) + '(' + ch + ')'; } |  | ||||||
| function leftPad(ch) { ch = ch.toString(); while (ch.length < 2) { ch = '0' + ch; } return ch; } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log('//   QUESTION   //'); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log(''); |  | ||||||
| for (count = 0; count < qdcount; count += 1) { |  | ||||||
|   console.log(''); |  | ||||||
|   console.log('Question ' + (count + 1) + ' of ' + qdcount + ' (byte index: 0x' + leftPad(q.total.toString(16)) + ' ' + q.total + ')'); |  | ||||||
|   q = unpackQuestion(dv, q.total, ab.byteLength); |  | ||||||
|   console.log(''); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function unpackResourceRecord(dv, q, ab) { |  | ||||||
|   var _q = unpackQuestion(dv, q.total, ab.byteLength); |  | ||||||
|   q.total = _q.total; |  | ||||||
|   console.log('ttl (len 4):', dv.getUint32(q.total, false)); |  | ||||||
|   q.total += 4; |  | ||||||
|   q.rdlength = dv.getUint16(q.total, false); |  | ||||||
|   console.log('rdlen (len 2):', q.rdlength); |  | ||||||
|   q.total += 2; |  | ||||||
|   console.log('rrdata (len ' + q.rdlength + '):'); |  | ||||||
|   console.log([].slice.call(new Uint8Array(ab), q.total, q.total + q.rdlength).map(mapChar).join(' ')); |  | ||||||
|   q.total += q.rdlength; |  | ||||||
|   console.log(''); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log('//    ANSWER    //'); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log(''); |  | ||||||
| for (count = 0; count < ancount; count += 1) { |  | ||||||
|   console.log(''); |  | ||||||
|   console.log('Answer', count + 1, 'of', ancount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); |  | ||||||
|   unpackResourceRecord(dv, q, ab); |  | ||||||
|   console.log(''); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log('//   AUTHORITY  //'); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log(''); |  | ||||||
| for (count = 0; count < nscount; count += 1) { |  | ||||||
|   console.log(''); |  | ||||||
|   console.log('Authority', count + 1, 'of', nscount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); |  | ||||||
|   unpackResourceRecord(dv, q, ab); |  | ||||||
|   console.log(''); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log('//  ADDITIONAL  //'); |  | ||||||
| console.log('//////////////////'); |  | ||||||
| console.log(''); |  | ||||||
| for (count = 0; count < arcount; count += 1) { |  | ||||||
|   console.log(''); |  | ||||||
|   console.log('Additional', count + 1, 'of', arcount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); |  | ||||||
|   unpackResourceRecord(dv, q, ab); |  | ||||||
|   console.log(''); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| console.log(''); |  | ||||||
| console.log('total bytes', dv.byteLength); |  | ||||||
| console.log('total bytes read', q.total); |  | ||||||
| console.log(''); |  | ||||||
| 
 |  | ||||||
| }()); |  | ||||||
| @ -1,46 +0,0 @@ | |||||||
| #!/usr/bin/env
 |  | ||||||
| (function () { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| var cli = { port: 65153, address: null, udp6: false, bin: process.argv[2] }; |  | ||||||
| var dgram = require('dgram'); |  | ||||||
| var server = dgram.createSocket({ |  | ||||||
|   type: cli.udp6 ? 'udp6' : 'udp4' |  | ||||||
| , reuseAddr: true |  | ||||||
| }); |  | ||||||
| var handlers = {}; |  | ||||||
| var bin = require('fs').readFileSync(cli.bin, null); |  | ||||||
| 
 |  | ||||||
| handlers.onMessage = function (nb, rinfo) { |  | ||||||
|   console.log('[DEBUG] got a message'); |  | ||||||
| 
 |  | ||||||
|   // replace the id to match
 |  | ||||||
|   bin[0] = nb[0]; |  | ||||||
|   bin[1] = nb[1]; |  | ||||||
|   server.send(bin, rinfo.port, rinfo.address, function () { |  | ||||||
|     console.log('[DEBUG] sent response'); |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| handlers.onListening = function () { |  | ||||||
|   /*jshint validthis:true*/ |  | ||||||
|   var server = this; |  | ||||||
| 
 |  | ||||||
|   if (cli.mdns || '224.0.0.251' === cli.nameserver) { |  | ||||||
|     server.setBroadcast(true); |  | ||||||
|     server.addMembership(cli.nameserver); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   console.log(''); |  | ||||||
|   console.log('Bound and Listening:'); |  | ||||||
|   console.log(server.address().address + '#' + server.address().port + ' (' + server.type + ')'); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| server.bind({ |  | ||||||
|   port: cli.port |  | ||||||
| , address: cli.address |  | ||||||
| }); |  | ||||||
| server.on('listening', handlers.onListening); |  | ||||||
| server.on('message', handlers.onMessage); |  | ||||||
| 
 |  | ||||||
| }()); |  | ||||||
| @ -9,60 +9,54 @@ var path = require('path'); | |||||||
| var filename = process.argv[2]; | var filename = process.argv[2]; | ||||||
| var outname = process.argv[3]; | var outname = process.argv[3]; | ||||||
| if (!filename) { | if (!filename) { | ||||||
| 	console.error( |   console.error("Usage: node bin/dns-pack.js <path/to/sample.json> <path/to/output.bin>"); | ||||||
| 		'Usage: node bin/dns-pack.js <path/to/sample.json> <path/to/output.bin>' |   console.error("Example: node bin/dns-pack.js ./samples/services-0.mdns.json ./services-0.mdns.bin"); | ||||||
| 	); |   process.exit(1); | ||||||
| 	console.error( |   return; | ||||||
| 		'Example: node bin/dns-pack.js ./samples/services-0.mdns.json ./services-0.mdns.bin' |  | ||||||
| 	); |  | ||||||
| 	process.exit(1); |  | ||||||
| 	return; |  | ||||||
| } | } | ||||||
| if (!outname) { | if (!outname) { | ||||||
| 	console.warn(''); |   console.warn(''); | ||||||
| 	console.warn( |   console.warn( | ||||||
| 		"Usage: node bin/dns-pack.js '" + |     "Usage: node bin/dns-pack.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '') + ".bin'" | ||||||
| 			filename + |   ); | ||||||
| 			"' './" + |   console.warn(''); | ||||||
| 			path.basename(filename).replace(path.extname(filename), '') + |  | ||||||
| 			".bin'" |  | ||||||
| 	); |  | ||||||
| 	console.warn(''); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| var PromiseA = require('bluebird'); | var PromiseA = require('bluebird'); | ||||||
| var fs = PromiseA.promisifyAll(require('fs')); | var fs = PromiseA.promisifyAll(require('fs')); | ||||||
| var dnsjs = require('../').DNSPacket; | var dnsjs = require('../').DNSPacket; | ||||||
| 
 | 
 | ||||||
| fs.readFileAsync(filename, null).then(function(nb) { | fs.readFileAsync(filename, null).then(function (nb) { | ||||||
| 	//
 |   //
 | ||||||
| 	// current reference impl
 |   // current reference impl
 | ||||||
| 	//
 |   //
 | ||||||
| 	//console.log(require('native-dns-packet').parse(nb));
 |   //console.log(require('native-dns-packet').parse(nb));
 | ||||||
| 
 | 
 | ||||||
| 	//
 |  | ||||||
| 	// other reference impl
 |  | ||||||
| 	//
 |  | ||||||
| 	//console.log(require('dns-js').DNSPacket.parse(nb));
 |  | ||||||
| 
 | 
 | ||||||
| 	// nb is a Uint8Array (ArrayBufferView) for nb.buffer
 |   //
 | ||||||
| 	// nb.buffer is the actual ArrayBuffer
 |   // other reference impl
 | ||||||
|  |   //
 | ||||||
|  |   //console.log(require('dns-js').DNSPacket.parse(nb));
 | ||||||
| 
 | 
 | ||||||
| 	//var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
 |   // nb is a Uint8Array (ArrayBufferView) for nb.buffer
 | ||||||
| 	var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); |   // nb.buffer is the actual ArrayBuffer
 | ||||||
| 
 | 
 | ||||||
| 	//console.log('[packet]', nb.byteLength, 'bytes:');
 |   //var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
 | ||||||
| 	//console.log(JSON.stringify(packet, null, 2));
 |   var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); | ||||||
| 
 | 
 | ||||||
| 	//TODO hexdump packet
 |   //console.log('[packet]', nb.byteLength, 'bytes:');
 | ||||||
| 	var hexdump = require('@root/hexdump'); |   //console.log(JSON.stringify(packet, null, 2));
 | ||||||
| 	var str = hexdump(packet); |  | ||||||
| 
 | 
 | ||||||
| 	console.log(str); |   //TODO hexdump packet
 | ||||||
|  |   var hexdump = require('hexdump.js').hexdump; | ||||||
|  |   var str = hexdump(packet); | ||||||
| 
 | 
 | ||||||
| 	if (outname) { |   console.log(str); | ||||||
| 		fs.writeFileSync(outname, packet, null); | 
 | ||||||
| 		console.log(''); |   if (outname) { | ||||||
| 		console.log("wrote '" + outname + "'"); |     fs.writeFileSync(outname, packet, null); | ||||||
| 	} |     console.log(''); | ||||||
|  |     console.log("wrote '" + outname + "'"); | ||||||
|  |   } | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										199
									
								
								bin/dns-test.js
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								bin/dns-test.js
									
									
									
									
									
								
							| @ -10,144 +10,117 @@ var filename = process.argv[2]; | |||||||
| var outname = process.argv[3]; | var outname = process.argv[3]; | ||||||
| 
 | 
 | ||||||
| if (!filename || /(-h)|(--help)/.test(process.argv.join(' '))) { | if (!filename || /(-h)|(--help)/.test(process.argv.join(' '))) { | ||||||
| 	console.error(''); |   console.error(""); | ||||||
| 	console.error( |   console.error("Accepts a DNS packet (binary or json), converts it, and then converts it back to verify the function of the parser and packer"); | ||||||
| 		'Accepts a DNS packet (binary or json), converts it, and then converts it back to verify the function of the parser and packer' |   console.error(""); | ||||||
| 	); |   console.error("Usage: node bin/dns-test.js <path/to/sample.json|.bin> <path/to/sample.bin|.json>"); | ||||||
| 	console.error(''); |   console.error("Example: node bin/dns-test.js ./samples/services-0.mdns.json ./samples/services-0.mdns.bin"); | ||||||
| 	console.error( |   process.exit(1); | ||||||
| 		'Usage: node bin/dns-test.js <path/to/sample.json|.bin> <path/to/sample.bin|.json>' |   return; | ||||||
| 	); |  | ||||||
| 	console.error( |  | ||||||
| 		'Example: node bin/dns-test.js ./samples/services-0.mdns.json ./samples/services-0.mdns.bin' |  | ||||||
| 	); |  | ||||||
| 	process.exit(1); |  | ||||||
| 	return; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var PromiseA = require('bluebird'); | var PromiseA = require('bluebird'); | ||||||
| var fs = PromiseA.promisifyAll(require('fs')); | var fs = PromiseA.promisifyAll(require('fs')); | ||||||
| var dnsjs = require('../').DNSPacket; | var dnsjs = require('../').DNSPacket; | ||||||
| var extname = path | var extname = path.extname(filename).substr(1).toLowerCase(); | ||||||
| 	.extname(filename) |  | ||||||
| 	.substr(1) |  | ||||||
| 	.toLowerCase(); |  | ||||||
| 
 | 
 | ||||||
| if ('json' !== extname && 'bin' !== extname) { | if ('json' !== extname && 'bin' !== extname) { | ||||||
| 	console.error( |   console.error("The file extension must end in .json or .bin (raw DNS packet)"); | ||||||
| 		'The file extension must end in .json or .bin (raw DNS packet)' |   process.exit(3); | ||||||
| 	); |   return; | ||||||
| 	process.exit(3); |  | ||||||
| 	return; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var hexdump = require('@root/hexdump'); | var hexdump = require('hexdump.js').hexdump; | ||||||
| 
 | 
 | ||||||
| function testJsonAsync(nb) { | function testJsonAsync(nb) { | ||||||
| 	var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); |   var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); | ||||||
| 	var str = hexdump(packet); |   var str = hexdump(packet); | ||||||
| 	console.info(str); |   console.info(str); | ||||||
| 	var json = dnsjs.parse(packet); |   var json = dnsjs.parse(packet); | ||||||
| 	if (json.error) { |   if (json.error) { | ||||||
| 		console.error(json); |     console.error(json); | ||||||
| 		process.exit(37); |     process.exit(37); | ||||||
| 		return; |     return; | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	console.info('[OK] JSON -> binary -> JSON'); |   console.info("[OK] JSON -> binary -> JSON"); | ||||||
| 
 | 
 | ||||||
| 	if (!outname) { |   if (!outname) { | ||||||
| 		console.warn(''); |     console.warn(''); | ||||||
| 		console.warn( |     console.warn( | ||||||
| 			"Usage: node bin/dns-test.js '" + |       "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.bin') + "'" | ||||||
| 				filename + |     ); | ||||||
| 				"' './" + |     console.warn(''); | ||||||
| 				path |     return; | ||||||
| 					.basename(filename) |   } | ||||||
| 					.replace(path.extname(filename), '.bin') + |  | ||||||
| 				"'" |  | ||||||
| 		); |  | ||||||
| 		console.warn(''); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	fs.writeFileSync(outname, packet, null); |   fs.writeFileSync(outname, packet, null); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function testBinAsync(nb) { | function testBinAsync(nb) { | ||||||
| 	var bin = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); |   var bin = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); | ||||||
| 	var json = dnsjs.parse(bin); |   var json = dnsjs.parse(bin); | ||||||
| 	if (json.error) { |   if (json.error) { | ||||||
| 		console.error(json); |     console.error(json); | ||||||
| 		process.exit(38); |     process.exit(38); | ||||||
| 		return; |     return; | ||||||
| 	} |   } | ||||||
| 	var bin2 = dnsjs.write(json); |   var bin2 = dnsjs.write(json); | ||||||
| 	//var debugname = outname || path.basename(filename);
 |   //var debugname = outname || path.basename(filename);
 | ||||||
| 	//fs.writeFileSync(debugname.replace(path.extname(debugname), '.bin'), bin2, null);
 |   //fs.writeFileSync(debugname.replace(path.extname(debugname), '.bin'), bin2, null);
 | ||||||
| 	var json2 = dnsjs.parse(bin2); |   var json2 = dnsjs.parse(bin2); | ||||||
| 	if (json2.error) { |   if (json2.error) { | ||||||
| 		console.error(json2); |     console.error(json2); | ||||||
| 		process.exit(37); |     process.exit(37); | ||||||
| 		return; |     return; | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	var assert = require('assert'); |   var assert = require('assert'); | ||||||
| 	// EXPLANATION:
 |   // EXPLANATION:
 | ||||||
| 	// The strategy used for compression pointers has not yet been proven
 |   // The strategy used for compression pointers has not yet been proven
 | ||||||
| 	// as deterministic... and we don't implement them anyway, so this may not be the same
 |   // as deterministic... and we don't implement them anyway, so this may not be the same
 | ||||||
| 	json = JSON.parse( |   json = JSON.parse(JSON.stringify(json) | ||||||
| 		JSON.stringify(json) |     .replace(/,"labels":.*?\]/, '') | ||||||
| 			.replace(/,"labels":.*?\]/, '') |     .replace(/,"cpcount":\d+/, '') | ||||||
| 			.replace(/,"cpcount":\d+/, '') |   ); | ||||||
| 	); |   json2 = JSON.parse(JSON.stringify(json2) | ||||||
| 	json2 = JSON.parse( |     .replace(/,"labels":.*?\]/, '') | ||||||
| 		JSON.stringify(json2) |     .replace(/,"cpcount":\d+/, '') | ||||||
| 			.replace(/,"labels":.*?\]/, '') |   ); | ||||||
| 			.replace(/,"cpcount":\d+/, '') |   //json2 = JSON.parse(JSON.stringify(json2));
 | ||||||
| 	); |   try { | ||||||
| 	//json2 = JSON.parse(JSON.stringify(json2));
 |     assert.deepEqual(json, json2); | ||||||
| 	try { |   } catch(e) { | ||||||
| 		assert.deepEqual(json, json2); |     console.error(''); | ||||||
| 	} catch (e) { |     console.error('Original'); | ||||||
| 		console.error(''); |     console.error(JSON.stringify(json, null, 2)); | ||||||
| 		console.error('Original'); |     console.error(''); | ||||||
| 		console.error(JSON.stringify(json, null, 2)); |     console.error('Converted'); | ||||||
| 		console.error(''); |     console.error(JSON.stringify(json2, null, 2)); | ||||||
| 		console.error('Converted'); |     console.error(''); | ||||||
| 		console.error(JSON.stringify(json2, null, 2)); |     process.exit(422); | ||||||
| 		console.error(''); |     return; | ||||||
| 		process.exit(422); |   } | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	console.info('[OK] binary -> JSON -> binary -> JSON'); |   console.info("[OK] binary -> JSON -> binary -> JSON"); | ||||||
| 	console.warn( |   console.warn("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); | ||||||
| 		'(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)' |  | ||||||
| 	); |  | ||||||
| 
 | 
 | ||||||
| 	if (!outname) { |   if (!outname) { | ||||||
| 		console.warn(''); |     console.warn(''); | ||||||
| 		console.warn( |     console.warn( | ||||||
| 			"Usage: node bin/dns-test.js '" + |       "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.json') + "'" | ||||||
| 				filename + |     ); | ||||||
| 				"' './" + |     console.warn(''); | ||||||
| 				path |     return; | ||||||
| 					.basename(filename) |   } | ||||||
| 					.replace(path.extname(filename), '.json') + |  | ||||||
| 				"'" |  | ||||||
| 		); |  | ||||||
| 		console.warn(''); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	fs.writeFileSync(outname, JSON.stringify(json, null, 2), null); |   fs.writeFileSync(outname, JSON.stringify(json, null, 2), null); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if ('json' === extname) { | if ('json' === extname) { | ||||||
| 	return fs.readFileAsync(filename, null).then(testJsonAsync); |   return fs.readFileAsync(filename, null).then(testJsonAsync); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if ('bin' === extname) { | if ('bin' === extname) { | ||||||
| 	return fs.readFileAsync(filename, null).then(testBinAsync); |   return fs.readFileAsync(filename, null).then(testBinAsync); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,13 +0,0 @@ | |||||||
| (function (exports) { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| var opcodes = exports.DNS_OPCODES = { |  | ||||||
|   QUERY:  0x00  //  0
 |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| // and in reverse
 |  | ||||||
| Object.keys(opcodes).forEach(function (key) { |  | ||||||
|   opcodes[opcodes[key]] = key; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| }('undefined' !== typeof window ? window : exports)); |  | ||||||
| @ -29,7 +29,7 @@ var dnspack = exports.DNS_PACKER = { | |||||||
|     dv.setUint16(10, (packet.additional||[]).length + (packet.payload ? 1 : 0), false); |     dv.setUint16(10, (packet.additional||[]).length + (packet.payload ? 1 : 0), false); | ||||||
| 
 | 
 | ||||||
|     function lint(r) { |     function lint(r) { | ||||||
|       if (!r.name && 'string' !== typeof r.name) { |       if (!r.name) { | ||||||
|         throw new Error("missing name"); |         throw new Error("missing name"); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
| @ -70,8 +70,7 @@ var dnspack = exports.DNS_PACKER = { | |||||||
|         labelsMap[total] = { total: total, name: sequence }; |         labelsMap[total] = { total: total, name: sequence }; | ||||||
|         labelsMap[sequence] = labelsMap[total]; |         labelsMap[sequence] = labelsMap[total]; | ||||||
|       } |       } | ||||||
|       // allow 0-length string for TLD root NS queries
 |       sequence.split('.').forEach(function (label) { | ||||||
|       (sequence && sequence.split('.') || []).forEach(function (label) { |  | ||||||
|         dv.setUint8(total, label.length, false); |         dv.setUint8(total, label.length, false); | ||||||
|         total += 1; |         total += 1; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,15 +0,0 @@ | |||||||
| (function (exports) { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| var rcodes = exports.DNS_RCODES = { |  | ||||||
|   SUCCESS:  0x00  //   0
 |  | ||||||
| , NXDOMAIN: 0x03  //   3
 |  | ||||||
| , REFUSED:  0x05  //   5
 |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| // and in reverse
 |  | ||||||
| Object.keys(rcodes).forEach(function (key) { |  | ||||||
|   rcodes[rcodes[key]] = key; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| }('undefined' !== typeof window ? window : exports)); |  | ||||||
| @ -49,8 +49,8 @@ var types = exports.DNS_TYPES = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // and in reverse
 | // and in reverse
 | ||||||
| Object.keys(types).forEach(function (key) { | for (var key in types) { | ||||||
|   types[types[key]] = key; |   types[types[key]] = key; | ||||||
| }); | } | ||||||
| 
 | 
 | ||||||
| }('undefined' !== typeof window ? window : exports)); | }('undefined' !== typeof window ? window : exports)); | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
| //
 | //
 | ||||||
| // NOTE:
 | // NOTE:
 | ||||||
| // "NAME"s are terminated with 0x00
 | // "NAME"s are terminated with 0x00
 | ||||||
| // "RDATA" is terminated by its length, but its labels may null-terminated
 | // "RDATA" is terminated by its length
 | ||||||
| exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { | exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { | ||||||
|   if (q.cpcount > 25) { |   if (q.cpcount > 25) { | ||||||
|     throw new Error("compression pointer loop detected (over 25 pointers seems like a loop)"); |     throw new Error("compression pointer loop detected (over 25 pointers seems like a loop)"); | ||||||
| @ -26,34 +26,19 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { | |||||||
|     len = ui8[total]; |     len = ui8[total]; | ||||||
|     if (len === undefined){ |     if (len === undefined){ | ||||||
|       // RDATA is terminated by undefined, not len === 0
 |       // RDATA is terminated by undefined, not len === 0
 | ||||||
|       q.trunc = true; |  | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Handle message compression pointers. See 4.1.4 of RFC1035 for details.
 |     // Handle message compression pointers. See 4.1.4 of RFC1035 for details.
 | ||||||
|     // 0xc0 // 192 // parseInt('11000000', 2).toString(16)
 |  | ||||||
|     if (len >= 0xc0) { |     if (len >= 0xc0) { | ||||||
|       // Only the two highest bits are used to signify the pointer.
 |  | ||||||
|       // The remaining bits may be used to specify the address of the pointer
 |  | ||||||
|       // (it would seem that only 1 extra bit is actually used since the message size is 512 bytes)
 |  | ||||||
|       var cpptr = ((ui8[total] & 0x3f) << 8) |  ui8[total + 1]; |       var cpptr = ((ui8[total] & 0x3f) << 8) |  ui8[total + 1]; | ||||||
|       if (cpptr >= total) { |  | ||||||
|         throw new Error( |  | ||||||
|           "Compression pointer at" |  | ||||||
|         + " 0x" + total.toString() + " (" + total + ")" |  | ||||||
|         + " points forward to" |  | ||||||
|         + " 0x" + cpptr.toString(16) + " (" + cpptr + ")" |  | ||||||
|         ); |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       // We're not coming back, so if this is the first time we're following one of
 |       // We're not coming back, so if this is the first time we're following one of
 | ||||||
|       // these pointers we up the byteLength to mark the pointer as part of the label
 |       // these pointers we up the byteLength to mark the pointer as part of the label
 | ||||||
|       if (!q.cpcount) { |       if (!q.cpcount) { | ||||||
|         q.byteLength += 2; // cp and len
 |         q.byteLength += 2; // cp and len
 | ||||||
|         //q.cps = [];
 |  | ||||||
|       } |       } | ||||||
|       q.cpcount += 1; |       q.cpcount += 1; | ||||||
|       //q.cps.push(cpptr);
 |  | ||||||
| 
 | 
 | ||||||
|       // recursion
 |       // recursion
 | ||||||
|       return exports.DNS_UNPACK_LABELS(ui8, cpptr, q); |       return exports.DNS_UNPACK_LABELS(ui8, cpptr, q); | ||||||
|  | |||||||
| @ -1,27 +0,0 @@ | |||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| var DNSPacket = require('../').DNSPacket; |  | ||||||
| var rnd = Math.floor(Math.random() * 65536); |  | ||||||
| 
 |  | ||||||
| var query = { |  | ||||||
| 	header: { |  | ||||||
| 		id: rnd, |  | ||||||
| 		qr: 0, |  | ||||||
| 		opcode: 0, |  | ||||||
| 		aa: 0, |  | ||||||
| 		rd: 1, |  | ||||||
| 		ra: 0, |  | ||||||
| 		rcode: 0 |  | ||||||
| 	}, |  | ||||||
| 	question: [ |  | ||||||
| 		{ |  | ||||||
| 			name: 'google.com', |  | ||||||
| 			typeName: 'A', |  | ||||||
| 			className: 'IN' |  | ||||||
| 		} |  | ||||||
| 	] |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| var buffer = DNSPacket.pack(query); |  | ||||||
| 
 |  | ||||||
| console.info(Buffer.from(buffer)); |  | ||||||
							
								
								
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
| 	"name": "dns-suite", |  | ||||||
| 	"version": "1.2.13", |  | ||||||
| 	"lockfileVersion": 1, |  | ||||||
| 	"requires": true, |  | ||||||
| 	"dependencies": { |  | ||||||
| 		"@root/hexdump": { |  | ||||||
| 			"version": "1.1.1", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@root/hexdump/-/hexdump-1.1.1.tgz", |  | ||||||
| 			"integrity": "sha512-AmrmLOutlzctR599ittO06lINOco1TIqb0c1wu83fP2Eoi5iSvx7kVWC4mDufze8rxPewC+aQOx4e6Pw7izV4A==" |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										45
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								package.json
									
									
									
									
									
								
							| @ -1,25 +1,24 @@ | |||||||
| { | { | ||||||
| 	"name": "dns-suite", |   "name": "dns-suite", | ||||||
| 	"version": "1.2.13", |   "version": "1.2.2", | ||||||
| 	"description": "DNS implemented in Vanilla JS for Node.js and Browsers", |   "description": "testing dns", | ||||||
| 	"main": "dns.js", |   "main": "dns.js", | ||||||
| 	"homepage": "https://git.coolaj86.com/coolaj86/dns-suite.js", |   "bin": { | ||||||
| 	"bin": { |     "dns-pack.js": "bin/dns-pack.js", | ||||||
| 		"dns-pack.js": "bin/dns-pack.js", |     "dns-parse.js": "bin/dns-parse.js", | ||||||
| 		"dns-parse.js": "bin/dns-parse.js", |     "dns-test.js": "bin/dns-test.js", | ||||||
| 		"dns-test.js": "bin/dns-test.js", |     "mdns-capture.js": "bin/mdns-capture.js" | ||||||
| 		"mdns-capture.js": "bin/mdns-capture.js" |   }, | ||||||
| 	}, |   "scripts": { | ||||||
| 	"scripts": { |     "test": "node test/parser.js && node test/packer.js" | ||||||
| 		"test": "node test/parser.js && node test/packer.js" |   }, | ||||||
| 	}, |   "repository": { | ||||||
| 	"repository": { |     "type": "git", | ||||||
| 		"type": "git", |     "url": "git@git.daplie.com:Daplie/dns-suite.git" | ||||||
| 		"url": "https://git.coolaj86.com:coolaj86/dns-suite.js.git" |   }, | ||||||
| 	}, |   "author": "", | ||||||
| 	"author": "", |   "license": "(MIT or Apache2)", | ||||||
| 	"license": "MPL-2.0", |   "developmentDependencies": { | ||||||
| 	"dependencies": { |     "bluebird": "^3.5.0" | ||||||
| 		"@root/hexdump": "^1.1.1" |   } | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,69 +0,0 @@ | |||||||
| (function (exports) { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
| // RFC 6844
 |  | ||||||
| // Explanation: https://tools.ietf.org/html/rfc6844#section-3
 |  | ||||||
| // Binary Format: https://tools.ietf.org/html/rfc6844#section-5
 |  | ||||||
| // Real-world Usage: https://support.dnsimple.com/articles/caa-record/
 |  | ||||||
| 
 |  | ||||||
| // A Certification Authority Authorization (CAA) record is used to specify which
 |  | ||||||
| // certificate authorities (CAs) are allowed to issue certificates for a domain.
 |  | ||||||
| 
 |  | ||||||
| // Value    Meaning/Use
 |  | ||||||
| //
 |  | ||||||
| // Flag     An unsigned integer between 0-255.
 |  | ||||||
| //          It is currently used to represent the critical flag, that has a
 |  | ||||||
| //          specific meaning per RFC 6844
 |  | ||||||
| // Tag      An ASCII string that represents the identifier of the property
 |  | ||||||
| //          represented by the record.
 |  | ||||||
| // Value    The value associated with the tag.
 |  | ||||||
| 
 |  | ||||||
| // The RFC currently defines 3 available tags:
 |  | ||||||
| //
 |  | ||||||
| // - issue:     explicity authorizes a single certificate authority to issue a
 |  | ||||||
| //              certificate (any type) for the hostname.
 |  | ||||||
| // - issuewild: explicity authorizes a single certificate authority to issue a
 |  | ||||||
| //              wildcard certificate (and only wildcard) for the hostname.
 |  | ||||||
| // - iodef:     specifies an URL to which a certificate authority may report
 |  | ||||||
| //              policy violations.
 |  | ||||||
| 
 |  | ||||||
| exports.DNS_PACKER_TYPE_CAA = function (ab, dv, total, record) { |  | ||||||
|   if ('number' !== typeof record.flag || isNaN(record.flag) || record.flag < 0 || record.flag > 255) { |  | ||||||
|     console.log(record); |  | ||||||
|     throw new Error("bad CAA flag:", record.flag); |  | ||||||
|   } |  | ||||||
|   if ('string' !== typeof record.tag || !record.tag || record.tag.length > 255) { |  | ||||||
|     throw new Error("bad CAA tag:", record.tag); |  | ||||||
|   } |  | ||||||
|   if ('string' !== typeof record.value || !record.value) { |  | ||||||
|     throw new Error("bad CAA value:", record.value); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // RDLEN = flag (1 byte) + taglen (1 byte) + tagstr (taglen bytes) + valuestr (valuelen bytes)
 |  | ||||||
|   dv.setUint16(total, 1 + 1 + record.tag.length + record.value.length, false); |  | ||||||
|   total += 2; |  | ||||||
| 
 |  | ||||||
|   // FLAG
 |  | ||||||
|   dv.setUint8(total, record.flag, false); |  | ||||||
|   total += 1; |  | ||||||
| 
 |  | ||||||
|   // TAG LENGTH
 |  | ||||||
|   dv.setUint8(total, record.tag.length, false); |  | ||||||
|   total += 1; |  | ||||||
| 
 |  | ||||||
|   // TAG
 |  | ||||||
|   record.tag.split('').forEach(function (ch) { |  | ||||||
|     dv.setUint8(total, ch.charCodeAt(0), false); |  | ||||||
|     total += 1; |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   // VALUE
 |  | ||||||
|   record.value.split('').forEach(function (ch) { |  | ||||||
|     dv.setUint8(total, ch.charCodeAt(0), false); |  | ||||||
|     total += 1; |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   return total; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| }('undefined' !== typeof window ? window : exports)); |  | ||||||
| @ -15,22 +15,20 @@ exports.DNS_PACKER_TYPE_CNAME = function (ab, dv, total, record) { | |||||||
|   // RDATA
 |   // RDATA
 | ||||||
|   // a sequence of labels
 |   // a sequence of labels
 | ||||||
|   record.data.split('.').forEach(function (label) { |   record.data.split('.').forEach(function (label) { | ||||||
|     cnameLen += 1 + label.length; |   cnameLen += 1 + label.length; | ||||||
| 
 |    | ||||||
|     dv.setUint8(total, label.length, false); |   dv.setUint8(total, label.length, false); | ||||||
|     total += 1; |  | ||||||
| 
 |  | ||||||
|     label.split('').forEach(function (ch) { |  | ||||||
|       dv.setUint8(total, ch.charCodeAt(0), false); |  | ||||||
|       total += 1; |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
|   dv.setUint8(total, 0x00, false); |  | ||||||
|   total += 1; |   total += 1; | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   label.split('').forEach(function (ch) { | ||||||
|   dv.setUint16(rdLenIndex, record.data.length + 2, false); |     dv.setUint8(total, ch.charCodeAt(0), false); | ||||||
|  |     total += 1; | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
| 
 | 
 | ||||||
|  |   // RDLENGTH
 | ||||||
|  |   dv.setUint16(rdLenIndex, record.data.length + 1, false); | ||||||
|  |    | ||||||
|   return total; |   return total; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ exports.DNS_PACKER_TYPE_MX = function (ab, dv, total, record) { | |||||||
|   // 16-bit priority and a sequence of labels as the exchange
 |   // 16-bit priority and a sequence of labels as the exchange
 | ||||||
|   record.exchange.split('.').forEach(function (label) { |   record.exchange.split('.').forEach(function (label) { | ||||||
|     mxLen += 1 + label.length; |     mxLen += 1 + label.length; | ||||||
| 
 |      | ||||||
|     dv.setUint8(total, label.length, false); |     dv.setUint8(total, label.length, false); | ||||||
|     total += 1; |     total += 1; | ||||||
| 
 | 
 | ||||||
| @ -31,13 +31,10 @@ exports.DNS_PACKER_TYPE_MX = function (ab, dv, total, record) { | |||||||
|       total += 1; |       total += 1; | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|   dv.setUint8(total, 0x00, false); |  | ||||||
|   total += 1; |  | ||||||
|   mxLen += 1; |  | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   // RDLENGTH
 | ||||||
|   dv.setUint16(rdLenIndex, mxLen, false); |   dv.setUint16(rdLenIndex, mxLen, false); | ||||||
| 
 |    | ||||||
|   return total; |   return total; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,34 +1,36 @@ | |||||||
| // NOTE: this should be EXACTLY the same as PTR
 |  | ||||||
| 
 |  | ||||||
| (function (exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| // NS name for the supplied domain. May be label, pointer or any combination
 | // NS name for the supplied domain. May be label, pointer or any combination
 | ||||||
| 
 | 
 | ||||||
| exports.DNS_PACKER_TYPE_NS = function (ab, dv, total, record) { | exports.DNS_PACKER_TYPE_NS = function (ab, dv, total, record) { | ||||||
|   if (!record.data) { |   if(!record.data){ | ||||||
|       throw new Error("no data on NS record"); |       throw new Error("no data on NS record"); | ||||||
|   } |   } | ||||||
|  |    | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   var nsLen = 0; | ||||||
|   // leading len and length of string and trailing null (all dots become lengths)
 |   var rdLenIndex = total; | ||||||
|   dv.setUint16(total, record.data.length + 2, false); |   total +=2; | ||||||
|   total += 2; |  | ||||||
| 
 | 
 | ||||||
|   // RDATA
 |   // RDATA 
 | ||||||
|   // a sequence of labels
 |   // a sequence of labels
 | ||||||
|   record.data.split('.').forEach(function (label) { |   record.data.split('.').forEach(function(label) { | ||||||
| 
 |       nsLen += 1 + label.length; | ||||||
|  |        | ||||||
|       dv.setUint8(total, label.length, false); |       dv.setUint8(total, label.length, false); | ||||||
|       total += 1; |       total += 1; | ||||||
| 
 | 
 | ||||||
|       label.split('').forEach(function (ch) { |       label.split('').forEach(function (ch){ | ||||||
|           dv.setUint8(total, ch.charCodeAt(0), false); |           dv.setUint8(total, ch.charCodeAt(0), false); | ||||||
|           total += 1; |           total += 1; | ||||||
|       }); |       }); | ||||||
|   }); |   }); | ||||||
|   dv.setUint8(total, 0x00, false); | 
 | ||||||
|   total += 1; |   // RDLENGTH
 | ||||||
|  |   dv.setUint16(rdLenIndex, record.data.length + 1, false); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|   return total; |   return total; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,35 +1,35 @@ | |||||||
| // NOTE: this should be EXACTLY the same as NS
 |  | ||||||
| 
 |  | ||||||
| (function (exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| // The host name that represents the supplied UP address
 | // The host name that represents the supplied UP address
 | ||||||
| // May be a label, pointer or any combination
 | // May be a label, pointer or any combination 
 | ||||||
| 
 | 
 | ||||||
| exports.DNS_PACKER_TYPE_PTR = function (ab, dv, total, record) { | exports.DNS_PACKER_TYPE_PTR = function (ab, dv, total, record) { | ||||||
|   if (!record.data) { |   if (!record.data) { | ||||||
|     throw new Error("no data for PTR record"); |     throw new Error("no data for PTR record"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   var ptrLen = 0; | ||||||
|   // leading len and length of string and trailing null (all dots become lengths)
 |   var rdLenIndex = total; | ||||||
|   dv.setUint16(total, record.data.length + 2, false); |  | ||||||
|   total += 2; |   total += 2; | ||||||
| 
 | 
 | ||||||
|   // RDATA
 |   // RDATA 
 | ||||||
|   // a sequence of labels
 |   // a sequence of labels
 | ||||||
|   record.data.split('.').forEach(function (label) { |   record.data.split('.').forEach(function (label){ | ||||||
|  |       console.log("the labels are: " + label); | ||||||
|  |       ptrLen += 1 + label.length; | ||||||
| 
 | 
 | ||||||
|       dv.setUint8(total, label.length, false); |       dv.setUint8(total, label.length, false); | ||||||
|       total += 1; |       total += 1; | ||||||
| 
 | 
 | ||||||
|       label.split('').forEach(function (ch) { |       label.split('').forEach(function (ch){ | ||||||
|           dv.setUint8(total, ch.charCodeAt(0), false); |           dv.setUint8(total, ch.charCodeAt(0), false); | ||||||
|           total += 1; |           total += 1; | ||||||
|       }); |       }); | ||||||
|   }); |   }); | ||||||
|   dv.setUint8(total, 0x00, false); | 
 | ||||||
|   total += 1; |   // RDLENGTH
 | ||||||
|  |   dv.setUint16(rdLenIndex, record.data.length + 1, false); | ||||||
| 
 | 
 | ||||||
|   return total; |   return total; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| // http://www.zytrax.com/books/dns/ch8/soa.html
 | // http://www.zytrax.com/books/dns/ch8/soa.html
 | ||||||
| // https://github.com/tjfontaine/node-dns#resourcerecord
 |  | ||||||
| 
 | 
 | ||||||
| // Value              Meaning/Use
 | // Value              Meaning/Use
 | ||||||
| // Primary NS         Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination
 | // Primary NS         Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination
 | ||||||
| @ -14,29 +13,25 @@ | |||||||
| // Minimum TTL        Unsigned 32-bit integer
 | // Minimum TTL        Unsigned 32-bit integer
 | ||||||
| 
 | 
 | ||||||
| exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | ||||||
|   function notNumber(n) { |   if(!record.name_server){ | ||||||
|     return 'number' !== typeof n || isNaN(n); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if (!record.primary && !record.name_server) { |  | ||||||
|     throw new Error("no name server for SOA record"); |     throw new Error("no name server for SOA record"); | ||||||
|   } |   } | ||||||
|   if (!record.admin && !record.email_addr) { |   if(!record.email_addr){ | ||||||
|     throw new Error("ne email address for SOA record"); |     throw new Error("ne email address for SOA record"); | ||||||
|   } |   } | ||||||
|   if (notNumber(record.serial) && notNumber(record.sn)) { |   if(!record.sn){ | ||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no serial number for SOA record"); | ||||||
|   } |   } | ||||||
|   if (notNumber(record.refresh) && notNumber(record.ref)) { |   if(!record.ref){ | ||||||
|     throw new Error("no refresh for SOA record"); |     throw new Error("no refresh for SOA record"); | ||||||
|   } |   } | ||||||
|   if (notNumber(record.retry) && notNumber(record.ret)) { |   if(!record.ret){ | ||||||
|     throw new Error("no update retry for SOA record"); |     throw new Error("no update retry for SOA record"); | ||||||
|   } |   } | ||||||
|   if (notNumber(record.expiration) && notNumber(record.ex)) { |   if(!record.ex){ | ||||||
|     throw new Error("no expiry for SOA record"); |     throw new Error("no expiry for SOA record"); | ||||||
|   } |   } | ||||||
|   if (notNumber(record.minimum) && notNumber(record.nx)) { |   if(!record.nx){ | ||||||
|     throw new Error("no nxdomain for SOA record"); |     throw new Error("no nxdomain for SOA record"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -45,9 +40,9 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|   var rdLenIndex = total; |   var rdLenIndex = total; | ||||||
|   total += 2; // Save space for RDLENGTH
 |   total += 2; // Save space for RDLENGTH
 | ||||||
| 
 | 
 | ||||||
|   //console.log('record.name_server', 1 + record.name_server.length, record.name_server);
 |   console.log('record.name_server', 1 + record.name_server.length, record.name_server); | ||||||
|   // pack name_server which is a sequence of labels
 |   // pack name_server which is a sequence of labels
 | ||||||
|   (record.primary || record.name_server).split('.').forEach(function (label) { |   record.name_server.split('.').forEach(function (label) { | ||||||
|     soaLen += (1 + label.length); |     soaLen += (1 + label.length); | ||||||
| 
 | 
 | ||||||
|     dv.setUint8(total, label.length, false); |     dv.setUint8(total, label.length, false); | ||||||
| @ -63,9 +58,9 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|   total += 1; |   total += 1; | ||||||
|   soaLen += 1; |   soaLen += 1; | ||||||
| 
 | 
 | ||||||
|   //console.log('record.email_addr', 1 + record.email_addr.length, record.email_addr);
 |   console.log('record.email_addr', 1 + record.email_addr.length, record.email_addr); | ||||||
|   // pack email address which is a sequence of labels
 |   // pack email address which is a sequence of labels
 | ||||||
|   (record.admin || record.email_addr).split('.').forEach(function (label) { |   record.email_addr.split('.').forEach(function (label) { | ||||||
|     soaLen += 1 + label.length; |     soaLen += 1 + label.length; | ||||||
| 
 | 
 | ||||||
|     dv.setUint8(total, label.length, false); |     dv.setUint8(total, label.length, false); | ||||||
| @ -82,20 +77,20 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|   soaLen += 1; |   soaLen += 1; | ||||||
| 
 | 
 | ||||||
|   // pack all 32-bit values
 |   // pack all 32-bit values
 | ||||||
|   dv.setUint32(total, parseInt(record.serial || record.sn, 10), false); |   dv.setUint32(total, parseInt(record.sn, 10), false); | ||||||
|   total+=4; |   total+=4; | ||||||
|   dv.setUint32(total, parseInt(record.refresh || record.ref, 10), false); |   dv.setUint32(total, parseInt(record.ref, 10), false); | ||||||
|   total+=4; |   total+=4; | ||||||
|   dv.setUint32(total, parseInt(record.retry || record.ret, 10), false); |   dv.setUint32(total, parseInt(record.ret, 10), false); | ||||||
|   total+=4; |   total+=4; | ||||||
|   dv.setUint32(total, parseInt(record.expiration || record.ex, 10), false); |   dv.setUint32(total, parseInt(record.ex, 10), false); | ||||||
|   total+=4; |   total+=4; | ||||||
|   dv.setUint32(total, parseInt(record.minimum || record.nx, 10), false); |   dv.setUint32(total, parseInt(record.nx, 10), false); | ||||||
|   total+=4; |   total+=4; | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   // RDLENGTH
 | ||||||
|   //console.log('rdAt', rdLenIndex);
 |   console.log('rdAt', rdLenIndex); | ||||||
|   //console.log('soaLen (lables + 2 + 20)', soaLen);
 |   console.log('soaLen (lables + 2 + 20)', soaLen); | ||||||
|   dv.setUint16(rdLenIndex, soaLen, false); |   dv.setUint16(rdLenIndex, soaLen, false); | ||||||
| 
 | 
 | ||||||
|   return total; |   return total; | ||||||
|  | |||||||
| @ -59,10 +59,6 @@ exports.DNS_PACKER_TYPE_SRV = function (ab, dv, total, record) { | |||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   dv.setUint8(total, 0x00, false); |  | ||||||
|   total += 1; |  | ||||||
|   srvLen += 1; |  | ||||||
| 
 |  | ||||||
|   // RDLENGTH
 |   // RDLENGTH
 | ||||||
| 
 | 
 | ||||||
|   dv.setUint16(rdLenIndex, srvLen, false); |   dv.setUint16(rdLenIndex, srvLen, false); | ||||||
|  | |||||||
| @ -2,44 +2,32 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| // Record type is just any text.
 | // Record type is just any text.
 | ||||||
| // RFC 1035 - 3.3. Standard RRs - <character-string>
 |  | ||||||
| // RFC 1035 - 3.3.14. TXT RDATA format
 |  | ||||||
| 
 | 
 | ||||||
| exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { | exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { | ||||||
|     if ('string' === typeof record.data) { |     if (!record.data){ | ||||||
|       console.warn("[WARN] 'data' should be an array of strings, not a single string"); |         throw new Error("no data for TXT record"); | ||||||
|       record.data = [ record.data ]; |  | ||||||
|     } |  | ||||||
|     if (!Array.isArray(record.data) || !record.data.length){ |  | ||||||
|         throw new Error("bad data or no data for TXT record"); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var txtLen = 0; |     var txtLen = 0; | ||||||
|     var rdLenIndex = total; |     var rdLenIndex = total; | ||||||
|     total += 2; // saving space for rdata length
 |     total += 3; | ||||||
| 
 | 
 | ||||||
|     // RDATA
 |     // RDATA
 | ||||||
|     record.data.forEach(function(str){ |     record.data.forEach(function(str){ | ||||||
| 
 | 
 | ||||||
|       if (str.length > 255) { |       str.split('').forEach(function(ch){ | ||||||
|         throw new Error("bad TXT string length " + str.length + " (max 255)"); |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       // size of this string
 |  | ||||||
|       dv.setUint8(total, str.length, false); |  | ||||||
|       total += 1; |  | ||||||
|       txtLen += 1; |       txtLen += 1; | ||||||
| 
 |       // console.log(chcim);
 | ||||||
|       str.split('').forEach(function(ch) { |       dv.setUint8(total, ch.charCodeAt(0), false); | ||||||
| 
 |       total += 1; | ||||||
|         dv.setUint8(total, ch.charCodeAt(0), false); |  | ||||||
|         total += 1; |  | ||||||
|         txtLen += 1; |  | ||||||
| 
 | 
 | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     dv.setUint16(rdLenIndex, txtLen, false); |     dv.setUint16(rdLenIndex, txtLen+1, false); | ||||||
|  |     dv.setUint8(rdLenIndex+2, txtLen, false); | ||||||
|  |     // total +=1;
 | ||||||
| 
 | 
 | ||||||
|     return total; |     return total; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,9 +1,6 @@ | |||||||
| (function (exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| // RFC 6844 https://tools.ietf.org/html/rfc6844#section-3
 |  | ||||||
| // https://support.dnsimple.com/articles/caa-record/
 |  | ||||||
| 
 |  | ||||||
| // A Certification Authority Authorization (CAA) record is used to specify which
 | // A Certification Authority Authorization (CAA) record is used to specify which
 | ||||||
| // certificate authorities (CAs) are allowed to issue certificates for a domain.
 | // certificate authorities (CAs) are allowed to issue certificates for a domain.
 | ||||||
| 
 | 
 | ||||||
| @ -29,23 +26,13 @@ exports.DNS_PARSER_TYPE_CAA = function (ab, packet, record) { | |||||||
| 
 | 
 | ||||||
|   var data = new Uint8Array(ab); |   var data = new Uint8Array(ab); | ||||||
|   var i = record.rdstart; |   var i = record.rdstart; | ||||||
|   var flag = data[i]; |   var flag = data[i++]; | ||||||
|   var mid = data[i + 1]; |   var mid = data[i++]; | ||||||
|   i += 2; |  | ||||||
|   mid += i; |   mid += i; | ||||||
|   var end = record.rdstart + record.rdlength; |   var end = record.rdstart + record.rdlength; | ||||||
|   var tag = ''; |   var tag = '', value = ''; | ||||||
|   var value = ''; |   while (i < mid) { tag += String.fromCharCode(data[i++]); } | ||||||
| 
 |   while (i < end) { value += String.fromCharCode(data[i++]); } | ||||||
|   while (i < mid) { |  | ||||||
|     tag += String.fromCharCode(data[i]); |  | ||||||
|     i += 1; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   while (i < end) { |  | ||||||
|     value += String.fromCharCode(data[i]); |  | ||||||
|     i += 1; |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   record.flag = flag; |   record.flag = flag; | ||||||
|   record.tag = tag; |   record.tag = tag; | ||||||
|  | |||||||
| @ -1,10 +1,6 @@ | |||||||
| (function (exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| // FORMAT:
 |  | ||||||
| // name   ttl   class   rr     name
 |  | ||||||
| // foo.   15    IN      NS     www.example.com.
 |  | ||||||
| 
 |  | ||||||
| // Comes in variable lengths. It is the name of the primary Master for the Domain.
 | // Comes in variable lengths. It is the name of the primary Master for the Domain.
 | ||||||
| // For example 'ns1.example.com'
 | // For example 'ns1.example.com'
 | ||||||
| // It may be a label, pointer or any combination
 | // It may be a label, pointer or any combination
 | ||||||
| @ -12,12 +8,11 @@ var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| exports.DNS_PARSER_TYPE_NS = function (ab , packet, record) { | exports.DNS_PARSER_TYPE_NS = function (ab , packet, record) { | ||||||
|   var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); |     record.data = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|   if (record.trunc) { |     return record; | ||||||
|     throw new Error("RDATA type NS must be `null`-terminated, not truncated by rdata length."); | 
 | ||||||
|   } |  | ||||||
|   record.data = labelInfo.name; |  | ||||||
|   return record; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }('undefined' !== typeof window ? window : exports)); | }('undefined' !== typeof window ? window : exports)); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -6,16 +6,12 @@ | |||||||
| // to a host name.
 | // to a host name.
 | ||||||
| 
 | 
 | ||||||
| // FORMAT:
 | // FORMAT:
 | ||||||
| // name   ttl   class   rr     name
 | // ame ttl  class   rr     name
 | ||||||
| // foo.   15    IN      PTR    www.example.com.
 | // 15         IN     PTR    www.example.com.
 | ||||||
| 
 | 
 | ||||||
| var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js').DNS_UNPACK_LABELS; | var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js').DNS_UNPACK_LABELS; | ||||||
| exports.DNS_PARSER_TYPE_PTR = function (ab, pack, record) { | exports.DNS_PARSER_TYPE_PTR = function (ab, pack, record) { | ||||||
|   var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); |     record.data = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|   if (record.trunc) { |     return record; | ||||||
|     throw new Error("RDATA type PTR must be `null`-terminated, not truncated by rdata length."); |  | ||||||
|   } |  | ||||||
|   record.data = labelInfo.name; |  | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| }('undefined' !== typeof window ? window : exports)); | }('undefined' !== typeof window ? window : exports)); | ||||||
|  | |||||||
| @ -13,22 +13,18 @@ | |||||||
| var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js').DNS_UNPACK_LABELS; | var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js').DNS_UNPACK_LABELS; | ||||||
| 
 | 
 | ||||||
| exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | ||||||
|   //
 |  | ||||||
|   // Look!
 |  | ||||||
|   // http://www.peerwisdom.org/2013/05/15/dns-understanding-the-soa-record/
 |  | ||||||
| 
 | 
 | ||||||
|   var rdataAb = ab.slice(record.rdstart, record.rdstart + record.rdlength); |   var rdataAb = ab.slice(record.rdstart, record.rdstart + record.rdlength); | ||||||
|   var dv = new DataView(rdataAb); |   var dv = new DataView(rdataAb); | ||||||
| 
 | 
 | ||||||
|   // we need this information for this parser
 |   // we need this information for this parser
 | ||||||
|   var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); |   var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); | ||||||
|   //var cpcount = labelInfo.cpcount;
 |   var cpcount = labelInfo.cpcount; | ||||||
|   var offset = labelInfo.byteLength; |   var offset = labelInfo.byteLength; | ||||||
|   //var labels = labelInfo.labels;
 |   var labels = labelInfo.labels; | ||||||
| 
 | 
 | ||||||
|   // Primary NS
 |   // Primary NS
 | ||||||
|   record.primary = labelInfo.name; |   record.name_server = labelInfo.name; | ||||||
|   record.name_server = record.primary; |  | ||||||
| 
 | 
 | ||||||
|   // TODO delete this commented out code after some testing
 |   // TODO delete this commented out code after some testing
 | ||||||
|   // (pretty sure it was unnecessary and it seemed to work on code with compression pointers just fine)
 |   // (pretty sure it was unnecessary and it seemed to work on code with compression pointers just fine)
 | ||||||
| @ -56,19 +52,18 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | |||||||
|     record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; |     record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|   } |   } | ||||||
|   */ |   */ | ||||||
|   record.admin = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; |   record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|   record.email_addr = record.admin; |  | ||||||
| 
 | 
 | ||||||
|   // Serial Number
 |   // Serial Number
 | ||||||
|   record.serial = record.sn = dv.getUint32(dv.byteLength - 20, false); |   record.sn = dv.getUint32(dv.byteLength - 20, false); | ||||||
|   // Refresh Interval
 |   // Refresh Interval
 | ||||||
|   record.refresh = record.ref = dv.getUint32(dv.byteLength - 16, false); |   record.ref = dv.getUint32(dv.byteLength - 16, false); | ||||||
|   // Retry Interval
 |   // Retry Interval
 | ||||||
|   record.retry = record.ret = dv.getUint32(dv.byteLength - 12, false); |   record.ret = dv.getUint32(dv.byteLength - 12, false); | ||||||
|   // Expiration Limit
 |   // Expiration Limit
 | ||||||
|   record.expiration = record.ex = dv.getUint32(dv.byteLength - 8, false); |   record.ex = dv.getUint32(dv.byteLength - 8, false); | ||||||
|   // Minimum TTL
 |   // Minimum TTL
 | ||||||
|   record.minimum = record.nx = dv.getUint32(dv.byteLength - 4, false); |   record.nx = dv.getUint32(dv.byteLength - 4, false); | ||||||
| 
 | 
 | ||||||
|   return record; |   return record; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								test/fixtures/www.linode.com.a.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								test/fixtures/www.linode.com.a.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | { header:  | ||||||
|  |    { id: 46894, | ||||||
|  |      qr: 1, | ||||||
|  |      opcode: 0, | ||||||
|  |      aa: 0, | ||||||
|  |      tc: 0, | ||||||
|  |      rd: 1, | ||||||
|  |      ra: 1, | ||||||
|  |      res1: 0, | ||||||
|  |      res2: 0, | ||||||
|  |      res3: 0, | ||||||
|  |      rcode: 0 }, | ||||||
|  |   question: [ { name: 'www.linode.com', type: 1, class: 1 } ], | ||||||
|  |   answer:  | ||||||
|  |    [ { name: 'www.linode.com', | ||||||
|  |        type: 1, | ||||||
|  |        class: 1, | ||||||
|  |        ttl: 291, | ||||||
|  |        address: '72.14.191.202' }, | ||||||
|  |      { name: 'www.linode.com', | ||||||
|  |        type: 1, | ||||||
|  |        class: 1, | ||||||
|  |        ttl: 291, | ||||||
|  |        address: '69.164.200.202' }, | ||||||
|  |      { name: 'www.linode.com', | ||||||
|  |        type: 1, | ||||||
|  |        class: 1, | ||||||
|  |        ttl: 291, | ||||||
|  |        address: '72.14.180.202' } ], | ||||||
|  |   authority: [], | ||||||
|  |   additional: [], | ||||||
|  |   edns_options: [], | ||||||
|  |   payload: undefined } | ||||||
							
								
								
									
										43
									
								
								test/fixtures/www.linode.com.a.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								test/fixtures/www.linode.com.a.json
									
									
									
									
										vendored
									
									
								
							| @ -1,43 +0,0 @@ | |||||||
| { |  | ||||||
| 	"header": { |  | ||||||
| 		"id": 46894, |  | ||||||
| 		"qr": 1, |  | ||||||
| 		"opcode": 0, |  | ||||||
| 		"aa": 0, |  | ||||||
| 		"tc": 0, |  | ||||||
| 		"rd": 1, |  | ||||||
| 		"ra": 1, |  | ||||||
| 		"res1": 0, |  | ||||||
| 		"res2": 0, |  | ||||||
| 		"res3": 0, |  | ||||||
| 		"rcode": 0 |  | ||||||
| 	}, |  | ||||||
| 	"question": [{ "name": "www.linode.com", "type": 1, "class": 1 }], |  | ||||||
| 	"answer": [ |  | ||||||
| 		{ |  | ||||||
| 			"name": "www.linode.com", |  | ||||||
| 			"type": 1, |  | ||||||
| 			"class": 1, |  | ||||||
| 			"ttl": 291, |  | ||||||
| 			"address": "72.14.191.202" |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"name": "www.linode.com", |  | ||||||
| 			"type": 1, |  | ||||||
| 			"class": 1, |  | ||||||
| 			"ttl": 291, |  | ||||||
| 			"address": "69.164.200.202" |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"name": "www.linode.com", |  | ||||||
| 			"type": 1, |  | ||||||
| 			"class": 1, |  | ||||||
| 			"ttl": 291, |  | ||||||
| 			"address": "72.14.180.202" |  | ||||||
| 		} |  | ||||||
| 	], |  | ||||||
| 	"authority": [], |  | ||||||
| 	"additional": [], |  | ||||||
| 	"edns_options": [], |  | ||||||
| 	"payload": undefined |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user