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