xref: /minix3/external/bsd/bind/dist/bin/tests/system/formerr/formerr.pl (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1#!/usr/bin/perl
2#
3# Copyright (C) 2013, 2014  Internet Systems Consortium, Inc. ("ISC")
4#
5# Permission to use, copy, modify, and/or distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15# PERFORMANCE OF THIS SOFTWARE.
16
17# Id: packet.pl,v 1.2 2011/04/15 01:02:08 each Exp
18
19# This is a tool for sending an arbitrary packet via UDP or TCP to an
20# arbitrary address and port.  The packet is specified in a file or on
21# the standard input, in the form of a series of bytes in hexidecimal.
22# Whitespace is ignored, as is anything following a '#' symbol.
23#
24# For example, the following input would generate normal query for
25# isc.org/NS/IN":
26#
27#     # QID:
28#     0c d8
29#     # header:
30#     01 00 00 01 00 00 00 00 00 00
31#     # qname isc.org:
32#     03 69 73 63 03 6f 72 67 00
33#     # qtype NS:
34#     00 02
35#     # qclass IN:
36#     00 01
37#
38# Note that we do not wait for a response for the server.  This is simply
39# a way of injecting arbitrary packets to test server resposnes.
40#
41# Usage: packet.pl [-a <address>] [-p <port>] [-t (udp|tcp)] [filename]
42#
43# If not specified, address defaults to 127.0.0.1, port to 53, protocol
44# to udp, and file to stdin.
45#
46# XXX: Doesn't support IPv6 yet
47
48require 5.006_001;
49
50use strict;
51use Getopt::Std;
52use IO::File;
53use IO::Socket;
54
55sub usage {
56    print ("Usage: packet.pl [-a address] [-p port] [file]\n");
57    exit 1;
58}
59
60my %options={};
61getopts("a:p:", \%options);
62
63my $addr = "127.0.0.1";
64$addr = $options{a} if defined $options{a};
65
66my $port = 53;
67$port = $options{p} if defined $options{p};
68
69my $file = "STDIN";
70if (@ARGV >= 1) {
71    my $filename = shift @ARGV;
72    open FH, "<$filename" or die "$filename: $!";
73    $file = "FH";
74}
75
76my $input = "";
77while (defined(my $line = <$file>) ) {
78    chomp $line;
79    $line =~ s/#.*$//;
80    $input .= $line;
81}
82
83$input =~ s/\s+//g;
84my $data = pack("H*", $input);
85my $len = length $data;
86
87my $output = unpack("H*", $data);
88print ("sending: $output\n");
89
90my $sock = IO::Socket::INET->new(PeerAddr => $addr, PeerPort => $port,
91				 Proto => "tcp") or die "$!";
92
93my $bytes;
94$bytes = $sock->syswrite(pack("n", $len), 2);
95$bytes = $sock->syswrite($data, $len);
96$bytes = $sock->sysread($data, 2);
97$len = unpack("n", $data);
98$bytes = $sock->sysread($data, $len);
99print "got: ", unpack("H*", $data). "\n";
100
101$sock->close;
102close $file;
103