A userspace application that filters DHCP floods to protect a DHCP server. It uses the Netfilter userspace packet queuing API.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

perftest.pl 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/perl
  2. use strict;
  3. use IO::Socket::INET;
  4. use Time::HiRes qw(sleep);
  5. use warnings;
  6. $| = 1;
  7. my($clients, $leasetime, $floodclients, $floodpps, $dest, $destport) = @ARGV;
  8. usage() if !defined $destport;
  9. if ( $clients !~ /^\d+$/ || $clients < 1 ) {
  10. print STDERR "clients count must be a positive integer\n";
  11. exit 1;
  12. }
  13. if ( $leasetime !~ /^\d+$/ || $leasetime < 3 ) {
  14. print STDERR "leasetime must be at least 3\n";
  15. exit 1;
  16. }
  17. if ( $floodclients !~ /^\d+$/ || $floodclients < 0 ) {
  18. print STDERR "floodclients must be a 0 or more\n";
  19. exit 1;
  20. }
  21. if ( $floodpps !~ /^\d+$/ || $floodpps < 0 ) {
  22. print STDERR "floodpps must be 0 or more\n";
  23. exit 1;
  24. }
  25. if ( $dest !~ /^(\d+\.\d+\.\d+\.\d+)$/ ) {
  26. print STDERR "destination IP must be a valid IPv4 address\n";
  27. exit 1;
  28. }
  29. if ( $destport !~ /^\d+$/ || $destport < 1 || $destport > 65535 ) {
  30. print STDERR "destport must be between 1 and 65535\n";
  31. exit 1;
  32. }
  33. main($clients, $leasetime, $floodclients, $floodpps, $dest, $destport);
  34. sub usage {
  35. print STDERR <<EOF;
  36. ==============================================
  37. = DHCP Protect testing client =
  38. = This is only to test dhcp_protect =
  39. = DO NOT SEND THIS TO YOUR DHCP SERVER !!!! =
  40. ==============================================
  41. Usage: $0 <clients> <leasetime> <floodclients> <floodpps> <destination> <port>
  42. clients : number of 'normal' dhcp clients to simulator.
  43. leasetime : the desired leasetime.
  44. floodclients : number of client flood the server.
  45. floodpps : packet rate at which the floodclients flood the server (per client).
  46. destination : target IP address.
  47. port : targer UDP port.
  48. EOF
  49. exit 1;
  50. }
  51. sub main {
  52. my($clients, $leasetime, $floodclients, $floodpps, $dest, $destport)=@_;
  53. # pseudo packet, the only really relevant thing
  54. # is that option 82 is present and at the right place
  55. my $hdr = "";
  56. $hdr .= pack("H2","01"); # Opcode, bootrequest
  57. $hdr .= pack("H2","01"); # Hardware type, ethernet
  58. $hdr .= pack("H2","06"); # HW addr len, MAC = 6
  59. $hdr .= pack("H2","01"); # hops, 1 relay
  60. $hdr .= pack("H8","00000000"); # transaction ID
  61. $hdr .= pack("H4","0000"); # secs
  62. $hdr .= pack("H4","0000"); # flags
  63. $hdr .= pack("H8","00000000"); # ciaddr
  64. $hdr .= pack("H8","00000000"); # yiaddr
  65. $hdr .= pack("H8","00000000"); # siaddr
  66. $hdr .= pack("H8","00000000"); # giaddr
  67. $hdr .= pack("H32","0"x32); # cihwaddr
  68. $hdr .= pack("H128","0"x128); # hostname
  69. $hdr .= pack("H256","0"x256); # boot filename
  70. $hdr .= pack("H8","63825363"); # magic cookie
  71. $hdr .= pack("C", 82); # opt 82
  72. $hdr .= pack("C", 21); # opt 82 len
  73. $hdr .= pack("C", 1); # subopt 1 (circuitid)
  74. $hdr .= pack("C", 11); # subopt 1 len
  75. $hdr .= "Hello World";
  76. $hdr .= pack("C", 2); # subopt 2 (remoteid)
  77. $hdr .= pack("C", 6); # subopt 2 len (mac)
  78. if ( $floodclients > 0 ) {
  79. my $pid = fork();
  80. # flood client
  81. if ( !$pid ) {
  82. my $int = 1/$floodpps/$floodclients;
  83. my $sock = IO::Socket::INET->new(
  84. Proto => 'udp',
  85. PeerAddr => "$dest:$destport",
  86. );
  87. while(1) {
  88. for(my $i=0; $i<$floodclients; $i++) {
  89. my $pkt = $hdr;
  90. $pkt .= pack("H12", sprintf("66666666%04x", $i));
  91. $sock->send($pkt);
  92. sleep($int);
  93. }
  94. }
  95. exit;
  96. }
  97. }
  98. my $int = $leasetime/3/$clients;
  99. my $sock = IO::Socket::INET->new(
  100. Proto => 'udp',
  101. PeerAddr => "$dest:$destport",
  102. );
  103. while(1) {
  104. for(my $i=0; $i<$clients; $i++) {
  105. my $pkt = $hdr;
  106. $pkt .= pack("H12", sprintf("00112233%04x",$i));
  107. $sock->send($pkt);
  108. sleep($int);
  109. }
  110. }
  111. }