我寫了個TCP connect的進行掃描百度的IP地址,可以掃描到80埠開了。但用TCO_SYN掃描不錯結果,不知道為什么?代碼流程是通過socker的原始套接字進行編程,先發送構造的SYN包,然后對接收到的資料包進行決議,看是不是TCP包,然后根據回傳的是RST 還是ACK等指令進行判斷埠是否打開。。。。但收到的包的協議顯示的是10,并不是tcp的數值6.。。代碼如下
#include "stdafx.h"
#include<WinSock2.h>
#include<string.h>
#include<WS2tcpip.h>
#include"mstcpip.h"
#pragma comment(lib,"ws2_32.lib")
char *DestIpAddr = "14.215.177.37";
typedef struct IpHeader{
unsigned char Version_HLen;
unsigned char TOS;
unsigned short Length;
unsigned short Ident;
unsigned short Flags_Offset;
unsigned TTL;
unsigned char Protocol;
unsigned short Checksum;
unsigned int SourceAddr;
unsigned int DestinationAddr;
}Ip_Header;
//TCP的標志
#define URG 0x20;
#define ACK 0x10;
#define PSH 0x08;
#define RST 0x04;
#define SYN 0x02;
#define FIN 0x01;
typedef struct TcpHeader{
USHORT SrcPort;
USHORT DstPort;
unsigned int SequenceNum;
unsigned int Acknowledgment;
unsigned char HdrLen;
unsigned char Flags;
USHORT AdvertisedWindow;
USHORT Checksum;
USHORT UrgPtr;
}Tcp_Header;
int PacketAnalyzer(char *);
int SendTCPSYNPacket(int );
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
SOCKET RecSocket;
LARGE_INTEGER nFreq;
LARGE_INTEGER StartTime;
LARGE_INTEGER EndTime;
HANDLE hCon;
int PortStart = 80;
int PortEnd = 90;
char RecvBuffer[65535] = {0};
char Name[255];
struct hostent *pHostent;
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwByteReturned = 0;
int Result;
if(Result = WSAStartup(MAKEWORD(2 ,1) ,&wsaData) != 0)
{
printf("WSAStartup error, %d" ,Result);
return -1;
}
RecSocket = socket(AF_INET ,SOCK_RAW ,IPPROTO_IP);
if(RecSocket == INVALID_SOCKET)
{
printf("socket failed ,%d\n" ,WSAGetLastError());
closesocket(RecSocket);
return -1;
}
Result = gethostname(Name ,255);
if(Result == SOCKET_ERROR)
{
printf("gethostname failed ,%d\n" ,WSAGetLastError());
closesocket(RecSocket);
return -1;
}
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 ,%d\n" ,WSAGetLastError());
closesocket(RecSocket);
return -1;
}
//設定SOCK_RAW 為SIO_RCVALL
Result = WSAIoctl(RecSocket ,SIO_RCVALL ,&dwBufferInLen ,sizeof(dwBufferInLen) ,dwBufferLen ,sizeof(dwBufferLen)
,&dwByteReturned ,NULL ,NULL);
if(Result == SOCKET_ERROR)
{
printf("WSAIoctl failed ,%d\n" ,WSAGetLastError());
closesocket(RecSocket);
return -1;
}
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(RecvBuffer ,0 ,sizeof(RecvBuffer));
Result = recv(RecSocket ,RecvBuffer ,65535 ,0);
if(Result == SOCKET_ERROR)
{
printf("recv failed ,%d\n" ,WSAGetLastError());
closesocket(RecSocket);
return -1;
}
Result = PacketAnalyzer(RecvBuffer);
if(Result == 0)
continue;
else
break;
}
SetConsoleTextAttribute(hCon ,14);
//獲取定時器的值
QueryPerformanceCounter(&EndTime);
}
}
double flnterval = EndTime.QuadPart - StartTime.QuadPart;
printf("Total Time: %fms\n" ,flnterval * 1000 /(double)nFreq.QuadPart);
SetConsoleTextAttribute(hCon ,bInfo.wAttributes);
if(closesocket(RecSocket) == SOCKET_ERROR)
{
printf("closesocket failed ,%d\n" ,WSAGetLastError());
return -1;
}
if(WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup error ,%d" ,WSAGetLastError());
return -1;
}
system("pause");
return 0;
}
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 Protocol;
unsigned short TcpLen;
}PSD_Tcp_Header;
//定義TCP首部
typedef struct tcp_hdr
{
USHORT SrcPort;
USHORT DstPort;
unsigned int SequenceNum;
unsigned int Acknowledgment;
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 szSendBuffer[100] = {0};
BOOL flag;
int nTimeOver;
int Result;
Result = WSAStartup(MAKEWORD(2 ,1) ,&wsaData);
if(Result == SOCKET_ERROR)
{
printf("WSAStartup failed ,%d\n" ,Result);
return -1;
}
if((SendSocket = WSASocket(AF_INET ,SOCK_RAW ,IPPROTO_RAW ,NULL ,0 ,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket failed ,%d\n" ,WSAGetLastError());
return false;
}
flag = true;
if(setsockopt(SendSocket ,IPPROTO_IP ,IP_HDRINCL ,(char*)&flag ,sizeof(flag)) == SOCKET_ERROR)
{
printf("setsockopt failed ,%d\n" ,WSAGetLastError());
return false;
}
nTimeOver = 1000;
if(setsockopt(SendSocket ,SOL_SOCKET ,SO_SNDTIMEO ,(char*)&nTimeOver ,sizeof(nTimeOver)) == SOCKET_ERROR)
{
printf("setsockopt failed ,%d\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("gethostname failed ,%d\n" ,WSAGetLastError());
return -1;
}
Hostent = (struct hostent*)malloc(sizeof(hostent));
Hostent = gethostbyname(HostName);
memcpy(&localaddr ,Hostent->h_addr_list[0] ,Hostent->h_length);
//printf("IP: ,%s\n" ,inet_ntoa(*(IN_ADDR*)Hostent->h_addr_list[0]));
//填充IP首部
//版本和長度
ipHeader.Version_HLen = (4 << 4 | sizeof(ipHeader) / sizeof(unsigned long));
ipHeader.TOS = 0;
ipHeader.Length = htons(sizeof(ipHeader) + sizeof(tcpHeader));
ipHeader.Ident = 1;
ipHeader.Flags_Offset = 0;
ipHeader.TTL = 128;
ipHeader.Protocol = IPPROTO_TCP;
ipHeader.Checksum = 0;
ipHeader.SourceAddr = localaddr.S_un.S_addr;
ipHeader.DestinationAddr = inet_addr(DestIpAddr);
//TCP首部
tcpHeader.DstPort = htons(Port);
tcpHeader.SrcPort = htons(6666);
tcpHeader.SequenceNum = htonl(0);
tcpHeader.Acknowledgment = 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.Protocol = IPPROTO_TCP;
psdHeader.TcpLen = htons(sizeof(tcpHeader));
//計算TCP校驗和
memcpy(szSendBuffer ,&psdHeader ,sizeof(psdHeader));
memcpy(szSendBuffer + sizeof(psdHeader) ,&tcpHeader ,sizeof(tcpHeader));
tcpHeader.Checksum = checksum((USHORT*)szSendBuffer ,sizeof(psdHeader) + sizeof(tcpHeader));
//計算IP校驗和
memcpy(szSendBuffer ,&ipHeader ,sizeof(ipHeader));
memcpy(szSendBuffer + sizeof(ipHeader) ,&tcpHeader ,sizeof(tcpHeader));
memset(szSendBuffer + sizeof(ipHeader) + sizeof(tcpHeader) ,0 ,4);
ipHeader.Checksum = checksum((USHORT*)szSendBuffer ,sizeof(ipHeader) + sizeof(tcpHeader));
//更新內容
memcpy(szSendBuffer ,&ipHeader ,sizeof(ipHeader));
memcpy(szSendBuffer + sizeof(ipHeader) ,&tcpHeader ,sizeof(tcpHeader));
Result = sendto(SendSocket ,szSendBuffer ,sizeof(ipHeader) + sizeof(tcpHeader) ,0 ,(struct sockaddr*)&addr_in ,sizeof(addr_in));
if(Result == SOCKET_ERROR)
{
printf("sentto failed ,%d\n" ,WSAGetLastError());
return -1;
}
printf("send byte:%d\n" ,Result);
if(closesocket(SendSocket) == SOCKET_ERROR)
{
printf("closesocket failed ,%d\n" ,WSAGetLastError);
return -1;
}
if(WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup failed ,%d\n" ,WSAGetLastError());
return -1;
}
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;
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hCon ,&bInfo);
iProtocol = pIpheader->Protocol;
saSource.sin_addr.S_un.S_addr = pIpheader->SourceAddr;
strcpy_s(szSourceIP ,inet_ntoa(saSource.sin_addr));
saDest.sin_addr.S_un.S_addr = pIpheader->DestinationAddr;
strcpy_s(szDestIP ,inet_ntoa(saDest.sin_addr));
iTTL = pIpheader->TTL;
//計算IP長度
int iIphLen = sizeof(unsigned long)*(pIpheader->Version_HLen & 0x0f);
//判斷是不是TCP協議資料
printf("iProtcol %d\n" ,iProtocol);
if(iProtocol == IPPROTO_TCP)
{
Tcp_Header *pTcpHeader;
pTcpHeader = (Tcp_Header*)(PacketBuffer + iIphLen);
if(strcmp((char *)pIpheader->SourceAddr ,(char *)inet_addr(DestIpAddr)) == 0)
{
//回傳值RST
if(pTcpHeader->Flags & 0X04)
{
SetConsoleTextAttribute(hCon ,10);
printf("Port %5d Close\n" ,ntohs(pTcpHeader->SrcPort));
return 1;
}
//回傳值SYN+ACK
else if((pTcpHeader->Flags & 0x02) && (pTcpHeader->Flags & 0x10))
{
SetConsoleTextAttribute(hCon ,14);
printf("Port %5d Open\n" ,ntohs(pTcpHeader->SrcPort));
return 1;
}
}
}
SetConsoleTextAttribute(hCon ,bInfo.wAttributes);
return 1;
}
uj5u.com熱心網友回復:
你測驗一下你發包的截圖,發出來看看,有可能不是你的問題,百度會設定SYN掃描不回應,前段防火墻有時候會屏蔽該包轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/130585.html
標籤:網絡協議與配置
上一篇:為什么我的Charles抓去不到pc端網路(http、https)請求
下一篇:有沒有千兆以太網通道技術?
