2012-02-13 8 views
2

私は、あなたが与えた任意のIPとポート番号でsynパケットを送出する小さなツールをコーディングしました - そして、私がWiresharkをポップアップしたとき、送られたパケットはうまく表示されます。あなたの典型的なTCP SYNパケットのように見えます。synの後にackを取得する

何らかの理由で、ACKがサーバーから送信されません。だから、2つの問題があります。 1つ、ACK応答なし。 2つ目は、私のプログラム(bind()?)を使ってackの応答を受け取る方法を知りません。

syn flooderからいくつかのコードを変更しましたが、私はオンラインのスクリプトコードを修正しました。スクリプトコードは簡単に実行できますが、何か不足している可能性があります。サーバのACK拒否。正当なIPアドレスからsynリクエストが送信されるように、コードが変更されています。次のコードは、私の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

あなたのパケットが破棄されているように見えます。私は両方のエンドポイントでスニッファをチェックすることをお勧めします。 – jweyrich

答えて

3

ライン:

tcph->window = htonl (65555); 

が問題を引き起こす可能性があります。 65555が0xFFFFよりも大きいためです。 windowのフィールドサイズは16ビットです。

だから、これは良いかもしれません:

tcph->window = htons (65535); 

お知らせ:htonlはhtonsに変更しました。

編集:

あるいはそれ以上の優れた(Contantをが利用可能な場合):

tcph->window = htons (TCP_MAXWIN); 

問題は、TCPチェックサムカウントの欠如にもすることができます。 コードでは、下位層がTCPチェックサムフィールドを更新することを前提としています。 すべてのネットワークインターフェイスカードがTCP checksum offloadをサポートしていないため、 のコードはすべてのホストで機能しない場合があります。

+0

おかげさまで、これは将来の問題に役立つかもしれませんが、主な問題は依然として残っています。私はACKを得ていない! (そして、はい、私は複数のホストに対して試しました!さらにhping2による検証があります) – Saustin

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; 

}

関連する問題