/*
程序可以根据需要做适当的修改
可以先对照看看我的第一个版本,使用-t 最好设置成5秒到10秒左右。否则将可能检测不到下面的第一种情况。
1.如果局域网内一台电脑使用了应用层防火墙比如天网之类,会connect超时。对方在线
2.connect success 连接成功,对方在线
3.connect refused 拒绝连接,对方在线
4.no route 连续发送5个arp请求(没有结果)和一个dns查询后(返回nxdomain),内核产生no route的错误。对方不在线
林汉杰 2008-7-16
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/time.h"
#include "sys/socket.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "netdb.h"
#include "fcntl.h"
#include "errno.h"
void usage() {
printf("use format:\n\t-s startip\n\t-e endip\n\t-t connect_timeout\n\t-p port\n");
exit(-1);
}
int main(int argc, char** argv) {
int start_ip = 1;
int end_ip = 254;
int time_connect = 10;
int port = 8888;
int opt;
while((opt = getopt(argc, argv, "s:e:t:p:")) != -1) {
switch(opt) {
case 's':start_ip = atoi(optarg);break;
case 'e':end_ip = atoi(optarg);break;
case 't':time_connect = atoi(optarg);break;
case 'p':port = atoi(optarg);break;
case '?':usage();break;
}
}
printf("-----------------------------------------------------------------------------------------------------\n");
printf("\t scan will use 192.168.1.%d -> 192.168.1.%d with connect timeout %d in port %d\n", start_ip, end_ip, time_connect, port);
printf("-----------------------------------------------------------------------------------------------------\n");
struct timeval timeout;
fd_set wset;
fd_set rset;
char straddr[100];
for(int i=start_ip; i
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)perror("socket()");
sprintf(straddr, "192.168.1.%d\0", i);
fprintf(stderr, "scan %s\t", straddr);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
if(inet_pton(AF_INET, straddr, &(server_addr.sin_addr)) != 1)perror("inet_pton()");
server_addr.sin_port = htons(port);
int flags;
if((flags = fcntl(sockfd, F_GETFL, 0)) < 0)perror("fcntl()");
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)< 0)perror("fcntl()");
int result = connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(server_addr));
if(result == -1) {
if(errno == EINPROGRESS) {
timeout.tv_sec = 10;
timeout.tv_usec = 0;
if(time_connect >= 100) {
timeout.tv_sec = 0;
timeout.tv_usec = time_connect;
} else if(time_connect > 0) {
timeout.tv_sec = time_connect;
timeout.tv_usec = 0;
}
FD_ZERO(&wset);
FD_SET(sockfd, &wset);
rset = wset;
int n = select(sockfd+1, &rset, &wset, 0, &timeout);
if(n == -1 && errno!= EINTR) {
perror("select() error");
} else if(n > 0) {
int optval;
int optlen = 4;
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&optval, (socklen_t*)&optlen) < 0)perror("getsockopt()");
if(optval == 0) {
fprintf(stderr, "success select\n");
} else {
fprintf(stderr, "failed select %d:%s\n", optval, strerror(optval));
}
} else if(n == 0) {
fprintf(stderr, "connect timeout\n");
}
} else {
close(sockfd);
perror("connect()");
}
} else {
printf("connect() success\n");
close(sockfd);
continue;
}
close(sockfd);
}
return 0;
}
阅读(2823) | 评论(0) | 转发(0) |