我编写了一个小工具,它只是在你给它的任何ip和端口号上抛出一个syn数据包 - 当我弹出Wireshark时,发送的数据包显示正常,没有错误或任何东西,它看起来就像你的典型的TCP SYN数据包。
由于某种原因,服务器不发送ACK。那么,有两个问题;一,没有ACK响应。二,我甚至不知道如何通过我的程序接收ack响应(bind()?)。
我修改了我在网上找到的一个syn flooder中的一些代码,因为对我来说似乎很容易遵循一些脚本小子代码,但我担心它可能会丢失一些东西,可能是服务器的结果拒绝否认。代码已被修改,因此syn请求从合法IP地址发送。以下代码显示了我的ip + tcp标头:
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
iph->id = htonl (54321); //Id of this packet
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = 6;
iph->check = 0; //Set to 0 before calculating checksum
iph->saddr = 0; //Source ip filled in by kernel
iph->daddr = sin.sin_addr.s_addr;
//TCP Header
tcph->source = htons (9999);
tcph->dest = htons (atoi(argv[2]));
tcph->seq = random ();
// tcph->ack_seq = 0;
tcph->doff = 5; /* first and only tcp segment */
tcph->syn = 1;
tcph->window = htonl (65555); /* maximum allowed window size */
tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack
should fill in the correct checksum during transmission */
tcph->urg_ptr = 0;
//Now the IP checksum
iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
所以,我发送,没有回复。我错过了什么?
答案 0 :(得分:3)
该行:
tcph->window = htonl (65555);
可能会导致问题。因为65555大于0xFFFF。
window
字段大小为16位。
所以这可能会更好:
tcph->window = htons (65535);
注意:htonl已更改为htons。
编辑:
甚至更好(如果有可用的话):
tcph->window = htons (TCP_MAXWIN);
问题也可能是缺乏TCP校验和计数。 您的代码假定较低层更新TCP校验和字段。 由于所有网络接口卡都不支持TCP checksum offload, 代码可能无法在每个主机中运行。
答案 1 :(得分:0)
你还没有写完整个代码。你可能会遗漏一些区域。
此代码可以帮助您。
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<errno.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
struct pseudo_header
{
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t tcp_length;
};
unsigned short csum(unsigned short *ptr,int nbytes)
{
register long sum;
unsigned short oddbyte;
register short answer;
sum=0;
while(nbytes>1) {
sum+=*ptr++;
nbytes-=2;
}
if(nbytes==1) {
oddbyte=0;
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
return(answer);
}
int main (void)
{
int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
if(s == -1) {
perror("Failed to create socket");
exit(1);
}
char datagram[4096] , source_ip[32] , *data , *pseudogram;
char buffer[4096];
memset (datagram, 0, 4096);
struct iphdr *iph = (struct iphdr *) datagram;
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct iphdr));
struct sockaddr_in sin;
struct pseudo_header psh;
data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr);
strcpy(data , "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
strcpy(source_ip , "127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(55559);
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data);
iph->id = htonl (54351);
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
iph->check = 0;
iph->saddr = inet_addr ( source_ip );
iph->daddr = sin.sin_addr.s_addr;
iph->check = csum ((unsigned short *) datagram, iph->tot_len);
tcph->source = htons (55554);
tcph->dest = sin.sin_port;
tcph->seq = htonl(4362);
tcph->ack_seq = htonl(0);
tcph->doff = 5;
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window = 1;
tcph->check = 0;
tcph->urg_ptr = 0;
psh.source_address = inet_addr( source_ip );
psh.dest_address = sin.sin_addr.s_addr;
psh.placeholder = 0;
psh.protocol = IPPROTO_TCP;
psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) );
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data);
pseudogram = malloc(psize);
memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data));
tcph->check = csum( (unsigned short*) pseudogram , psize);
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
{
perror("Error setting IP_HDRINCL");
exit(0);
}
sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin));
return 0;
}