- 论坛徽章:
- 0
|
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include "mstcpip.h"
#pragma comment(lib,"ws2_32"
#define DEFAULT_DEST_PORT 12000
#define DEST_HOST "192.168.2.195"
#define SEQ 0x28376839
typedef struct _iphdr
{
unsigned char h_lenver; /*位首部长度+4位IP版本号*/
unsigned char tos; /*8位服务类型TOS*/
unsigned short total_len; /*16位总长度(字节)*/
unsigned short ident; /*16位标识*/
unsigned short frag_and_flags; /* 3位标志位*/
unsigned char ttl; /*8位生存时间 TTL*/
unsigned char proto; /*8位协议 (TCP, UDP 或其他) */
unsigned short checksum; /*16位IP首部校验和*/
int sourceIP; /*32位源IP地址*/
unsigned int destIP; /*32位目的IP地址*/
}IP_HEADER;
typedef struct _tcphdr /*定义TCP首部*/
{
USHORT th_sport; /*16位源端口*/
USHORT th_dport; /* 16位目的端口*/
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_lenres; /* 4位首部长度/6位保留字*/
unsigned char th_flag; /*6位标志位*/
USHORT th_win; /*16位窗口大小*/
USHORT th_sum; /*16位校验和*/
USHORT th_urp; /*16位紧急数据偏移量*/
}TCP_HEADER;
struct /*定义TCP伪首部*/
{
unsigned long saddr; /*源地址*/
unsigned long daddr; /*目的地址*/
char mbz;
char ptcl; /*协议类型*/
unsigned short tcpl; /*TCP长度*/
}psd_header;
SOCKET sockRaw = INVALID_SOCKET;
SOCKET sockListen = INVALID_SOCKET;
struct sockaddr_in dest;
/*SOCK错误处理程序*/
void CheckSockError(int iErrorCode, char *pErrorMsg, char *pFileName, int line)
{
if(iErrorCode==SOCKET_ERROR || NULL == pFileName)
{
printf("%s Error:%d\t[%s\t%d]\n", pErrorMsg, GetLastError(), pFileName, line);
closesocket(sockRaw);
ExitProcess(-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);
}
/*IP解包程序*/
bool DecodeIPHeader(char *buf, int bytes)
{
IP_HEADER *iphdr;
TCP_HEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IP_HEADER *)buf;
iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
tcphdr = (TCP_HEADER*)(buf + iphdrlen);
/*是否来自目标IP*/
if(iphdr->sourceIP != dest.sin_addr.s_addr)
return false;
/*序列号是否正确*/
if((ntohl(tcphdr->th_ack) != (SEQ+1)) && (ntohl(tcphdr->th_ack) != SEQ))
return false;
/*RST/ACK - 无服务*/
if(tcphdr->th_flag == 20)
{
printf(".\n" ;
return true;
}
/*SYN/ACK - 扫描到一个端口*/
if(tcphdr ->th_flag == 1
{
printf("%d\n",ntohs(tcphdr->th_sport));
return true;
}
return true;
}
/*主函数*/
int main(int argc,char **argv)
{
int iErrorCode;
int datasize;
struct hostent *hp;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
char SendBuf[128]={0};
char RecvBuf[65535]={0};
/*初始化SOCKET*/
WSADATA wsaData;
iErrorCode = WSAStartup(MAKEWORD(2,2),&wsaData);
CheckSockError(iErrorCode, "WSAStartup()", __FILE__, __LINE__ );
#if 0
sockRaw = socket( AF_INET, SOCK_DGRAM, 0 );
#else
sockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
#endif
CheckSockError(sockRaw, "socket()", __FILE__, __LINE__ );
sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockListen, "socket()", __FILE__, __LINE__ );
/*设置IP头操作选项*/
int bOpt = true;
iErrorCode = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt));
CheckSockError(iErrorCode, "setsockopt()", __FILE__, __LINE__ );
/*获得本地IP*/
SOCKADDR_IN sa;
unsigned char LocalName[256];
iErrorCode = gethostname((char*)LocalName,sizeof(LocalName)-1);
CheckSockError(iErrorCode, "gethostname()", __FILE__, __LINE__ );
printf( "LocalName is %s", LocalName );
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
CheckSockError(SOCKET_ERROR, "gethostbyname()", __FILE__, __LINE__ );
}
memcpy(&sa.sin_addr.S_un.S_addr,hp->h_addr_list[0],hp->h_length);
sa.sin_family = AF_INET;
sa.sin_port = htons(50000);
printf( "\tip :%s\r\n", inet_ntoa( sa.sin_addr ) );
iErrorCode = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa));
CheckSockError(iErrorCode, "bind", __FILE__, __LINE__ );
/*设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包*/
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
iErrorCode=WSAIoctl(sockListen, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),
&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
CheckSockError(iErrorCode, "Ioctl", __FILE__, __LINE__ );
/*获得目标主机IP*/
memset(&dest,0,sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(DEFAULT_DEST_PORT);
if((dest.sin_addr.S_un.S_addr = inet_addr(DEST_HOST)) == INADDR_NONE)
{
if((hp = gethostbyname(DEST_HOST)) != NULL)
{
memcpy(&(dest.sin_addr),hp->h_addr_list[0],hp->h_length);
dest.sin_family = hp->h_addrtype;
printf("dest.sin_addr = %s\n",inet_ntoa(dest.sin_addr));
}
else
{
CheckSockError(SOCKET_ERROR, "gethostbyname()", __FILE__, __LINE__ );
}
}
printf( "dest IP %s\r\n", inet_ntoa( dest.sin_addr ) );
/*填充IP首部*/
ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
/*高四位IP版本号,低四位首部长度*/
ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); /*16位总长度(字节)*/
ip_header.ident=1; /*16位标识*/
ip_header.frag_and_flags=0; /*3位标志位*/
ip_header.ttl=128; /*8位生存时间TTL*/
ip_header.proto=IPPROTO_TCP; /*8位协议(TCP,UDP…)*/
ip_header.checksum=0; /*16位IP首部校验和*/
ip_header.sourceIP=sa.sin_addr.s_addr; /*32位源IP地址*/
ip_header.destIP=dest.sin_addr.s_addr; /*32位目的IP地址*/
/*填充TCP首部*/
tcp_header.th_sport=htons(50000); /*源端口号*/
tcp_header.th_dport=htons(DEFAULT_DEST_PORT); /*目的端口号*/
tcp_header.th_seq=htonl(SEQ); /*SYN序列号*/
tcp_header.th_ack=0; /*ACK序列号置为0*/
tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0); /*TCP长度和保留位*/
tcp_header.th_flag=2; /*SYN 标志*/
tcp_header.th_win=htons(16384); /*窗口大小*/
tcp_header.th_urp=0; /*偏移*/
tcp_header.th_sum=0; /*校验和*/
/*填充TCP伪首部(用于计算校验和,并不真正发送)*/
psd_header.saddr=ip_header.sourceIP;
psd_header.daddr=ip_header.destIP;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(sizeof(tcp_header));
/*计算TCP校验和,计算校验和时需要包括TCP pseudo header */
memcpy(SendBuf,&psd_header,sizeof(psd_header));
memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));
/*计算IP校验和*/
memcpy(SendBuf,&ip_header,sizeof(ip_header));
memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)SendBuf,datasize);
/*填充发送缓冲区*/
memcpy(SendBuf,&ip_header,sizeof(ip_header));
/*发送TCP报文*/
iErrorCode=sendto(sockRaw,SendBuf,datasize,0,(struct sockaddr*) &dest,sizeof(dest));
CheckSockError(iErrorCode, "sendto()", __FILE__, __LINE__ );
/*接收数据*/
DWORD timeout = 2000;
DWORD start = GetTickCount();
while(true)
{
/*计时,2s超时*/
if((GetTickCount() - start) >= timeout)
break;
memset(RecvBuf, 0, sizeof(RecvBuf));
iErrorCode = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0);
CheckSockError(iErrorCode, "recv", __FILE__, __LINE__ );
if(DecodeIPHeader(RecvBuf,iErrorCode))
break;
}
/* 退出前清理 */
if(sockRaw != INVALID_SOCKET) closesocket(sockRaw);
WSACleanup();
return 0;
} |
|