当终端系统无法到达目的地的IP数据包时,为了方便获取诊断信息。一种称为Internet控制消息协议(ICMP)的特殊协议与IP结合使用,以提供与IP协议层配置和IP数据包处理相关的诊断和控制信息。主要的原因是IP协议没有内置机制,在源设备发送的数据包无法到达目标时通知源设备。对于错误报告和控制,它取决于ICMP协议。

ICMP和ICMPv6的报头格式

下图显示了ICMPv4和ICMPv6消息的格式。前4个字节对所有消息都具有相同的格式,但其余的字节因消息而异。

类型字段用于确定特定的报文,ICMPv4和ICMPv6的该字段值并不相同;代码字段进一步肯定报文的含义,ICMPv4和ICMPv6的该字段值并不相同;校验和字段用于确定报文信息的正确性。

  • Wireshark抓包获取ICMP(以Echo (ping)request为例):

我们日常使用最多的ping,就是响应请求(Type=8)和应答(Type=0),一台主机向一个节点发送一个Type=8的ICMP报文,如果途中没有异常(例如被路由器丢弃、目标不回应ICMP或传输失败),则目标返回Type=0的ICMP报文,说明这台主机存在,更详细的tracert通过计算 ICMP报文通过的节点来确定主机与目标之间的网络距离。


对于ICMPv4,信息消息包括:

回声请求(类型8)
回音回复(类型0)
路由器播发(类型9)
路由器请求(类型10)

路由器广告和路由器请求统称为路由器发现。最常见的错误消息类型包括:

目标无法访问(类型3)
重定向(类型5)
超过时间(类型11)
参数问题(类型12)

  • Wireshark抓包获取ICMPv6(以Echo (ping)request为例):


类型:标识ICMPv6报文类型,它的值根据报文的内容来确定。
代码:用于确定ICMPv6进一步的信息,对同一类型的报文进行了更详细的分类。
校验和:用于检测ICMPv6的报文是否正确传送。
报文体:用于返回出错的参数和记录出错报文的片段,帮助源结点判断错误的原因。或是其它参数。

类型字段值为128 ,表示该ICMPv6信息报文中的回送请求报文。代码字段在发送端置为0校验和字段在计算之前被置0.标识字段与序列号字段用于在回送请求报文与回送应答报文之间建立对应关系。数据字段是诊断的内容,为8b的整数倍。

在ICMPv6中,与ICMPv4中一样,消息被分组为信息类和错误类。

然而,在ICMPv6中,所有错误消息的类型字段的高位都有一个0。因此,ICMPv6类型0到127都是错误,类型128到255都是信息性的。许多信息性消息是请求/回复对。

Linux发送ECHO request消息C/C++代码实现

...
int main(int argc, char *argv[])
{...for (int i=1; i<argc; ++i) {const char *const arg = argv[i];union {struct sockaddr_in  sin;struct sockaddr_in6 sin6;} u;bzero(&u, sizeof(u));if (0 == strcmp("--help", arg)) {print_usage();return 0;} else if (0 == strcmp("--version", arg)) {print_version();return 0;}else if ((0 == strcmp("--dry-run", arg)) || (0 == strcmp("-n", arg))) {dry_run = true;continue;} else if (0 == strcmp("--loop", arg)) {do_loop = true;continue;} else if (0 == strcmp("-qq", arg)) {switch (verbosity) {case VERB_NORMAL:verbosity = VERB_MUTE;break;default:error_exit("Illegal use of -qq");}continue;} else if ((0 == strcmp("--quiet", arg)) || (0 == strcmp("-q", arg))) {switch (verbosity) {case VERB_NORMAL:verbosity = VERB_QUIET;break;case VERB_QUIET:verbosity = VERB_MUTE;break;default:error_exit("Illegal use of --quiet/-q");}continue;} else if (0 == strcmp("-vv", arg)) {switch (verbosity) {case VERB_NORMAL:verbosity = VERB_VERY;break;default:error_exit("Illegal use of -vv");}continue;} else if ((0 == strcmp("--verbose", arg)) || (0 == strcmp("-v", arg))) {switch (verbosity) {case VERB_NORMAL:verbosity = VERB_VERBOSE;break;case VERB_VERBOSE:verbosity = VERB_VERY;break;default:error_exit("Illegal use of --verbose/-v");}continue;} else if (1 == inet_pton(AF_INET6, arg, &u.sin6.sin6_addr)) {enlarge_array(arg);u.sin6.sin6_family = AF_INET6;memcpy(&tasks[task_cnt].sas, &u.sin6, sizeof(u.sin6));} else if (1 == inet_pton(AF_INET, arg, &u.sin.sin_addr)) {enlarge_array(arg);u.sin.sin_family = AF_INET;memcpy(&tasks[task_cnt].sas, &u.sin, sizeof(u.sin));} else {error_exitf("Cannot parse address: %s", arg);}tasks[task_cnt].delay.tv_sec  = 0;tasks[task_cnt].delay.tv_nsec = 500000000;++task_cnt;}...return 0;
}
...

发送回显请求将一个ICMP(IPv4)或ICMPv6(IPv6)回显请求分别发送到一个地址列表,而无需等待回显回复数据包。每0.5秒发送一个数据包。或者,在无限循环中重复发送数据包。

运行结果:


tcpdump抓取ICMP ECHO request消息:


使用

./send_echo_request -q --loop 39.156.66.10

使用-q选项可以抑制信息回显在终端。

tcpdump抓取ICMP ECHO request消息:

发送ICMPv6 echo request消息:


tcpdump抓包
tcpdump -i ens33 “icmp6 && ip6[40] == 128”

总结

在IPv4中,Internet控制报文协议ICMP向源节点报告关于向目的地传输IP数据包过程中的错误和信息。在IPv6中,ICMPv6除了提供ICMPv4常用的功能之外,还是其它一些功能的基础,如邻接点发现、无状态地址配置(包括重复地址检测)、PMTU发现等。最后写个测试例子来发送回显请求,并且进行抓包分析。有助于理解ICMP和ICMPv6

Linux 下C/C++实现发送ICMP和ICMPv6(报文分析)相关推荐

  1. python将Linux下使用top命令获取的进程信息进行分析做可视化展示

    python将Linux下使用top命令获取的进程信息进行分析做可视化展示 版本 版本 作者 日期 备注 v1.0 ZY 2020.11.10 初版完成 文章目录 python将Linux下使用top ...

  2. 遇到一个在linux下无法跨网段发送接收广播包的问题

    正在进行的项目中有个网络广播包搜索设备的模块,需要在上位机发送搜索设备的XML命令,然后设备端再发真正的搜索广播包到交换机上所有的连接设备.测试部反馈了一个bug:无法跨网段搜索到设备,同一个网段内, ...

  3. LINUX 下 HYLAFAX IAX搭建发送传真

    HYLAFAX IAX搭建发送传真 系统环境 UBUNTU14 64bit 该笔记不太完整,请结合其他资料进行配置. 安装配置步骤 首先需要安装 IAXMODEM 以及 HYLAFAX 安装完毕后,修 ...

  4. Linux下raise函数,信号发送函数kill()和raise()

    本文关键字: 信号发送函数,kill(),raise() kill()函数同读者熟知的kill系统命令一样,可以发送信号给进程或进程组(实际上,kill系统命令只是kill()函数的一个用户接口).这 ...

  5. linux下电池测试软件,你们要的App电量分析测试来了

    原标题:你们要的App电量分析测试来了 Batterystats 是包含在 Android 框架中的一种工具,用于收集设备上的电池数据.您可以使用 adb 将收集的电池数据转储到开发计算机,并创建一份 ...

  6. linux下h.264码流实时rtp打包与发送,Linux下H.264码流实时RTP打包与发送

    由于项目要求在DM6467T平台上添加实时RTP打包发送模块,这才找了找有没有人分享 这方面的经验.这里需要感谢网友:yanyuan9527,他写的文章对我帮助很大,可以说让一个完全小白的人了解了RT ...

  7. Linux下使用mail命令发送邮件

    因为需要经常备份网站的数据,所以了解并学习了下linux下如何通过shell来发送邮件,这里以CentOS为例,使用mail命令来进行外部邮件的发送.mail命令的语法如下: Usage: mail ...

  8. linux设置send时间,[转]Socket 的send,recv在windows与linux下的超时设置

    从昨天到今天一真在搞这个网络断线检测的问题,一直没搞好,网上大多都说用ping 可以搞定,不过我就是搞不定,没办法之下想了个不是办法的办法,在 服务器上开了一个 UDP端口,监听数据,然后回发,不用T ...

  9. linux邮箱发文件夹,Linux下使用mail命令发送邮件

    Linux服务器mail程序本身就是调用sendmail来进行邮件发送的,sendmail服务器提供对外的邮件发送功能.CentOS默认不能发送邮件,需要发送邮件的童鞋可以安装一个sendmail程序 ...

最新文章

  1. IsNull和IsEmpty的区别
  2. zip 文件下载函数封装
  3. HDU3183 A Magic Lamp —— 贪心(单调队列优化)/ RMQ / 线段树
  4. js怎么获取一个元素与屏幕右边的距离_js中如何获取某个元素到浏览器最左和最右的距离...
  5. 前端学习(2881):初始化dom和数据化线程池
  6. NVDKC6416平台H.264算法优化
  7. 土耳其电信与华为签署5G协议谅解备忘录
  8. maven源码阅读之一(Guice介绍)
  9. html如何改成花体英文字体,花体英文在线转换
  10. 大工之星编程挑战赛第五周题解
  11. 腾讯云对象存储操作流程
  12. 一款 Material Design 风格的妹子福利 App.
  13. 微型计算机硬件调研报告,计算机软硬件的产品调查报告分析.doc
  14. VScommunity2019 0x00007FFCCA14B7EC (ucrtbased.dll) (Project1.exe 中)处有未经处理的异常: 将一个无效参数传递给了将无效参数视为严重错误
  15. PDPS软件:带颜色的机器人工作站二维布局图JT格式文件转换方法
  16. 平稳/非平稳信号举例
  17. spring 定时任务的 执行时间设置规则
  18. python中plt.imshow()不显示图片
  19. 计算机科学与技术专业适合什么人,计算机科学与技术专业怎么样 主要学什么内容...
  20. idea E9 OA环境搭建

热门文章

  1. mybatis的parameterType可以不写(我一般都不写)
  2. 电机磁链和反电动势系数辨识
  3. 静态成员函数访问非静态成员
  4. 【论文阅读】——Spons Shields: Practical Isolation for Trusted Execution
  5. 带alpha通道的图像合成(Python语言)
  6. Struts2的常量及配置:
  7. oracle 转换为double,Oracle中的类型转换 (转)
  8. 手把手教你批量剪辑视频
  9. 中国高分系列卫星介绍
  10. 求二叉树中的第一条最长路径长度,并输出最长路径上的节点