Home | History | Annotate | Line # | Download | only in system
      1      1.1  christos #!/usr/bin/perl
      2  1.1.1.3  christos 
      3      1.1  christos # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4      1.1  christos #
      5  1.1.1.3  christos # SPDX-License-Identifier: MPL-2.0
      6  1.1.1.3  christos #
      7      1.1  christos # This Source Code Form is subject to the terms of the Mozilla Public
      8  1.1.1.3  christos # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9  1.1.1.2  christos # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10      1.1  christos #
     11      1.1  christos # See the COPYRIGHT file distributed with this work for additional
     12      1.1  christos # information regarding copyright ownership.
     13      1.1  christos 
     14      1.1  christos # This is a tool for sending queries via UDP to specified address and
     15      1.1  christos # port, then exiting without waiting for a response.
     16      1.1  christos #
     17      1.1  christos # Usage: ditch.pl [-s <address>] [-p <port>] [filename]
     18      1.1  christos #
     19      1.1  christos # Input (in filename, if specified, otherwise stdin) is a series of one
     20      1.1  christos # or more DNS names and types to send as queries, e.g.:
     21      1.1  christos #
     22      1.1  christos # www.example.com A
     23      1.1  christos # www.example.org MX
     24      1.1  christos #
     25      1.1  christos # If not specified, address defaults to 127.0.0.1, port to 53.
     26      1.1  christos 
     27      1.1  christos require 5.006.001;
     28      1.1  christos 
     29      1.1  christos use strict;
     30      1.1  christos use Getopt::Std;
     31      1.1  christos use Net::DNS;
     32      1.1  christos use Net::DNS::Packet;
     33      1.1  christos use IO::File;
     34      1.1  christos use IO::Socket;
     35      1.1  christos 
     36      1.1  christos sub usage {
     37  1.1.1.4  christos     print ("Usage: ditch.pl [-s address] [-p port] [-b source_port] [file]\n");
     38      1.1  christos     exit 1;
     39      1.1  christos }
     40      1.1  christos 
     41      1.1  christos my %options={};
     42  1.1.1.4  christos getopts("s:p:b:", \%options);
     43      1.1  christos 
     44      1.1  christos my $addr = "127.0.0.1";
     45      1.1  christos $addr = $options{s} if defined $options{s};
     46      1.1  christos 
     47      1.1  christos my $port = 53;
     48      1.1  christos $port = $options{p} if defined $options{p};
     49      1.1  christos 
     50  1.1.1.4  christos my $source_port = 0;
     51  1.1.1.4  christos $source_port = $options{b} if defined $options{b};
     52  1.1.1.4  christos 
     53      1.1  christos my $file = "STDIN";
     54      1.1  christos if (@ARGV >= 1) {
     55      1.1  christos     my $filename = shift @ARGV;
     56      1.1  christos     open FH, "<$filename" or die "$filename: $!";
     57      1.1  christos     $file = "FH";
     58      1.1  christos }
     59      1.1  christos 
     60      1.1  christos my $input = "";
     61      1.1  christos while (defined(my $line = <$file>) ) {
     62      1.1  christos     chomp $line;
     63      1.1  christos     next if ($line =~ m/^ *#/);
     64      1.1  christos     my @tokens = split (' ', $line);
     65      1.1  christos 
     66      1.1  christos     my $packet;
     67      1.1  christos     if ($Net::DNS::VERSION > 0.68) {
     68      1.1  christos             $packet = new Net::DNS::Packet();
     69      1.1  christos             $@ and die $@;
     70      1.1  christos     } else {
     71      1.1  christos             my $err;
     72      1.1  christos             ($packet, $err) = new Net::DNS::Packet();
     73      1.1  christos             $err and die $err;
     74      1.1  christos     }
     75      1.1  christos 
     76      1.1  christos     my $q = new Net::DNS::Question($tokens[0], $tokens[1], "IN");
     77      1.1  christos     $packet->header->rd(1);
     78      1.1  christos     $packet->push(question => $q);
     79      1.1  christos 
     80  1.1.1.4  christos     my $sock = IO::Socket::INET->new(
     81  1.1.1.4  christos         PeerAddr => $addr,
     82  1.1.1.4  christos         PeerPort => $port,
     83  1.1.1.4  christos         Proto => "udp",
     84  1.1.1.4  christos         LocalPort => $source_port,
     85  1.1.1.4  christos         ) or die "$!";
     86      1.1  christos 
     87      1.1  christos     my $bytes = $sock->send($packet->data);
     88      1.1  christos     #print ("sent $bytes bytes to $addr:$port:\n");
     89      1.1  christos     #print ("  ", unpack("H* ", $packet->data), "\n");
     90      1.1  christos 
     91      1.1  christos     $sock->close;
     92      1.1  christos }
     93      1.1  christos 
     94      1.1  christos close $file;
     95