A userspace application that filters DHCP floods to protect a DHCP server. It uses the Netfilter userspace packet queuing API.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

perftest.pl 4.0KB

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