64,654
社区成员
发帖
与我相关
我的任务
分享
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#pragma comment(lib,"WS2_32.lib")
#define MAXDATASIZE 1024 //缓冲区大小
#include "WS2TCPIP.H"
#define SEQ 0x28376839 //ip数据包的首部数据结构
struct sockaddr_in target,source;
int rawsock;
typedef struct _iphdr {
unsigned char h_lenver; //4位首部长度+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首部校验和
unsigned 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; //32位序列号
unsigned int th_ack; //32位确认号
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;
//SOCK错误处理程序
void CheckSockError(int iErrorCode, char *pErrorMsg)
{
if(iErrorCode==SOCKET_ERROR) {
printf("%s Error:%d\n", pErrorMsg, GetLastError());
closesocket(rawsock);
ExitProcess(-1);
}
}
//计算检验和
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
unsigned short answer=0;
while (size > 1) {
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size==1) {
*(char *)&answer=*(char *)buffer;
cksum += answer;
}
while(cksum >> 16)
cksum = (cksum >> 16) + (cksum & 0xffff);
return (USHORT)(~cksum);
}
//IP解包程序
int DecodeIPHeader(char *recvbuf, int bytes)
{
IP_HEADER *iphdr;
TCP_HEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IP_HEADER *)recvbuf;
iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
iphdrlen=sizeof(IP_HEADER);
tcphdr = (TCP_HEADER*)(recvbuf + iphdrlen);
//是否来自目标IP
if(iphdr->sourceIP != target.sin_addr.s_addr) {
printf("不来自目标IP\n");
return 0;
}
//序列号是否正确
if(ntohl(tcphdr->th_ack) != (SEQ+1)) {
printf("序列号错误\n");
return 0;
}
//RST/ACK - 无服务
if(tcphdr->th_flag == 20) {
printf("RST+ACK 无服务.\n");
return 1;
}
//SYN/ACK - 扫描到一个端口
if(tcphdr ->th_flag == 18) {
printf("%d\n",ntohs(tcphdr->th_sport));
return 2;
}
printf("未知\n");
return 1;
}
int main()
{
int datasize;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
char ip_data[MAXDATASIZE]={0};
char RecvBuf[65535]={0};
WSAData data;
struct sockaddr_in target,source;
WORD w = MAKEWORD(2,2); //版本号
WSAStartup(w,&data); //初始化
if((rawsock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))== INVALID_SOCKET)
{
printf("socket error!\n");
printf("%d\n",GetLastError());
exit(1);
}
bool bOpt=true;
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
WSAIoctl(rawsock, _WSAIOW(IOC_VENDOR,1),&dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
setsockopt(rawsock,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt));
source.sin_family=AF_INET;
source.sin_addr.S_un.S_addr=inet_addr("192.168.1.203");
source.sin_port=htons(1234);
bind(rawsock,(struct sockaddr *)&source,sizeof(source));
target.sin_family=AF_INET;
target.sin_addr.S_un.S_addr=inet_addr("192.168.1.202");
target.sin_port=htons(80);
ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long)); //高四位IP版本号,低四位首部长度
ip_header.tos=0;
ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位总长度(字节)
ip_header.ident=0; //16位标识
ip_header.frag_and_flags=0; //3位标志位
ip_header.ttl=128; //8位生存时间TTL
ip_header.proto=IPPROTO_TCP; //8位协议
ip_header.checksum=0; //16位IP首部校验和
ip_header.sourceIP=source.sin_addr.s_addr; //32位源IP地址
ip_header.destIP=target.sin_addr.s_addr; //32位目的IP地址 //填充TCP首部
tcp_header.th_sport=source.sin_port; //源端口号
tcp_header.th_dport=target.sin_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(ip_data,&psd_header,sizeof(psd_header));
memcpy(ip_data+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)ip_data,sizeof(psd_header)+sizeof(tcp_header)); //计算IP校验和
memcpy(ip_data,&ip_header,sizeof(ip_header));
memcpy(ip_data+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(ip_data+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)ip_data,datasize); //填充发送缓冲区
memcpy(ip_data,&ip_header,sizeof(ip_header));
datasize=sizeof(ip_header)+sizeof(tcp_header);
if ((sendto(rawsock,ip_data,datasize,0,(struct sockaddr *)&target,sizeof(target)))<0)
{
printf("sendto error!\n");
printf("%d\n",GetLastError());
}
//接收数据
DWORD timeout = 200000;//2000
DWORD start = GetTickCount();
int sizedest=sizeof(target);
while(true) { //计时,2s超时
if((GetTickCount() - start) >= timeout) break;
memset(RecvBuf, 0, sizeof(RecvBuf));
int iErrorCode = recv(rawsock, RecvBuf, sizeof(RecvBuf), 0);
CheckSockError(iErrorCode, "recv");
if(int i = DecodeIPHeader(RecvBuf,iErrorCode)) {
if(i == 1) break;
tcp_header.th_flag=4; //RST 标志
//计算TCP校验和,计算校验和时需要包括TCP pseudo header
memcpy(ip_data,&psd_header,sizeof(psd_header));
memcpy(ip_data+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)ip_data,sizeof(psd_header)+sizeof(tcp_header)); //计算IP校验和
memcpy(ip_data,&ip_header,sizeof(ip_header));
memcpy(ip_data+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(ip_data+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)ip_data,datasize); //填充发送缓冲区
memcpy(ip_data,&ip_header,sizeof(ip_header)); //发送TCP报文
iErrorCode=sendto(rawsock,ip_data,datasize,0,(struct sockaddr*) &target, sizeof(target));
CheckSockError(iErrorCode, "sendto2()");
break;
}
} //退出前清理 */
return 0;
if(rawsock != INVALID_SOCKET) closesocket(rawsock);
WSACleanup();
return 0;
}
memcpy(ip_data,&psd_header,sizeof(psd_header));
memcpy(ip_data+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)ip_data,sizeof(psd_header)+sizeof(tcp_header)); //计算IP校验和
memcpy(ip_data,&ip_header,sizeof(ip_header));
memcpy(ip_data+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(ip_data+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)ip_data,datasize); //填充发送缓冲区
memcpy(ip_data,&ip_header,sizeof(ip_header));