1# $Id: Fingerprint.pm,v 1.17 2005/09/05 13:33:36 jakob Exp $
2#
3# Copyright (c) 2011 Verisign, Inc.
4# Copyright (c) 2003,2004,2005 Roy Arends & Jakob Schlyter.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16# 3. The name of the authors may not be used to endorse or promote products
17#    derived from this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
20# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30package Net::DNS::Fingerprint;
31
32use strict;
33use warnings;
34use Net::DNS;
35
36our $VERSION = "0.10.0";
37
38my %default = (
39    source   => undef,
40    timeout  => 5,
41    retry    => 1,
42    forcetcp => 0,
43    debug    => 0,
44    qversion => 0,
45    qchaos   => 0,
46);
47
48my $versionlength = 40;
49
50my $ignore_recurse = 0;
51
52#
53# This hack works around a problem in Net::DNS.  Up to Net::DNS 0.68
54# the opcode was coded as NS_NOTIFY_OP.  That was changed in version
55# 0.69 through 0.71 with no backwards compatibility.  This hack
56# tests for the new NOTIFY and falls back to NS_NOTIFY_OP if necessary.
57#
58my $NOTIFY = 'NOTIFY';
59eval { my $p = new Net::DNS::Packet; $p->header->opcode($NOTIFY); };
60$NOTIFY = 'NS_NOTIFY_OP' if $@;
61
62my @qy = (
63    "0,QUERY,0,0,0,0,0,0,NOERROR,0,0,0,0",          #qy0
64    "0,QUERY,0,0,0,1,0,1,NOERROR,0,0,0,0",          #qy1
65    "0,$NOTIFY,0,1,1,0,1,1,NOTIMP,0,0,0,0",    #qy2
66    "0,IQUERY,0,0,0,1,1,1,NOERROR,0,0,0,0",         #qy3
67    "0,QUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",          #qy4
68    "0,QUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",          #qy5
69    "0,IQUERY,0,1,1,0,0,0,NOTIMP,0,0,0,0",          #qy6
70    "0,QUERY,0,0,0,0,0,1,NOTIMP,0,0,0,0",           #qy7
71    "0,UPDATE,0,0,1,0,0,0,NOERROR,0,0,0,0",         #qy8
72    "0,QUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",          #qy9
73    "0,QUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",          #qy10
74    "0,QUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",          #qy11
75);
76
77my @nct = (
78    ". IN A",                                       #nct0
79    ". IN A",                                       #nct1
80    ". IN A",                                       #nct2
81    ". IN A",                                       #nct3
82    "jjjjjjjjjjjj. CH A",                           #nct4
83    "jjjjjjjjjjjj. CH RRSIG",                       #nct5
84    ". IN A",                                       #nct6
85    ". IN A",                                       #nct7
86    ". IN A",                                       #nct8
87    ". IN DNSKEY",                                  #nct9
88    "jjjjjjjjjjjj. ANY TKEY",                       #nct10
89    ". IN IXFR",                                    #nct11
90);
91
92my %initrule = (header => $qy[0], query => $nct[0],);
93my @iq = (
94    "1,QUERY,0,0,0,0,0,0,SERVFAIL,1,0,0,0",           #iq0
95    "1,QUERY,0,0,0,0,0,0,NXDOMAIN,1,0,0,0",           #iq1
96    "1,QUERY,0,0,0,0,0,0,NOERROR,1,0,0,0",            #iq2
97    "1,QUERY,0,0,0,1,0,0,NOERROR,.+,.+,.+,.+",        #iq3
98    "1,$NOTIFY,0,0,1,1,0,1,FORMERR,1,0,0,0",     #iq4
99    "1,$NOTIFY,0,0,1,1,0,0,FORMERR,1,0,0,0",     #iq5
100    "1,$NOTIFY,0,0,1,1,0,0,REFUSED,1,0,0,0",     #iq6
101    "0,$NOTIFY,0,1,1,0,1,1,NOTIMP,1,0,0,0",      #iq7
102    "1,IQUERY,0,0,0,1,0,0,NOTIMP,1,0,0,0",            #iq8
103    "0,IQUERY,0,0,0,1,1,1,NOERROR,1,0,0,0",           #iq9
104    "1,QUERY,0,0,1,0,0,0,NOTIMP,1,0,0,0",             #iq10
105    "0,QUERY,0,0,1,0,0,0,NOERROR,1,0,0,0",            #iq11
106    "1,$NOTIFY,0,0,1,1,0,0,SERVFAIL,1,0,0,0",    #iq12
107    "1,IQUERY,0,0,1,1,0,0,SERVFAIL,1,0,0,0",          #iq13
108    "1,IQUERY,0,0,1,1,0,0,NOTIMP,0,0,0,0",            #iq14
109    "1,QUERY,0,0,0,1,0,0,NOTIMP,.+,.+,.+,.+",         #iq15
110    "1,QUERY,0,0,0,1,0,1,NOERROR,.+,.+,.+,.+",        #iq16
111    "1,UPDATE,0,0,1,1,0,0,FORMERR,1,0,0,0",           #iq17
112    "1,QUERY,0,0,1,0,0,0,SERVFAIL,1,0,0,0",           #iq18
113    "1,QUERY,0,0,1,0,0,0,REFUSED,1,0,0,0",            #iq19
114    "1,UPDATE,0,0,1,1,0,0,FORMERR,0,0,0,0",           #iq20
115    "1,QUERY,0,0,1,1,0,0,NOERROR,.+,.+,.+,.+",        #iq21
116    "1,QUERY,0,1,1,1,0,0,NOERROR,.+,.+,.+,.+",        #iq22
117    "1,QUERY,0,0,0,0,0,0,REFUSED,0,0,0,0",            #iq23
118    "1,QUERY,0,0,1,1,0,0,REFUSED,1,0,0,0",            #iq24
119    "1,QUERY,0,0,1,1,0,0,NXDOMAIN,.+,.+,.+,.+",       #iq25
120);
121
122my @ruleset = (
123    {
124        fingerprint => $iq[0],
125        result      => {
126            vendor  => "NLnetLabs",
127            product => "NSD",
128            version => "3.1.0 -- 3.2.8"
129        },
130    },
131    {
132        fingerprint => $iq[1],
133        result =>
134          { vendor => "Unlogic", product => "Eagle DNS", version => "1.1.1" },
135    },
136    {
137        fingerprint => $iq[2],
138        result      => {
139            vendor  => "Unlogic",
140            product => "Eagle DNS",
141            version => "1.0 -- 1.0.1"
142        },
143    },
144    {
145        fingerprint => $iq[3],
146        header      => $qy[1],
147        query       => $nct[1],
148        ruleset     => [
149            {
150                fingerprint => $iq[3],
151                header      => $qy[2],
152                query       => $nct[2],
153                ruleset     => [
154                    {
155                        fingerprint => $iq[4],
156                        result      => {
157                            vendor  => "ISC",
158                            product => "BIND",
159                            version => "9.3.0 -- 9.3.6-P1"
160                        },
161                    },
162                    {
163                        fingerprint => $iq[5],
164                        result      => {
165                            vendor  => "ISC",
166                            product => "BIND",
167                            version => "9.2.3 -- 9.2.9"
168                        },
169                    },
170                    {
171                        fingerprint => $iq[6],
172                        result      => {
173                            vendor  => "ISC",
174                            product => "BIND",
175                            version => "9.1.1 -- 9.1.3"
176                        },
177                    },
178                    {
179                        fingerprint => "query timed out",
180                        header      => $qy[3],
181                        query       => $nct[3],
182                        ruleset     => [
183                            {
184                                fingerprint => $iq[8],
185                                result      => {
186                                    vendor  => "Microsoft",
187                                    product => "Windows DNS",
188                                    version => "2003"
189                                },
190                            },
191                            {
192                                fingerprint => "query timed out",
193                                header      => $qy[4],
194                                query       => $nct[4],
195                                ruleset     => [
196                                    {
197                                        fingerprint => $iq[10],
198                                        result      => {
199                                            vendor  => "Microsoft",
200                                            product => "Windows DNS",
201                                            version => "2003 R2"
202                                        },
203                                    },
204                                    {
205                                        fingerprint => "query timed out",
206                                        header      => $qy[5],
207                                        query       => $nct[5],
208                                        ruleset     => [
209                                            {
210                                                fingerprint =>
211                                                  "query timed out",
212                                                result => {
213                                                    vendor  => "Microsoft",
214                                                    product => "Windows DNS",
215                                                    version => "2008 R2"
216                                                },
217                                            },
218                                            {
219                                                fingerprint => $iq[10],
220                                                result      => {
221                                                    vendor  => "Microsoft",
222                                                    product => "Windows DNS",
223                                                    version => "2008"
224                                                },
225                                            },
226                                            {
227                                                fingerprint => ".+",
228                                                state =>
229                                                  "q0r3q1r3q2r7q3r9q4r11q5r?"
230                                            },
231                                        ]
232                                    },
233                                ]
234                            },
235                        ]
236                    },
237                    {
238                        fingerprint => $iq[12],
239                        header      => $qy[6],
240                        query       => $nct[6],
241                        ruleset     => [
242                            {
243                                fingerprint => $iq[13],
244                                result      => {
245                                    vendor  => "",
246                                    product => "Google DNS",
247                                    version => ""
248                                },
249                            },
250                            {
251                                fingerprint => $iq[14],
252                                header      => $qy[7],
253                                query       => $nct[7],
254                                ruleset     => [
255                                    {
256                                        fingerprint => $iq[15],
257                                        result      => {
258                                            vendor  => "ISC",
259                                            product => "BIND",
260                                            version => "9.2.0rc3"
261                                        },
262                                    },
263                                    {
264                                        fingerprint => $iq[3],
265                                        result      => {
266                                            vendor  => "ISC",
267                                            product => "BIND",
268                                            version => "9.2.0 -- 9.2.2-P3"
269                                        },
270                                    },
271                                    {
272                                        fingerprint => ".+",
273                                        state => "q0r3q1r3q2r7r12q6r14q7r?"
274                                    },
275                                ]
276                            },
277                        ]
278                    },
279                ]
280            },
281            {
282                fingerprint => $iq[16],
283                header      => $qy[2],
284                query       => $nct[2],
285                ruleset     => [
286                    {
287                        fingerprint => "query timed out",
288                        result      => {
289                            vendor  => "Microsoft",
290                            product => "Windows DNS",
291                            version => "2000"
292                        },
293                    },
294                    {
295                        fingerprint => $iq[4],
296                        header      => $qy[8],
297                        query       => $nct[8],
298                        ruleset     => [
299                            {
300                                fingerprint => $iq[17],
301                                header      => $qy[4],
302                                query       => $nct[4],
303                                ruleset     => [
304                                    {
305                                        fingerprint => $iq[18],
306                                        result      => {
307                                            vendor  => "ISC",
308                                            product => "BIND",
309                                            version => "9.7.2"
310                                        },
311                                    },
312                                    {
313                                        fingerprint => $iq[19],
314                                        result      => {
315                                            vendor  => "ISC",
316                                            product => "BIND",
317                                            version => "9.6.3 -- 9.7.3"
318                                        },
319                                    },
320                                    {
321                                        fingerprint => ".+",
322                                        state => "q0r3q1r3r16q2r4q8r17q4r?"
323                                    },
324                                ]
325                            },
326                            {
327                                fingerprint => $iq[20],
328                                header      => $qy[4],
329                                query       => $nct[4],
330                                ruleset     => [
331                                    {
332                                        fingerprint => $iq[19],
333                                        result      => {
334                                            vendor  => "ISC",
335                                            product => "BIND",
336                                            version => "9.5.2 -- 9.7.1"
337                                        },
338                                    },
339                                    {
340                                        fingerprint => $iq[18],
341                                        header      => $qy[9],
342                                        query       => $nct[9],
343                                        ruleset     => [
344                                            {
345                                                fingerprint => $iq[21],
346                                                result      => {
347                                                    vendor  => "ISC",
348                                                    product => "BIND",
349                                                    version =>
350                                                      "9.6.0 OR 9.4.0 -- 9.5.1"
351                                                },
352                                            },
353                                            {
354                                                fingerprint => $iq[22],
355                                                result      => {
356                                                    vendor  => "ISC",
357                                                    product => "BIND",
358                                                    version => "9.4.0 -- 9.5.1"
359                                                },
360                                            },
361                                            {
362                                                fingerprint => ".+",
363                                                state =>
364"q0r3q1r3r16q2r4q8r17r20q4r18q9r?"
365                                            },
366                                        ]
367                                    },
368                                ]
369                            },
370                        ]
371                    },
372                ]
373            },
374        ]
375    },
376    {
377        fingerprint => $iq[23],
378        header      => $qy[10],
379        query       => $nct[10],
380        ruleset     => [
381            {
382                fingerprint => $iq[24],
383                result      => {
384                    vendor  => "NLnetLabs",
385                    product => "Unbound",
386                    version => "1.3.0 -- 1.4.0"
387                },
388            },
389            {
390                fingerprint => $iq[25],
391                header      => $qy[11],
392                query       => $nct[11],
393                ruleset     => [
394                    {
395                        fingerprint => "header section incomplete",
396                        result      => {
397                            vendor  => "NLnetLabs",
398                            product => "Unbound",
399                            version => "1.4.1 -- 1.4.9"
400                        },
401                    },
402                    {
403                        fingerprint => $iq[19],
404                        result      => {
405                            vendor  => "NLnetLabs",
406                            product => "Unbound",
407                            version => "1.4.10 -- 1.4.12"
408                        },
409                    },
410                    { fingerprint => ".+", state => "q0r3r23q10r25q11r?" },
411                ]
412            },
413        ]
414    },
415);
416
417my @qy_old = (
418    "0,IQUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",
419    "0,$NOTIFY,0,0,0,0,0,0,NOERROR,0,0,0,0",
420    "0,QUERY,0,0,0,0,0,0,NOERROR,0,0,0,0",
421    "0,IQUERY,0,0,0,0,1,1,NOERROR,0,0,0,0",
422    "0,QUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
423    "0,IQUERY,1,0,1,1,1,1,NOERROR,0,0,0,0",
424    "0,UPDATE,0,0,0,1,0,0,NOERROR,0,0,0,0",
425    "0,QUERY,1,1,1,1,1,1,NOERROR,0,0,0,0",
426    "0,QUERY,0,0,0,0,0,1,NOERROR,0,0,0,0",
427);
428
429my %old_initrule = (header => $qy_old[2], query => ". IN MAILB",);
430
431my @iq_old = (
432    "1,IQUERY,0,0,1,0,0,0,FORMERR,0,0,0,0",    # iq_old0
433    "1,IQUERY,0,0,1,0,0,0,FORMERR,1,0,0,0",    # iq_old1
434    "1,IQUERY,0,0,1,0,0,0,NOTIMP,0,0,0,0",     # iq_old2
435    "1,IQUERY,0,0,1,0,0,0,NOTIMP,1,0,0,0",     # iq_old3
436    "1,IQUERY,0,0,1,1,0,0,FORMERR,0,0,0,0",    # iq_old4
437    "1,IQUERY,0,0,1,1,0,0,NOTIMP,0,0,0,0",     # iq_old5
438    "1,IQUERY,0,0,1,1,0,0,NOTIMP,1,0,0,0",     # iq_old6
439    "1,IQUERY,1,0,1,0,0,0,NOTIMP,1,0,0,0",     # iq_old7
440    "1,QUERY,1,0,1,0,0,0,NOTIMP,1,0,0,0",
441    "1,QUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
442    "1,IQUERY,0,0,1,1,0,0,FORMERR,1,0,0,0",    # iq_old10
443    "1,$NOTIFY,0,0,0,0,0,0,FORMERR,1,0,0,0",
444    "1,$NOTIFY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
445    "1,$NOTIFY,0,0,0,0,0,0,NOTIMP,1,0,0,0",
446    "1,$NOTIFY,0,0,0,0,0,0,NXDOMAIN,1,0,0,0",
447    "1,$NOTIFY,0,0,0,0,0,0,REFUSED,1,0,0,0",
448    "1,$NOTIFY,0,0,0,0,0,0,SERVFAIL,1,0,0,0",
449    "1,$NOTIFY,0,0,0,1,0,0,FORMERR,1,0,0,0",
450    "1,$NOTIFY,0,0,0,1,0,0,NOTIMP,0,0,0,0",
451    "1,$NOTIFY,0,0,0,1,0,0,NOTIMP,1,0,0,0",
452    "1,$NOTIFY,0,0,0,1,0,0,REFUSED,1,0,0,0",    # iq_old20
453    "1,$NOTIFY,0,0,0,1,0,0,SERVFAIL,1,0,0,0",
454    "1,$NOTIFY,1,0,0,0,0,0,NOTIMP,1,0,0,0",
455    "1,QUERY,1,0,0,0,0,0,NOTIMP,1,0,0,0",
456    "1,$NOTIFY,1,0,0,0,0,0,SERVFAIL,1,0,0,0",
457    "1,IQUERY,0,0,0,0,1,1,NOTIMP,0,0,0,0",
458    "1,IQUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
459    "1,IQUERY,0,0,1,1,1,1,FORMERR,0,0,0,0",
460    "1,IQUERY,1,0,1,1,1,1,FORMERR,0,0,0,0",
461    "1,QUERY,.,0,1,.,.,.,NOTIMP,.+,.+,.+,.+",
462    "1,QUERY,.,0,1,.,.,.,.+,.+,.+,.+,.+",            #iq_old30
463    "1,QUERY,0,0,.,.,0,0,NXDOMAIN,1,0,0,0",
464    "1,QUERY,0,0,.,.,0,0,FORMERR,1,0,0,0",
465    "1,UPDATE,0,0,0,0,0,0,NOTIMP,0,0,0,0",
466    "1,UPDATE,0,0,0,1,0,0,NOTIMP,0,0,0,0",
467    "1,QUERY,0,0,1,0,0,0,NOERROR,1,0,0,0",
468    "1,QUERY,1,1,1,1,1,1,NOTIMP,1,0,0,0",
469    "1,QUERY,0,0,0,0,0,0,NOERROR,1,0,.+,0",
470    "1,QUERY,0,0,1,0,0,0,FORMERR,1,0,0,0",
471    "1,IQUERY,0,0,1,0,1,1,NOTIMP,1,0,0,0",
472    "1,IQUERY,0,0,0,1,1,1,REFUSED,1,0,0,0",          #iq_old40
473    "1,UPDATE,0,0,0,1,0,0,REFUSED,1,0,0,0",
474    "1,IQUERY,0,0,0,1,1,1,FORMERR,0,0,0,0",
475    "1,IQUERY,0,0,0,1,0,0,NOTIMP,0,0,0,0",
476    "1,QUERY,1,0,1,0,0,0,FORMERR,1,0,0,0",
477    "1,UPDATE,0,0,0,0,0,0,FORMERR,1,0,0,0",
478    "1,UPDATE,0,0,0,0,0,0,FORMERR,0,0,0,0",
479    "1,QUERY,0,0,1,0,0,0,FORMERR,0,0,0,0",
480    "1,QUERY,0,0,1,0,0,0,SERVFAIL,1,0,0,0",          #iq_old48
481    "1,QUERY,1,0,1,0,0,0,NXDOMAIN,1,0,1,0",
482    "1,QUERY,0,0,1,0,0,0,REFUSED,1,0,0,0",           #iq_old50
483    "1,QUERY,0,0,1,0,0,0,NOERROR,1,1,0,0",
484    "1,IQUERY,0,0,1,0,0,0,REFUSED,0,0,0,0",
485    "1,QUERY,0,0,0,0,0,0,FORMERR,0,0,0,0",
486    "1,QUERY,0,0,1,1,1,0,NOERROR,1,0,1,0",
487    "1,QUERY,0,0,1,1,0,0,NOERROR,1,0,1,0",
488    "1,QUERY,0,0,1,0,1,0,NOERROR,.+,.+,.+,.+",
489    "1,QUERY,0,0,1,0,0,0,.+,.+,.+,.+,.+",
490    "1,QUERY,1,0,1,0,0,0,NOERROR,1,1,0,0",
491    "1,QUERY,0,0,1,1,0,0,SERVFAIL,1,0,0,0",
492    "1,QUERY,1,0,1,1,0,0,NOERROR,1,1,0,0",           #iq_old60
493    "1,QUERY,0,0,1,1,0,0,REFUSED,1,0,0,0",
494    "1,QUERY,0,0,0,0,0,0,NOTIMP,1,0,0,0",
495    "1,QUERY,1,0,1,1,0,0,NOERROR,1,0,1,0",
496    "1,IQUERY,0,0,1,1,1,1,NOTIMP,0,0,0,0",
497    "1,UPDATE,0,0,0,0,0,0,REFUSED,0,0,0,0",
498    "1,IQUERY,0,0,0,1,1,1,NOTIMP,1,0,0,0",
499    "1,IQUERY,0,0,0,1,0,0,NOTIMP,1,0,0,0",
500    "1,QUERY,0,1,1,1,1,1,NOERROR,1,0,.,0",
501    "1,QUERY,0,1,1,1,0,1,NOERROR,1,0,.,0",
502    "1,IQUERY,0,0,1,0,0,0,REFUSED,1,0,0,0",          #iq_old70
503    "1,IQUERY,1,0,1,1,1,1,NOTIMP,1,0,0,0",
504    "1,IQUERY,0,0,1,0,0,0,NOERROR,1,0,0,0",
505    "1,QUERY,1,0,1,1,0,0,NOERROR,1,0,0,0",
506    "1,IQUERY,1,0,1,1,0,0,NXDOMAIN,1,0,0,0",
507    "1,UPDATE,0,0,0,1,0,0,FORMERR,0,0,0,0",
508    "1,IQUERY,1,0,1,0,0,0,NXDOMAIN,1,0,0,0",
509    "1,QUERY,0,0,1,1,0,0,FORMERR,1,0,0,0",
510    "1,QUERY,0,0,0,1,0,0,SERVFAIL,1,0,0,0",
511    "1,QUERY,0,0,1,1,0,0,NOERROR,1,1,0,0",
512    "1,IQUERY,1,0,1,0,0,0,NOERROR,1,0,1,0",          #iq_old80
513    "1,IQUERY,1,0,1,1,0,0,NOTIMP,1,0,0,0",
514    "1,QUERY,0,0,1,1,0,0,NOERROR,1,0,0,0",
515    "1,QUERY,1,0,1,1,0,0,NOERROR,1,1,1,.+",
516    "1,QUERY,0,0,1,1,0,0,REFUSED,0,0,0,0",
517    "1,UPDATE,0,0,0,1,0,0,NOTIMP,1,0,0,0",
518    "1,QUERY,1,0,0,1,0,0,NXDOMAIN,1,0,0,0",
519    "1,QUERY,0,0,0,1,0,0,NOTIMP,0,0,0,0",
520    "1,QUERY,0,0,0,0,0,0,REFUSED,1,0,0,0",
521    "1,QUERY,1,0,1,1,0,0,NXDOMAIN,1,0,0,0",          #iq_old89
522    "1,QUERY,1,0,0,0,0,0,NOERROR,1,1,0,0",           #iq_old90
523    "1,IQUERY,1,0,1,1,0,1,NOTIMP,1,0,0,0",
524    "1,QUERY,0,0,0,1,0,0,NOTIMP,1,0,0,0",
525    "1,QUERY,0,0,1,0,0,1,SERVFAIL,1,0,0,0",
526    "1,QUERY,0,0,0,1,0,0,NOERROR,1,0,13,13",         #iq_old94
527    "1,QUERY,0,0,0,1,0,0,NOERROR,1,0,1,0",           #iq_old95
528    "1,QUERY,0,0,1,0,0,0,NOERROR,1,0,13,13",
529    "1,IQUERY,1,0,0,0,0,0,NOTIMP,1,0,0,0",           #iq_old97
530    "1,IQUERY,1,0,0,0,1,1,NOTIMP,1,0,0,0",           #iq_old98
531    "1,IQUERY,0,0,1,1,0,0,NOERROR,1,0,1,0",          #iq_old99
532    "1,QUERY,.,0,1,0,0,0,NOERROR,1,0,0,0",           #iq_old100
533    "1,QUERY,0,0,1,0,0,0,NXDOMAIN,1,0,0,0",          #101
534);
535
536my @old_ruleset = (
537    {
538        fingerprint => $iq_old[89],
539        result      => {
540            vendor  => "Simon Kelley",
541            product => "dnsmasq",
542            version => ""
543        },
544        qv => "version.bind",
545    },
546    {
547        fingerprint => ".+",
548        header      => $qy_old[0],
549        query       => ". IN A",
550        ruleset     => [
551            {
552                fingerprint => "query timed out",
553                header      => $qy_old[0],
554                query       => "com. IN A",
555                ruleset     => [
556                    {
557                        fingerprint => "query timed out",
558                        header      => $qy_old[7],
559                        query       => ". CH A",
560                        ruleset     => [
561                            {
562                                fingerprint => "query timed out",
563                                header      => $qy_old[6],
564                                query       => ". IN A",
565                                ruleset     => [
566                                    {
567                                        fingerprint => $iq_old[38],
568                                        result      => {
569                                            vendor  => "Digital Lumber",
570                                            product => "Oak DNS",
571                                            version => ""
572                                        },
573                                        qv => "version.oak",
574                                    },
575                                    {
576                                        fingerprint => "query timed out",
577                                        result      => "TIMEOUT",
578                                    },
579                                    {
580                                        fingerprint => ".+",
581                                        state       => "q0tq0tq7tq6r?",
582                                    },
583                                ]
584                            },
585                            {
586                                fingerprint => $iq_old[35],
587                                result      => {
588                                    vendor  => "XBILL",
589                                    product => "jnamed (dnsjava)",
590                                    version => ""
591                                },
592                            },
593                            {
594                                fingerprint => $iq_old[36],
595                                result      => {
596                                    vendor  => "Men & Mice",
597                                    product => "QuickDNS for MacOS Classic",
598                                    version => ""
599                                },
600                            },
601                            {
602                                fingerprint => $iq_old[37],
603                                result      => {
604                                    vendor  => "unknown",
605                                    product => "NonSequitur DNS",
606                                    version => ""
607                                },
608                            },
609                            { fingerprint => ".+", state => "q0tq0tq7r?", },
610                        ]
611                    },
612                    {
613                        fingerprint => $iq_old[35],
614                        result      => {
615                            vendor  => "eNom",
616                            product => "eNom DNS",
617                            version => ""
618                        },
619                    },
620                    { fingerprint => ".+", state => "q0tq0r?", },
621                ]
622            },
623
624            {
625                fingerprint => $iq_old[0],
626                header      => $qy_old[1],
627                query       => "jjjjjjjjjjjj IN A",
628                ruleset     => [
629                    {
630                        fingerprint => $iq_old[12],
631                        result      => {
632                            vendor  => "ISC",
633                            product => "BIND",
634                            version => "8.4.1-p1"
635                        },
636                        qv => "version.bind",
637                    },
638                    {
639                        fingerprint => $iq_old[13],
640                        result      => {
641                            vendor  => "ISC",
642                            product => "BIND",
643                            version => "8 plus root server modifications"
644                        },
645                        qv => "version.bind",
646                    },
647                    {
648                        fingerprint => $iq_old[15],
649                        result      => {
650                            vendor  => "Cisco",
651                            product => "CNR",
652                            version => ""
653                        },
654                    },
655                    {
656                        fingerprint => $iq_old[16],
657                        header      => $qy_old[2],
658                        query       => "hostname.bind CH TXT",
659                        ruleset     => [
660                            {
661                                fingerprint => $iq_old[58],
662                                result      => {
663                                    vendor  => "ISC",
664                                    product => "BIND",
665                                    version => "8.3.0-RC1 -- 8.4.4"
666                                },
667                                qv => "version.bind",
668                            },
669                            {
670                                fingerprint => $iq_old[50],
671                                result      => {
672                                    vendor  => "ISC",
673                                    product => "BIND",
674                                    version => "8.3.0-RC1 -- 8.4.4"
675                                },
676                                qv => "version.bind",
677                            },
678                            {
679                                fingerprint => $iq_old[48],
680                                result      => {
681                                    vendor  => "ISC",
682                                    product => "BIND",
683                                    version => "8.2.2-P3 -- 8.3.0-T2A"
684                                },
685                                qv => "version.bind",
686                            },
687                            { fingerprint => ".+", state => "q0r0q1r16q2r?", },
688                        ]
689                    },
690                    { fingerprint => ".+", state => "q0r0q1r?", },
691                ]
692            },
693
694            {
695                fingerprint => $iq_old[1],
696                header      => $qy_old[2],
697                query       => ". IN IXFR",
698                ruleset     => [
699                    {
700                        fingerprint => $iq_old[31],
701                        result      => {
702                            vendor  => "Microsoft",
703                            product => "Windows DNS",
704                            version => "2000"
705                        },
706                    },
707                    {
708                        fingerprint => $iq_old[32],
709                        result      => {
710                            vendor  => "Microsoft",
711                            product => "Windows DNS",
712                            version => "NT4"
713                        },
714                    },
715                    {
716                        fingerprint => $iq_old[50],
717                        result      => {
718                            vendor  => "Microsoft",
719                            product => "Windows DNS",
720                            version => "2003"
721                        },
722                    },
723                    { fingerprint => ".+", state => "q0r1q2r?", },
724                ]
725            },
726
727            {
728                fingerprint => $iq_old[2],
729                header      => $qy_old[1],
730                ruleset     => [
731                    {
732                        fingerprint => $iq_old[11],
733                        result      => {
734                            vendor  => "ISC",
735                            product => "BIND",
736                            version => "9.2.3rc1 -- 9.4.0a4"
737                        },
738                        qv => "version.bind",
739                    },
740                    {
741                        fingerprint => $iq_old[12],
742                        header      => $qy_old[3],
743                        ruleset     => [
744                            {
745                                fingerprint => $iq_old[25],
746                                header      => $qy_old[6],
747                                ruleset     => [
748                                    {
749                                        fingerprint => $iq_old[33],
750                                        result      => {
751                                            vendor  => "bboy",
752                                            product => "MyDNS",
753                                            version => ""
754                                        },
755                                    },
756                                    {
757                                        fingerprint => $iq_old[34],
758                                        header      => $qy_old[2],
759                                        query =>
760"012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012345678901234567890123456789012345678901234567890. IN A",
761                                        ruleset => [
762                                            {
763                                                fingerprint => $iq_old[47],
764                                                result      => {
765                                                    vendor  => "NLnetLabs",
766                                                    product => "NSD",
767                                                    version => "1.0.3 -- 1.2.1"
768                                                },
769                                                qv => "version.server",
770                                            },
771                                            {
772                                                fingerprint => $iq_old[48],
773                                                header      => $qy_old[2],
774                                                query => "hostname.bind CH TXT",
775                                                ruleset => [
776                                                    {
777                                                        fingerprint =>
778                                                          $iq_old[50],
779                                                        result => {
780                                                            vendor =>
781                                                              "NLnetLabs",
782                                                            product => "NSD",
783                                                            version => "1.2.2"
784                                                        },
785                                                        qv => "version.server",
786                                                    },
787                                                    {
788                                                        fingerprint =>
789                                                          $iq_old[51],
790                                                        header  => $qy_old[8],
791                                                        query   => ". IN A",
792                                                        ruleset => [
793                                                            {
794                                                                fingerprint =>
795                                                                  $iq_old[93],
796                                                                result => {
797                                                                    vendor =>
798"NLnetLabs",
799                                                                    product =>
800                                                                      "NSD",
801                                                                    version =>
802"1.2.3 -- 2.1.2"
803                                                                },
804                                                                qv =>
805"version.server",
806                                                            },
807                                                            {
808                                                                fingerprint =>
809                                                                  $iq_old[48],
810                                                                result => {
811                                                                    vendor =>
812"NLnetLabs",
813                                                                    product =>
814                                                                      "NSD",
815                                                                    version =>
816                                                                      "2.1.3"
817                                                                },
818                                                                qv =>
819"version.server",
820                                                            },
821                                                            {
822                                                                fingerprint =>
823                                                                  ".+",
824                                                                state =>
825"q0r2q1r12q3r25q6r34q2r48q2r51q8r?",
826                                                            },
827                                                        ]
828                                                    },
829                                                    {
830                                                        fingerprint => ".+",
831                                                        state =>
832"q0r2q1r12q3r25q6r34q2r48q2r?",
833                                                    },
834                                                ]
835                                            },
836                                            {
837                                                fingerprint => $iq_old[49],
838                                                header      => $qy_old[2],
839                                                query => "hostname.bind CH TXT",
840                                                ruleset => [
841                                                    {
842                                                        fingerprint =>
843                                                          $iq_old[50],
844                                                        result => {
845                                                            vendor =>
846                                                              "NLnetLabs",
847                                                            product => "NSD",
848                                                            version =>
849                                                              "1.2.2 [root]"
850                                                        },
851                                                        qv => "version.server",
852                                                    },
853                                                    {
854                                                        fingerprint =>
855                                                          $iq_old[51],
856                                                        result => {
857                                                            vendor =>
858                                                              "NLnetLabs",
859                                                            product => "NSD",
860                                                            version =>
861                                                              "1.2.3 [root]"
862                                                        },
863                                                        qv => "version.server",
864                                                    },
865                                                    {
866                                                        fingerprint => ".+",
867                                                        state =>
868"q0r2q1r12q3r25q6r34q2r49q2r?",
869                                                    },
870                                                ]
871                                            },
872                                            {
873                                                fingerprint => $iq_old[53],
874                                                result      => {
875                                                    vendor  => "NLnetLabs",
876                                                    product => "NSD",
877                                                    version => "1.0.2"
878                                                },
879                                                qv => "version.server",
880                                            },
881                                            {
882                                                fingerprint => ".+",
883                                                state =>
884                                                  "q0r2q1r12q3r25q6r34q2a?",
885                                            },
886                                        ]
887                                    },
888                                    {
889                                        fingerprint => ".+",
890                                        state       => "q0r2q1r12q3r25q6r?",
891                                    },
892                                ]
893                            },
894                            {
895                                fingerprint => $iq_old[26],
896                                result      => {
897                                    vendor  => "VeriSign",
898                                    product => "ATLAS",
899                                    version => ""
900                                },
901                            },
902                            { fingerprint => ".+", state => "q0r2q1r12q3r?", },
903                        ]
904                    },
905                    {
906                        fingerprint => $iq_old[15],
907                        header      => $qy_old[6],
908                        ruleset     => [
909                            {
910                                fingerprint => $iq_old[45],
911                                result      => {
912                                    vendor  => "Nominum",
913                                    product => "ANS",
914                                    version => ""
915                                },
916                                qv => "version.bind",
917                            },
918                            {
919                                fingerprint => $iq_old[65],
920                                result      => {
921                                    vendor  => "ISC",
922                                    product => "BIND",
923                                    version => "9.2.3rc1 -- 9.4.0a4"
924                                },
925                                qv => "version.bind",
926                            },
927                            {
928                                fingerprint => $iq_old[46],
929                                header      => $qy_old[7],
930                                ruleset     => [
931                                    {
932                                        fingerprint => $iq_old[56],
933                                        result      => {
934                                            vendor  => "ISC",
935                                            product => "BIND",
936                                            version => "9.0.0b5 -- 9.0.1"
937                                        },
938                                        qv => "version.bind",
939                                    },
940                                    {
941                                        fingerprint => $iq_old[57],
942                                        result      => {
943                                            vendor  => "ISC",
944                                            product => "BIND",
945                                            version => "9.1.0 -- 9.1.3"
946                                        },
947                                        qv => "version.bind",
948                                    },
949                                    {
950                                        fingerprint => ".+",
951                                        state       => "q0r2q1r15q6r46q7r?",
952                                    },
953                                ]
954                            },
955                            { fingerprint => ".+", state => "q0r2q1r15q6r?", },
956                        ]
957                    },
958                    {
959                        fingerprint => $iq_old[16],
960                        header      => $qy_old[4],
961                        ruleset     => [
962                            {
963                                fingerprint => $iq_old[29],
964                                result      => {
965                                    vendor  => "ISC",
966                                    product => "BIND",
967                                    version => "9.2.0a1 -- 9.2.0rc3"
968                                },
969                                qv => "version.bind",
970                            },
971                            {
972                                fingerprint => $iq_old[30],
973                                header      => $qy_old[0],
974                                query       => ". A CLASS0",
975                                ruleset     => [
976                                    {
977                                        fingerprint => $iq_old[2],
978                                        result      => {
979                                            vendor  => "ISC",
980                                            product => "BIND",
981                                            version => "9.2.0rc7 -- 9.2.2-P3"
982                                        },
983                                        qv => "version.bind",
984                                    },
985                                    {
986                                        fingerprint => $iq_old[0],
987                                        result      => {
988                                            vendor  => "ISC",
989                                            product => "BIND",
990                                            version => "9.2.0rc4 -- 9.2.0rc6"
991                                        },
992                                        qv => "version.bind",
993                                    },
994                                    {
995                                        fingerprint => ".+",
996                                        result      => {
997                                            vendor  => "ISC",
998                                            product => "BIND",
999                                            version => "9.2.0rc4 -- 9.2.2-P3"
1000                                        },
1001                                        qv => "version.bind",
1002                                    },
1003                                ]
1004                            },
1005                            { fingerprint => ".+", state => "q0r2q1r16q4r?", },
1006                        ]
1007                    },
1008                    { fingerprint => ".+", state => "q0r2q1r?", },
1009                ]
1010            },
1011
1012            {
1013                fingerprint => $iq_old[3],
1014                header      => $qy_old[1],
1015                ruleset     => [
1016                    {
1017                        fingerprint => "query timed out",
1018                        header      => $qy_old[5],
1019                        ruleset     => [
1020                            {
1021                                fingerprint => $iq_old[3],
1022                                result      => {
1023                                    vendor  => "sourceforge",
1024                                    product => "Dents",
1025                                    version => ""
1026                                },
1027                                qv => "version.bind",
1028                            },
1029                            {
1030                                fingerprint => $iq_old[81],
1031                                result      => {
1032                                    vendor  => "Microsoft",
1033                                    product => "Windows DNS",
1034                                    version => "2003"
1035                                },
1036                            },
1037                            {
1038                                fingerprint => $iq_old[91],
1039                                result      => {
1040                                    vendor  => "Microsoft",
1041                                    product => "Windows DNS",
1042                                    version => "2003"
1043                                },
1044                            },
1045                            { fingerprint => ".+", state => "q0r3q1tq5r?", },
1046                          ]
1047
1048                    },
1049                    {
1050                        fingerprint => $iq_old[14],
1051                        result      => {
1052                            vendor  => "UltraDNS",
1053                            product => "",
1054                            version => "v2.7.0.2 -- 2.7.3"
1055                        },
1056                        qv => "version.bind",
1057                    },
1058                    {
1059                        fingerprint => $iq_old[13],
1060                        header      => $qy_old[5],
1061                        ruleset     => [
1062                            {
1063                                fingerprint => $iq_old[39],
1064                                result      => {
1065                                    vendor  => "pliant",
1066                                    product => "DNS Server",
1067                                    version => ""
1068                                },
1069                            },
1070                            {
1071                                fingerprint => $iq_old[7],
1072                                result      => {
1073                                    vendor  => "JHSOFT",
1074                                    product => "simple DNS plus",
1075                                    version => ""
1076                                },
1077                            },
1078                            {
1079                                fingerprint => $iq_old[71],
1080                                header      => $qy_old[6],
1081                                ruleset     => [
1082                                    {
1083                                        fingerprint => $iq_old[41],
1084                                        result      => {
1085                                            vendor  => "Netnumber",
1086                                            product => "ENUM server",
1087                                            version => ""
1088                                        },
1089                                    },
1090                                    {
1091                                        fingerprint => $iq_old[85],
1092                                        result      => {
1093                                            vendor  => "Raiden",
1094                                            product => "DNSD",
1095                                            version => ""
1096                                        },
1097                                    },
1098                                ]
1099                            },
1100                            { fingerprint => ".+", state => "q0r3q1r13q5r?", },
1101                        ]
1102                    },
1103                    { fingerprint => ".+", state => "q0r3q1r?", },
1104                ]
1105            },
1106
1107            {
1108                fingerprint => $iq_old[4],
1109                header      => $qy_old[1],
1110                query       => "jjjjjjjjjjjj IN A",
1111                ruleset     => [
1112                    {
1113                        fingerprint => $iq_old[17],
1114                        result      => {
1115                            vendor  => "ISC",
1116                            product => "BIND",
1117                            version => "9.0.0b5 -- 9.0.1 [recursion enabled]"
1118                        },
1119                        qv => "version.bind",
1120                    },
1121                    {
1122                        fingerprint => $iq_old[18],
1123                        header      => $qy_old[5],
1124                        query       => ". IN A",
1125                        ruleset     => [
1126                            {
1127                                fingerprint => $iq_old[27],
1128                                result      => {
1129                                    vendor  => "ISC",
1130                                    product => "BIND",
1131                                    version => "4.9.3 -- 4.9.11"
1132                                },
1133                                qv => "version.bind",
1134                            },
1135                            {
1136                                fingerprint => $iq_old[28],
1137                                result      => {
1138                                    vendor  => "ISC",
1139                                    product => "BIND",
1140                                    version => "4.8 -- 4.8.3"
1141                                },
1142                            },
1143                            { fingerprint => ".+", state => "q0r4q1r18q5r?", },
1144                        ]
1145                    },
1146                    {
1147                        fingerprint => $iq_old[19],
1148                        result      => {
1149                            vendor  => "ISC",
1150                            product => "BIND",
1151                            version => "8.2.1 [recursion enabled]"
1152                        },
1153                        qv => "version.bind",
1154                    },
1155                    {
1156                        fingerprint => $iq_old[20],
1157                        header      => $qy_old[3],
1158                        query       => ". IN A",
1159                        ruleset     => [
1160                            {
1161                                fingerprint => $iq_old[42],
1162                                result      => {
1163                                    vendor  => "ISC",
1164                                    product => "BIND",
1165                                    version =>
1166                                      "8.1-REL -- 8.2.1-T4B [recursion enabled]"
1167                                },
1168                                qv => "version.bind",
1169                            },
1170                            { fingerprint => ".+", state => "q0r4q1r20q3r?", },
1171                        ]
1172                    },
1173                    {
1174                        fingerprint => $iq_old[21],
1175                        header      => $qy_old[2],
1176                        query       => "hostname.bind CH TXT",
1177                        ruleset     => [
1178                            {
1179                                fingerprint => $iq_old[60],
1180                                result      => {
1181                                    vendor  => "ISC",
1182                                    product => "BIND",
1183                                    version =>
1184                                      "8.3.0-RC1 -- 8.4.4 [recursion enabled]"
1185                                },
1186                                qv => "version.bind",
1187                            },
1188                            {
1189                                fingerprint => $iq_old[59],
1190                                header      => $qy_old[7],
1191                                query       => ". IN A",
1192                                ruleset     => [
1193                                    {
1194                                        fingerprint => $iq_old[68],
1195                                        result      => {
1196                                            vendor  => "ISC",
1197                                            product => "BIND",
1198                                            version =>
1199"8.1-REL -- 8.2.1-T4B [recursion enabled]"
1200                                        },
1201                                        qv => "version.bind",
1202                                    },
1203                                    {
1204                                        fingerprint => $iq_old[69],
1205                                        result      => {
1206                                            vendor  => "ISC",
1207                                            product => "BIND",
1208                                            version =>
1209"8.2.2-P3 -- 8.3.0-T2A [recursion enabled]"
1210                                        },
1211                                        qv => "version.bind",
1212                                    },
1213                                    {
1214                                        fingerprint => "connection failed",
1215                                        result      => {
1216                                            vendor  => "Runtop",
1217                                            product => "dsl/cable",
1218                                            version => ""
1219                                        },
1220                                    },
1221                                    {
1222                                        fingerprint => ".+",
1223                                        state       => "q0r4q1r21q2r59q7r?",
1224                                    },
1225                                ]
1226                            },
1227
1228                            {
1229                                fingerprint => $iq_old[58],
1230                                result      => {
1231                                    vendor  => "ISC",
1232                                    product => "BIND",
1233                                    version =>
1234                                      "8.3.0-RC1 -- 8.4.4 [recursion local]"
1235                                },
1236                                qv => "version.bind",
1237                            },
1238                            {
1239                                fingerprint => $iq_old[50],
1240                                result      => {
1241                                    vendor  => "ISC",
1242                                    product => "BIND",
1243                                    version =>
1244                                      "8.3.0-RC1 -- 8.4.4 [recursion local]"
1245                                },
1246                                qv => "version.bind",
1247                            },
1248                            {
1249                                fingerprint => $iq_old[61],
1250                                result      => {
1251                                    vendor  => "ISC",
1252                                    product => "BIND",
1253                                    version =>
1254                                      "8.3.0-RC1 -- 8.4.4 [recursion local]"
1255                                },
1256                                qv => "version.bind",
1257                            },
1258                            {
1259                                fingerprint => $iq_old[48],
1260                                result      => {
1261                                    vendor  => "ISC",
1262                                    product => "BIND",
1263                                    version =>
1264                                      "8.2.2-P3 -- 8.3.0-T2A [recursion local]"
1265                                },
1266                                qv => "version.bind",
1267                            },
1268                            { fingerprint => ".+", state => "q0r4q1r21q2r?", },
1269                        ]
1270                    },
1271                    { fingerprint => ".+", state => "q0r4q1r?", },
1272                ]
1273            },
1274
1275            {
1276                fingerprint => $iq_old[5],
1277                header      => $qy_old[1],
1278                ruleset     => [
1279                    {
1280                        fingerprint => $iq_old[11],
1281                        result      => {
1282                            vendor  => "ISC",
1283                            product => "BIND",
1284                            version => "9.2.3rc1 -- 9.4.0a4",
1285                            option  => "recursion enabled,split view"
1286                        },
1287                        qv => "version.bind",
1288                    },
1289                    {
1290                        fingerprint => $iq_old[17],
1291                        result      => {
1292                            vendor  => "ISC",
1293                            product => "BIND",
1294                            version => "9.2.3rc1 -- 9.4.0a4 [recursion enabled]"
1295                        },
1296                        qv => "version.bind",
1297                    },
1298                    {
1299                        fingerprint => $iq_old[18],
1300                        header      => $qy_old[5],
1301                        ruleset     => [
1302                            {
1303                                fingerprint => $iq_old[5],
1304                                header      => $qy_old[7],
1305                                query       => ". IN A",
1306                                ruleset     => [
1307                                    {
1308                                        fingerprint => $iq_old[84],
1309                                        result      => {
1310                                            vendor  => "Nominum",
1311                                            product => "CNS",
1312                                            version => ""
1313                                        },
1314                                        qv => "version.bind",
1315                                    },
1316                                    {
1317                                        fingerprint => $iq_old[59],
1318                                        result      => {
1319                                            vendor  => "Mikrotik",
1320                                            product => "dsl/cable",
1321                                            version => ""
1322                                        },
1323                                    },
1324                                    {
1325                                        fingerprint => $iq_old[82],
1326                                        result      => {
1327                                            vendor  => "Mikrotik",
1328                                            product => "dsl/cable",
1329                                            version => ""
1330                                        },
1331                                    },
1332                                    {
1333                                        fingerprint => ".+",
1334                                        state       => "q0r5q1r18q5r5q7r?",
1335                                    },
1336                                ]
1337                            },
1338                            {
1339                                fingerprint => $iq_old[64],
1340                                result => "unknown, smells like old BIND 4",
1341                            },
1342                            { fingerprint => ".+", state => "q0r5q1r18q5r?", },
1343                        ]
1344                    },
1345                    {
1346                        fingerprint => $iq_old[20],
1347                        header      => $qy_old[7],
1348                        ruleset     => [
1349                            {
1350                                fingerprint => $iq_old[54],
1351                                result      => {
1352                                    vendor  => "ISC",
1353                                    product => "BIND",
1354                                    version =>
1355                                      "9.0.0b5 -- 9.0.1 [recursion enabled]"
1356                                },
1357                                qv => "version.bind",
1358                            },
1359                            {
1360                                fingerprint => $iq_old[55],
1361                                result      => {
1362                                    vendor  => "ISC",
1363                                    product => "BIND",
1364                                    version =>
1365                                      "9.1.0 -- 9.1.3 [recursion enabled]"
1366                                },
1367                                qv => "version.bind",
1368                            },
1369                            {
1370                                fingerprint => $iq_old[63],
1371                                result      => {
1372                                    vendor  => "ISC",
1373                                    product => "BIND",
1374                                    version =>
1375                                      "4.9.3 -- 4.9.11 [recursion enabled]"
1376                                },
1377                                qv => "version.bind",
1378                            },
1379                            {
1380                                fingerprint => $iq_old[61],
1381                                result      => {
1382                                    vendor  => "ISC",
1383                                    product => "BIND",
1384                                    version =>
1385                                      "9.0.0b5 -- 9.1.3 [recursion local]"
1386                                },
1387                                qv => "version.bind",
1388                            },
1389                            { fingerprint => ".+", state => "q0r5q1r20q7r?", },
1390                        ]
1391                    },
1392                    {
1393                        fingerprint => $iq_old[21],
1394                        header      => $qy_old[4],
1395                        ruleset     => [
1396                            {
1397                                fingerprint => "query timed out",
1398                                result      => {
1399                                    vendor  => "ISC",
1400                                    product => "BIND",
1401                                    version =>
1402                                      "9.2.0a1 -- 9.2.2-P3 [recursion enabled]"
1403                                },
1404                                qv => "version.bind",
1405                            },
1406                            {
1407                                fingerprint => $iq_old[29],
1408                                result      => {
1409                                    vendor  => "ISC",
1410                                    product => "BIND",
1411                                    version =>
1412                                      "9.2.0a1 -- 9.2.0rc3 [recursion enabled]"
1413                                },
1414                                qv => "version.bind",
1415                            },
1416                            {
1417                                fingerprint => $iq_old[61],
1418                                header      => $qy_old[0],
1419                                query       => ". A CLASS0",
1420                                ruleset     => [
1421                                    {
1422                                        fingerprint => $iq_old[2],
1423                                        result      => {
1424                                            vendor  => "ISC",
1425                                            product => "BIND",
1426                                            version =>
1427"9.2.0rc7 -- 9.2.2-P3 [recursion local]"
1428                                        },
1429                                        qv => "version.bind",
1430                                    },
1431                                    {
1432                                        fingerprint => $iq_old[0],
1433                                        result      => {
1434                                            vendor  => "ISC",
1435                                            product => "BIND",
1436                                            version =>
1437"9.2.0a1 -- 9.2.0rc6 [recursion local]"
1438                                        },
1439                                        qv => "version.bind",
1440                                    },
1441                                    {
1442                                        fingerprint => ".+",
1443                                        result      => {
1444                                            vendor  => "ISC",
1445                                            product => "BIND",
1446                                            version =>
1447"9.2.0a1 -- 9.2.2-P3 [recursion local]"
1448                                        },
1449                                        qv => "version.bind",
1450                                    },
1451                                ]
1452                            },
1453                            {
1454                                fingerprint => $iq_old[30],
1455                                header      => $qy_old[0],
1456                                query       => ". A CLASS0",
1457                                ruleset     => [
1458                                    {
1459                                        fingerprint => $iq_old[2],
1460                                        result      => {
1461                                            vendor  => "ISC",
1462                                            product => "BIND",
1463                                            version =>
1464"9.2.0rc7 -- 9.2.2-P3 [recursion enabled]"
1465                                        },
1466                                        qv => "version.bind",
1467                                    },
1468                                    {
1469                                        fingerprint => $iq_old[0],
1470                                        result      => {
1471                                            vendor  => "ISC",
1472                                            product => "BIND",
1473                                            version =>
1474"9.2.0rc4 -- 9.2.0rc6 [recursion enabled]"
1475                                        },
1476                                        qv => "version.bind",
1477                                    },
1478                                    {
1479                                        fingerprint => ".+",
1480                                        result      => {
1481                                            vendor  => "ISC",
1482                                            product => "BIND",
1483                                            version =>
1484"9.2.0rc4 -- 9.2.2-P3 [recursion enabled]"
1485                                        },
1486                                        qv => "version.bind",
1487                                    },
1488                                ]
1489                            },
1490                            { fingerprint => ".+", state => "q0r5q1r21q4r?", },
1491                        ]
1492                    },
1493                    { fingerprint => ".+", state => "q0r5q1r?", },
1494                ]
1495            },
1496
1497            {
1498                fingerprint => $iq_old[6],
1499                header      => $qy_old[1],
1500                ruleset     => [
1501                    {
1502                        fingerprint => $iq_old[15],
1503                        result      => {
1504                            vendor  => "incognito",
1505                            product => "DNS commander",
1506                            version => "v2.3.1.1 -- 4.0.5.1"
1507                        },
1508                        qv => "version.bind",
1509                    },
1510                    {
1511                        fingerprint => $iq_old[19],
1512                        header      => $qy_old[3],
1513                        ruleset     => [
1514                            {
1515                                fingerprint => $iq_old[66],
1516                                result      => {
1517                                    vendor  => "vermicelli",
1518                                    product => "totd",
1519                                    version => ""
1520                                },
1521                            },
1522                            {
1523                                fingerprint => $iq_old[67],
1524                                result      => {
1525                                    vendor  => "JHSOFT",
1526                                    product => "simple DNS plus",
1527                                    version => "[recursion enabled]"
1528                                },
1529                            },
1530                            { fingerprint => ".+", state => "q0r6q1r19q3r?", },
1531                        ]
1532                    },
1533                    { fingerprint => ".+", state => "q0r6q1r?", },
1534                ]
1535            },
1536
1537            {
1538                fingerprint => $iq_old[7],
1539                header      => $qy_old[1],
1540                ruleset     => [
1541                    {
1542                        fingerprint => $iq_old[22],
1543                        header      => $qy_old[3],
1544                        ruleset     => [
1545                            {
1546                                fingerprint => $iq_old[97],
1547                                result      => {
1548                                    vendor  => "PowerDNS",
1549                                    product => "PowerDNS",
1550                                    version => "2.9.4 -- 2.9.19"
1551                                },
1552                                qv => "version.bind",
1553                            },
1554                            {
1555                                fingerprint => $iq_old[98],
1556                                result      => {
1557                                    vendor  => "Stanford",
1558                                    product => "lbnamed",
1559                                    version => "1.0.0 -- 2.3.2"
1560                                },
1561                            },
1562                            { fingerprint => ".+", state => "q0r7q1r22q3r?", },
1563                        ]
1564                    },
1565                    {
1566                        fingerprint => $iq_old[24],
1567                        result      => {
1568                            vendor  => "PowerDNS",
1569                            product => "PowerDNS",
1570                            version => "2.8 -- 2.9.3"
1571                        },
1572                        qv => "version.bind",
1573                    },
1574                    { fingerprint => ".+", state => "q0r7q1r?", },
1575                ]
1576            },
1577
1578            {
1579                fingerprint => $iq_old[8],
1580                header      => $qy_old[1],
1581                ruleset     => [
1582                    {
1583                        fingerprint => $iq_old[23],
1584                        header      => $qy_old[2],
1585                        query       => ". CH A",
1586                        ruleset     => [
1587                            {
1588                                fingerprint => "query timed out",
1589                                result      => {
1590                                    vendor  => "DJ Bernstein",
1591                                    product => "TinyDNS",
1592                                    version => "1.04"
1593                                },
1594                            },
1595                            {
1596                                fingerprint => $iq_old[32],
1597                                result      => {
1598                                    vendor  => "DJ Bernstein",
1599                                    product => "TinyDNS",
1600                                    version => "1.05"
1601                                },
1602                            },
1603                            { fingerprint => ".+", state => "q0r8q1r23q2r?", },
1604                        ]
1605                    },
1606                    { fingerprint => ".+", state => "q0r8q1r?", },
1607                ]
1608            },
1609
1610            {
1611                fingerprint => $iq_old[9],
1612                header      => $qy_old[1],
1613                ruleset     => [
1614                    {
1615                        fingerprint => $iq_old[9],
1616                        result      => {
1617                            vendor  => "Sam Trenholme",
1618                            product => "MaraDNS",
1619                            version => ""
1620                        },
1621                        qv => "erre-con-erre-cigarro.maradns.org"
1622                    },
1623                    { fingerprint => ".+", state => "q0r9q1r?", },
1624                ]
1625            },
1626
1627            {
1628                fingerprint => $iq_old[10],
1629                result      => {
1630                    vendor  => "Microsoft",
1631                    product => "?",
1632                    version => ""
1633                },
1634            },
1635            {
1636                fingerprint => $iq_old[26],
1637                result      => {
1638                    vendor  => "Meilof Veeningen",
1639                    product => "Posadis",
1640                    version => ""
1641                },
1642            },
1643            {
1644                fingerprint => $iq_old[43],
1645                header      => $qy_old[6],
1646                ruleset     => [
1647                    {
1648                        fingerprint => $iq_old[34],
1649                        result      => {
1650                            vendor  => "Paul Rombouts",
1651                            product => "pdnsd",
1652                            version => ""
1653                        },
1654                    },
1655                    {
1656                        fingerprint => $iq_old[75],
1657                        result      => {
1658                            vendor  => "antirez",
1659                            product => "Yaku-NS",
1660                            version => ""
1661                        },
1662                    },
1663                    { fingerprint => ".+", state => "q0r43q6r?", },
1664                ]
1665            },
1666
1667            {
1668                fingerprint => $iq_old[44],
1669                result      => {
1670                    vendor  => "cpan",
1671                    product => "Net::DNS Nameserver",
1672                    version => ""
1673                },
1674                qv => "version.bind",
1675            },
1676            {
1677                fingerprint => $iq_old[52],
1678                result      => {
1679                    vendor  => "NLnetLabs",
1680                    product => "NSD",
1681                    version => "1.0 alpha"
1682                },
1683            },
1684            {
1685                fingerprint => $iq_old[55],
1686                header      => $qy_old[3],
1687                ruleset     => [
1688                    {
1689                        fingerprint => $iq_old[94],
1690                        result      => {
1691                            vendor  => "robtex",
1692                            product => "Viking DNS module",
1693                            version => ""
1694                        },
1695                    },
1696                    {
1697                        fingerprint => $iq_old[95],
1698                        result      => {
1699                            vendor  => "cisco",
1700                            product => "dns resolver/server",
1701                            version => ""
1702                        },
1703                    },
1704                    { fingerprint => ".+", state => "q0r55q3r?", },
1705                ]
1706            },
1707            {
1708                fingerprint => $iq_old[59],
1709                result      => {
1710                    vendor  => "Max Feoktistov",
1711                    product => "small HTTP server [recursion enabled]",
1712                    version => ""
1713                },
1714            },
1715            {
1716                fingerprint => $iq_old[60],
1717                result      => {
1718                    vendor  => "Axis",
1719                    product => "video server",
1720                    version => ""
1721                },
1722            },
1723            {
1724                fingerprint => $iq_old[62],
1725                header      => $qy_old[7],
1726                query       => "1.0.0.127.in-addr.arpa. IN PTR",
1727                ruleset     => [
1728                    {
1729                        fingerprint => $iq_old[62],
1730                        result      => {
1731                            vendor  => "Michael Tokarev",
1732                            product => "rbldnsd",
1733                            version => ""
1734                        },
1735                        qv => "version.bind",
1736                    },
1737                    {
1738                        fingerprint => $iq_old[79],
1739                        result      => {
1740                            vendor  => "4D",
1741                            product => "WebSTAR",
1742                            version => ""
1743                        },
1744                    },
1745                    {
1746                        fingerprint => $iq_old[83],
1747                        result      => {
1748                            vendor  => "Netopia",
1749                            product => "dsl/cable",
1750                            version => ""
1751                        },
1752                    },
1753                    {
1754                        fingerprint => $iq_old[90],
1755                        result      => {
1756                            vendor  => "TZO",
1757                            product => "Tzolkin DNS",
1758                            version => ""
1759                        },
1760                    },
1761                    {
1762                        fingerprint => "query timed out",
1763                        result      => {
1764                            vendor  => "Netopia",
1765                            product => "dsl/cable",
1766                            version => ""
1767                        },
1768                    },
1769                    { fingerprint => ".+", state => "q0r62q7r?", },
1770                ]
1771            },
1772            {
1773                fingerprint => $iq_old[70],
1774                result      => {
1775                    vendor  => "Yutaka Sato",
1776                    product => "DeleGate DNS",
1777                    version => ""
1778                },
1779            },
1780            {
1781                fingerprint => $iq_old[72],
1782                result      => {
1783                    vendor  => "",
1784                    product => "sheerdns",
1785                    version => ""
1786                },
1787            },
1788            {
1789                fingerprint => $iq_old[73],
1790                result      => {
1791                    vendor  => "Matthew Pratt",
1792                    product => "dproxy",
1793                    version => ""
1794                },
1795            },
1796            {
1797                fingerprint => $iq_old[74],
1798                result      => {
1799                    vendor  => "Brad Garcia",
1800                    product => "dnrd",
1801                    version => ""
1802                },
1803            },
1804            {
1805                fingerprint => $iq_old[76],
1806                result      => {
1807                    vendor  => "Sourceforge",
1808                    product => "JDNSS",
1809                    version => ""
1810                },
1811            },
1812            {
1813                fingerprint => $iq_old[77],
1814                result      => {
1815                    vendor  => "Dan Kaminsky",
1816                    product => "nomde DNS tunnel",
1817                    version => ""
1818                },
1819            },
1820            {
1821                fingerprint => $iq_old[78],
1822                result      => {
1823                    vendor  => "Max Feoktistov",
1824                    product => "small HTTP server",
1825                    version => ""
1826                },
1827            },
1828            {
1829                fingerprint => $iq_old[79],
1830                result      => {
1831                    vendor  => "robtex",
1832                    product => "Viking DNS module",
1833                    version => ""
1834                },
1835            },
1836            {
1837                fingerprint => $iq_old[80],
1838                result      => {
1839                    vendor  => "Fasthosts",
1840                    product => "Envisage DNS server",
1841                    version => ""
1842                },
1843            },
1844            {
1845                fingerprint => $iq_old[81],
1846                result      => {
1847                    vendor  => "WinGate",
1848                    product => "Wingate DNS",
1849                    version => ""
1850                },
1851            },
1852            {
1853                fingerprint => $iq_old[82],
1854                result      => {
1855                    vendor  => "Ascenvision",
1856                    product => "SwiftDNS",
1857                    version => ""
1858                },
1859            },
1860            {
1861                fingerprint => $iq_old[86],
1862                result      => {
1863                    vendor  => "Nortel Networks",
1864                    product => "Instant Internet",
1865                    version => ""
1866                },
1867            },
1868            {
1869                fingerprint => $iq_old[87],
1870                result      => {
1871                    vendor  => "ATOS",
1872                    product => "Stargate ADSL",
1873                    version => ""
1874                },
1875            },
1876            {
1877                fingerprint => $iq_old[88],
1878                result      => {
1879                    vendor  => "3Com",
1880                    product => "Office Connect Remote",
1881                    version => ""
1882                },
1883            },
1884            {
1885                fingerprint => $iq_old[89],
1886                result      => {
1887                    vendor  => "Alteon",
1888                    product => "ACEswitch",
1889                    version => ""
1890                },
1891            },
1892            {
1893                fingerprint => $iq_old[90],
1894                result      => {
1895                    vendor  => "javaprofessionals",
1896                    product => "javadns/jdns",
1897                    version => ""
1898                },
1899            },
1900            {
1901                fingerprint => $iq_old[92],
1902                result      => {
1903                    vendor  => "Beehive",
1904                    product => "CoDoNS",
1905                    version => ""
1906                },
1907            },
1908            {
1909                fingerprint => $iq_old[96],
1910                result      => {
1911                    vendor  => "Beevihe",
1912                    product => "AAAAAA",
1913                    version => ""
1914                },
1915                qv => "version.bind",
1916            },
1917            {
1918                fingerprint => $iq_old[100],
1919                result      => {
1920                    vendor  => "ValidStream",
1921                    product => "ValidDNS",
1922                    version => ""
1923                },
1924            },
1925            {
1926                fingerprint => $iq_old[101],
1927                result      => {
1928                    vendor  => "ValidStream",
1929                    product => "ValidDNS",
1930                    version => ""
1931                },
1932            },
1933            { fingerprint => ".+", state => "q0r?", },
1934
1935        ]
1936    },
1937
1938);
1939
1940######################################################################
1941
1942sub new {
1943    my $proto = shift;
1944    my $class = ref($proto) || $proto;
1945    my $self  = {};
1946
1947    my %config = @_;
1948
1949    foreach my $k (keys %default) {
1950        if (defined $config{$k}) {
1951            $self->{$k} = $config{$k};
1952        } else {
1953            $self->{$k} = $default{$k};
1954        }
1955    }
1956
1957    bless $self, $class;
1958    return $self;
1959}
1960
1961sub hash {
1962    my $self = shift;
1963
1964    my $addr = shift;
1965    my $port = shift;
1966
1967    $port = 53 unless ($port);
1968
1969    return $self->init($addr, $port);
1970}
1971
1972sub string {
1973    my $self = shift;
1974
1975    my $addr = shift;
1976    my $port = shift;
1977
1978    $port = 53 unless ($port);
1979
1980    my %r = $self->hash($addr, $port);
1981
1982    my @s = ();
1983
1984    if (defined $r{error}) {
1985        push @s, $r{error};
1986    } elsif (defined $r{result}) {
1987        push @s, $r{result};
1988    } else {
1989        push @s, $r{vendor}     if (defined $r{vendor});
1990        push @s, $r{product}    if (defined $r{product});
1991        push @s, $r{version}    if (defined $r{version});
1992        push @s, "[$r{option}]" if (defined $r{option});
1993        push @s, "[$r{ruleset} Rules]" if (defined $r{ruleset});
1994    }
1995
1996    push @s, $r{vstring} if (defined $r{vstring});
1997
1998    push @s, $r{state} if (defined $r{state} && $self->{debug});
1999
2000    return join(" ", @s);
2001}
2002
2003sub query_version {
2004    my $self = shift;
2005
2006    my $qserver = shift;
2007    my $qport   = shift;
2008    my $ident   = shift;
2009
2010    my $rrset    = " id: ";
2011    my $resolver = Net::DNS::Resolver->new;
2012
2013    $resolver->nameservers($qserver);
2014    $resolver->port($qport);
2015    $resolver->srcaddr($self->{source}) if $self->{source};
2016    $resolver->retry($self->{retry});
2017    $resolver->retrans($self->{timeout});
2018    $resolver->usevc($self->{forcetcp});
2019    my $query = $resolver->query($ident, 'TXT', 'CH');
2020
2021    if ($query && $query->header->ancount > 0) {
2022        foreach my $rr ($query->answer) {
2023            ($rrset = $rrset . "\"" . $rr->txtdata . "\" ")
2024              if ($rr->type eq "TXT");
2025        }
2026        $rrset =~ s/\n/\" \"/g;
2027        if (length($rrset) > $versionlength) {
2028            $rrset = substr($rrset, 0, $versionlength) . "...";
2029        }
2030        return $rrset;
2031    }
2032
2033    return " id unavailable (" . $resolver->errorstring . ")";
2034}
2035
2036sub init {
2037    my $self = shift;
2038
2039    my $qserver = shift;
2040    my $qport   = shift;
2041
2042    my %match =
2043      $self->process($qserver,
2044	$qport,
2045	$initrule{header},
2046	$initrule{query},
2047        \@ruleset,
2048	"New");
2049
2050    return %match if (defined $match{product});
2051
2052    #For backwards compatibility with old fingerprint code which never set the rd
2053    $ignore_recurse = 1;
2054    return $self->process($qserver,
2055	$qport,
2056	$old_initrule{header},
2057        $old_initrule{query},
2058	\@old_ruleset,
2059	"Old");
2060}
2061
2062sub process {
2063    my $self = shift;
2064
2065    my $qserver = shift;
2066    my $qport   = shift;
2067    my $qheader = shift;
2068    my $qstring = shift;
2069    my $ruleref = shift;
2070    my $rulenam = shift;
2071    my $ver;
2072    my $id;
2073    my %ret;
2074
2075    if ($self->{debug}) {
2076        print STDERR "==> PROCESS $qserver:$qport $qheader $qstring\n";
2077        print STDERR "\n";
2078    }
2079
2080    my ($answer, $ress) = $self->probe($qserver, $qport, $qheader, $qstring);
2081
2082    if ($answer) {
2083        $id = header2fp($answer->header);
2084    } else {
2085        $id = $ress;
2086    }
2087
2088    print STDERR "==> \"$id\"\n" if ($self->{debug});
2089
2090    for my $rule (@$ruleref) {
2091
2092        $ver = " ";
2093
2094        # we must have a fingerprint
2095        die "missing fingerprint" unless (defined $rule->{fingerprint});
2096
2097        # skip to next rule unless we have a matching fingerprint
2098        next unless ($id =~ /$rule->{fingerprint}/);
2099
2100        # return if we have a result
2101        if (defined $rule->{result}) {
2102            if (defined $rule->{qv}) {
2103                $ver = $self->query_version($qserver, $qport, $rule->{qv})
2104                  if $self->{qversion};
2105            }
2106            if ($self->{qchaos}) {
2107                $ver = $self->query_version($qserver, $qport, "version.bind");
2108            }
2109            $ret{vstring} = $ver if ($ver);
2110
2111            if (ref($rule->{result})) {
2112                $ret{vendor}  = $rule->{result}{vendor};
2113                $ret{product} = $rule->{result}{product};
2114                $ret{version} = $rule->{result}{version};
2115                $ret{option}  = $rule->{result}{option};
2116                $ret{state}   = $rule->{result}{state};
2117		$ret{ruleset} = $rulenam;
2118            } else {
2119                $ret{result} = $rule->{result};
2120            }
2121
2122            return %ret;
2123        }
2124
2125        # print state if no matches
2126        if (defined $rule->{state}) {
2127            $ver = $self->query_version($qserver, $qport, "hostname.bind")
2128              if $self->{qversion};
2129            $ret{vstring} = $ver if ($ver);
2130
2131            $ret{error} = "No match found";
2132            $ret{state} = $rule->{state};
2133            $ret{id}    = $id;
2134
2135            return %ret;
2136        }
2137
2138        # update query if defined
2139        if (defined $rule->{query}) {
2140            $qstring = $rule->{query};
2141        }
2142
2143        # recurse if we have a new header and a new ruleset
2144        if (defined $rule->{header} && defined $rule->{ruleset}) {
2145            return $self->process(
2146                $qserver, $qport, $rule->{header},
2147                $qstring, $rule->{ruleset}, $rulenam
2148            );
2149        }
2150
2151        die "syntax error";
2152    }
2153
2154    return %ret;
2155}
2156
2157sub header2fp {
2158    my $header = shift;
2159
2160    my @list = (
2161        $header->qr,      $header->opcode,  $header->aa,
2162        $header->tc,      $header->rd,      $header->ra,
2163        $header->ad,      $header->cd,      $header->rcode,
2164        $header->qdcount, $header->ancount, $header->nscount,
2165        $header->arcount
2166    );
2167
2168    return join(",", @list);
2169}
2170
2171sub fp2header {
2172    my @list = split(/,/, shift);
2173    my $header = shift;
2174
2175    $header->qr(shift @list);
2176    $header->opcode(shift @list);
2177    $header->aa(shift @list);
2178    $header->tc(shift @list);
2179    $header->rd(shift @list);
2180    $header->ra(shift @list);
2181    $header->ad(shift @list);
2182    $header->cd(shift @list);
2183    $header->rcode(shift @list);
2184
2185    my ($qdcount, $ancount, $nscount, $arcount) = @list;
2186    $header->qdcount($qdcount) unless $qdcount == $header->qdcount;
2187    $header->ancount($ancount) unless $ancount == $header->ancount;
2188    $header->nscount($nscount) unless $nscount == $header->nscount;
2189    $header->arcount($arcount) unless $arcount == $header->arcount;
2190}
2191
2192sub probe {
2193    my $self = shift;
2194
2195    my $qserver = shift;
2196    my $qport   = shift;
2197    my $qheader = shift;
2198    my @qstring = split(/ /, shift);
2199
2200    my $packet = new Net::DNS::Packet;
2201    fp2header($qheader, $packet->header);
2202    $packet->push("question", Net::DNS::Question->new(@qstring));
2203
2204    if ($self->{debug}) {
2205        print STDERR "==> QUERY BEGIN\n";
2206        print STDERR $packet->print, "\n";
2207        print STDERR "==> QUERY END\n";
2208        print STDERR "\n";
2209    }
2210
2211    my $resolver = Net::DNS::Resolver->new;
2212    $resolver->nameservers($qserver);
2213    if (!$ignore_recurse) {
2214        $resolver->recurse($packet->header->rd);
2215    }
2216    $resolver->port($qport);
2217    $resolver->srcaddr($self->{source}) if $self->{source};
2218    $resolver->retry($self->{retry});
2219    $resolver->retrans($self->{timeout});
2220    $resolver->usevc($self->{forcetcp});
2221    my $answer = $resolver->send($packet);
2222    if ($answer && $self->{debug}) {
2223        print STDERR "==> ANSWER BEGIN\n";
2224        print STDERR $answer->string, "\n";
2225        print STDERR "==> ANSWER END\n";
2226        print STDERR "\n";
2227    }
2228
2229    return ($answer, $resolver->errorstring);
2230}
2231
2232sub version {
2233    return $VERSION;
2234}
2235
22361;
2237