FC2ブログ
--.--
--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

05.20
Sun
さてー、タイトルの通りSYNパケットを送ってみます。

まず、SYNパケットとは何かについて書きます。


SYNパケットというのはトランスポート層のプロトコルであるTCPが使う

SYNフラグの立った特殊なパケットのことです(セグメントって言うべきなのかな)

TCPというプロトコルはUDPと違って信頼性があります。

なので、通信の初めに通信相手と仮想的なコネクションを張るのですが

その制御のために使われるのがSYNパケットです

まず通信したい側がこのSYNパケットを送って

これから接続したいんだけどー的な旨を伝えます

そうすると、接続される側(サーバ)は接続のための準備に入ります

具体的にはここでサーバはいろいろリソースをクライアントのために割り当てます。

そんで、サーバはクライアントにSYN,ACKパケットを返して

接続に来ておっけーだよーって言います

おっけーじゃないときはRSTフラグの立ったパケットが返ると思います。

そして最後にクライアントがACKを送信することで接続が完了します.

3段階を踏んでいるので、これをスリーウェイハンドシェイクって言います

ということで、以下のコードはその一番最初のSYNを送るものです.

普通この接続処理はconnect()とかがやってくれているはずですが、

生ソケットを使ったりすると、この辺の実装から行えるわけです。

本当はもっと低レイヤのプロトコルのヘッダからいじれるのですが、

私の技量不足等により今回はTCPあたりを。

このコードの説明とかはいつかのブログのネタにとっておきますw

特にチェックサムあたりのめんどい部分は忘れてしまいそうなので。


動作環境はUbuntuです

このコードはループバックアドレス127.0.0.1のポート12345から

127.0.0.1のポート80へSYNパケットを送信します



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>


struct dummyIPheader{
	
	unsigned int srcIP;
	unsigned int dstIP;
	unsigned char zero;
	unsigned char protocol;
	unsigned short len;
	
};

struct dummyHeader {
	struct dummyIPheader pIPheader;
	struct tcphdr pTCPheader;
};

unsigned short checksum(unsigned short *ptr , int size);

int main(void)
{
	
	struct tcphdr TCPheader;
	struct dummyHeader pHeader;
	struct sockaddr_in peer;
	int sock;
	int srcport = 12345;
	int dstport = 80;
	int windowsize = 512;
	char srcip[] = "127.0.0.1";
	char dstip[] = "127.0.0.1";
	
	TCPheader.source = htons(srcport);
	TCPheader.dest = htons(dstport);
	TCPheader.seq = 1;
	TCPheader.window = htons(windowsize);
	TCPheader.fin = 0;
	TCPheader.syn = 1;
	TCPheader.doff = 5;
	TCPheader.rst = 0;
	TCPheader.urg = 0;
	TCPheader.urg_ptr = 0;
	TCPheader.psh = 0;
	TCPheader.ack_seq = 0;
	TCPheader.ack = 0;
	TCPheader.check = 0;
	TCPheader.res1 = 0;
	TCPheader.res2 = 0;
	
	inet_aton(srcip , &pHeader.pIPheader.srcIP);
	inet_aton(dstip , &pHeader.pIPheader.dstIP);
	pHeader.pIPheader.zero = 0;
	pHeader.pIPheader.protocol = 6;
	pHeader.pIPheader.len = htons(20);	

		
	inet_aton(dstip , &peer.sin_addr);
	peer.sin_port = htons(dstport);
	peer.sin_family = AF_INET;

	bcopy((char *)&TCPheader , (char *)&pHeader.pTCPheader , 20);

	TCPheader.check = checksum((unsigned short *)&pHeader , 32);

	sock = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);

	if (sock < 0 ){
		perror("socket");
		return 1;
	}
	
	if (sendto(sock , &TCPheader , sizeof(TCPheader) , 0 , (struct sockaddr *)&peer , sizeof(peer)) <0 ){
		perror("sendto");
		close(sock);
		return 1;
	}

	close(sock);
	return 0;
}
unsigned short checksum(unsigned short *ptr , int size)  
{  
    int index = 0;  
    int sum = 0;  
    short int proc = 0;  
  
    for (index = 0;index<size;index+=2){  
          
            sum += *(ptr++);  
    }  
  
    short int carry = sum >> 16;  
    
    short int main = 0x0000ffff & sum;
    
    short int result = ~(main+carry);  
  
    return result;  
}  

スポンサーサイト

comment 0 trackback 0
トラックバックURL
http://telracsmoratori.blog.fc2.com/tb.php/116-e2ef5507
トラックバック
コメント
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。