<?php
//可优化 根据ip类型具体链接,非只有ip fsockopen
$ip = @trim($_POST['host'])?trim($_POST['host']):'';
if($ip){
$re = check_ip($ip);
if($re['type']=='error'){
die('IP error');
}
$ip = $re['ip'];
//格式 以,隔开 eg: 8080,3306
$ports = explode(',',str_replace(" ", "", $a=str_replace(",",",",$_POST['ports'])));
//端口号去重
$ports = array_unique($ports);
//端口结果展示
$list = array();
//错误信息收集
$ERR = array();
foreach($ports as $port){
if(check_port($ip,$port,$timeout=15)){
$list[$ip]['open'][] = $port;
}else{
$list[$ip]['close'][] = $port;
}
}
//echo '<pre>';print_r($list);die;
}
function check_port($ip,$port,$timeout=30) {
global $ERR;
$conn = @fsockopen($ip, $port, $errno, $errstr, $timeout);
if ($conn) {
fclose($conn);
return true;
}else{
$ERR[$ip.':'.$port] = iconv('gbk','utf-8',"$errstr ($errno)");
}
}
/**
* 检查ip
* @param string $ip 需要检查的ip
* return array 检查结果 ip 检查的ip type ip类型
* type: IPv4 IPv6 ReservedIP PrivateIP(私有IP) error(不合格IP)
* */
function check_ip($ip){
//判断是否是合法IP
if(filter_var($ip, FILTER_VALIDATE_IP)) {//IPv4,IPv6,私有和保留范围IP
//FILTER_FLAG_NO_PRIV_RANGE
// 无法验证以下私有IPv4范围:10.0.0.0/8 , 172.16.0.0/12 和 192.168.0.0/16
// 无法验证从FD或FC开始的IPv6地址。
//FILTER_FLAG_NO_RES_RANGE
// 无法验证以下保留的IPv4范围:0.0.0.0/8 , 169.254.0.0/16 , 127.0.0.0/8 和 240.0.0.0/4
// 无法验证以下保留的IPv6范围:::1/128 ,::/128,::ffff:0:0/96 和 fe80::/10
//仅IPv4(例如120.138.20.36)
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_IPV4)) {
return $result = array(
'ip'=>$ip,
'type'=>'IPv4'
);
}
//仅IPv6
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_IPV6)) {
return $result = array(
'ip'=>$ip,
'type'=>'IPv6'
);
}
//排除私有的,使用FILTER_FLAG_NO_PRIV_RANGE标志
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
//127.X.X.X是保留地址,用做循环测试用的。
//169.254.X.X是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP
return $result = array(
'ip'=>$ip,
'type'=>'ReservedIP'
);
}
//排除存在大量保留的IP地址范围,使用FILTER_FLAG_NO_RES_RANGE标志
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)) {
//私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
//10.0.0.0-10.255.255.255
//172.16.0.0—172.31.255.255
//192.168.0.0-192.168.255.255
return $result = array(
'ip'=>$ip,
'type'=>'PrivateIP'
);
}
}
return $result = array(
'ip'=>$ip,
'type'=>'error'
);
}
?>
<html lang="en">
<head>
<title>扫描端口</title>
<!-- no cache headers -->
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<!-- end no cache headers -->
<style>
.SMSearTxt {
color: #56688a;
width: 700px;
border: none;
border: 1px solid #c6cede;
background-color: #fff;
min-height: 103px;
padding: 7px 5px;
line-height: 24px;
font-size: 16px;
white-space: normal;
display: inline-block;
}
.search-write-cont {
float: left;
color: #56688a;
height: 25px;
width: 680px;
line-height: 25px;
margin: 6px 0px 0px 10px;
padding: 0px;
background: none;
border: 0px none;
outline: 0px none;
}
.search-write-left02 {
border: solid #c6cede;
height: 38px;
border-image: none;
background: #FFF;
vertical-align: top;
overflow: hidden;
font: 16px arial;
margin: 0;
zoom: 1;
display: block;
}
.SMSearBtn {
height: 35px;
line-height: 35px;
color: #fff;
background-color: #55a7e3;
border: none;
font-size: 14px;
}
.w114 {
width: 114px;
}
.tr {
text-align: right;
}
.w700 {
width: 700px;
}
.lh24 {
line-height: 24px !important;
}
.col-gray04 {
color: #929db3;
}
.ReListhalf {
line-height: 30px;
padding-top: 5px;
padding: 5px;
display: inline-block;
float: left;
color: #444444;
text-align: center;
}
.w50-0 {
width: 48%;
}
.tc {
text-align: center !important;
}
.ResultListHead {
width: 100%;
min-height: 40px;
}
.clearfix {
zoom: 1;
}
.bor-b1s02 {
border-bottom: 1px solid #f2f2f2;
}
.bg-blue08 {
background-color: #BCC7DD !important;
}
.col-gray03 {
color: #56688a;
}
.col-blue02 {
color: #0474c8 !important;
}
.col-red {
color: #ff0000 !important;
}
.col-green02 {
color: #228b22 !important;
}
</style>
</head>
<body>
<form action="" method="post" autocomplete="off">
<span class="search-write-left02 w700">
<input class="search-write-cont" name="host" placeholder="请输入扫描ip">
</span>
<textarea class="SMSearTxt" name="ports" size="90">80,8080,3128,8081,9080,1080,21,23,443,69,22,25,110,7001,9090,3389,1521,1158,2100,1433</textarea>
<p class="lh24 col-gray04">多个端口号请用逗号隔开,例:8080,8081</p>
<div class="w700 tr">
<input class="SMSearBtn w114" type="submit" value="开始扫描">
</div>
<?php
if(!empty($list)){
echo '<p class="ResultListHead bg-blue08 col-gray03 clearfix bor-b1s02">
<span class="ReListhalf w50-0 tc">端口</span>
<span class="ReListhalf w50-0 tc">状态</span>
</p>';
foreach ($list as $ip=>$v){
echo '<p class="ResultListwrap clearfix bor-b1s02" style="background-color: #55a7e3;">'.$ip.'</p>';
//开启端口
if(isset($v['open']) && !empty($v['open'])){
foreach ($v['open'] as $post){
echo ' <span class="ReListhalf w50-0 tc YaHei col-blue02 portitem">'.$post.'</span>';
echo ' <span class="ReListhalf w50-0 tc bg-port col-green02">open</span>';
}
}
//关闭端口
if(isset($v['close']) && !empty($v['close'])){
foreach ($v['close'] as $post){
echo ' <span class="ReListhalf w50-0 tc YaHei col-blue02 portitem">'.$post.'</span>';
echo ' <span class="ReListhalf w50-0 tc bg-port col-red">close</span>';
}
}
}
//错误提示
/*if(!empty($ERR)){
$err_str = '<br/>ERROR:<br/>';
foreach ($ERR as $k=>$v){
$err_str .= $k.':'.$v.'<br/>';
}
echo $err_str;
}*/
}
?>
</form>
</body>
</html>