print-dnsmasq.pl 6.2 KB

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