print-dhcpd.pl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/perl
  2. #
  3. # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
  4. #
  5. use FindBin '$Bin';
  6. use lib "$Bin/";
  7. use strict;
  8. use DBI;
  9. use Time::Local;
  10. use Net::Patricia;
  11. use NetAddr::IP;
  12. use Data::Dumper;
  13. use Rstat::config;
  14. use Rstat::main;
  15. use Rstat::mysql;
  16. use Rstat::net_utils;
  17. use File::Basename;
  18. use File::Path;
  19. setpriority(0,0,19);
  20. my %dhcp_conf;
  21. my $connected = new Net::Patricia;
  22. my $dhcp_networks = new Net::Patricia;
  23. my $int_addr=do_exec('/sbin/ip addr show | grep "scope global"');
  24. foreach my $address (split(/\n/,$int_addr)) {
  25. if ($address=~/inet\s+(.*)\s+brd/i) {
  26. if ($1) { $connected->add_string($1); }
  27. }
  28. }
  29. my @subnets=get_records_sql($dbh,'SELECT * FROM subnets WHERE dhcp=1 and office=1 and vpn=0 and hotspot=0 ORDER BY ip_int_start');
  30. foreach my $subnet (@subnets) {
  31. next if (!$subnet->{gateway});
  32. $dhcp_networks->add_string($subnet->{subnet});
  33. my $subnet_name = $subnet->{subnet};
  34. $subnet_name=~s/\/\d+$//g;
  35. $dhcp_conf{$subnet_name}->{first_ip}=IpToStr($subnet->{dhcp_start});
  36. $dhcp_conf{$subnet_name}->{last_ip}=IpToStr($subnet->{dhcp_stop});
  37. if ($connected->match_string(IpToStr($subnet->{gateway}))) { $dhcp_conf{$subnet_name}->{relay_ip}='direct'; } else { $dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway}); }
  38. }
  39. foreach my $zone (keys %dhcp_conf) {
  40. $dhcp_conf{$zone}->{first_aton} = StrToIp($dhcp_conf{$zone}->{first_ip});
  41. $dhcp_conf{$zone}->{last_aton} = StrToIp($dhcp_conf{$zone}->{last_ip});
  42. for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}; $i++) {
  43. $dhcp_conf{$zone}->{pool}->{$i}=0;
  44. }
  45. }
  46. my $dir_name = "/etc/dhcp/stat";
  47. my $new_dir = $dir_name.".new";
  48. if (! -d "$dir_name" ) { mkpath($dir_name); }
  49. if (! -d "$new_dir" ) { mkpath($new_dir); }
  50. #get userid list
  51. my $sSQL="SELECT id,ip,ip_int,mac,comments FROM User_auth where dhcp=1 and deleted=0 and user_id<>$hotspot_user_id and user_id<>$default_user_id ORDER by ip_int";
  52. my @users = get_records_sql($dbh,$sSQL);
  53. foreach my $row (@users) {
  54. next if (!$row);
  55. next if (!$dhcp_networks->match_string($row->{ip}));
  56. next if ($hotspot_networks->match_string($row->{ip}));
  57. my $info = $office_networks->match_string($row->{ip});
  58. next if (!$info);
  59. next if (!$row->{mac});
  60. next if (!$row->{ip});
  61. $info=~s/(\/\d+)$//;
  62. #push(@{$dhcp_conf{$info}},"host $row->{id} { hardware ethernet $row->{mac}; fixed-address $row->{ip}; }");
  63. my @u_mac_array;
  64. foreach my $octet (split(/:/,$row->{mac})){$octet=~s/0(\S:?)/$1/g;push(@u_mac_array,$octet);}
  65. my $u_mac=join(':',@u_mac_array);
  66. push(@{$dhcp_conf{$info}->{conf}},"# Data for $row->{id}");
  67. push(@{$dhcp_conf{$info}->{conf}},"class \"".$row->{id}."_fixed\" {");
  68. push(@{$dhcp_conf{$info}->{conf}},"match if (");
  69. push(@{$dhcp_conf{$info}->{conf}},"binary-to-ascii(16,8,\":\",substring(hardware,1,6))=\"".$u_mac.'"');
  70. if ($dhcp_conf{$info}->{relay_ip}!~/direct/i) {
  71. push(@{$dhcp_conf{$info}->{conf}},"and binary-to-ascii(10,8,\".\",packet(24,4))=\"".$dhcp_conf{$info}->{relay_ip}.'"');
  72. }
  73. push(@{$dhcp_conf{$info}->{conf}},");");
  74. push(@{$dhcp_conf{$info}->{conf}},"}");
  75. push(@{$dhcp_conf{$info}->{conf}},"pool {");
  76. push(@{$dhcp_conf{$info}->{conf}},"range $row->{ip} $row->{ip};");
  77. push(@{$dhcp_conf{$info}->{conf}},"allow members of \"".$row->{id}."_fixed\";");
  78. push(@{$dhcp_conf{$info}->{conf}},"}");
  79. $dhcp_conf{$info}->{pool}->{$row->{ip_int}} = 1;
  80. }
  81. foreach my $zone (keys %dhcp_conf) {
  82. # print "Analyze zone: $zone\n";
  83. my $start_pool = 0;
  84. for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}; $i++) {
  85. if (($dhcp_conf{$zone}->{pool}->{$i} or $i==$dhcp_conf{$zone}->{last_aton}) and $start_pool) {
  86. my $conf_str="range ".IpToStr($start_pool)." ".IpToStr($i-1).";";
  87. # print "$conf_str\n";
  88. push(@{$dhcp_conf{$zone}->{conf}},$conf_str);
  89. $start_pool = 0;
  90. }
  91. if (!$dhcp_conf{$zone}->{pool}->{$i} and !$start_pool) {
  92. $start_pool = $i;
  93. }
  94. }
  95. }
  96. foreach my $lease_file (keys %dhcp_conf) {
  97. my $full_zone_path=$new_dir."/".$lease_file.".conf";
  98. #my $full_zone_path=$dir_name."/".$lease_file.".conf";
  99. write_to_file($full_zone_path,$dhcp_conf{$lease_file}->{conf});
  100. }
  101. exit 0;