print-dnsmasq.pl 6.1 KB

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