| use strict; | use strict; | ||||
| use IO::Socket::INET; | use IO::Socket::INET; | ||||
| use IO::Socket::INET6; | |||||
| use Time::HiRes qw(sleep); | use Time::HiRes qw(sleep); | ||||
| use warnings; | use warnings; | ||||
| exit 1; | exit 1; | ||||
| } | } | ||||
| if ( $dest !~ /^(\d+\.\d+\.\d+\.\d+)$/ ) { | |||||
| print STDERR "destination IP must be a valid IPv4 address\n"; | |||||
| if ( $dest !~ /^(\d+\.\d+\.\d+\.\d+)$/ && $dest !~ /^[0-9a-fA-F:]+$/ ) { | |||||
| print STDERR "destination IP must be a valid IPv4/IPv6 address\n"; | |||||
| exit 1; | exit 1; | ||||
| } | } | ||||
| sub main { | sub main { | ||||
| my($clients, $leasetime, $floodclients, $floodpps, $dest, $destport)=@_; | my($clients, $leasetime, $floodclients, $floodpps, $dest, $destport)=@_; | ||||
| # pseudo packet, the only really relevant thing | |||||
| # is that option 82 is present and at the right place | |||||
| my $hdr = ""; | my $hdr = ""; | ||||
| my $sock; | |||||
| if ( $dest =~ /:/ ) { # IPv6 | |||||
| $sock = IO::Socket::INET6->new( | |||||
| Proto => 'udp', | |||||
| PeerAddr => $dest, | |||||
| PeerPort => $destport, | |||||
| ); | |||||
| $hdr .= pack("H2", "01"); # msg-type | |||||
| $hdr .= pack("H6", "000000"); # transaction-id | |||||
| $hdr .= pack("C", 1); # DUID option | |||||
| $hdr .= pack("C", 6); # DUID length | |||||
| } | |||||
| else { # IPv4 | |||||
| $sock = IO::Socket::INET->new( | |||||
| Proto => 'udp', | |||||
| PeerAddr => "$dest:$destport", | |||||
| ); | |||||
| # pseudo packet, the only really relevant thing | |||||
| # is that option 82 is present and at the right place | |||||
| $hdr .= pack("H2","01"); # Opcode, bootrequest | |||||
| $hdr .= pack("H2","01"); # Hardware type, ethernet | |||||
| $hdr .= pack("H2","06"); # HW addr len, MAC = 6 | |||||
| $hdr .= pack("H2","01"); # hops, 1 relay | |||||
| $hdr .= pack("H8","00000000"); # transaction ID | |||||
| $hdr .= pack("H4","0000"); # secs | |||||
| $hdr .= pack("H4","0000"); # flags | |||||
| $hdr .= pack("H8","00000000"); # ciaddr | |||||
| $hdr .= pack("H8","00000000"); # yiaddr | |||||
| $hdr .= pack("H8","00000000"); # siaddr | |||||
| $hdr .= pack("H8","00000000"); # giaddr | |||||
| $hdr .= pack("H32","0"x32); # cihwaddr | |||||
| $hdr .= pack("H128","0"x128); # hostname | |||||
| $hdr .= pack("H256","0"x256); # boot filename | |||||
| $hdr .= pack("H8","63825363"); # magic cookie | |||||
| $hdr .= pack("C", 82); # opt 82 | |||||
| $hdr .= pack("C", 21); # opt 82 len | |||||
| $hdr .= pack("C", 1); # subopt 1 (circuitid) | |||||
| $hdr .= pack("C", 11); # subopt 1 len | |||||
| $hdr .= "Hello World"; | |||||
| $hdr .= pack("C", 2); # subopt 2 (remoteid) | |||||
| $hdr .= pack("C", 6); # subopt 2 len (mac) | |||||
| } | |||||
| $hdr .= pack("H2","01"); # Opcode, bootrequest | |||||
| $hdr .= pack("H2","01"); # Hardware type, ethernet | |||||
| $hdr .= pack("H2","06"); # HW addr len, MAC = 6 | |||||
| $hdr .= pack("H2","01"); # hops, 1 relay | |||||
| $hdr .= pack("H8","00000000"); # transaction ID | |||||
| $hdr .= pack("H4","0000"); # secs | |||||
| $hdr .= pack("H4","0000"); # flags | |||||
| $hdr .= pack("H8","00000000"); # ciaddr | |||||
| $hdr .= pack("H8","00000000"); # yiaddr | |||||
| $hdr .= pack("H8","00000000"); # siaddr | |||||
| $hdr .= pack("H8","00000000"); # giaddr | |||||
| $hdr .= pack("H32","0"x32); # cihwaddr | |||||
| $hdr .= pack("H128","0"x128); # hostname | |||||
| $hdr .= pack("H256","0"x256); # boot filename | |||||
| $hdr .= pack("H8","63825363"); # magic cookie | |||||
| $hdr .= pack("C", 82); # opt 82 | |||||
| $hdr .= pack("C", 21); # opt 82 len | |||||
| $hdr .= pack("C", 1); # subopt 1 (circuitid) | |||||
| $hdr .= pack("C", 11); # subopt 1 len | |||||
| $hdr .= "Hello World"; | |||||
| $hdr .= pack("C", 2); # subopt 2 (remoteid) | |||||
| $hdr .= pack("C", 6); # subopt 2 len (mac) | |||||
| if ( $floodclients > 0 ) { | if ( $floodclients > 0 ) { | ||||
| if ( !$pid ) { | if ( !$pid ) { | ||||
| my $int = 1/$floodpps/$floodclients; | my $int = 1/$floodpps/$floodclients; | ||||
| my $sock = IO::Socket::INET->new( | |||||
| Proto => 'udp', | |||||
| PeerAddr => "$dest:$destport", | |||||
| ); | |||||
| while(1) { | while(1) { | ||||
| for(my $i=0; $i<$floodclients; $i++) { | for(my $i=0; $i<$floodclients; $i++) { | ||||
| } | } | ||||
| my $int = $leasetime/3/$clients; | my $int = $leasetime/3/$clients; | ||||
| my $sock = IO::Socket::INET->new( | |||||
| Proto => 'udp', | |||||
| PeerAddr => "$dest:$destport", | |||||
| ); | |||||
| while(1) { | while(1) { | ||||
| for(my $i=0; $i<$clients; $i++) { | for(my $i=0; $i<$clients; $i++) { |