承接上一博文而来,继续解析网络数据包,对于承载在以太网上的三种协议进行了解析,主要是分为依据RFC定义的标准先解析头部数据,然后得到有效载荷,即为协议包括的实体数据,更上层进行进一步处理。

一、ARP协议

该协议作为局域网IP地址和MAC地址映射的重要协议,与DNS将域名与IP地址进行映射有异曲同工之妙。当以太网的类型字段为 0x0806时即为ARP协议数据包。定义例如以下图:

硬件类型即为以太网的代码。ARP支持的协议类型为IP(0x0800),硬件地址长度即MAC地址长度为6,协议地址长度为IP地址长度为4,OP字段为当前数据报的类型,0x0001表示请求包,0x0002表示应答包。这些就构成了ARP数据报头,一共8个Byte。

随后的20个Byte分别如上图所看到的,用来进行MAC地址和IP地址映射。

解析例如以下:

    /// <summary>
/// Define the ARP packet header by RFC826
/// </summary>
public class ARPPacketHeader : INetworkLayerHeader
{
public ushort HardwareType = 0; //2 Bytes 硬件类型
public ushort ProtocalType = 0; //2 Bytes 协议类型
public byte HardwareAddressLength = 6; //1 Byte 硬件地址长度(即MAC地址长度为6)
public byte ProtocolAddressLength = 4; //1 Byte 协议地址长度(即IP地址长度为4)
public ushort OP = 0; //2 Byte ARP包类型(0x0001:请求包 0x0002:应答包)
}
/// <summary>
/// Parse the ARP packet
/// </summary>
public class ARPPacket : INetworkLayerPacket
{
private byte[] RawPacket; public ARPPacketHeader Header;
public string SenderMAC;
public string SenderIP;
public string ReceiverMAC;
public string ReceiverIP; public ARPPacket(byte[] rawArpPacket)
{
SenderMAC = Util.JoinByteArr(Util.SubByteArr(rawArpPacket, 8, 6), "-");
SenderIP = Util.JoinByteArr(Util.SubByteArr(rawArpPacket, 14, 4), ".", "d");
ReceiverMAC = Util.JoinByteArr(Util.SubByteArr(rawArpPacket, 18, 6), "-");
ReceiverIP = Util.JoinByteArr(Util.SubByteArr(rawArpPacket, 24, 4), ".", "d"); RawPacket = rawArpPacket;
} public INetworkLayerHeader getHeader()
{
Header = new ARPPacketHeader();
Header.HardwareType = (ushort)((ushort)(RawPacket[0] << 8) + (ushort)RawPacket[1]);
Header.ProtocalType = (ushort)((ushort)(RawPacket[2] << 8) + (ushort)RawPacket[3]);
Header.HardwareAddressLength = (byte)RawPacket[4];
Header.ProtocolAddressLength = (byte)RawPacket[5];
Header.OP = (ushort)((ushort)(RawPacket[6] << 8) + (ushort)RawPacket[7]);
return Header;
} public byte[] getBody()
{
return Util.SubByteArr(RawPacket, 8);
}
}

二、IPv4协议

解析过程与上述类似,能够进行类比。作为最广泛的网络层协议,具体结构就不赘述。直接看结构图:

解析步骤例如以下:

    /// <summary>
/// Define the IPv4 packet header by RFC791
/// </summary>
public class IPv4PacketHeader : INetworkLayerHeader
{
public byte Version = 4; //3 bits 版本
public byte Length = 0; //5 bits 头部长度
public byte Tos = 0; //1 Byte 服务类型
public ushort DatagramLength = 0; //2 Bytes 数据包长度 public ushort Identification = 0; //2 Bytes 标识
public byte Mark = 0; //3 bits 标志
public ushort Offset = 0; //13 bits 片偏移 public byte TTL = 0; //1 Byte 数据包寿命
public byte UpperProtocal = 0; //1 Byte 上层协议
public ushort HeaderChecksum = 0; //2 Byte 头部检查和 public string SrcIP = ""; //4 Bytes 源IP地址 public string DstIP = ""; //4 Bytes 目的IP地址
}
/// <summary>
/// Parse the IPv4 packet
/// </summary>
public class IPv4Packet : INetworkLayerPacket
{
private byte[] RawPacket; public IPv4PacketHeader Header;
public byte[] Body; public IPv4Packet(byte[] rawPacket)
{
RawPacket = rawPacket;
} public INetworkLayerHeader getHeader()
{
Header = new IPv4PacketHeader();
Header.Length = (byte)(RawPacket[0] & 0x1f);
Header.Tos = RawPacket[1];
Header.DatagramLength = (ushort)((ushort)(RawPacket[2] << 8) + (ushort)RawPacket[3]);
Header.Identification = (ushort)((ushort)(RawPacket[4] << 8) + (ushort)RawPacket[5]);
Header.Mark = (byte)(RawPacket[6] >> 5);
Header.Offset = (ushort)((ushort)((RawPacket[6] & 0x1f) << 8) + (ushort)RawPacket[7]);
Header.TTL = RawPacket[8];
Header.UpperProtocal = RawPacket[9];
Header.HeaderChecksum = (ushort)((ushort)(RawPacket[10] << 8) + (ushort)RawPacket[11]); Header.SrcIP = Util.JoinByteArr(Util.SubByteArr(RawPacket, 12, 4), ".", "d");
Header.DstIP = Util.JoinByteArr(Util.SubByteArr(RawPacket, 16, 4), ".", "d");
return Header;
} public byte[] getBody()
{
Body = Util.SubByteArr(RawPacket, 20);
return Body;
}
}

三、IPv6协议

IPv6是用来替代IPv4以解决地址空间不足的问题而发展起来的,同一时候改协议在IPv4的基础上也做了非常大其它方面的修改,如不同意在中间路由器上进行分片操作等。眼下应用范围尽管难以达到代替IPv4的程度,可是提供了较大优势。下图为其数据报结构:

解析步骤例如以下:

    /// <summary>
/// Define the IPv6 packet header by RFC 2460
/// </summary>
public class IPv6PacketHeader : INetworkLayerHeader
{
public byte Version = 6; //3 bits 版本
public byte Tos = 0; //1 Byte 流量(服务)类型
public uint FlowTag = 0; //21 bits 流标签 public ushort AvaiLoad = 0; //2 Bytes 有效载荷长度
public byte NextHeader = 0; //1 Byte 下个首部(与IPv4中的协议字段值同样)
public byte HopLimit = 0; //1 Byte 跳数限制 public string SrcIP = ""; //16 Bytes 源IPv6地址 public string DstIP = ""; //16 Bytes 目的IPv6地址
}
/// <summary>
/// Parse the IPv6 packet
/// </summary>
public class IPv6Packet : INetworkLayerPacket
{
private byte[] RawPacket; public IPv6PacketHeader Header;
public byte[] Body; public IPv6Packet(byte[] rawPacket)
{
RawPacket = rawPacket;
} public INetworkLayerHeader getHeader()
{
Header = new IPv6PacketHeader();
Header.Tos = (byte)((RawPacket[0] & 0x1fu) << 3 + RawPacket[1] >> 5);
Header.FlowTag = (uint)((RawPacket[1] & 0x1fu) << 16 + RawPacket[2] << 8 + RawPacket[3]);
Header.AvaiLoad = (ushort)((ushort)(RawPacket[4] << 8) + (ushort)RawPacket[5]);
Header.NextHeader = RawPacket[6];
Header.HopLimit = RawPacket[7]; Header.SrcIP = Util.JoinByteArr(Util.SubByteArr(RawPacket, 8, 16), ":", "X2", 2);
Header.DstIP = Util.JoinByteArr(Util.SubByteArr(RawPacket, 24, 16), ":", "X2", 2);
return Header;
} public Byte[] getBody()
{
Body = Util.SubByteArr(RawPacket, 40);
return Body;
}
}

通过对这些协议的亲自剖析,能够更加对网络传输有了更深的理解,同一时候相应用层的应用开发也有非常好的指导作用。

承载于以太网帧之上的数据包的解析——ARP、IPv4、IPv6的更多相关文章

  1. 010 使用netmap API接管网卡,接收数据包,回应ARP请求

    一.本文目的: 上一节中,我们已经在CentOS 6.7 上安装好了netmap,也能接收和发送包了,这节我们来调用netmap中的API,接管网卡,对网卡上收到的数据包做分析,并回应ARP请求. 二 ...

  2. IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习

    相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...

  3. WebSocket协议理解-数据包格式解析

    WebSocket 的诞生 做客户端开发时,接触最多的应用层网络协议,就是 HTTP 协议,而今天介绍的 WebSocket,下层和 HTTP 一样也是基于 TCP 协议,这是一种轻量级网络通信协议, ...

  4. GPS数据包格式解析

    四种定位系统:1.美国的全球定位系统(Global Positioning System,GPS)2.俄罗斯的格罗拉斯(Global Nabigation Satellite System,GLONA ...

  5. IP数据包格式与ARP转发原理

    一.网络层简介1.网络层功能2.网络层协议字段二.ICMP与封装三.ARP协议与ARP欺骗1.ARP协议2.ARP欺骗 1.网络层功能 1. 定义了基于IP地址的逻辑地址2. 连接不同的媒介3. 选择 ...

  6. EasyPusher RTSP直播之RTP数据包格式解析

    -本篇由团队成员Fantasy供稿! RTP包头格式 码流总体结构 h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL).H.264 的编码视频序列包括一系列的NAL 单元,每个NAL ...

  7. python解析发往本机的数据包示例 (解析数据包)

    tcp.py # -*- coding: cp936 -*- import socket from struct import * from time import ctime,sleep from ...

  8. 以太网,IP,TCP,UDP数据包分析【转】

    原文地址:http://www.cnblogs.com/feitian629/archive/2012/11/16/2774065.html 1.ISO开放系统有以下几层: 7 应用层 6 表示层 5 ...

  9. 以太网,IP,TCP,UDP数据包分析(此文言简意赅,一遍看不懂的话,耐心的看个10遍就懂了,感谢作者无私奉献)

    1.ISO开放系统有以下几层: 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层 2.TCP/IP 网络协议栈分为应用层(Application).传输层(Tra ...

随机推荐

  1. javascript每日一练(三)——DOM一

    一.Dom基础 childNodes(有兼容问题),children nodeType getAttribute() firstChild,lastChild,previousSilbing,next ...

  2. ActiveMQ消息队列介绍(转)

    ActiveMQ是一个开源兼容Java Message Service (JMS) 1.1面向消息的中件间. 来自Apache Software Foundation. ActiveMQ提供松耦合的应 ...

  3. 开始着手Oracle中Scott用户的管理系统

    准备好长时间,一直想把最近所学用于实践,正好想到Oracle的Scott用户的表设计还算合理,且自己也很熟悉,现将整个系统的架构设定如下: 1.数据库不用说,Oracle 11g 的 Scott 用户 ...

  4. Swift - String与NSString的区别,以及各自的使用场景

    String是Swift里新增加的类型,它与原来的NSString可以很方便地互相转换.但在实际开发中,我们该如何选择? 1,能使用String类型就尽量使用String类型,原因如下: (1)现在C ...

  5. Windows下实战Apache+PHP [转]

        一.Apache 1.下载登陆Apache Lougne(http://www.apachelounge.com/download/),找到最新版本的Apache.笔者下载的是带IPv6和Cr ...

  6. 在Python中使用正则表达式同时匹配邮箱和电话并进行简单的分类

    在Python使用正则表达式需要使用re(regular exprssion)模块,使用正则表达式的难点就在于如何写好p=re.compile(r' 正则表达式')的内容. 下面是在Python中使用 ...

  7. 基于visual Studio2013解决面试题之0708字符串全排列

     题目

  8. 全方位深度剖析--性能测试之LoardRunner 介绍

    一.介绍 LoardRunner是一种预测系统行为和性能负载的测试工具.通过模拟上千万用户实施并发负载及实时性能监控的方式来确认和查找系统的瓶颈,LoardRunner能够对整个企业架构进行测试.通过 ...

  9. 解决Java compiler level does not match the version of the installed Java project facet.问题

    其实之前遇到过Java compiler level does not match the version of the installed Java project facet.这个问题,因为当时没 ...

  10. UltraEdit配置python和lua环境

    [语法高亮] 在UltraEdit的wordfile中添加python和lua的语法支持(红色的为python,蓝色的为lua): /L10"Python" Line Commen ...