statzone

DNS zone file analyzer targeted at TLD zones
Log | Files | Refs | README | LICENSE

commit 08ab489ff6fe560053063d68ea34c58d5153ebe9
Author: Frederic Cambus <fcambus@users.sourceforge.net>
Date:   Sun,  2 Aug 2015 23:18:42 +0200

Initial commit

Diffstat:
AAUTHORS | 6++++++
ALICENSE | 28++++++++++++++++++++++++++++
AREADME.md | 29+++++++++++++++++++++++++++++
Astatzone.go | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -0,0 +1,6 @@ +StatZone is developed by : + +Frederic Cambus <fcambus AT users DOT sourceforge DOT net> + +Site : http://www.cambus.net +Twitter : @fcambus diff --git a/LICENSE b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012-2015, Frederic Cambus +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of StatZone nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md @@ -0,0 +1,29 @@ +# StatZone + +StatZone is a DNS zone file analyzer targeted at TLD zones. + +## Features + +Currently implemented features : + +- Counting IPv4 and IPv6 glue +- Counting name servers (total and unique) +- Counting DS records +- Counting DNSSEC signed domains +- Counting IDNs domains +- Counting domains + +## License + +StatZone is released under the BSD 3-Clause license. See `LICENSE` file for details. + +## Author + +StatZone is developed by Frederic Cambus + +- Site : http://www.cambus.net +- Twitter: http://twitter.com/fcambus + +## Resources + +GitHub : https://github.com/fcambus/statzone diff --git a/statzone.go b/statzone.go @@ -0,0 +1,126 @@ +/*****************************************************************************/ +/* */ +/* StatZone (c) by Frederic Cambus 2012-2015 */ +/* http://www.statdns.com */ +/* */ +/* Created: 2012/02/13 */ +/* Last Updated: 2015/08/02 */ +/* */ +/* StatZone is released under the BSD 3-Clause license. */ +/* See LICENSE file for details. */ +/* */ +/*****************************************************************************/ + +package main + +import ( + "bufio" + "fmt" + "github.com/miekg/dns" + "os" + "strings" +) + +type Domains struct { + count int + idn int + previous string + suffix int +} + +var rrParsed int + +// Return rdata +func rdata(RR dns.RR) string { + return strings.Replace(RR.String(), RR.Header().String(), "", -1) +} + +func main() { + header := `------------------------------------------------------------------------------- + StatZone (c) by Frederic Cambus 2012-2015 +-------------------------------------------------------------------------------` + + inputFile := os.Args[1] + + fmt.Println(header) + + fmt.Println("\nParsing zone :", inputFile) + + domains := new(Domains) + + ns := map[string]int{} + signed := map[string]int{} + + zoneFile, err := os.Open(inputFile) + if err != nil { + fmt.Println("ERROR : Can't open zone file.") + } + + zone := dns.ParseZone(bufio.NewReader(zoneFile), "", "") + + var rrtypes [100]int + + for parsedLine := range zone { + if parsedLine.RR != nil { + rrtypes[parsedLine.RR.Header().Rrtype]++ + + switch parsedLine.RR.Header().Rrtype { + case dns.TypeDS: + /* Increment Signed Domains counter */ + signed[parsedLine.RR.Header().Name]++ + case dns.TypeNS: + /* Increment NS counter */ + ns[rdata(parsedLine)]++ + + if parsedLine.RR.Header().Name != domains.previous { // Unique domain + + /* Increment Domain counter */ + domains.count++ + domains.previous = parsedLine.RR.Header().Name + + /* Check if the domain is an IDN */ + + if strings.HasPrefix(strings.ToLower(parsedLine.RR.Header().Name), "xn--") { + domains.idn++ + } + + /* Display progression */ + if domains.count%1000000 == 0 { + fmt.Printf("*") + } else if domains.count%100000 == 0 { + fmt.Printf(".") + } + } + } + } else { + fmt.Println("ERROR : A problem occured while parsing the zone file.") + } + + /* Increment number of resource records parsed */ + rrParsed++ + } + + /* Don't count origin */ + domains.count-- + + fmt.Println("\n---[ Parsing results ]---------------------------------------------------------\n") + fmt.Println(rrParsed, "RRs parsed.") + for loop := 0; loop < len(rrtypes); loop++ { + rrtype := rrtypes[loop] + if rrtype != 0 { + fmt.Println(dns.TypeToString[uint16(loop)], "records :", rrtype) + } + } + + fmt.Println("\n---[ Results ]-----------------------------------------------------------------\n") + fmt.Println("Domains : ", domains.count) + fmt.Println("DNSSEC Signed : ", len(signed)) + + fmt.Println("IDNs : ", domains.idn) + fmt.Println("NS : ", len(ns)) + + fmt.Println("\n---[ CSV values ]--------------------------------------------------------------\n") + + fmt.Println("IPv4 Glue ; IPv6 Glue ; NS ; Unique NS ; DS ; Signed ; IDNs ; Domains") + fmt.Println(rrtypes[dns.TypeA], ";", rrtypes[dns.TypeAAAA], ";", rrtypes[dns.TypeNS], ";", len(ns), ";", rrtypes[dns.TypeDS], ";", len(signed), ";", domains.idn, ";", domains.count) +}