NS3网络仿真:ICMPv4协议性能分析

ICMP的全称是 Internet ControlMessage Protocol 。

其目的就是让我们可以检測网络的连通状况。ICMP主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连接状况。本节利用NS3学习一下此协议。



1.1    报文格式

ICMP的报文格式例如以下:

NS3网络仿真(12): ICMPv4协议_校验和


即ICMP报文是IP报文的数据。而IPv4报文的格式例如以下:

NS3网络仿真(12): ICMPv4协议_ide_02


在网上抓一个ping包来看看:

NS3网络仿真(12): ICMPv4协议_数据_03




这是一个从192.168.24.1到192.168.24.129的ping包。再看看192.168.24.129的回应:

NS3网络仿真(12): ICMPv4协议_数据_04


非常easy和前面的报文格式相应上。



1.2    用NS3生成ICMP的请求包

接下来试试用NS3生成上面的ICMP的请求包。


依照NS3数据包的生成规则,首先须要准备ICMP请求的数据部分,即报文中的abcde...:


// 填充的数据内容  uint8_t buffer[2048] = { 0 };  for (int i = 0; i < m_nCurPacketLen; i++)  {    buffer[i] = 'a' + (i % 23);  }  Ptr<Packet> data = ns3::Create<Packet>(buffer, m_nCurPacketLen);接下来填充Icmp Echo的包头:  // 生成要发送的数据包列表  Ptr<Packet> pkt = ns3::Create<Packet>();  // 加入icmp echo头  Icmpv4Echo eh;  eh.SetData(data);  eh.SetSequenceNumber(0x0019/*m_nCurPacketSeq*/);  eh.SetIdentifier(1);  pkt->AddHeader(eh);这里的seq是一个可变的整数,仅仅只是我们为了与上面的数据包一致写入了一个固定的数值。接下来填充Icmp Header:  // 加入icmp头  Icmpv4Header ih;  ih.SetCode(0);  ih.SetType(Icmpv4Header::ECHO);  ih.EnableChecksum();  pkt->AddHeader(ih);这里唯一须要注意的是EnableChecksum必须在AddHeader前调用,否则不会生成校验和。再加上IP包头:  // 加入IP头  Ipv4Header iph;  iph.SetDestination((const char*)dest_ip);  iph.SetSource((const char*)src_ip);  iph.SetIdentification(0x49fb);  iph.SetTtl(64);  iph.SetProtocol(Icmpv4L4Protocol::PROT_NUMBER);  iph.SetPayloadSize(pkt->GetSize());  iph.EnableChecksum();  pkt->AddHeader(iph);最后加上以太网包头:  // 加入以太网头  EthernetHeader eeh;  eeh.SetDestination((const char*)dest_mac);  eeh.SetSource((const char*)src_mac);  eeh.SetLengthType(ns3::Ipv4L3Protocol::PROT_NUMBER);  pkt->AddHeader(eeh);  int len = pkt->CopyData(buffer, 2048);1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.


大功告成!看看我们生成的数据包内容:

NS3网络仿真(12): ICMPv4协议_数据_05


与前面从网上抓下来的包一模一样。




1.3    用NS3分析ICMP请求包


分析包的过程和构造包的过程刚好相反。从最外面的以太网包一直分析到数据:


/* Callback function invoked by libpcap for every incoming packet */void CCommonIcmpSendDlg::packet_handler(void *_param, const void *_header, const void *_pkt_data){  uint8_t buffer[2048], *p;  p = (uint8_t *)_pkt_data + 12;  if (p[0] != 8 || p[1] != 0)    return;  const struct pcap_pkthdr *header = (const struct pcap_pkthdr *)_header;  Ptr<Packet> pkt = ns3::Create<Packet>((uint8_t*)_pkt_data, header->len);  // ip 包  EthernetHeader eh;  Ipv4Header iph;  pkt->RemoveHeader(eh);  pkt->RemoveHeader(iph);  if (iph.GetProtocol() != Icmpv4L4Protocol::PROT_NUMBER)    return;  Icmpv4Header ih;  Icmpv4Echo ieh;  SIcmpPacket* ppkt;  pkt->RemoveHeader(ih);  if (ih.GetType() == Icmpv4Header::ECHO_REPLY)  {    pkt->RemoveHeader(ieh);    if (ieh.GetIdentifier() != dlg->m_nIcmpId)      return;    int seq = ieh.GetSequenceNumber();.....    return;  }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.


1.4    winpcap发包的问题

在发送ICMP包时,使用了pcap_sendpacket函数进行发包,但此函数的发包延迟较大,从函数调用到从网卡上抓到这个包可以有几百个毫秒的延迟。

NS3网络仿真(12): ICMPv4协议_i++_06


暂且记下来以供后继參考。

 


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空