I need to use tcp half-open scan to check the port status of a large number of servers.
I sendto()
a packet with syn=1
to destip's destport,and should recvfrom()
a packet ,if syn=1
and ack=1
, port is open, else if rst=1
, port is close.
I use epoll , after socket send packet,socket's status doesn't become EPOLLIN
.
Is that ack packet is not a EPOLLIN?
I set socket IP_HDRINCL
,so I can build a pseudo header with syn=1
and i tried nonblock socket and block socket ,both doesn't work.
this is part of my code:
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
always == EPOLLOUT
2.data_size = recvfrom(sock_raw, buffer, 65536, 0, &saddr, &saddr_size)
data_size always < 0.