一份发送数据包的VC源代码作者:rootshell 日期:2007年4月11日 点击:11899次
阅读提示:软件提供了常用的4种报文的自定义发送(包括所有能修改的字段),并提供5种伪造源格式,用预先计算效验和的办法,提高发送报文速度等...其他的,就用代码说明吧
// 数据包发送程序1.0 //
//////////////////////////////////////////////////////////////
//若干的头文件
//////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <winsock2.h>
#include <windows.h>
#include <Ws2tcpip.h>
//////////////////////////////////////////////////////////////
//若干的宏定义
//////////////////////////////////////////////////////////////
#define IPVER 4 //ip协议预定
#define MAX_TIMEOUT 2000 //最大超时时间
#define MAX_HOSTNAME_LAN 1024 //主机名最长
#define MAX_BUFF_LEN 65500 //发送缓冲区最大
#define MAX_PORT 65500 //端口最大
#define MAX_CHAR 255 //uchar类型最大
#define MAX_SHORT 65535 //ushort类型最大
#define MAX_LONG 4294967294 //ulong类型最大
#define DEF_PORT_DA 1025 //默认的端口
#define DEF_FORGE_IP 0xffffffff //默认的伪造IP
#define DEF_FORGE_PORT 0xffff //默认的伪造端口
//////////////////////////////////////////////////////////////
//若干的报文头部首部结构定义
//////////////////////////////////////////////////////////////
//定义IP首部
typedef struct _iphdr{
UCHAR h_verlen; //4位首部长度,4位IP版本号
UCHAR tos; //8位服务类型TOS
USHORT total_len; //16位总长度(字节)
USHORT ident; //16位标识
USHORT frag_and_flags; //3位标志位
UCHAR ttl; //8位生存时间 TTL
UCHAR proto; //8位协议 (TCP, UDP 或其他)
USHORT checksum; //16位IP首部校验和
ULONG sourceIP; //32位源IP地址
ULONG destIP; //32位目的IP地址
}IP_HEADER;
//定义TCP伪首部
typedef struct _psdhdr{
ULONG saddr; //源地址
ULONG daddr; //目的地址
UCHAR mbz; //没用
UCHAR ptcl; //协议类型
USHORT tcpl; //TCP长度
}PSD_HEADER;
//定义TCP首部
typedef struct _tcphdr{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
ULONG th_seq; //32位序列号
ULONG th_ack; //32位确认号
UCHAR th_lenres; //4位首部长度/6位保留字
UCHAR th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
//定义UDP首部
typedef struct _udphdr{
USHORT uh_sport; //16位源端口
USHORT uh_dport; //16位目的端口
USHORT uh_len; //16位长度
USHORT uh_sum; //16位校验和
} UDP_HEADER;
//定义ICMP首部
typedef struct _icmphdr{
UCHAR i_type; //8位类型
UCHAR i_code; //8位代码
USHORT i_cksum; //16位校验和
USHORT i_id; //识别号(一般用进程号作为识别号)
USHORT i_seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
//定义IGMP首部
typedef struct _igmphdr{
UCHAR i_code; //8位代码
UCHAR i_type; //8位类型
USHORT i_nv; //没用
USHORT i_cksum; //16位校验和
ULONG i_addr; //32位组地址
}IGMP_HEADER;
//////////////////////////////////////////////////////////////
//若干的报文首部结构变量
//////////////////////////////////////////////////////////////
IP_HEADER ip_header = {0}; //ip首部结构
PSD_HEADER psd_header = {0}; //伪首部结构
TCP_HEADER tcp_header = {0}; //tcp首部结构
UDP_HEADER udp_header = {0}; //udp首部结构
ICMP_HEADER icmp_header = {0}; //icmp首部结构
IGMP_HEADER igmp_header = {0}; //igmp首部结构
//////////////////////////////////////////////////////////////
//若干的全局变量
//////////////////////////////////////////////////////////////
//有关临时堆变量的指针
ULONG *Ip_Buff = NULL; //IP缓冲区
USHORT *Port_Buff = NULL; //端口缓冲区
USHORT *Ip_Chk_Buff = NULL; //IP首部效验和缓冲区
USHORT *Other_Chk_Buff = NULL; //其他首部效验和缓冲区
//发送有关的参数
char Dest_Ip[MAX_HOSTNAME_LAN] = {0}; //目的ip
short Send_Data_Type = 2; //发送类型
ULONG Send_Degree = 10; //发送次数
ULONG Send_Sdeg = 1; //同一报文发送次数
USHORT Delay_Time = 0; //延时时间
SOCKET SockRaw = 0; //socket句柄
struct sockaddr_in DestAddr = {0}; //socket地址结构
char Send_Dest_Data[MAX_BUFF_LEN] = {0}; //发送的报文信息
char Send_Data_File[MAX_PATH] = {0}; //数据文件路径
int Send_Data_Size = 0; //发送信息大小
//各个报文的可变参数变量
UCHAR IP_TOSE = 0; //IP服务类型
USHORT IP_IDENT = 0; //IP16位标识
USHORT IP_FLAG = 0; //IP标志
UCHAR IP_TTLE = 128; //IP ttl值
USHORT TCP_WINS = 16384; //TCP窗口值
UCHAR TCP_FLAG = 2; //TCP标志
ULONG TCP_SEQ = 1; //32位序列号
ULONG TCP_ACK = 0; //32位确认号
USHORT TCP_URP = 0; //TCP紧急数据偏移
USHORT ICMP_TYPE = 8; //ICMP类型值
USHORT ICMP_CODE = 0; //ICMP代码值
USHORT ICMP_ID = 2; //ICMP识别号值
USHORT ICMP_SEQ = 1; //ICMP序号值
ULONG ICMP_TIME = 1; //ICMP时间戳值
USHORT IGMP_CODE = 1; //IGMP版本值
USHORT IGMP_TYPE = 1; //IGMP类型值
ULONG IGMP_ADDR = 100; //IGMP32位组地址
//伪造有关的变量
ULONG Ip_Forge_Deg = 100; //伪造个数
short Forge_Type = 1; //伪造模式
char Forge_Ip_File[MAX_PATH] = {0}; //伪造ip文件路径
char Forge_Ip[MAX_HOSTNAME_LAN] = {0}; //伪造IP
USHORT Forge_Port = DEF_PORT_DA; //伪造的端口
//和程序有关的临时变量
USHORT PORTT = 0; //临时变量,记录目的IP的端口
ULONG IPTL = 0; //临时变量,记录目的ip
int ErrorCode = 0; //错误返回寄存变量
//////////////////////////////////////////////////////////////
//若干函数的声名
//////////////////////////////////////////////////////////////
void Usage();
USHORT checksum(USHORT *buffer, int size);
int SetInitializeValue(int argc, char *argv[]);
int SetInitializeSock();
int GetIpAndPortByLine(char *IPL);
int MakeForgeData();
int AccCheckSum();
//重载函数
int AssMemory(ULONG **a, ULONG sa, USHORT **b, ULONG sb);
int AssMemory(USHORT **a, ULONG sa, USHORT **b, ULONG sb);
//////////////////////////////////////////////////////////////
//主函数
//////////////////////////////////////////////////////////////
int main(int argc, char *argv[]){
//参数少于2个,退出
if (argc < 2){
Usage();
return 0;
}
fprintf(stderr, "1.开始分析命令行,获得参数,稍等...\n");
//分析命令行,赋初始化值.
if(!SetInitializeValue(argc, argv))
return 0;
fprintf(stderr, "2.正在初始化网络,稍等...\n");
//初始化连接函数
if(!SetInitializeSock())
return 0;
fprintf(stderr, "3.正在构造伪造数据包,稍等...\n");
//构造伪造数据
if(!MakeForgeData())
return 0;
fprintf(stderr, "4.正在计算效验和,稍等...\n");
//计算效验和
if(!AccCheckSum())
return 0;
//下面开始发送信息
//填充地址结构
memset(&DestAddr, 0, sizeof(DestAddr));
DestAddr.sin_family = AF_INET; //internet网络
DestAddr.sin_port = htons(PORTT);
DestAddr.sin_addr.s_addr = htonl(IPTL); //目的IP
//开始循环发送消息,因为效验和已经计算好,这里就是一些指针和内存的操作
char Sendto_Buff[MAX_BUFF_LEN];
ULONG i = 0, j, HL = 0, SZE = sizeof(DestAddr);
for(j = 0; j < Send_Degree; j++, i++){
//循环使用ip段
if(i >= Ip_Forge_Deg)
i = 0;
//发送缓冲区清空,可要可不要
memset(Sendto_Buff, 0, MAX_BUFF_LEN);
//填充可变参数
ip_header.sourceIP = htonl(Ip_Buff[i]);
ip_header.ident = htons((USHORT)((i + IP_IDENT) % MAX_SHORT) + 1);
ip_header.checksum = Ip_Chk_Buff[i];
//填充发送缓冲区
memcpy(Sendto_Buff, &ip_header, sizeof(IP_HEADER));
//判断是什么类型报文,发送
switch(Send_Data_Type){
case 1:
//填充tcp伪首部和tcp首部
psd_header.saddr = ip_header.sourceIP;
tcp_header.th_seq = htonl((TCP_SEQ + i) % MAX_SHORT);;
tcp_header.th_sport = htons(Port_Buff[i]);
//填充效验和,已经计算的
tcp_header.th_sum = Other_Chk_Buff[i];
//填充缓冲区
memcpy