日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Windows 2000下的Raw Socket編程( 三 )


addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);

//
//
//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader) sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr("本地地址");
ipHeader.destIP=inet_addr(argv[1]);

//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[2]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口號
tcpHeader.th_seq=htonl(0x12345678);
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=2; //修改這里來實現(xiàn)不同的標志位探測,2是SYN,1是FIN,16是ACK探測 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;

psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));

//計算校驗和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader) sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf sizeof(ipHeader) sizeof(tcpHeader), 0, 4);
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader) sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));

rect=sendto(sock, szSendBuf, sizeof(ipHeader) sizeof(tcpHeader),
0, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%dn",WSAGetLastError());
return false;
}
else
printf("send ok!n");

closesocket(sock);
WSACleanup();

return 0;
}

4、接收數(shù)據(jù)
和 發(fā)送原始套接字數(shù)據(jù)相比,接收就比較麻煩了 。因為在WIN我們不能用recv()來接收raw socket上的數(shù)據(jù),這是因為,所有的IP包都是先遞交給系統(tǒng)核心,然后再傳輸?shù)接脩舫绦?,當發(fā)送一個raws socket包的時候(比如syn),核心并不知道,也沒有這個數(shù)據(jù)被發(fā)送或者連接建立的記錄,因此,當遠端主機回應的時候,系統(tǒng)核心就把這些包都全部丟 掉,從而到不了應用程序上 。所以,就不能簡單地使用接收函數(shù)來接收這些數(shù)據(jù)報 。

要達到接收數(shù)據(jù)的目的,就必須采用嗅探,接收所有通過的數(shù)據(jù)包,然后進行篩選,留下符合我們需要的 。可以再定義一個原始套接字,用來完成接收數(shù)據(jù)的任務,需要設置SIO_RCVALL,表示接收所有的數(shù)據(jù) 。

SOCKET sniffersock;
sniffsock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);

DWORD lpvBuffer = 1;
DWORD lpcbBytesReturned = 0 ;
WSAIoctl(sniffersock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL);

創(chuàng)建一個用于接收數(shù)據(jù)的原始套接字,我們可以用接收函數(shù)來接收數(shù)據(jù)包了 。然后在使用一個過濾函數(shù)達到篩選的目的,接收我們需要的數(shù)據(jù)包 。
在 http://www.xici.net/board/doc.asp?id=5891453&sub=15 提供了一個完整的發(fā)送和接收的程序,可以參考 。

------------------------------------------------------------
reference:
1、《MS Windows 2000 TCP-IP Implementation Details》
2、ziss《Raw Sockets in Windows 2000/XP》
3、MSDN Platform SDK:《Windows Sockets 2》

推薦閱讀