我需要使用tcp半开扫描来检查大量服务器的端口状态。
我sendto()
是一个带有syn=1
到destip的destport的recvfrom()
数据包,如果一个数据包,如果syn=1
和ack=1
,端口是开放的,否则如果rst=1
,端口是关闭的。
我用epoll,socket发包后,socket的状态没有变成EPOLLIN
。
那个确认包不是EPOLLIN吗?
我设置socket IP_HDRINCL
了,所以我可以构建一个伪头,syn=1
我尝试了非阻塞套接字和阻塞套接字,都不起作用。
这是我的代码的一部分:
int main()
{
char localIp[20] = {0};
GetSelfServerIP(localIp);//to get local IP
int epollfd = epoll_create(1);
if (epollfd == -1)
{
error(1, errno, "Error epoll creating");
return 0;
}
SOCKET sock = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
if(!IS_VALID_SOCK(sock))
error(1, 0, "Error socket initialization");
if(SetNonBlock(sock) < 0)
error(1, errno, "Error switching socket to non-block mode.");
if(SetReusable(sock) < 0)
error(1, errno, "Error making socket reusable");
if(SetHdrincl(sock) < 0)
error(1, errno, "Error making socket Hdrincl");
struct epoll_event ev; //only one ev for test
ev.events = EPOLLIN | EPOLLPRI;
ev.data.fd = sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1)
error(1, errno, "Error adding event m to epoll");
char * targetip = "xxx.xxx.xxx.xxx";//test target ip
struct epoll_event events[1];
memset(events, 0, sizeof(struct epoll_event));
while(1)
{
Sendpacket(ev.data.fd,localIp,get_random_sport(),targetIp);//to send syn=1 packet to targetIp port 1 to 1000;
size_t nfds = epoll_wait(epollfd, events, 2, 1000);
size_t i = 0;
if (nfds == -1)
error(1, errno, "Error calling epoll");
for (i = 0; i < nfds; ++i)
{
if ((events[i].events & EPOLLIN) == EPOLLIN ||
(events[i].events & EPOLLPRI) == EPOLLPRI)
{
int sock_raw;
int saddr_size, data_size;
struct sockaddr saddr;
unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!
saddr_size = sizeof saddr;
data_size = recvfrom(sock_raw, buffer, 65536, 0, &saddr, &saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
fflush(stdout);
return 1;
}
//Now process the packet
}
}
fflush(stdout);
}
return 1;
}
1.events[i].event
总是==EPOLLOUT
2. data_size = recvfrom(sock_raw, buffer, 65536, 0, &saddr, &saddr_size)
data_size 总是 < 0。