1. #!/usr/bin/perl -w 
  2. ##################################### 函数 get_ip_array ########################################## 
  3. ################## 输入从www.5maila.com 上面搜索并下载的 文件名字  
  4. #################  输出 从里面找到的 ip地址段 
  5. sub get_ip_array{ 
  6. $filename="$_[0]"
  7. open "file","$filename"
  8. my @nets; 
  9. foreach $file_line (<file>){ 
  10.     if ($file_line=~ /href=\'ip_(.*).htm/){ 
  11.         $file_line_net = $1; 
  12.         push (@nets,$file_line_net); 
  13.     } 
  14.     else
  15.         next
  16.     } 
  17. return @nets; 
  18.  
  19. ##################################函数 let_array_clear########################################### 
  20. #################### 输入一个含有若干ip地址的 数组 
  21. #################### 输出  同一个/24网络里面 只有 一个 ip地址 存在 
  22. # 函数,让数组 清楚一些 
  23. sub let_array_clear{ 
  24.     my @array = @_; 
  25.     my @new_array; 
  26.     my $ifsame = 0; 
  27.     foreach $array (@array) { 
  28.         #默认将 老数组中的每个值跟 新数组中的任一个值都不一样 
  29.         $ifsame=0; 
  30.         # 查询新数组序列中的每个值 
  31.         foreach $new_array (@new_array){ 
  32.             #将新数组中的一个值 按照 小数点进行 分隔成4块 
  33.             @new_array_numbers = split("\\.",$new_array); 
  34.             #将老数组中的一个值 按照 小数点进行 分隔成4块 
  35.             @array_numbers = split("\\.",$array); 
  36.             #判断数组4块中的前三块儿是否相同 
  37.             if ( $new_array_numbers[0] == $array_numbers[0] and $new_array_numbers[1] == $array_numbers[1] and $new_array_numbers[2] == $array_numbers[2] ){ 
  38.                 #如果相同,那么就将是否相同 设置为1 
  39.                 $ifsame = 1; 
  40.             } 
  41.         } 
  42.         # 比对完成后,对结果 ifsame 进行判断,如果相同,就进行下次循环,否则, 进行push操作 
  43.         if ($ifsame == 1) { 
  44.             next
  45.         } 
  46.  
  47.         elsif ($ifsame == 0) { 
  48.             $new_array = $array; 
  49.             push (@new_array,$new_array); 
  50.         } 
  51.     } 
  52.     return @new_array; 
  53.  
  54. ######################################## 连接数据库 #################################################### 
  55. use DBI; 
  56. use DBD::mysql; 
  57. my $dbh = DBI -> connect("DBI:mysql:db_iplocate;host=127.0.0.1""admin","admin",{RaiseError=>1}); 
  58. my $sth = $dbh->prepare( q{select city_cn,city_en from `gps`}) or die("Cannot prepare statement:", $dbh->errstr(),"\n"); 
  59. my $rc = $sth->execute() or die("Cannot execute statement:", $sth->errstr(), "\n"); 
  60. # 初始化两个数组 , 用来存放 从 数据库中得出的 城市 中文名字 和 英文名字 
  61. my @city_cn; 
  62. my @city_en; 
  63. # 将从mysql得到的city_cn和city_en放到相应的数组中 
  64. while (my @row = $sth -> fetchrow_array()){ 
  65.     push @city_cn,$row[0]; 
  66.     push @city_en,$row[1]; 
  67. # 初始化两个数组,用来存放 三个运营商的 中文名字 和 英文名字  
  68. my @isps_cn = ("移动","联通","电信"); 
  69. my @isps_en = ("ChinaMobile","ChinaUnicom","ChinaTelecom"); 
  70. # 对城市列表数组 进行 循环 
  71. foreach $i(0..(@city_cn-1)){ 
  72.     # 对 运营商数组 进行循环 
  73.     foreach $j(0..@isps_cn-1) { 
  74.         # 组合出英文文件名称        
  75.         $file_name = "$city_en[$i]" . "_" . "$isps_en[$j]"
  76.         # 开始处理 
  77.         print "开始处理$file_name......Ready!" 
  78.         # 1. 使用get_ip_array 的到 可能的ip地址段  
  79.         # 2. 使用let_array_clear 将得到的 ip地址段 数组 清洗, 确保不重复 
  80.         my @result = &let_array_clear(&get_ip_array("$file_name")); 
  81.         # 初始化 $nmap_target  
  82.         $nmap_target = ""
  83.         # 循环读出 result数组中存在的目标网段, 并在结尾加上 /24并 合并 
  84.         foreach $result (@result){ 
  85.             $nmap_target .= $result . "/24 "
  86.         } 
  87.         print `nmap -n -sP $nmap_target -oN result_nmap/$file_name`; 
  88.         print "处理$file_name......Complete!\n"
  89.     } 
  90.  
  91. warn($DBI::errstr) if $DBI::err; 
  92. $dbh->disconnect(); 
  93. $sth->finish();