xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/formerr/formerr.pl (revision 8aaca124c0ad52af9550477f296b63debc7b4c98)
1#!/usr/bin/perl
2
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# SPDX-License-Identifier: MPL-2.0
6#
7# This Source Code Form is subject to the terms of the Mozilla Public
8# License, v. 2.0.  If a copy of the MPL was not distributed with this
9# file, you can obtain one at https://mozilla.org/MPL/2.0/.
10#
11# See the COPYRIGHT file distributed with this work for additional
12# information regarding copyright ownership.
13
14# This is a tool for sending an arbitrary packet via UDP or TCP to an
15# arbitrary address and port.  The packet is specified in a file or on
16# the standard input, in the form of a series of bytes in hexadecimal.
17# Whitespace is ignored, as is anything following a '#' symbol.
18#
19# For example, the following input would generate normal query for
20# isc.org/NS/IN":
21#
22#     # QID:
23#     0c d8
24#     # header:
25#     01 00 00 01 00 00 00 00 00 00
26#     # qname isc.org:
27#     03 69 73 63 03 6f 72 67 00
28#     # qtype NS:
29#     00 02
30#     # qclass IN:
31#     00 01
32#
33# Note that we do not wait for a response for the server.  This is simply
34# a way of injecting arbitrary packets to test server resposnes.
35#
36# Usage: packet.pl [-a <address>] [-p <port>] [-t (udp|tcp)] [filename]
37#
38# If not specified, address defaults to 127.0.0.1, port to 53, protocol
39# to udp, and file to stdin.
40#
41# XXX: Doesn't support IPv6 yet
42
43require 5.006_001;
44
45use strict;
46use Getopt::Std;
47use IO::File;
48use IO::Socket;
49
50sub usage {
51    print ("Usage: packet.pl [-a address] [-p port] [file]\n");
52    exit 1;
53}
54
55my %options={};
56getopts("a:p:", \%options);
57
58my $addr = "127.0.0.1";
59$addr = $options{a} if defined $options{a};
60
61my $port = 53;
62$port = $options{p} if defined $options{p};
63
64my $file = "STDIN";
65if (@ARGV >= 1) {
66    my $filename = shift @ARGV;
67    open FH, "<$filename" or die "$filename: $!";
68    $file = "FH";
69}
70
71my $input = "";
72while (defined(my $line = <$file>) ) {
73    chomp $line;
74    $line =~ s/#.*$//;
75    $input .= $line;
76}
77
78$input =~ s/\s+//g;
79my $data = pack("H*", $input);
80my $len = length $data;
81
82my $output = unpack("H*", $data);
83print ("sending: $output\n");
84
85my $sock = IO::Socket::INET->new(PeerAddr => $addr, PeerPort => $port,
86				 Proto => "tcp") or die "$!";
87
88my $bytes;
89$bytes = $sock->syswrite(pack("n", $len), 2);
90$bytes = $sock->syswrite($data, $len);
91$bytes = $sock->sysread($data, 2);
92$len = unpack("n", $data);
93$bytes = $sock->sysread($data, $len);
94print "got: ", unpack("H*", $data). "\n";
95
96$sock->close;
97close $file;
98