我已经使用TCP原始套接字来实现简单的TCP握手,以便创建一个简单的端口扫描程序。在这个端口扫描程序中,我想要遵循方法半开。正如我们在这种方法中所知,我们首先将SYN数据包发送到远程主机,然后:
我已经完成了这种方法的实施。但我觉得我的代码有问题。例如,当我将SYN发送到Web服务器的端口80时,它会重置与RST数据包的连接
任何人都可以请指出我的代码中的错误是什么?提前致谢
请注意,我使用ubuntu 14.04作为操作系统,eclipse使用IDE
int scan(char *hostip, int port){
// file descriptor for the socket
int fd;
// tcp header length
int tcphdr_len = sizeof(struct tcphdr);
// buffers containing raw packets
char send_buffer[PACKET_LENGTH], recv_buffer[PACKET_LENGTH];
// tcp header segment of raw packet
struct tcphdr *tcp = (struct tcphdr *) send_buffer;
// address of the destination entry point
struct sockaddr_in addr;
// size of received packet
int recvd_size;
int one = 1, result;
// clearing whole of the packet
memset(send_buffer, 0, PACKET_LENGTH);
memset(recv_buffer, 0, PACKET_LENGTH);
// creating raw socket
fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if(fd < 0){
die("failed to create socket");
}
// address family
addr.sin_family = AF_INET;
// destination port
addr.sin_port = htons(port);
// destination ip
addr.sin_addr.s_addr = inet_addr(hostip);
// the tcp structure
// source port
tcp->source = htons(12345);
// destination port
tcp->dest = addr.sin_port;
tcp->seq = htonl(1);
tcp->doff = 5;
tcp->syn = 1;
tcp->window = htons(65535);
if(sendto(fd, send_buffer, tcphdr_len, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0){
die("sendto failed");
}
recvd_size = recvfrom(fd, recv_buffer, PACKET_LENGTH, 0, 0, 0);
if(recvd_size < 0){ // error occurred
close(fd);
die("failed to receive packet");
}
if(recvd_size == 0){ // timed out
close(fd);
return ST_FILTERED;
}
result = process_packet(recv_buffer, recvd_size);
if(result == PCK_UNKNOWN){
close(fd);
return ST_UNKNOWN;
}
if(result == PCK_RST){
close(fd);
return ST_CLOSED;
}
close(fd);
return ST_OPEN;
}
这是函数process_packet
int process_packet(char *buffer, int size){
struct tcphdr *tcp = (struct tcphdr *) buffer;
fprintf(stdout, "\nsport=%i\ndport=%i\nsyn=%i\nack=%i\nrst=%i\nrecv size=%i\n", ntohs(tcp->source),
ntohs(tcp->dest),
tcp->syn,
tcp->ack,
tcp->rst,
size);
if(tcp->syn & tcp->ack){
return PCK_SYN_ACK;
}
if(tcp->rst){
return PCK_RST;
}
return PCK_UNKNOWN;
}
这是我的./myprg -t 81.31.160.39
target=81.31.160.39 *** port=80 *** status=
sport=17664
dport=1400
syn=0
ack=0
rst=1
recv size=1024
closed
此外,目标端口应为12345,但不是。
答案 0 :(得分:0)
您最好在wireshark中查看数据包,并尝试确定哪些字段有误。
然而documentation说:
用于接收IP标头始终包含在数据包中。
这意味着收到的数据以IP头开头,你的process_packet()必须在你到达tcp头之前解析它。