我在WIN 7環境下使用RAW_SOCKET做TCP半連接掃描,使用sendto函式發送TCP的syn請求,sendto函式回傳值表明已經發送成功,但是wireshark并沒有抓到相應的資料包,不知道為什么。麻煩大家幫幫忙!代碼是我從網上找的:
[code=c#include <stdio.h>
#include <string.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#include "mstcpip.h"
#pragma comment(lib,"WS2_32.lib")
//定義目標主機的ip地址
char *DestIpAddr="10.8.180.125";
char *SourceIpAddr = "10.8.184.157";
//定義ip首部
typedef struct IpHeader
{
unsigned char Version_HLen; //首部長度ip版本號
unsigned char TOS; //服務型別TOS
unsigned short Length; //總長度
unsigned short Ident; //標識
unsigned short Flags_Offset;//標志位
unsigned char TTL; //生存時間TTL
unsigned char Protocol; //協議
unsigned short Checksum; //ip首部校驗和
unsigned int SourceAddr; //源ip地址
unsigned int DestinationAddr;//目的ip地址
}Ip_Header;
//tcp 標志位
#define URG 0x20
#define ACK 0x10
#define PSH 0x08
#define RST 0x04
#define SYN 0x02
#define FIN 0x01
//定義tcp首部
typedef struct TcpHeader
{
USHORT SrcPort; //16位源埠
USHORT DstPort; //16位目的埠
unsigned int SequenceNum; //32位序號
unsigned int Acknowledgment;//32位確認序號
unsigned char Hdrlen; //首部長度
unsigned char Flags; //6位標志位
USHORT AdvertisedWindow; //16位視窗大小
USHORT Checksum; //16位校驗和
USHORT UrgPtr; //16位緊急指標
}Tcp_Header;
//函式參考
//分析資料包
int PacketAnalyzer(char*);
//發送資料吧
int SendTCPSYNPacket(int);
//主函式
int main(int argc,char **argv)
{
//開始埠
int PortStart=80;
//結束埠
int PortEnd=90;
//套接字
SOCKET RecSocket;
int Result;
char RecvBuf[65535]={0};
//定時器的頻率
LARGE_INTEGER nFreq;
char Name[255];
//起始獲得定時器的值
LARGE_INTEGER StartTime;
//終止定時器的值
LARGE_INTEGER EndTime;
HANDLE hCon;
WSADATA wsaData;
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD dwBytesReturned=0;
struct hostent *pHostent;
//初始化SOCKET
Result=WSAStartup(MAKEWORD(2,1),&wsaData);
if(Result==SOCKET_ERROR)
{
printf("WSAStartup failed with error %d\n",Result);
return 0;
}
//創建接收資料的套接字
RecSocket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(Result==SOCKET_ERROR)
{
printf("socket failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//獲得本機ip地址
Result=gethostname(Name,255);
if(Result==SOCKET_ERROR)
{
printf("gethostname1 failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
pHostent=(struct hostent*)malloc(sizeof(struct hostent));
pHostent=gethostbyname(Name);
SOCKADDR_IN sock;
sock.sin_family=AF_INET;
sock.sin_port=htons(5555);
memcpy(&sock.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
//系結套接字
Result=bind(RecSocket,(PSOCKADDR)&sock,sizeof(sock));
if(Result==SOCKET_ERROR)
{
printf("bind failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//設定SOCK_RAW為SIO_RCVALL
Result=WSAIoctl(
RecSocket,
SIO_RCVALL,//表示接收所有ip資料包
&dwBufferInLen,
sizeof(dwBufferInLen),
&dwBufferLen,
sizeof(dwBufferLen),
&dwBytesReturned,NULL,NULL);
if(Result==SOCKET_ERROR)
{
printf("WSAIoctl failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
hCon=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hCon,&bInfo);
if(QueryPerformanceFrequency(&nFreq))
{
//獲取定時器的值
QueryPerformanceCounter(&StartTime);
//回圈掃描每個埠
for(int p=PortStart;p<=PortEnd;p++)
{
//發送構造的tcpsyn資料包
SendTCPSYNPacket(p);
//回圈監聽是否有資料包到達
while(true)
{
memset(RecvBuf,0,sizeof(RecvBuf));
Result=recv(RecSocket,RecvBuf,sizeof(RecvBuf),0);
if(Result==SOCKET_ERROR)
{
printf("recv failed with error %d\n",WSAGetLastError());
closesocket(RecSocket);
return 0;
}
//分析資料包
Result=PacketAnalyzer(RecvBuf);
if(Result==0)
{
continue;
}
else
{
break;
}
}
SetConsoleTextAttribute(hCon,14);
QueryPerformanceCounter(&EndTime);
}//end for
}
//技術時間
double fInterval=EndTime.QuadPart-StartTime.QuadPart;
printf("Total Time:%ffms\n",fInterval*1000/(double)nFreq.QuadPart);
SetConsoleTextAttribute(hCon,bInfo.wAttributes);
//關閉套接字
if(closesocket(RecSocket)==SOCKET_ERROR)
{
printf("closesocket failed with error %d\n",WSAGetLastError());
return 0;
}
if(WSACleanup()==SOCKET_ERROR)
{
printf("WSACleanup failed with error %d\n",WSAGetLastError());
return 0;
}
return 1;
}
//計算校驗和
USHORT checksum(USHORT *buffer,int size)
{
unsigned long cksum=0;
while (size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR*)buffer;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
//發送tcp協議資料
//為了獨立性,協議的資料結構全部定義在內部
int SendTCPSYNPacket(int Port)
{
//定義ip首部
typedef struct ipHeader
{
u_char Version_HLen;
u_char TOS;
short Length;
short Ident;
short Flags_Offset;
u_char TTL;
u_char Protocol;
short Checksum;
unsigned int SourceAddr;
unsigned int DestinationAddr;
}Ip_Header;
//定義tcp偽首部
typedef struct PsdTcpHeader
{
unsigned long SourceAddr;
unsigned long DestinationAddr;
char Zero;
char Protcol;
unsigned short TcpLen;
}PSD_Tcp_Header;
//定義tcp首部
typedef struct tcp_hdr
{
USHORT SrcPort;
USHORT DstPort;
unsigned int SequenceNum;
unsigned int Acknowledgement;
unsigned char HdrLen;
unsigned char Flags;
USHORT AdvertisedWindow;
USHORT Checksum;
USHORT UrgPtr;
}Tcp_Header;
//本級ip地址
struct in_addr localaddr;
//本地主機名
char HostName[255];
struct hostent *Hostent;
WSADATA wsaData;
//發送用套接字
SOCKET SendSocket;
SOCKADDR_IN addr_in;
//表示ip首部
Ip_Header ipHeader;
//表示tcp首部
Tcp_Header tcpHeader;
//表示tcp偽首部
PSD_Tcp_Header psdHeader;
//發送緩沖區
char szSendBuf[100]={0};
BOOL flag;
int nTimeOver;
int Result;
Result=WSAStartup(MAKEWORD(2,1),&wsaData);
if(Result==SOCKET_ERROR)
{
printf("WSAStartup failed with error%d\n",Result);
return 0;
}
if((SendSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("WSASocket failed with error %d\n",WSAGetLastError());
return false;
}
flag=true;
if(setsockopt(SendSocket,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt failed with error %d\n",WSAGetLastError());
return false;
}
nTimeOver=1000;
if(setsockopt(SendSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&nTimeOver,sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt failed with error %d\n\n",WSAGetLastError());
return false;
}
addr_in.sin_family =AF_INET;
addr_in.sin_port =htons(1000);
addr_in.sin_addr .S_un.S_addr =inet_addr(DestIpAddr);
//獲取本地主機
Result=gethostname(HostName,255);
if(Result==SOCKET_ERROR)
{
printf("gethostname12 failed with error %d\n",WSAGetLastError());
return 0;
}
Hostent=(struct hostent*)malloc(sizeof(struct hostent));
Hostent=gethostbyname(HostName);
//填充ip首部
//版本和長度
ipHeader.Version_HLen=(4<<4|sizeof(ipHeader)/sizeof(unsigned long));
//服務型別
ipHeader.TOS=0;
ipHeader.Length=htons(sizeof(ipHeader)+sizeof(tcpHeader));
//16為標識
ipHeader.Ident=1;
ipHeader.Flags_Offset=0;
ipHeader.TTL=128;
ipHeader.Protocol=IPPROTO_TCP;
ipHeader.Checksum=0;
ipHeader.SourceAddr=inet_addr(SourceIpAddr) ;
ipHeader.DestinationAddr=inet_addr(DestIpAddr);
//填充tcp首部
tcpHeader.DstPort=htons(Port);
tcpHeader.SrcPort=htons(6666);
tcpHeader.Acknowledgement=0;
tcpHeader.HdrLen=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.Flags=2;
tcpHeader.AdvertisedWindow=htons(512);
tcpHeader.UrgPtr=0;
tcpHeader.Checksum=0;
//填寫tcp偽首部
psdHeader.SourceAddr=ipHeader.SourceAddr;
psdHeader.DestinationAddr=ipHeader.DestinationAddr;
psdHeader.Zero=0;
psdHeader.Protcol=IPPROTO_TCP;
psdHeader.TcpLen=htons(sizeof(tcpHeader));
//計算tcp校驗和
memcpy(szSendBuf,&psdHeader,sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader));
tcpHeader.Checksum=checksum((USHORT*)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
//計算ip校驗和
memcpy(szSendBuf,&ipHeader,sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader),&tcpHeader,sizeof(tcpHeader));
tcpHeader.Checksum=checksum((USHORT*)szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader));
//更新內容
memcpy(szSendBuf,&ipHeader,sizeof(ipHeader));
Result=sendto(SendSocket,szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader),0,(struct sockaddr*)&addr_in,sizeof(addr_in));
if(Result==SOCKET_ERROR)
{
printf("sendto failed with error%d\n",WSAGetLastError());
return 0;
}
if(closesocket(SendSocket)==SOCKET_ERROR)
{
printf("closesocket failed with error%d\n",WSAGetLastError());
return 0;
}
if(WSACleanup()==SOCKET_ERROR)
{
printf("WSACleanup failed with error%d\n",WSAGetLastError());
return 0;
}
return 1;
}
//資料包分析
int PacketAnalyzer(char*PacketBuffer)
{
Ip_Header *pIpheader;
int iProtocol,iTTL;
char szSourceIP[16],szDestIP[16];
SOCKADDR_IN saSource,saDest;
pIpheader=(Ip_Header*)PacketBuffer;
iProtocol=pIpheader->Protocol;
saSource.sin_addr.S_un.S_addr=pIpheader->SourceAddr;
::strcpy (szSourceIP,inet_ntoa(saSource.sin_addr ));
saDest.sin_addr .S_un .S_addr=pIpheader->SourceAddr;
::strcpy(szDestIP,inet_ntoa(saDest.sin_addr ));
iTTL=pIpheader->TTL;
int iIphLen=sizeof(unsigned long)*pIpheader->Version_HLen&0x0f;
if(iProtocol==IPPROTO_TCP)
{
Tcp_Header*pTcpHeader;
pTcpHeader=(Tcp_Header*)(PacketBuffer+iIphLen);
if(pIpheader->SourceAddr==inet_addr(DestIpAddr))
{
//如果回傳rst
if(pTcpHeader->Flags &RST)
{
printf("Port %d Close\n",ntohs(pTcpHeader->SrcPort));
return 1;
}
else if((pTcpHeader->Flags &SYN)&&(pTcpHeader->Flags &ACK))
{
//表示埠開放
printf("Port %d Open\n",ntohs(pTcpHeader->SrcPort ));
return 1;
}
}
}
return 0;
}][/code]
uj5u.com熱心網友回復:
先看你用的wireshark是否支持相應版本的系統吧。uj5u.com熱心網友回復:
謝謝你的答復,我的wireshark可以正常抓包。我把IP包頭的上層協議改成UDP就可以抓到包。這是不是因為sendto函式只能傳送UDP?但是我經常可以看到網上的大牛使用sendto來發送syn請求。uj5u.com熱心網友回復:
樓主你好,你解決這個問題了嗎uj5u.com熱心網友回復:
<iframe marginwidth="0" marginheight="0" frameborder="0" scrolling="no" width="100%" src="https://bbs.csdn.net/bettings/123/embed"></iframe>uj5u.com熱心網友回復:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/66026.html
標籤:網絡及通訊開發
