zoukankan      html  css  js  c++  java
  • NS3网络仿真(12): ICMPv4协议

    快乐虾

    http://blog.csdn.net/lights_joy/

    欢迎转载,但请保留作者信息


    ICMP的全称是 Internet ControlMessage Protocol

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


    1.1    报文格式


    ICMP的报文格式例如以下:


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


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



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


    非常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.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函数进行发包,但此函数的发包延迟较大,从函数调用到从网卡上抓到这个包可以有几百个毫秒的延迟。



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












    
  • 相关阅读:
    Sass基础——Rem与Px的转换
    彻底弄懂css中单位px和em,rem的区别
    在Eclipse Android中设置模拟器屏幕大小
    设置Android模拟器的窗口大小
    安卓模拟器Android SDK 4.0.3 R2安装完整图文教程
    自适应网页设计(Responsive Web Design)
    手机web——自适应网页设计(html/css控制)
    jQuery动态创建html元素的常用方法汇总
    javascript——URI的编解码方法
    为革命保护视力 --- 给 Visual Studio 换颜色
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7182646.html
Copyright © 2011-2022 走看看