📄 ans.pl
字号:
#!/usr/bin/perl## Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")# Copyright (C) 2001 Internet Software Consortium.## Permission to use, copy, modify, and distribute this software for any# purpose with or without fee is hereby granted, provided that the above# copyright notice and this permission notice appear in all copies.## THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR# PERFORMANCE OF THIS SOFTWARE.# $Id: ans.pl,v 1.2.206.1 2004/03/06 10:22:08 marka Exp $## This is the name server from hell. It provides canned# responses based on pattern matching the queries, and# can be reprogrammed on-the-fly over a TCP connection.## The server listens for control connections on port 5301.# A control connection is a TCP stream of lines like## /pattern/# name ttl type rdata# name ttl type rdata# ...# /pattern/# name ttl type rdata# name ttl type rdata# ...## There can be any number of patterns, each associated# with any number of response RRs. Each pattern is a# Perl regular expression.## Each incoming query is converted into a string of the form# "qname qtype" (the printable query domain name, space,# printable query type) and matched against each pattern.## The first pattern matching the query is selected, and# the RR following the pattern line are sent in the# answer section of the response.## Each new control connection causes the current set of# patterns and responses to be cleared before adding new# ones.## The server handles UDP and TCP queries. Zone transfer# responses work, but must fit in a single 64 k message.#use IO::File;use IO::Socket;use Net::DNS;use Net::DNS::Packet;my $ctlsock = IO::Socket::INET->new(LocalAddr => "10.53.0.2", LocalPort => 5301, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!";my $udpsock = IO::Socket::INET->new(LocalAddr => "10.53.0.2", LocalPort => 5300, Proto => "udp", Reuse => 1) or die "$!";my $tcpsock = IO::Socket::INET->new(LocalAddr => "10.53.0.2", LocalPort => 5300, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!";my $pidf = new IO::File "ans.pid", "w" or die "cannot write pid file: $!";print $pidf "$$\n";$pidf->close;sub rmpid { unlink "ans.pid"; exit 1; };$SIG{INT} = \&rmpid;$SIG{TERM} = \&rmpid;my @answers = ();sub handle { my ($buf) = @_; my ($packet, $err) = new Net::DNS::Packet(\$buf, 0); $err and die $err; $packet->header->qr(1); $packet->header->aa(1); my @questions = $packet->question; my $qname = $questions[0]->qname; my $qtype = $questions[0]->qtype; my $r; foreach $r (@rules) { my $pattern = $r->{pattern}; warn "match $qname $qtype == $pattern"; if ("$qname $qtype" =~ /$pattern/) { my $a; foreach $a (@{$r->{answer}}) { $packet->push("answer", $a); } last; } } # $packet->print; return $packet->data;}for (;;) { $rin = ''; vec($rin, fileno($ctlsock), 1) = 1; vec($rin, fileno($tcpsock), 1) = 1; vec($rin, fileno($udpsock), 1) = 1; select($rout = $rin, undef, undef, undef); if (vec($rout, fileno($ctlsock), 1)) { warn "ctl conn"; my $conn = $ctlsock->accept; @rules = (); while (my $line = $conn->getline) { chomp $line; if ($line =~ m!^/(.*)/$!) { $rule = { pattern => $1, answer => [] }; push(@rules, $rule); } else { push(@{$rule->{answer}}, new Net::DNS::RR($line)); } } $conn->close; } elsif (vec($rout, fileno($udpsock), 1)) { printf "UDP request\n"; $udpsock->recv($buf, 512); $response = handle($buf); $udpsock->send($response); } elsif (vec($rout, fileno($tcpsock), 1)) { my $conn = $tcpsock->accept; for (;;) { printf "TCP request\n"; my $n = $conn->sysread($lenbuf, 2); last unless $n == 2; my $len = unpack("n", $lenbuf); $n = $conn->sysread($buf, $len); last unless $n == $len; $response = handle($buf); $len = length($response); $n = $conn->syswrite(pack("n", $len), 2); $n = $conn->syswrite($response, $len); } $conn->close; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -