资源简介
基于ICMP数据包的主机扫描进行网络管理时,常常需要确定当前网络中处理活动状态的主机。本设计的目标就是编制程序,利用ICMP的回送请求和回送应答消息,来发现指定网段中的活动主机,即ping消息的请求和应答。
代码片段和文件信息
#pragma pack(4)
#pragma comment(lib“ws2_32.lib“)
#include “windows.h“
#include “winsock.h“
#include “stdio.h“
#include
#define IP_RECORD_ROUTE 0x7 //IP记录路由
#define ICMP_ECHO 8 //ICMP回显
#define ICMP_ECHOREPLY 0 //ICMP回显应答
#define ICMP_MIN 8 //ICMP数据包最小长度
#define DEF_PACKET_SIZE 32 //差错报文长度
#define MAX_PACKET 0x10000 // ICMP包最大长度
#define MAX_IP_HDR_SIZE 60 //IP首部最大字节数
//IP头文件定义
typedef struct _iphdr
{
unsigned int h_len:4; //头部长度 4字节
unsigned int version:4; //IP版本号 IPv4
unsigned char tos; //服务类型
unsigned short total_len; //数据包总长度
unsigned short ident; //ID标识
unsigned short frag_and_flags; //3位标志,13位片偏移
unsigned char ttl; //生存期
unsigned char proto; //协议类型
unsigned short checksum; //IP头部的检验和
unsigned int sourceIP; //源地址
unsigned int destIP; //目的地址
} IpHeader;
//ICMP头部定义
typedef struct _icmphdr
{
BYTE i_type; //ICMP类型(8位)
BYTE i_code; //代码类型(8位)
USHORT i_cksum; //头部及数据检验和(16位)
USHORT i_id;//ID标识
USHORT i_seq; //序列号
ULONG timestamp; //时间戳
} IcmpHeader;
//IP选项首部定义
typedef struct _ipoptionhdr
{
unsigned char code; //IP选项的类型
unsigned char len; //RR选项总字节长度
unsigned char ptr; //指针字段
unsigned long addr[9]; // IP地址清单
} IpOptionHeader;
BOOL bRecordRoute;
int datasize;
char *lpdest;
//定义3个全局变量
//使用信息
void usage(char *progname)
{
printf(“usage: ping -r [data size]\n“);
printf(“ -r record route\n“);
printf(“ host remote machine to ping\n“);
printf(“ datasize can be up to 0x10000 Byte\n“);
ExitProcess(-1); //结束进程
}
//ICMP首部初始化
void FillICMPData(char *icmp_data int datasize)
{
IcmpHeader *icmp_hdr = NULL;
char *datapart = NULL; //指针定义及初始化
icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->i_type = ICMP_ECHO; //ICMP回显请求
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();//取得当前进程号
icmp_hdr->i_cksum = 0; //检验和字段置0
icmp_hdr->i_seq = 0;
datapart = icmp_data + sizeof(IcmpHeader); //datapart指针指向数据报文开头
memset(datapart ‘E‘ datasize - sizeof(IcmpHeader)); //填充数据段
}
//计算检验和
USHORT checksum(USHORT *buffer int size)
{
unsigned long cksum = 0; // 检验和字段置0
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);//将检验和字段高16位右移16位再与低16位相加
cksum += (cksum >>16);//将所加的检验和再与剩余低16位相加
return (USHORT)(~cksum);//检验和取反,并返回
}
//解析IP选项
void DecodeIPOptions(char *buf int bytes)
{
IpOptionHeader *ipopt = NULL;
IN_ADDR inaddr; //声明结构体
int i;
HOSTENT *host = NULL;
ipopt = (IpOptionHeader *)(buf + 20); //去掉IP首部,指针指向数据选项首部
printf(“RR: “);
for(i = 0; i < (ipopt->ptr / 4) - 1; i++)
{
inaddr.S_un.S_addr = ipopt->addr[i];
if (i != 0)
{
printf(“ “);
}
host = gethostbyaddr((char *)&inaddr.S_un.S_addr sizeof(inaddr.S_un.S_addr) AF_INET);//通过IP地址获得主机信息
if (host)
{
printf
- 上一篇:C语言链表完整代码
- 下一篇:矩阵相乘的c语言代码
评论
共有 条评论