print-dnsmasq.pl 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/perl
  2. #
  3. # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
  4. #
  5. use utf8;
  6. use open ":encoding(utf8)";
  7. use Encode;
  8. no warnings 'utf8';
  9. use English;
  10. use base;
  11. use FindBin '$Bin';
  12. use lib "/opt/Eye/scripts";
  13. use strict;
  14. use DBI;
  15. use Time::Local;
  16. use Net::Patricia;
  17. use NetAddr::IP;
  18. use Data::Dumper;
  19. use eyelib::config;
  20. use eyelib::main;
  21. use eyelib::database;
  22. use eyelib::net_utils;
  23. use File::Basename;
  24. use File::Path;
  25. use Fcntl qw(:flock);
  26. open(SELF,"<",$0) or die "Cannot open $0 - $!";
  27. flock(SELF, LOCK_EX|LOCK_NB) or exit 1;
  28. binmode(STDOUT,':utf8');
  29. setpriority(0,0,19);
  30. my $dhcp_networks = new Net::Patricia;
  31. my %dhcp_conf;
  32. my %static_hole;
  33. my %mac_subnets;
  34. 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');
  35. foreach my $subnet (@subnets) {
  36. next if (!$subnet->{gateway});
  37. $dhcp_networks->add_string($subnet->{subnet});
  38. my $subnet_name = $subnet->{subnet};
  39. $subnet_name=~s/\/\d+$//g;
  40. $dhcp_conf{$subnet_name}->{first_ip}=IpToStr($subnet->{dhcp_start});
  41. $dhcp_conf{$subnet_name}->{last_ip}=IpToStr($subnet->{dhcp_stop});
  42. $dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway});
  43. my $dhcp=GetDhcpRange($subnet->{subnet});
  44. if ($subnet->{static}) {
  45. $static_hole{$dhcp_conf{$subnet_name}->{last_ip}}->{mac}="01:02:03:04:05:06";
  46. $static_hole{$dhcp_conf{$subnet_name}->{last_ip}}->{skip}=0;
  47. print "dhcp-range=net-$subnet_name,$dhcp_conf{$subnet_name}->{last_ip},$dhcp_conf{$subnet_name}->{last_ip},$dhcp->{mask},$subnet->{dhcp_lease_time}m\n";
  48. } else {
  49. print "dhcp-range=net-$subnet_name,$dhcp_conf{$subnet_name}->{first_ip},$dhcp_conf{$subnet_name}->{last_ip},$dhcp->{mask},$subnet->{dhcp_lease_time}m\n";
  50. }
  51. print "dhcp-option=net:net-$subnet_name,option:router,$dhcp_conf{$subnet_name}->{relay_ip}\n";
  52. }
  53. #get userid list
  54. my $sSQL="SELECT id,ip,ip_int,mac,comments,dns_name,dhcp_option_set,dhcp_acl,ou_id FROM User_auth where dhcp=1 and deleted=0 ORDER by ip_int";
  55. my @users = get_records_sql($dbh,$sSQL);
  56. foreach my $row (@users) {
  57. next if (!$row);
  58. next if (!$dhcp_networks->match_string($row->{ip}));
  59. next if (!$row->{mac});
  60. next if (!$row->{ip});
  61. next if (is_default_ou($dbh,$row->{ou_id}));
  62. if (exists $static_hole{$row->{ip}}) { $static_hole{$row->{ip}}{skip}=1; }
  63. my $subnet = $dhcp_networks->match_string($row->{ip});
  64. $mac_subnets{$subnet} ||= {
  65. name => $subnet,
  66. macs => {}
  67. };
  68. if (exists $mac_subnets{$subnet}{macs}{$row->{mac}}) {
  69. my $old_row = $mac_subnets{$subnet}{macs}{$row->{mac}};
  70. db_log_warning($dbh,"Mac $row->{mac} already exists in DHCP fo subnet $subnet! auth_id: $row->{id} and auth_id: $old_row->{id}");
  71. next;
  72. }
  73. $mac_subnets{$subnet}{macs}{$row->{mac}} = $row;
  74. print '#Comment:'.$row->{comments}."\n" if ($row->{comments});
  75. my $dns_name = '';
  76. if ($row->{dns_name}) {
  77. print '#DNS:'.$row->{dns_name}."\n";
  78. $dns_name = ','.$row->{dns_name};
  79. }
  80. my $dhcp_set = '';
  81. if ($row->{dhcp_option_set}) {
  82. $dhcp_set = ',set:'.$row->{dhcp_option_set};
  83. }
  84. print 'dhcp-host='.$row->{mac}.$dns_name.','.$row->{ip}.$dhcp_set."\n";
  85. }
  86. foreach my $ip (keys %static_hole) {
  87. if (!$static_hole{$ip}{skip}) {
  88. print '#BlackHole for static subnet\n';
  89. print 'dhcp-host='.$static_hole{$ip}->{mac}.', '.$ip."\n";
  90. }
  91. }
  92. # DNS
  93. print "#--- DNS ---#\n";
  94. #get userid list
  95. my $sSQL="SELECT id,ou_id,ip,dns_name,dhcp_hostname,dns_ptr_only FROM User_auth WHERE deleted=0 AND ip>'' AND (dns_name>'' OR dhcp_hostname>'') AND dns_name NOT LIKE '%.' ORDER by ip_int;";
  96. my @users = get_records_sql($dbh,$sSQL);
  97. foreach my $row (@users) {
  98. next if (!$row);
  99. next if (is_default_ou($dbh,$row->{ou_id}));
  100. next if (!$office_networks->match_string($row->{ip}));
  101. my $dns_name = trim($row->{dns_name});
  102. if ($dns_name) {
  103. $dns_name =~s/_/-/g;
  104. # $dns_name =~s/[\.]/-/g;
  105. $dns_name =~s/ /-/g;
  106. $dns_name =~s/-$//g;
  107. $dns_name = trim($dns_name);
  108. if ($dns_name and $dns_name!~/\.$domain_name$/) { $dns_name = $dns_name .".".$domain_name; }
  109. } else { $dns_name=''; }
  110. next if (!$dns_name);
  111. #if (!$row->{dns_ptr_only} and ($dns_name or $row->{dhcp_hostname})) {
  112. if (!$row->{dns_ptr_only} and $dns_name) {
  113. print '#Comment:'.$row->{comments}."\n" if ($row->{comments});
  114. if ($dns_name) {
  115. print '#DNS A-record '.$dns_name."\n";
  116. print 'address=/'.$dns_name.'/'.$row->{ip}."\n";
  117. }
  118. # else {
  119. # if ($row->{dhcp_hostname} and $row->{dhcp_hostname}!~/UNDEFINED/i) {
  120. # $dns_name = $row->{dhcp_hostname};
  121. # $dns_name = $dns_name .".".$domain_name; }
  122. # $dns_name =~s/_/-/g;
  123. ## $dns_name =~s/[\.]/-/g;
  124. # $dns_name =~s/ /-/g;
  125. # $dns_name =~s/-$//g;
  126. # $dns_name = trim($dns_name);
  127. # if ($dns_name) {
  128. # print '#DNS-from-DHCP A-record '.$dns_name."\n";
  129. # print 'address=/'.$dns_name.'/'.$row->{ip}."\n";
  130. # }
  131. # }
  132. #aliases
  133. if ($dns_name) {
  134. my $aSQL="SELECT * FROM `User_auth_alias` WHERE auth_id=$row->{id} AND alias>'' AND alias NOT LIKE '%.';";
  135. my @aliases = get_records_sql($dbh,$aSQL);
  136. print '#DNS aliases for '.$dns_name."\n" if (@aliases and scalar @aliases);
  137. foreach my $alias (@aliases) {
  138. my $dns_alias = trim($alias->{alias});
  139. # $dns_alias =~s/$domain_name//i;
  140. $dns_alias =~s/_/-/g;
  141. $dns_alias =~s/[\.]/-/g;
  142. $dns_alias =~s/ /-/g;
  143. $dns_alias =~s/-$//g;
  144. $dns_alias = trim($dns_alias);
  145. if ($dns_alias and $dns_alias !~ /\.\Q$domain_name\E$/i) { $dns_alias = $dns_alias .".".$domain_name; }
  146. print 'address=/'.$dns_alias.'/'.$row->{ip}."\n" if ($dns_alias);
  147. }
  148. }
  149. }
  150. my $ptr_record='';
  151. if ($dns_name and $row->{ip}=~/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/) {
  152. $ptr_record=$4.".".$3.".".$2.".".$1.".in-addr.arpa";
  153. print '#PTR for '.$dns_name."\n";
  154. print 'ptr-record='.$ptr_record.','.$dns_name."\n";
  155. }
  156. }
  157. exit 0;