一开始想直接在上个程序改,自己构造IP包头,但后来发现不行,微软不让干了,所以后来选用libcap库来收发包

代码写的很乱..

 #pragma pack(4)

 #define  ECHO_REQUEST       8
#define DATASIZE 65500
#define PACKETSIZE 65535
#define IPCOUNT 9
#define MACSIZE 6
#define OPTION_RR 7 struct ethhdr
{
char mac_dst[MACSIZE];
char mac_src[MACSIZE]; unsigned short eth_protocol;
char eth_data[DATASIZE];
}; struct iphdr
{
unsigned char ip_hdr_len : ; //包头长度
unsigned char ip_version : ; //版本
unsigned char ip_tos; unsigned short ip_length; //总长度
unsigned short ip_identify;//标识
unsigned short ip_offset;//片偏移
unsigned char ip_ttl;
unsigned char ip_protocol;
unsigned short ip_cksum; struct in_addr ip_src; //源地址
struct in_addr ip_dst; //目的地址 unsigned char ip_code;
unsigned char ip_len;
unsigned char ip_ptr; struct in_addr ip_router[IPCOUNT]; char ip_data[DATASIZE];
}; struct icmphdr
{
unsigned char icmp_type; //8位类型
unsigned char icmp_code; //8位代码
unsigned short icmp_cksum; //16位的校验和 unsigned short icmp_identify;
unsigned short icmp_seq; LONGLONG icmp_timestamp;
char icmp_data[DATASIZE];
}; bool ping_rr(char * target,int payload,int count)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(, ), &wsaData); if(payload > DATASIZE)
{
printf("发送的字节数有错误,有效范围从 0 到 %d",DATASIZE);
return false;
} payload = payload - sizeof(LONGLONG); struct hostent* phostent = gethostbyname(target);
if (!phostent)
{
printf("解析IP失败!\n");
return false;
} struct in_addr addrSrv = {};
addrSrv.S_un.S_addr = *(u_long *)phostent->h_addr_list[]; printf("正在 Ping %s [%s] 具有 %d 字节的数据: \n",target,inet_ntoa(addrSrv),payload + sizeof(LONGLONG)); icmphdr ihdr = {};
iphdr ip_hdr = {};
ethhdr eth_hdr = {}; unsigned char mac_src[] = "\x68\xf7\x28\x7f\xc2\x71"; //本机MAC地址
unsigned char mac_dst[] = "\x84\xd9\x31\xb9\x21\x98"; //目的MAC地址 memcpy((void *)eth_hdr.mac_src,(void *)mac_src,sizeof(mac_src) -);
memcpy((void *)eth_hdr.mac_dst,(void *)mac_dst,sizeof(mac_dst) -); eth_hdr.eth_protocol = htons(); //0x0800 //链路层IP数据报 ip_hdr.ip_hdr_len = 0xf; //包头设置为最大长度
ip_hdr.ip_version = ;
ip_hdr.ip_identify = (unsigned short)GetCurrentProcessId();
ip_hdr.ip_offset = ;
ip_hdr.ip_ttl = 0x40;//默认设置为64
ip_hdr.ip_protocol = IPPROTO_ICMP;
ip_hdr.ip_src.s_addr = inet_addr("172.30.1.145"); //本机IP
ip_hdr.ip_dst.s_addr = *(u_long *)phostent->h_addr_list[];
ip_hdr.ip_code = OPTION_RR; //RR选项为7
ip_hdr.ip_len = 0x27; //39字节 最多能存9个IP地址
ip_hdr.ip_ptr = ;
ip_hdr.ip_cksum = ; memset((void *)ip_hdr.ip_router,,sizeof(struct in_addr) * IPCOUNT); memset((void *)ihdr.icmp_data,,DATASIZE);
memset((void *)ip_hdr.ip_data,,DATASIZE); packet_pad(ihdr.icmp_data,payload); //填充数据 ihdr.icmp_type = ECHO_REQUEST;
ihdr.icmp_identify = (unsigned short)GetCurrentProcessId(); int hdr_len = payload + sizeof(icmphdr) - DATASIZE;
int datalen = hdr_len + (ip_hdr.ip_hdr_len << );
int sendlen = datalen + sizeof(ethhdr) - DATASIZE;
ip_hdr.ip_length = htons(datalen); char recv[PACKETSIZE] = {}; unsigned long interval = ;
unsigned long avgdelay = ;
unsigned long maxdelay = ;
unsigned long mindelay = ~; unsigned int sendcnt = count;
unsigned int losscnt = ; char strErrorbuf[PCAP_ERRBUF_SIZE] = {}; std::string strNickName = "\\Device\\NPF_{D8AECAAE-F28C-4161-BA6B-BCA1B807F2E5}"; //本机网卡 pcap_t* pcap_handle = NULL;
if ((pcap_handle = pcap_open_live(strNickName.c_str(),,,,strErrorbuf))==NULL)
{
return false;
} if( pcap_datalink(pcap_handle) != DLT_EN10MB )
{
return false;
} unsigned int netip,netmask;
if (pcap_lookupnet(strNickName.c_str(),&netip,&netmask,strErrorbuf) < )
{
return false;
} std::string strFilter = "icmp"; //协议过滤 只抓icmp的包
struct bpf_program nFcode;
if ( pcap_compile(pcap_handle, &nFcode,strFilter.c_str(), , netmask) < )
{
return false;
} if ( pcap_setfilter(pcap_handle, &nFcode) < )
{
return false;
} int next = ; struct pcap_pkthdr * header = NULL;
const unsigned char* pkt_data = NULL; for(int seq = ; seq < count; ++seq)
{
memset((void *)ip_hdr.ip_router,,sizeof(struct in_addr) * IPCOUNT); ihdr.icmp_seq = seq;
ihdr.icmp_cksum = ;
ihdr.icmp_timestamp = GetSysTickCount64(); //发送时间
ihdr.icmp_cksum = checksum(hdr_len,(unsigned short *)&ihdr); memcpy((void *)ip_hdr.ip_data,(void *)&ihdr,hdr_len); ip_hdr.ip_cksum = ;
ip_hdr.ip_ptr = ;
ip_hdr.ip_cksum = checksum(datalen,(unsigned short *)&ip_hdr); memcpy((void *)eth_hdr.eth_data,(void *)&ip_hdr,datalen); if(pcap_sendpacket(pcap_handle,(unsigned char *)&eth_hdr,sendlen) != ) //发送数据包
{
--sendcnt;
continue;
} while(next = pcap_next_ex(pcap_handle, &header, &pkt_data))
{
iphdr* piphdr = (iphdr *) (pkt_data + sizeof(ethhdr) - DATASIZE); if(checksum(piphdr->ip_hdr_len << ,(unsigned short *)piphdr) != )
{
printf("invalid ip packet!\n");
continue;
} icmphdr* pichdr = (icmphdr *)(pkt_data + sendlen - hdr_len);
if(checksum(hdr_len,(unsigned short *)pichdr) != )
{
printf("invalid icmp packet!\n");
continue;
} if(piphdr->ip_ptr == )
{
continue;
} memcpy((void *)piphdr->ip_router,(void *)((char *)piphdr->ip_router -),sizeof(struct in_addr) * IPCOUNT);//内存对齐问题 interval = GetSysTickCount64() - pichdr->icmp_timestamp;
avgdelay+= interval; maxdelay = interval > maxdelay ? interval : maxdelay;
mindelay = interval > mindelay ? mindelay : interval; int record = (piphdr->ip_ptr-) >> ; printf("来自 %s 的回复: 字节=%d 时间=%dms TTL=%u\n",inet_ntoa(addrSrv),payload + sizeof(LONGLONG),interval,piphdr->ip_ttl); printf(" 路由: %s -->\n",inet_ntoa(piphdr->ip_router[]));
for(int i = ; i < record;i++)
{
printf(" %s -->\n",inet_ntoa(piphdr->ip_router[i]));
} break;
} if(next == -)
{
losscnt++;
} } printf("\n");
printf("%s 的 Ping 统计信息: \n",inet_ntoa(addrSrv));
printf(" 数据包: 已发送 = %d, 已接收 = %d, 丢失 = %d (%.2f%% 丢失),\n",sendcnt,sendcnt-losscnt,losscnt,(losscnt * ) / (double)sendcnt);
printf("往返行程的估计时间(以毫秒为单位):\n");
printf(" 最短 = %dms, 最长 = %dms, 平均 = %dms\n",mindelay,maxdelay,avgdelay / sendcnt);
printf("\n"); return true;
}

TCP协议学习记录 (三) Ping程序 RR选项 记录路由hop的更多相关文章

  1. TCP/IP协议学习之实例ping命令学习笔记

    TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...

  2. [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]

    [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...

  3. TCP协议中的三次握手和四次挥手(图解)【转】

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...

  4. TCP协议学习记录 (二) Ping程序

    简单的实现了一个ping程序,没有做icmp差错报文的检查. 支持自定义字节数,支持发包个数 #pragma pack(4) #define ECHO_REQUEST 8 #define DATASI ...

  5. TCP协议学习笔记(一)首部以及TCP的三次握手连接四次挥手断开

    TCP协议是一种面向连接的.可靠的流协议. 流即不间断的数据结构.这样能够保证接收到数据顺序与发送相同.但是犹如数据间没有间隔,因此在TCP通信中,发送端应用可以在自己所要发送的消息中设置一个标示长度 ...

  6. TCP协议学习总结(上)

    在计算机领域,数据的本质无非0和1,创造0和1的固然伟大,但真正百花齐放的还是基于0和1之上的各种层次之间的组合(数据结构)所带给我们人类各种各样的可能性.例如TCP协议,我们的生活无不无时无刻的站在 ...

  7. 计算机网络:这是一份全面 & 详细 的TCP协议学习指南

    原文链接:blog.csdn.net 用这个媒体播放器组件,实时互动时也可共同观看本地视频juejin.im 前言 计算机网络基础 该是程序猿需掌握的知识,但往往会被忽略 今天,我将详细讲解计算机网络 ...

  8. TCP协议学习总结(中)

    很多人都说TCP协议是一个十分复杂的协议,在学习当中,我对协议每一个问题都分解学习后,每一个分解我都能体会和理解它的要点,并不难理解.但我把这些拆分的细节合并后,确认感觉这样一个协议相对“臃肿”但又好 ...

  9. TCP协议学习笔记

    TCP协议数据格式 TCP协议在互联网ISO协议的传输层. 在互联网传输过程中,互联网包在数据链路层,是传输数据的最基础的包.一个互联网的包包含IP包,即互联网包 = 互联网信息包头(至少20字节)+ ...

随机推荐

  1. 使用python+pychram进行API测试(接口测试)初级STEP 1

    花了一天时间安装了解了下最基本的python+pychram进行API测试,下面这个可以指导自己以后入门:基本的开发级别还需要学习 1.python下载地址:https://www.python.or ...

  2. For Your Dream

    队名:Braveheart 队员介绍: 队长:李洋洋 队员:姚欢,杨仁波,张波,乔闯 项目名称:数据沈航 总体任务: 收集整理学校的数据,为每个想要了解沈航的人展现一份我们收集来的信息 项目分组: ( ...

  3. 解决json日期格式问题的3种方法

    这篇文章主要介绍了解决json日期格式问题的3种方法 ,需要的朋友可以参考下 开发中有时候需要从服务器端返回json格式的数据,在后台代码中如果有DateTime类型的数据使用系统自带的工具类序列化后 ...

  4. 脚本工具: 查看当前系统被写入的FD

    #!/bin/bash touch /tmp/sn2 /tmp/sn4 /tmp/sn6 /tmp/sn3 redir=/dev/null which lsof >&/dev/null ...

  5. 永久修改 CMD 的 PROMPT 显示结果/给cmd命令显示加上运行时间

    1.环境 windows10 系统 2.打开 cmd ,快捷键 Ctrl + x 然后a 3.输入 REG ADD "HKLM\SYSTEM\CurrentControlSet\Contro ...

  6. java学习第12天

    今天主要是看下正则表达式,其实在编译原理中就接触过.正则表达式就是符合一定规则的字符串. A:字符 x 字符 x.举例:'a'表示字符a \\ 反斜线字符. \n 新行(换行)符 ('\u000A') ...

  7. 跨域的get和post的区别

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二.最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数.当你在面试中被 ...

  8. 关于移动端常用的盒模型与flex布局

    在移动端选择布局的方式中常用盒模型display:-webkit-box达到自适应,然而display:-webkit-flex也同样能达到效果,因自在己移动端用-webkit-box比felx方式熟 ...

  9. [CSS]多浏览器兼容的垂直居中,兼容多个IE

    相信你都是在兼容垂直居中而烦恼,翻阅多个网站总是找不到理想的方法而苦恼,来到这里你的问题解决了!如果对你有帮助请点个赞,谢谢. 多兼容垂直居中,在IE6-9亲自测试并通过 <!doctype h ...

  10. poj1050

    To the Max Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39081   Accepted: 20639 Desc ...