iThunder has asked for the wisdom of the Perl Monks concerning the following question:

Hello i am trying to use a code (taken from perlmonks webiste) but i am not seeing any packet being sent out (checking via Wireshark). What am i doing wrong? Thanks

#!C:\Strawberry\perl\bin use Socket; $src_host = $ARGV[0]; # The source IP/Hostname $src_port = $ARGV[1]; # The Source Port $dst_host = $ARGV[2]; # The Destination IP/Hostname $dst_port = $ARGV[3]; # The Destination Port. if(!defined $src_host or !defined $src_port or !defined $dst_host or +!defined $dst_port) { print "Usage: $0 <source host> <source port> <dest host> <dest port ++>\n"; exit; } else { main(); } sub main { my $src_host = (gethostbyname($src_host))[4]; my $dst_host = (gethostbyname($dst_host))[4]; #socket(RAW, AF_INET, SOCK_RAW,6) || die $!; #setsockopt(RAW, 0, 1, 1); my ($packet) = makeheaders($src_host, $src_port, $dst_host, $dst_port +); my ($destination) = pack('Sna4x8', AF_INET, $dst_port, $dst_host); socket(RAW, AF_INET, SOCK_RAW,62) || die $!; setsockopt(RAW, 0, 1, 1); #my $test = unpack($destination); print $destination,"\n"; send(RAW,$packet,0,$destination); #print "packet sent\n"; } sub makeheaders { local($src_host,$src_port,$dst_host,$dst_port) = @_; my $zero_cksum = 0; # Lets construct the TCP half my $tcp_proto = 6; my ($tcp_len) = 20; my $syn = 13456; my $ack = 0; my $tcp_headerlen = "5"; my $tcp_reserved = 0; my $tcp_head_reserved = $tcp_headerlen . $tcp_reserved; my $tcp_urg = 0; # Flag bits my $tcp_ack = 0; # eh no my $tcp_psh = 0; # eh no my $tcp_rst = 0; # eh no my $tcp_syn = 1; # yeah lets make a connexion! :) my $tcp_fin = 0; my $null = 0; my $tcp_win = 124; my $tcp_urg_ptr = 0; my $tcp_all = $null . $null . $tcp_urg . $tcp_ack . $tcp_psh . $tcp_rst . $tcp_syn . $tcp_fin ; # In order to calculate the TCP checksum we have # to create a fake tcp header, hence why we did # all this stuff :) Stevens called it psuedo headers :) my ($tcp_pseudo) = pack('a4a4CCnnnNNH2B8nvn', $src_host,$dst_host,$tcp_proto,$tcp_len, $src_port,$dst_port,$syn,$ack, $tcp_head_reserved,$tcp_all,$tcp_win,$null,$tcp_urg_ptr); my ($tcp_checksum) = &checksum($tcp_pseudo); # Now lets construct the IP packet my $ip_ver = 4; my $ip_len = 5; my $ip_ver_len = $ip_ver . $ip_len; my $ip_tos = 00; my ($ip_tot_len) = $tcp_len + 20; my $ip_frag_id = 19245; my $ip_frag_flag = "010"; my $ip_frag_oset = "0000000000000"; my $ip_fl_fr = $ip_frag_flag . $ip_frag_oset; my $ip_ttl = 30; # Lets pack this baby and ship it on out! my ($pkt) = pack('H2H2nnB16C2na4a4nnNNH2B8nvn', $ip_ver_len,$ip_tos,$ip_tot_len,$ip_frag_id, $ip_fl_fr,$ip_ttl,$tcp_proto,$zero_cksum,$src_host, $dst_host,$src_port,$dst_port,$syn,$ack,$tcp_head_reserved, $tcp_all,$tcp_win,$tcp_checksum,$tcp_urg_ptr); print "tcp header completed\n"; return $pkt; } sub checksum { # This of course is a blatent rip from _the_ GOD, # W. Richard Stevens. my ($msg) = @_; my ($len_msg,$num_short,$short,$chk); $len_msg = length($msg); $num_short = $len_msg / 2; $chk = 0; foreach $short (unpack("S$num_short", $msg)) { $chk += $short; } $chk += unpack("C", substr($msg, $len_msg - 1, 1)) if $len_msg % 2; $chk = ($chk >> 16) + ($chk & 0xffff); print "checksum completed\n"; return(~(($chk >> 16) + $chk) & 0xffff); }

Replies are listed 'Best First'.
Re: Perl code to send TCP/IP packet not working
by trippledubs (Deacon) on Mar 14, 2015 at 10:59 UTC

    I got it to work by running the command prompt as administrator. The code Simple Construction of a RAW TCP/IP Packet. you are using is 15 years old. Pretty sweet that it still works, little out of date though. You should be able to find more recent examples through super search.

      thanks. i was able to send it when ran command prompt as administrator but it doesn't run if i change my protocol to 6 (change the 62 in socket statement to 6).does it run for you?

Re: Perl code to send TCP/IP packet not working
by VinsWorldcom (Prior) on Mar 15, 2015 at 00:08 UTC

    This is much easier with the Net::Frame library. It works fine on Windows / Strawberry (which I gather you're running based on the shebang in your code).

    <shameless plug>You can also check out the Perl Packet Crafter (PPC) which provides a scapy (http://www.secdev.org/projects/scapy/)-like interface to the Net::Frame suite.</shameless plug>

    POD: http://www.vinsworld.com/software/ppc.html
    Direct Download: http://www.vinsworld.com/software/ppc.zip

    In your case, your TCP SYN packet is as easy as:

    VinsWorldcom@C:\Users\VinsWorldcom\tmp\ppc> ppc -i "Wireless Network C +onnection" Welcome to Perl Packet Crafter (PPC) Version: 1.02 Copyright (C) VinsWorldcom 2012 Wireless Network Connection ppc> $r = srp( packet( ETHER, IPv4(dst=>'www.google.com',id=>'19245',f +lags=>NF_IPv4_DONT_FRAGMENT),TCP(dst=>80,seq=>'13456')) ); Sent => Received ppc> $r->report; Packet 1 Sent: Sat Mar 14 20:03:17 2015 (1426377797.565053) ETH: dst:xx:xx:xx:xx:xx:xx src:xx:xx:xx:xx:xx:xy type:0x0800 IPv4: version:4 hlen:5 tos:0x00 length:40 id:19245 IPv4: flags:0x02 offset:0 ttl:128 protocol:0x06 checksum:0x3092 IPv4: src:192.168.10.105 dst:216.58.219.196 TCP: src:5443 dst:80 seq:0x3490 ack:0x0000 TCP: off:0x05 x2:0x0 flags:0x02 win:65535 checksum:0xe6ae urp:0x0 +0 Recv: Sat Mar 14 20:03:17 2015 (1426377797.591432) ETH: dst:c0:cb:38:08:46:76 src:58:6d:8f:78:ad:40 type:0x0800 IPv4: version:4 hlen:5 tos:0x20 length:44 id:39786 IPv4: flags:0x00 offset:0 ttl:55 protocol:0x06 checksum:0x6931 IPv4: src:216.58.219.196 dst:192.168.10.105 TCP: src:80 dst:5443 seq:0x15f689c0 ack:0x3491 TCP: off:0x06 x2:0x0 flags:0x12 win:42900 checksum:0x87b4 urp:0x0 +0 TCP: optionsLength:4 options:02040596 Interval = 0.026379 secs ppc>

    Note the MAC's above have been obscured. And you can specify your source IP and TCP port if you want, although I didn't. Note if you "spoof" your source IP, you won't get the response packet - that should be pretty obvious.