c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#!/usr/bin/perl
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews# Copyright (C) 2011, 2012, 2016 Internet Systems Consortium, Inc. ("ISC")
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews#
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews# This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews# License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews# file, You can obtain one at http://mozilla.org/MPL/2.0/.
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# $Id: packet.pl,v 1.2 2011/04/15 01:02:08 each Exp $
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# This is a tool for sending an arbitrary packet via UDP or TCP to an
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# arbitrary address and port. The packet is specified in a file or on
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# the standard input, in the form of a series of bytes in hexidecimal.
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# Whitespace is ignored, as is anything following a '#' symbol.
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# For example, the following input would generate normal query for
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# isc.org/NS/IN":
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# # QID:
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# 0c d8
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# # header:
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# 01 00 00 01 00 00 00 00 00 00
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# # qname isc.org:
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# 03 69 73 63 03 6f 72 67 00
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# # qtype NS:
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# 00 02
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# # qclass IN:
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# 00 01
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# Note that we do not wait for a response for the server. This is simply
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# a way of injecting arbitrary packets to test server resposnes.
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# Usage: packet.pl [-a <address>] [-p <port>] [-t (udp|tcp)] [filename]
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# If not specified, address defaults to 127.0.0.1, port to 53, protocol
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# to udp, and file to stdin.
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt#
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt# XXX: Doesn't support IPv6 yet
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntrequire 5.006.001;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntuse strict;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntuse Getopt::Std;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntuse IO::File;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntuse IO::Socket;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntsub usage {
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt print ("Usage: packet.pl [-a address] [-p port] [-t (tcp|udp)] [file]\n");
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt exit 1;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt}
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy %options={};
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntgetopts("a:p:t:", \%options);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $addr = "127.0.0.1";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt$addr = $options{a} if defined $options{a};
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $port = 53;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt$port = $options{p} if defined $options{p};
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $proto = "udp";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt$proto = lc $options{t} if defined $options{t};
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntusage if ($proto !~ /^(udp|tcp)$/);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $file = "STDIN";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntif (@ARGV >= 1) {
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt my $filename = shift @ARGV;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt open FH, "<$filename" or die "$filename: $!";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $file = "FH";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt}
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $input = "";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntwhile (defined(my $line = <$file>) ) {
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt chomp $line;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $line =~ s/#.*$//;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $input .= $line;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt}
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt$input =~ s/\s+//g;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $data = pack("H*", $input);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $len = length $data;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $output = unpack("H*", $data);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntprint ("sending: $output\n");
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $sock = IO::Socket::INET->new(PeerAddr => $addr, PeerPort => $port,
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt Proto => $proto,) or die "$!";
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntmy $bytes;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntif ($proto eq "udp") {
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $bytes = $sock->send($data);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt} else {
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $bytes = $sock->syswrite(pack("n", $len), 2);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt $bytes += $sock->syswrite($data, $len);
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt}
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntprint ("sent $bytes bytes to $addr:$port\n");
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Hunt$sock->close;
c92122485d6868a88e6cc1469e06a9c8f306b575Evan Huntclose $file;