下面是关于发送TCP数据包的程序,用VC++后面扩展名.cpp可以编译连接成功,但不知道该如何写入数据,高手请帮忙运行出结果然后把结果的截图发过来,谢谢!
#include<iostream.h>
#include<winsock2.h>
#include<ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#define IPVER 4
#define MAX_BUFF_LEN 65500
//定义ip头部结构体
typedef struct _iphdr
{
UCHAR h_verlen;
UCHAR tos;
USHORT total_len;
USHORT ident;
USHORT frag_and_flags;
UCHAR ttl;
UCHAR proto;
USHORT checksum;
ULONG sourceIP;
ULONG destIP;
}IP_HEADER;
//定义TCP伪头部
typedef struct _psdhdr
{
ULONG saddr;
ULONG daddr;
UCHAR mbz;
UCHAR ptcl;
USHORT tcpl;
}PSD_HEADER;
//定义TCP头部结构体
typedef struct _tcphdr
{
USHORT th_sport;
USHORT th_dport;
ULONG th_seq;
ULONG th_ack;
UCHAR th_lenres;
UCHAR th_flag;
USHORT th_win;
USHORT th_sum;
USHORT th_urp;
}TCP_HEADER;
USHORT checksum(USHORT *buffer,int size);
IP_HEADER ip_header = {0};
PSD_HEADER psd_header = {0};
TCP_HEADER tcp_header = {0};
char Sendto_Buff[MAX_BUFF_LEN];
unsigned short check_Buff[MAX_BUFF_LEN];
const char tcp_send_data[]={"This is my homework of network,I an happy!"};
int main(int argc,char * argv[])
{
if(argc!=5)
{
cout<<"Usage:";
cout<<"SendTCP sourip sourport destip destport"<<endl;
cout<<"例如 :SendTCP 10.10.114.1 27 10.10.117.25 54"<<endl<<endl;
return 0;
}
//初始化网络
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup(wVersionRequested,&wsaData);
if( err != 0) {
/*Tell the user that we could not find a usable WinSock Dll.*/
return 0;
}
if(LOBYTE( wsaData.wVersion)!= 2 ||HIBYTE(wsaData.wVersion) !=2)
{
/*Tell the user that we could not find a usable WinSock DLL.*/
WSACleanup();
return 0;
}
//创建sockRaw
SOCKET sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);
if(sockRaw == INVALID_SOCKET)
{
cout<<"failed to create sockRaw\n";
return 0;
}
//设置发送延迟时间
int timeout=1000;
int bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*) &timeout,sizeof(timeout));
if(bread == SOCKET_ERROR)
{
cout<<"failed to set send timeout\n";
return 0;
}
//设置IP_HDRINCL以自己填充IP头部
int flag=1;
int ErrorCode= setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *) &flag,sizeof(int));
if(ErrorCode == SOCKET_ERROR){
cout<<"failed to set IP_HDRINCL\n";
return 0;
}
//填充IP首部
/*版本号*/
ip_header.h_verlen =(IPVER <<4 |sizeof(ip_header)/sizeof(unsigned long));
ip_header.tos = (UCHAR)0; //服务类型
/*16位总长度(字节)*/
ip_header.total_len = htons((unsigned short) (sizeof(IP_HEADER) +sizeof(TCP_HEADER) +sizeof(tcp_send_data)));
ip_header.ident = 0;
ip_header.frag_and_flags =0;
ip_header.ttl = (UCHAR)128;
ip_header.proto =IPPROTO_TCP;
ip_header.checksum = 0;
ip_header.sourceIP = inet_addr(argv[1]);
ip_header.destIP = inet_addr(argv[3]);
//计算IP头部校验和
memset(check_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&ip_header,sizeof(IP_HEADER));
ip_header.checksum = checksum(check_Buff,sizeof(IP_HEADER));
//构造TCP伪首部
psd_header.saddr = ip_header.sourceIP;
psd_header.daddr = ip_header.destIP;
psd_header.mbz = 0;
psd_header.ptcl = ip_header.proto;
psd_header.tcpl = htons(sizeof(sizeof(TCP_HEADER) + sizeof(tcp_send_data)));
//填充TCP首部
tcp_header.th_sport = htons((unsigned short)atoi(argv[2]));
tcp_header.th_dport = htons((unsigned short)atoi(argv[4]));
tcp_header.th_seq = 0;
tcp_header.th_ack = 0;
/*TCP长度和保留位*/
tcp_header.th_lenres = (sizeof(TCP_HEADER)/sizeof(unsigned long) << 4|0);
tcp_header.th_flag = (UCHAR)2;
tcp_header.th_win = htons((unsigned short)16384);
tcp_header.th_urp = 0;
tcp_header.th_sum = 0;
//计算TCP校验和
memset(check_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&psd_header,sizeof(PSD_HEADER));
memcpy(check_Buff+sizeof(PSD_HEADER),&tcp_header,sizeof(TCP_HEADER));
memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));
tcp_header.th_sum = checksum(check_Buff,sizeof(PSD_HEADER) +sizeof(TCP_HEADER) +sizeof(tcp_send_data));
//填充发送缓冲区
memset(Sendto_Buff,0,MAX_BUFF_LEN);
memcpy(Sendto_Buff,&ip_header,sizeof(IP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcp_header,sizeof(TCP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));
int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data);
sockaddr_in dest;
memset(&dest,0,sizeof(dest));
dest.sin_family=AF_INET;
dest.sin_addr.s_addr = inet_addr(argv[3]);
//发送
int bwrote = sendto(sockRaw,Sendto_Buff,datasize,0,(struct sockaddr*)&dest,sizeof(dest));
if(bwrote == SOCKET_ERROR)
{
cout<<"send errt1!\n";
return 0;
}
if(bwrote<datasize)
{
cout<<"send error2!\n";
return 0;
}
cout<<"send OK!"<<endl;
WSACleanup();
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);
}