NS3网络仿真(12): ICMPv4协议
2015-08-17 22:03
801 查看
快乐虾http://blog.csdn.net/lights_joy/欢迎转载,但请保留作者信息
ICMP的全称是 Internet ControlMessage Protocol 。其目的就是让我们能够检测网络的连通状况。ICMP主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连接状况。本节利用NS3学习一下此协议。
即ICMP报文是IP报文的数据,而IPv4报文的格式如下:
在网上抓一个ping包来看看:
这是一个从192.168.24.1到192.168.24.129的ping包,再看看192.168.24.129的回应:
很容易和前面的报文格式对应上。
按照NS3数据包的生成规则,首先需要准备ICMP请求的数据部分,即报文中的abcde...:
大功告成!看看我们生成的数据包内容:
与前面从网上抓下来的包一模一样。
暂且记下来以供后继参考。
ICMP的全称是 Internet ControlMessage Protocol 。其目的就是让我们能够检测网络的连通状况。ICMP主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连接状况。本节利用NS3学习一下此协议。
1.1 报文格式
ICMP的报文格式如下:即ICMP报文是IP报文的数据,而IPv4报文的格式如下:
在网上抓一个ping包来看看:
这是一个从192.168.24.1到192.168.24.129的ping包,再看看192.168.24.129的回应:
很容易和前面的报文格式对应上。
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.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.4 winpcap发包的问题
在发送ICMP包时,使用了pcap_sendpacket函数进行发包,但此函数的发包延迟较大,从函数调用到从网卡上抓到这个包可以有几百个毫秒的延迟。暂且记下来以供后继参考。
相关文章推荐
- iOS 9 适配系列教程 --https
- 39.网络编程
- centos在没有网络连接的情况下安装rpm包
- iOS应用架构谈 网络层设计方案
- 面向对象的方式进行数据交换网络之间的差异
- 网络爬虫源码
- java网络编程基础
- 监听手机网络状态变化
- fatal: could not read Username for 'https://github.com': No such file or directo
- 网络请求数据
- 解析数据与网络请求
- Linux环境下的TCP/IP通信
- PHP—— 跨域 HTTP 请求
- 谷歌语音转录背后的神经网络
- 打造安全的App!iOS安全系列之 HTTPS
- Dhcp 在企业网中的应用
- Unable to locate Spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/jaxws]
- ArcServer 10安装完成后,访问ArcGIS Server Manager时出现HTTP 错误 500.19 - internet server error
- 第八章 主机名称与主机地址
- iOS请求网络数据的方式