#!/usr/bin/perl # # Copyright (C) Roman Dmitriev, rnd@rajven.ru # use utf8; use warnings; use Encode; use open qw(:std :encoding(UTF-8)); no warnings 'utf8'; use English; use base; use FindBin '$Bin'; use lib "/opt/Eye/scripts"; use strict; use DBI; use Time::Local; use Net::Patricia; use NetAddr::IP; use Data::Dumper; use eyelib::config; use eyelib::main; use eyelib::logconfig; use eyelib::database; use eyelib::common; use eyelib::net_utils; use File::Basename; use File::Path; use Fcntl qw(:flock); open(SELF,"<",$0) or die "Cannot open $0 - $!"; flock(SELF, LOCK_EX|LOCK_NB) or exit 1; binmode(STDOUT,':utf8'); setpriority(0,0,19); my $dhcp_networks = new Net::Patricia; my %dhcp_conf; my %static_hole; my %mac_subnets; 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'); foreach my $subnet (@subnets) { next if (!$subnet->{gateway}); $dhcp_networks->add_string($subnet->{subnet}); my $subnet_name = $subnet->{subnet}; $subnet_name=~s/\/\d+$//g; $dhcp_conf{$subnet_name}->{first_ip}=IpToStr($subnet->{dhcp_start}); $dhcp_conf{$subnet_name}->{last_ip}=IpToStr($subnet->{dhcp_stop}); $dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway}); my $dhcp=GetDhcpRange($subnet->{subnet}); if ($subnet->{static}) { $static_hole{$dhcp_conf{$subnet_name}->{last_ip}}->{mac}="01:02:03:04:05:06"; $static_hole{$dhcp_conf{$subnet_name}->{last_ip}}->{skip}=0; 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"; } else { 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"; } print "dhcp-option=net:net-$subnet_name,option:router,$dhcp_conf{$subnet_name}->{relay_ip}\n"; } #get userid list 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"; my @users = get_records_sql($dbh,$sSQL); foreach my $row (@users) { next if (!$row); next if (!$dhcp_networks->match_string($row->{ip})); next if (!$row->{mac}); next if (!$row->{ip}); next if (is_default_ou($dbh,$row->{ou_id})); if (exists $static_hole{$row->{ip}}) { $static_hole{$row->{ip}}{skip}=1; } my $subnet = $dhcp_networks->match_string($row->{ip}); $mac_subnets{$subnet} ||= { name => $subnet, macs => {} }; if (exists $mac_subnets{$subnet}{macs}{$row->{mac}}) { my $old_row = $mac_subnets{$subnet}{macs}{$row->{mac}}; db_log_warning($dbh,"Mac $row->{mac} already exists in DHCP fo subnet $subnet! auth_id: $row->{id} and auth_id: $old_row->{id}"); next; } $mac_subnets{$subnet}{macs}{$row->{mac}} = $row; print '#Comment:'.$row->{description}."\n" if ($row->{description}); my $dns_name = ''; if ($row->{dns_name}) { print '#DNS:'.$row->{dns_name}."\n"; $dns_name = ','.$row->{dns_name}; } my $dhcp_set = ''; if ($row->{dhcp_option_set}) { $dhcp_set = ',set:'.$row->{dhcp_option_set}; } print 'dhcp-host='.$row->{mac}.$dns_name.','.$row->{ip}.$dhcp_set."\n"; } foreach my $ip (keys %static_hole) { if (!$static_hole{$ip}{skip}) { print '#BlackHole for static subnet\n'; print 'dhcp-host='.$static_hole{$ip}->{mac}.', '.$ip."\n"; } } # DNS print "#--- DNS ---#\n"; #get userid list my $uSQL = " SELECT id, ou_id, ip, dns_name, dhcp_hostname, dns_ptr_only FROM user_auth WHERE deleted = 0 AND ip IS NOT NULL AND ( (dns_name IS NOT NULL AND dns_name != '' AND dns_name NOT LIKE '%.') OR (dhcp_hostname IS NOT NULL AND dhcp_hostname != '') ) ORDER BY ip_int "; @users = get_records_sql($dbh, $uSQL); foreach my $row (@users) { next if (!$row); next if (is_default_ou($dbh,$row->{ou_id})); next if (!$office_networks->match_string($row->{ip})); my $dns_name = trim($row->{dns_name}); if ($dns_name) { $dns_name =~s/_/-/g; # $dns_name =~s/[\.]/-/g; $dns_name =~s/ /-/g; $dns_name =~s/-$//g; $dns_name = trim($dns_name); if ($dns_name and $dns_name!~/\.$domain_name$/) { $dns_name = $dns_name .".".$domain_name; } } else { $dns_name=''; } next if (!$dns_name); #if (!$row->{dns_ptr_only} and ($dns_name or $row->{dhcp_hostname})) { if (!$row->{dns_ptr_only} and $dns_name) { print '#Comment:'.$row->{description}."\n" if ($row->{description}); if ($dns_name) { print '#DNS A-record '.$dns_name."\n"; print 'address=/'.$dns_name.'/'.$row->{ip}."\n"; } # else { # if ($row->{dhcp_hostname} and $row->{dhcp_hostname}!~/UNDEFINED/i) { # $dns_name = $row->{dhcp_hostname}; # $dns_name = $dns_name .".".$domain_name; } # $dns_name =~s/_/-/g; ## $dns_name =~s/[\.]/-/g; # $dns_name =~s/ /-/g; # $dns_name =~s/-$//g; # $dns_name = trim($dns_name); # if ($dns_name) { # print '#DNS-from-DHCP A-record '.$dns_name."\n"; # print 'address=/'.$dns_name.'/'.$row->{ip}."\n"; # } # } #aliases if ($dns_name) { my $aSQL = "SELECT * FROM user_auth_alias WHERE auth_id = ? AND alias IS NOT NULL AND alias != '' AND alias NOT LIKE '%.'"; my @aliases = get_records_sql($dbh, $aSQL, $row->{id}); print '#DNS aliases for '.$dns_name."\n" if (@aliases and scalar @aliases); foreach my $alias (@aliases) { my $dns_alias = trim($alias->{alias}); # $dns_alias =~s/$domain_name//i; $dns_alias =~s/_/-/g; $dns_alias =~s/[\.]/-/g; $dns_alias =~s/ /-/g; $dns_alias =~s/-$//g; $dns_alias = trim($dns_alias); if ($dns_alias and $dns_alias !~ /\.\Q$domain_name\E$/i) { $dns_alias = $dns_alias .".".$domain_name; } print 'address=/'.$dns_alias.'/'.$row->{ip}."\n" if ($dns_alias); } } } my $ptr_record=''; if ($dns_name and $row->{ip}=~/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/) { $ptr_record=$4.".".$3.".".$2.".".$1.".in-addr.arpa"; print '#PTR for '.$dns_name."\n"; print 'ptr-record='.$ptr_record.','.$dns_name."\n"; } } exit 0;