快乐虾

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

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

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的回应:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

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



NS3网络仿真(12): ICMPv4协议的更多相关文章

  1. NS3网络仿真(6): 总线型网络

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载.但请保留作者信息 在NS3提供的第一个演示样例first.py中,模拟了一个点对点的网络,接下来的一个演示样例代码模 ...

  2. NS3网络仿真(7): Wifi节点

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 在上一节中.我们仿真了一个总线型网络,这一节尝试将上一节中的n0变成一个无线的AP.再连上几个节点 ...

  3. NS3网络仿真(2):first.py

    1    安装基本模块 11  安装Python 12  安装PTVS 13  加入对python-279的支持 2    在vs2013下编译NS3 3    编译NetAnim 4    在vs2 ...

  4. NS3网络仿真(11): ARP

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 ARP(Address ResolutionProtocol,地址解析协议)协议的基本功能就是通过 ...

  5. NS3网络仿真(9): 构建以太网帧

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 在NS3使用了一个叫Packet的类来表示一个数据帧,本节尝试用它构造一个以太网帧. 以下是一个典 ...

  6. NS3网络仿真(3): NetAnim

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 在NS3提供的演示样例first.py中,并没有生成NetAnim所须要的xml文件,本节我们尝试 ...

  7. NS3网络仿真(4): DataRate属性

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 在first.py中创建了一个点到点的信道,且配置了两个属性: pointToPoint = ns ...

  8. 网络教程(12) TCP协议

    IP协议的限制 IP协议需要 datalink帧来包装它 Ethernet或者PPP 一般都有1500byte字节或者大小的限制 可能会出现的问题 Packet loss – retransmit R ...

  9. NS3网络仿真(10): 解析以太网帧

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载.但请保留作者信息 解析以太网帧的过程是构建以太网帧的逆过程,当我们接收到一个以太网帧时,仍然以上一节中的ARP帧为例 ...

随机推荐

  1. C++知识点总结(纯C++!!)

    1.重载函数是否能够通过函数返回值的类型不同来区分? 不可以.因为在C++编程中,函数的返回值可以忽略(不使用其返回值),程序中调用此时函数名相同和参数相同的两个函数对编译器和程序员来说是没有办法区分 ...

  2. MySQL多版本并发控制(MVCC)

    MVCC是行级锁的一个变种,但是它在很多的情况下避免了加锁操作,因此开销更低.MySQL,包括Oracle.PostgreSQL都实现了MVCC,虽然每个关系数据库实现不一样,但大都是实现了非阻塞的读 ...

  3. 不同子系统采用不同MySQL编码LATIN1和UTF8的兼容

    程序处理 这是一个历史遗留系统, 旧的系统是C++开发的, 插入数据的时候, 没有统一MYSQL各个层次(服务器, 数据库, 表, 列)的编码, 这个情况基本上是MYSQL的默认安装导致的, 实际的数 ...

  4. Linux基础(Ubuntu)

    更换apt源为清华源 1.备份 /etc/apt/sources.list 2.vim 编辑 /etc/apt/sources.list 添加 deb http://mirrors.tuna.tsin ...

  5. 周三面试Python开发,这几道Python面试题差点答错,Python面试题No7

    第1题:阅读下面的代码,默读出A0,A1至An的最终值. A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5))) A1 = range(10) A2 = [ ...

  6. 有关OEP脱壳

    首先补充: OEP:(Original Entry Point),程序的入口点,软件加壳就是隐藏了OEP(或者用了假的OEP), 只要我们找到程序真正的OEP,就可以立刻脱壳. PUSHAD (压栈) ...

  7. UVa 1354 天平难题 (枚举二叉树)

    题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...

  8. Excel数据导入Sql Server出现Null(转)

    Excel文件: 序号 姓名 内部电话 住址 1 小李 1234 …… 2 小王 5678 …… 3 小张 2345(国内长途) …… …… …… …… …… 如上结构的Excel文件,用SQL Se ...

  9. HDU 1278

    题目大意: 从(1,1)到(n,n),每经过一个点都要花费一定的时间,问花最短时间的路径有多少条 dfs+dp 先用bfs把所有到n花费的时间逆向dp计算一遍 再用dfs不断找到前一个对应的较短路径的 ...

  10. 微软2016校园招聘在线笔试 B Professor Q's Software [ 拓扑图dp ]

    传送门 题目2 : Professor Q's Software 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Professor Q develops a new s ...