精华内容
下载资源
问答
  • 以太帧

    千次阅读 2011-05-08 22:49:00
    在以太网链路上的数据包称作以太帧。... 目录[隐藏]1结构1.1前导码和帧开始符1.2报头1.3帧校验码1.4帧间距2以太帧类型2.1Ethernet I2.2802.2 LLC2.3子网接入协议2.4Novell raw 802.33效率4矮帧5Notes6Refe
    
    

    以太网链路上的数据包称作以太帧。以太帧起始部分由前导码和帧开始符组成。后面紧跟着一个以太网报头,以MAC地址说明目的地址和源地址。帧的中部是该帧负载的包含其他协议报头的数据包(例如IP协议)。以太帧由一个32位冗余校验码结尾。它用于检验数据传输是否出现损坏。

    目录

    [隐藏]
    • 1 结构
      • 1.1 前导码和帧开始符
      • 1.2 报头
      • 1.3 帧校验码
      • 1.4 帧间距
    • 2 以太帧类型
      • 2.1 Ethernet I
      • 2.2 802.2 LLC
      • 2.3 子网接入协议
      • 2.4 Novell raw 802.3
    • 3 效率
    • 4 矮帧
    • 5 Notes
    • 6 References

     结构

    来自线路的二进制数据包称作一个帧。从物理线路上看到的帧,除其他信息外,还可看到前导码和帧开始符。任何物理硬件都会需要这些信息。[note 1]

    下面的表格显示了在以1500个八位元组MTU传输(有些吉比特以太网甚至更高速以太网支持更大的帧,称作巨型帧)时的完整帧格式。[note 2]一个八位元组是八个位组成的数据(也就是现代计算机的一个字节)。

    802.3 以太网帧结构
    前导码帧开始符MAC 目标地址MAC 源地址802.1Q 标签 (可选)以太类型或长度负载冗余校验帧间距
    10101010 7个octet 10101011 1个octet 6 octets 6 octets (4 octets) 2 octets 46–1500 octets 4 octets 12 octets
      64–1522 octets  
    72–1530 octets  
    84–1542 octets

     前导码和帧开始符

    参见:Syncword

    10/100M 网卡(MII PHY)一次传输4位(一个半字)。因此前导符会成为7组0101+0101,而帧开始符成为0101+1101。8位数据会先发送低4位,再发送高4位。1000M网卡(GMII)一次传输8位,而10Gbit/s(en:XGMII) PHY芯片一次传输32位。 注意当以octet描述时,先传输7个01010101然后传输11010101。由于8位数据的低4位先发送,所以先发送帧开始符的0101,之后发送1101。

     报头

    报头包含源地址和目标地址的MAC地址,以太类型字段和可选的用于说明VLAN成员关系和传输优先级的IEEE 802.1Q VLAN 标签。

     帧校验码

    帧校验码是一个32位循环冗余校验码,以便验证帧数据是否被损坏。

     帧间距

    主条目:en:Interframe gap

    当一个帧发送出去之后,发送方在下次发送帧之前,需要再发送至少12个octet的空闲线路状态码。

     以太帧类型

    以太帧有很多种类型。不同类型的帧具有不同的格式和MTU值。但在同种物理媒体上都可同时存在。

    • 以太网第二版[note 3]或者称之为Ehternet II 帧,DIX帧,是最常见的帧类型。并通常直接被IP协议使用。
    • Novell的非标准IEEE 802.3帧变种。
    • IEEE 802.2 逻辑链路控制 (LLC) 帧
    • 子网接入协议(SNAP)帧

    所有四种以太帧类型都可包含一个IEEE 802.1Q选项来确定它属于哪个VLAN以及他的IEEE 802.1p优先级(QoS)。这个封装由IEEE 802.3ac定义并将帧大小从4字节扩充到1522字节(注:不包含7个前导字节和1个字节的帧开始符以及12个帧间距字节)。

    IEEE 802.1Q标签,如果出现,需要放在源地址字段和以太类型或长度字段的中间。这个标签的前两个字节是标签协议标识符(TPID)值0x8100。这与没有标签帧的以太类型/长度字段的位置相同,所以以太类型0x8100就表示包含标签的帧,而实际的以太类型/长度字段则放在Q-标签的后面。TPID后面是两个字节的标签控制信息(TCI)。(IEEE 802.1p 优先级(QoS)和VLAN ID)。Q标签后面就是通常的帧内容。

     Ethernet II

    以太 II 帧 (也称作DIX以太网,是以这个设计的主要成员,DEC,IntelXerox的名字命名的。[1]),把紧接在目标和源MAC地址后面的以太类型这个两字节字段定义为帧数据的。

    例如,一个0x0800的以太类型说明这个帧包含的是IPv4数据报。同样的,一个0x0806的以太类型说明这个帧是一个ARP帧,0x8100说明这是一个IEEE 802.1Q帧,而0x86DD说明这是一个IPv6帧。

    当这个工业界的标准通过正式的IEEE标准化过程后,在802.3标准中以太类型字段变成了一个(数据)长度字段。(最初的以太包通过包括他们的帧来确定它们的长度,而不是以一个明确的数值。)但是包的接收层仍需知道如何解析包,因此标准要求将IEEE802.2头跟在长度字段后面,定义包的类型。多年之后,802.3x-1997标准,一个802.3标准的后继版本,正式允许两种类型的封包同时存在。实际上,两种封包都被广泛使用,而最初的以太封包在以太局域网中被广泛应用,因为他的简便和低开销。

    为了允许一些使用以太II版本的数据报和一些使用802.3封装的最初版本的数据包能够在同一个以太网段使用,以太类型值必须大于等于1536(0x0600)。这个值比802.3封包的最大长度1500byte (0x05DC)要更大。因此如果这个字段的值大于等于1536,则这个帧是以太II帧,而那个字段是类型字段。否则(小于1500而大于46字节),他是一个IEEE 802.3帧,而那个字段是长度字段。1500~1536(不包含)的数值未定义。[2]

     802.2 LLC

    一些协议,尤其是为OSI模型设计的,会直接在802.2 LLC层上操作。802.2 LLC层同时提供数据报和面向连接的网络服务。

    802.2以太网变种没有在常规网络中普遍使用。只有一些大公司的没有与IP网络融合的Netware设备。以前,很多公司Netware网络支持802.2以太网,以便支持从以太网到IEEE 802.5令牌环网或FDDI网络的透明桥接。当今最流行的封包是以太网版本二,由基于IP协议的网络使用,将其以太类型设置为0x0800用于封装IPv4或者0x86DD来支持IPv6

    还有一个英特网标准来使用LLC/SNAP报头将IPv4封装在IEEE 802.2帧中。[3]这几乎从未在以太网中实现过。(但在FDDI以及令牌环网IEEE 802.11和其他IEEE 802网络中使用)。如果不使用SNAP,IP传输无法封装在IEEE 802.2 LLC帧中。这是因为LLC协议中虽然有一种IP协议类型,却没有ARP。IPv6同样可使用LLC/SNAP在IEEE 802.2以太网上传播,但,如同IPv4,它也绝少被这样使用。(尽管LLC/SNAP的IPv6封包在IEEE 802网络中被使用)。

     子网接入协议

    通过检查802.2 LLC头,可以确定他是否后继一个SNAP头。LLC头包含两个附加的8位地址字段,在OSI模型术语中称作服务访问点(SAPs)。当源和目标SAP都设置为0xAA时,就会使用SNAP服务。SNAP头允许以太类型值被任何IEEE 802协议使用,即使支持的是私有协议ID空间。在IEEE 802.3x-1997中,IEEE 以太标准被修改为明确允许紧接着MAC地址的16位字段即可用于长度字段,也可用于类型字段。

    Mac OS使用 802.2/SNAP 封包来实现以太网上的AppleTalk V2协议套件("EhterTalk")。

     Novell raw 802.3

    Novell的"raw"802.3帧格式基于早期IEEE 802.3的工作。Novell以它作为起点来创建他自己的以太网上IPX协议的的第一个实现。他们没有使用LLC头,而是直接在长度字段后面开始IPX数据包。这不符合IEEE 802.3标准,但由于IPX的前两个字节一直是FF(而在IEEE 802.2 LLC中这种模式虽然理论上是可能的但实际上概率极其微小),实用中这种方式与其他以太实现共同存在。但须注意在一些早期的DECnet可能无法识别之。

    直到90年代中期,Novell NetWare默认使用这个帧类型,而由于Netware曾如此流行,而那时IP还不是那么流行,在过去的一些时候,大多数的以太网上都运载着负载IPX的"raw" 802.3封包。直到Netware 4.10,当使用IPX时,Netware才默认使用IEEE 802.2和LLC(Nerware 帧类型Ethernet_802.2)。

     效率

    我们可以计算以太网的效率和比特率

    /text{Efficiency} = /frac{/text{Payload size}}{/text{Frame size}}

    当达到允许的最大负载值时可达到最高效率,对于无标签的以太网封包是/frac{1500}{1538} = 97.53%,而使用802.1Q VLAN标签时是/frac{1500}{1542} = 97.28%

    由效率中可计算比特率:

    /text{Net bit rate} = /text{Efficiency} /times /text{Wire bit rate}/,/!

    不带802.1Q标签的100BASE-TX以太网的最大比特率是97.53 Mbit/s. 注:不带标签的最大帧尺寸=1518 + 20 (7-byte 前导符,1-byte 帧开始符, 12-byte 帧间距)= 1538。

     矮帧

    矮帧是一个尺寸不及IEEE 802.3定义的最小长度64字节的以太网帧。可能的原因是以太网碰撞,数据不足,网卡错误或软件错误。[4]

    展开全文
  • 如IPv4为0x0800,ARP为0x0806等,网卡驱动收到以太帧后通过接口函数netif_receive_skb()(netif_rx实际最后也是调用netif_receive_skb)交到上层,而这个接口函数就完成对以太帧类型的区分,交到不同的协议处理程序。...

    1. 前言

    以太头中除了6字节目的MAC地址、6字节源MAC地址外,还有两字节的以太帧类型值,如IPv4为0x0800,ARP为0x0806等,网卡驱动收到以太帧后通过接口函数netif_receive_skb()(netif_rx实际最后也是调用netif_receive_skb)交到上层,而这个接口函数就完成对以太帧类型的区分,交到不同的协议处理程序。如果想自己编写某一以太类型帧的处理程序,需要自己添加相应的
    以下Linux内核代码为2.6.17.11。
     
    2. 数据结构

    每种协议都要定义一个packet_type结构,引导进入相关的协议数据处理函数,所有节点组成一个链表(HASH链表)。
    /* include/linux/netdevice.h */
    struct packet_type {
     __be16   type; /* This is really htons(ether_type). */
     struct net_device *dev; /* NULL is wildcarded here      */
     int   (*func) (struct sk_buff *,
          struct net_device *,
          struct packet_type *,
          struct net_device *);
     void   *af_packet_priv;
     struct list_head list;
    };
    参数说明:
    type:以太帧类型,16位
    dev:所附着的网卡设备,如果为NULL则匹配全部网卡
    func:协议入口接收处理函数
    af_packet_priv:协议私有数据
    list:链表扣
    一般各协议的packet_type结构都是静态存在,初始化时只提供type和func两个参数就可以了,每个协议在初始化时都要将此结构加入到系统类型链表中。

    3. 处理函数

    3.1 添加节点
    /* net/core/dev.c */
    /**
     * dev_add_pack - add packet handler
     * @pt: packet type declaration
     *
     * Add a protocol handler to the networking stack. The passed &packet_type
     * is linked into kernel lists and may not be freed until it has been
     * removed from the kernel lists.
     *
     * This call does not sleep therefore it can not
     * guarantee all CPU's that are in middle of receiving packets
     * will see the new packet type (until the next received packet).
     */
    void dev_add_pack(struct packet_type *pt)
    {
     int hash;
     spin_lock_bh(&ptype_lock);
    // 如果类型是全部以太类型,则节点链接到ptype_all链
     if (pt->type == htons(ETH_P_ALL)) {
      netdev_nit++;
      list_add_rcu(&pt->list, &ptype_all);
     } else {
    // 根据协议类型取个HASH,共15个HASH链表
      hash = ntohs(pt->type) & 15;
    // 将节点链接到HASH链表中,list_add_rcu是加了smp_wmb()保护的list_add链表操作
      list_add_rcu(&pt->list, &ptype_base[hash]);
     }
     spin_unlock_bh(&ptype_lock);
    }

    3.2  删除节点

    /**
     * __dev_remove_pack  - remove packet handler
     * @pt: packet type declaration
     *
     * Remove a protocol handler that was previously added to the kernel
     * protocol handlers by dev_add_pack(). The passed &packet_type is removed
     * from the kernel lists and can be freed or reused once this function
     * returns.
     *
     *      The packet type might still be in use by receivers
     * and must not be freed until after all the CPU's have gone
     * through a quiescent state.
     */
    void __dev_remove_pack(struct packet_type *pt)
    {
     struct list_head *head;
     struct packet_type *pt1;
     spin_lock_bh(&ptype_lock);
    // 根据协议类型找是在ptype_all表还是某一HASH链表中
     if (pt->type == htons(ETH_P_ALL)) {
      netdev_nit--;
      head = &ptype_all;
     } else
      head = &ptype_base[ntohs(pt->type) & 15];
    // 直接用地址比对进行查找,而不是类型,因为同一个类型也可能有多个节点
     list_for_each_entry(pt1, head, list) {
      if (pt == pt1) {
       list_del_rcu(&pt->list);
       goto out;
      }
     }
     printk(KERN_WARNING "dev_remove_pack: %p not found./n", pt);
    out:
     spin_unlock_bh(&ptype_lock);
    }
    /**
     * dev_remove_pack  - remove packet handler
     * @pt: packet type declaration
     *
     * Remove a protocol handler that was previously added to the kernel
     * protocol handlers by dev_add_pack(). The passed &packet_type is removed
     * from the kernel lists and can be freed or reused once this function
     * returns.
     *
     * This call sleeps to guarantee that no CPU is looking at the packet
     * type after return.
     */
    // 只是__dev_remove_pack()的包裹函数
    void dev_remove_pack(struct packet_type *pt)
    {
     __dev_remove_pack(pt);
     
     synchronize_net();
    }

    4. 实例

    4.1 IP
    /* net/ipv4/af_inet.c */
    static struct packet_type ip_packet_type = {
     .type = __constant_htons(ETH_P_IP),
     .func = ip_rcv, // IP接收数据的入口点
    };
    static int __init inet_init(void)
    {
    ......
     dev_add_pack(&ip_packet_type);
    ......
    由于IP协议部分不能作为内核模块,所以是没有卸载函数的,没必要调用dev_remove_pack()函数。

    4.2 8021q vlan
    /* net/8021q/vlan.c */
    static struct packet_type vlan_packet_type = {
     .type = __constant_htons(ETH_P_8021Q),
     .func = vlan_skb_recv, /* VLAN receive method */
    };
    ......
    static int __init vlan_proto_init(void)
    {
    ......
     dev_add_pack(&vlan_packet_type);
    ......

    static void __exit vlan_cleanup_module(void)
    {
    ......
     dev_remove_pack(&vlan_packet_type);
    ......
    由于VLAN可为模块方式存在,所以在模块清除函数中要调用dev_remove_pack()。
     
    5. 网络接收

    网卡驱动收到数据包构造出skb后,通过接口函数netif_receive_skb()传递到上层进行协议处理分配。

    /* net/core/dev.c */
    int netif_receive_skb(struct sk_buff *skb)
    {
    ......
    // 先查处理所有以太类型的链表各节点
     list_for_each_entry_rcu(ptype, &ptype_all, list) {
      if (!ptype->dev || ptype->dev == skb->dev) {
       if (pt_prev)
        ret = deliver_skb(skb, pt_prev, orig_dev);
       pt_prev = ptype;
      }
     }
    ......
    // 再查指定协议的HASH链表
     list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
      if (ptype->type == type &&
          (!ptype->dev || ptype->dev == skb->dev)) {
       if (pt_prev)
        ret = deliver_skb(skb, pt_prev, orig_dev);
       pt_prev = ptype;
      }
     }
    ......

    // 该函数就是调用个协议的接收函数处理该skb包,进入第三层网络层处理
    static __inline__ int deliver_skb(struct sk_buff *skb,
          struct packet_type *pt_prev,
          struct net_device *orig_dev)
    {
     atomic_inc(&skb->users);
     return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
    }
     
    6. 结论

    通过链表挂接方式,Linux内核可以很容易的添加各种协议的接收处理函数。
    数据流程:
              _____________
             |             |
    网卡驱动--->netif_rx()--->netif_receive_skb()->deliver_skb()->packet_type.func
    展开全文
  • 如IPv4为0x0800,ARP为0x0806等,网卡驱动收到以太帧后通过接口函数netif_receive_skb()(netif_rx实际最后也是调用netif_receive_skb)交到上层,而这个接口函数就完成对以太帧类型的区分,交到不同的协议处理程序。...
  • 1.用协议分析工具软件捕获ping命令及tracert命令发出的ICMP报文,...2.分析承载ARP报文的以太帧类型码与承载IP报文的以太帧类型的不同,并把截图写入报告。 3、分析ARP协议的执行过程,并截取以太帧进行配图分析。
  • 以太网根据IEEE 802.3标准来管理和控制数据。网络通信协议:OSI、TCP/IP、IPX/SPX、SNA局域网:IEEE802、以太网广域网:PPP、HDLC不同的协议栈用于定义和管理不同的数据转发规则。OSI分层模型7 应用层 为应用程序...

    以太网根据IEEE 802.3标准来管理和控制数据帧。

    网络通信协议:OSI、TCP/IP、IPX/SPX、SNA

    局域网:IEEE802、以太网

    广域网:PPP、HDLC

    不同的协议栈用于定义和管理不同的数据转发规则。

    OSI分层模型

    7 应用层 为应用程序提供网络服务(端口号)

    6 表示层 数据格式化,加密、解密

    5 会话层 建立、维护、管理会话连接

    4 传输层 建立、维护、管理端到端连接(TCP、UDP)

    3 网络层 IP寻址和路由选择(路由器)

    2 数据链路层 控制网络层与物理层之间通信(MAC地址)

    1 物理层 比特流传输

    TCP 可靠的连接 A与B握手后发送数据

    UDP 不可靠的连接 A直接向B发送数据

    7-1 封装 1-7 解封装

    TCP/IP分层模型

    应用层 为应用程序提供网络服务

    传输层

    网络层

    网络接口层(数据链路层 和 物理层)

    数据封装

    应用层 数据(Data)

    传输层 TCP报头+数据=数据段(Segment)

    网络层 IP报头+数据段=数据包(Packet)

    数据链层 MAC报头+数据包+帧校验(Traile)=数据帧(Frame)

    物理层 比特(Bit)

    数据链路层控制数据帧在物理链路上传输。

    帧格式

    Ethernet_II D.MAC S.MAC Type Data FCS

    IEEE802.3 D.MAC S.MAC Length LLC SNAP Data FCS

    Etherner_II帧类型大于等于1536(0x0600),以太网数据帧的长度在64-1518字节之间。

    D.MAC(6B,目的MAC地址) S.MAC(6B,源MAC地址) Type(2B,可以确定网络层协议,0x0800 IP协议,0x0806 ARP协议) Data(46-1500B) FCS(4B,帧校验)

    6ff03bd3dffcb7a19451cb6540a43a17.png

    IEEE802.3帧长度字段值小于等于1500(0x05DC)。

    D.MAC(6B,目的MAC地址) S.MAC(6B,源MAC地址) Length(2B,帧长度,小于等于1500) LLC(3B) SNAP(5B) Data(38-1492B) FCS(4B,帧校验)

    2f02a010bfdd500aba81a524803fb2c8.png

    以太网的MAC地址

    OUI(24B)+由供应商分配(24B)=MAC地址(48B)

    MAC地址由两部分组成,分别是供应商代码和序列号。其中前24位代表该供应商代码,由IEEE管理和分配,剩下的24位序列号由厂商自己分配。

    单播:一对一之间进行发送(7B+0(8B))

    组播:一对一个组进行发送(7B+1(8B))

    广播:一对局域网中所有的设备进行发送(FF-FF-FF-FF-FF-FF)

    数据帧的发送和接收

    当主机接收到数据帧所包含的目的MAC地址是自己时,会把以太网封装剥掉后送往上层协议。

    展开全文
  • python之分解以太帧

    2019-09-25 09:23:06
    通过了解socket(int domain, int type, int protocol...或者PF_PACKET域,和类型SOCK_RAW再加上协议就可以监听获得指定协议的以太帧。 1.获得各个协议的头部  以太协议类型有很多,仅贴上一部分,如下图:  ...

      通过了解socket(int domain, int type, int protocol)接口,我们知道利用socket的AF_PACKET

    或者PF_PACKET域,和类型SOCK_RAW再加上协议就可以监听获得指定协议的以太帧。

          1.获得各个协议的头部

      以太协议类型有很多,仅贴上一部分,如下图:

                                      图一

    更多以太类型见:http://en.wikipedia.org/wiki/EtherType

       本文仅介绍0x0800(IPV4)的监听与拆分。现在我们就可以利用:

    s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

    获得ipv4协议的以太帧。然后就是接收,并根据协议格式拆分了。先看以太帧格式部分,如下:

                                                                              图二

      我们接收的数据没有Preamble部分,此部分被以太网硬件过滤掉了。这里说一下,上图Type/Length

    部分是Ethernet-II才有的type,在原始的IEEE 802.3帧此部分是负载的数据长度,怎样区分的呢,数值小于

    1500表示帧负载数据长度,而>=1536(十六进制0x0600)表示Ethernet-II的type(见图一ethertype的值)。

      另外提一下vlan类型大小是0x8100,此类型的协议现在使用比较广泛,格式如下:

                                                                             图三

    vlan tag中有12bit用来表示vlan id的。此处和本文没有多少关系,主要是应用广泛介绍一下。继续正文。

      我们用pkt表示接受的数据,pkt为str类型,通过图二可知用pkt[:14]包含了目的mac(6 bytes)、

    源mac(6 bytes)和Type(2 bytes)。ipv4数据包封装在以太帧中,下一步看ipv4头格式:

     

                                                                       图四

    了解更详细IPv4:http://en.wikipedia.org/wiki/IPv4

    从图四可以知道ipv4最小长度20bytes(每行四字节,共5行),所以通过pkt[14:34]得到其头部。

    由于ipv4之上有Tcp、UDP等协议,这里介绍获取的TCP数据,在ipv4头部的protocol为6时即是tcp包。

    TCP header如下:

                                                                         图五

    Tcp头部最小也是20bytes,所以tcp_header=pkt[34:54]

      2.获得每个协议的每个字段

      在此之前,要说一个问题。比如要把4存进int型的低8位,在python中这个还好说,再去取来也

    没什么难度。但是如果把4存进2bytes的数中或者从保存4的2bytes str类型中获得4,就没有c等语言

    简单。这里介绍struct模块,有了它,一切就简单了!我们通过如下:

    tcp_h=struct.unpack("<HHIIbbHHH", tcp_header)

    此方法就得到了tcp头部的个部分信息。

      首先"<HHIIbbHHH"中的'<'表示开始部分,还可以是 '>'、'!' 或者 '='。H表示无符号16位,

    I表示unsigned int,b表示signed char。所以HHII分别是source port(16bits)、Destination port(16bits)、

    Sequence number(32bits)、Ack number(32bits)(看图五),bbHHH同理。

      根据你设置的格式化字符串unpack()返回对应长度的数组,比如上面的“HHIIbbHHH”(9个字符)

    就会返回长度为9的数组,并且每个元素都是int型。

      同理,对于以太帧头部和ipv4头部处理与tcp header类似。

      更详细的格式化字符对照如下:

      3.代码实现

      通过上面讲述实现主体代码如下:

     

     1 ipv4=0x0800
     2 udptype=0x11
     3 tcptype=0x06
     4 bufsize=1500
     5 s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(ipv4))
     6 
     7 while True:
     8     pkt=s.recv(bufsize)
     9     if len(pkt)<=0:
    10         break
    11     elif len(pkt)>54:
    12         ether_header = pkt[0:14]
    13         ip_header  = pkt[14:34]        
    14         ether_h = struct.unpack("!6s6s2s",ether_header)
    15         ip_h  = struct.unpack("<bbHHHbbHII",ip_header)        
    16         ip  = IPv4Parser(ip_h) #做位运算等处理
    17         if ip.protocol==tcptype: #判断是否为tcp包
    18             tcp_header = pkt[34:54]
    19             tcp_h = struct.unpack("<HHIIbbHHH", tcp_header)
    20             tcp = TCPParser(tcp_h)
    21             print ip.sourceip()+':'+str(tcp.sport)+'-->'+ip.destinationip()+\
    22                 ':'+str(tcp.dport)

     16、17行用了两个类对ip和tcp头部解析,如下:

     1 import os,socket
     2 import struct
     3 class IPv4Parser:
     4     def __init__(self,ip):
     5         self.ip=ip
     6     @property
     7     def version(self):
     8         v=self.ip[0]>>4
     9         return v
    10     @property
    11     def headerLen(self):
    12         l=(self.ip[0]&0x000f)*4
    13         return l
        @property
        def protocol(self):
          return self.ip[6]
    14 def sourceip(self): 15 sip=self.__getstrip(self.ip[8]) 16 return sip 17 def destinationip(self): 18 dip=self.__getstrip(self.ip[9]) 19 return dip 20 def totalLen(self): 21 return ((self.ip[2]&0xff)<<8)|((self.ip[2]>>8)&0xff)
    22 def checksum(self): 23 pass 24 def __getstrip(self,intip): 25 strip=str(intip&0xff)+'.'+str((intip>>8)&0xff)+'.'+\ 26 str((intip>>16)&0xff)+'.'+str((intip>>24)&0xff) 27 return strip 28 class TCPParser: 29 def __init__(self,tcp): 30 self.tcp=tcp 31 @property 32 def sport(self): 33 sp=self.tcp[0] 34 return ((sp&0xff)<<8)|(sp>>8) 35 @property 36 def dport(self): 37 return ((self.tcp[1]&0xff)<<8)|(self.tcp[1]>>8)
    38 @property 39 def headerLen(self): 40 return ((self.tcp[4]>>4)&0x0f)*4

      上面并没有解析ip和tcp header的所有部分,当然你可以补全,解析头部注意字节序

      把上面两处代码放在一个文件中没意外就可以运行了,注意需要root权限。运行输出的

    信息如下,当然也可以输出更详细的信息。

      我们完全可以更进一步,对于tcp上层的协议比如http继续解包。

     

    转载于:https://www.cnblogs.com/wuchaofan/p/3450979.html

    展开全文
  • 一个设备的几个层面:控制层面(协议)、数据转发层面(传送报文)、(管理层面) 常见设备管理方式: 面对面管理:Console(primary interface),(有些设备使用mini USB)本地管理 远程管理:Telnet/SSH(既有业务流量也有...
  • 通过了解socket(int domain, int type, int protocol)接口,我们知道利用socket的AF_PACKET或者PF_PACKET域,和类型SOCK_RAW再加上协议就可以监听获得指定协议的以太帧。1.获得各个协议的头部以太协议类型有很多,仅...
  • TCP/IP笔记-Qt使用Win10pcap发送以太帧(理论与实践)

    千次阅读 多人点赞 2020-04-28 10:56:11
    首先来介绍下以太帧理论: 以太帧是包含MAC帧的,先看下MAC帧: 目的地址:接收帧的网络适配器的物理地址(MAC地址); 源地址:发送帧的网络适配器的物理地址(MAC地址); 类型:上层协议类型。在处理数据...
  • 802.1q以太帧

    2020-06-01 17:20:27
    相反,在以太网格式里,在MAC地址源 与 以太网类型/长度 之间添加一个32位的域(field)。VLAN标签领域必须遵守下列格式(4个字节):16 bits 3 bits 1bit 12 bitsTPID PCP CFI VID标签协议识别符(Tag Protocol Ident...
  • 以太帧(V2)与802.3帧格式区别

    千次阅读 2011-09-19 15:16:29
    6bytes的目的地址+6bytes的源地址+2Bytes的协议类型字段+数据; 802.3以太网格式: 前导码(7字节)、起始定界符(1字节)、目的MAC地址(6字节)、源MAC地址(6字节)、类型/长度(2字节)、数据(46~1500字节...
  • EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要的。...
  • 链路层(网卡驱动macb_rx_frame())接收到以太网后,通过接口函数netif_receive_skb()(netif_rx实际最后也是调用netif_receive_skb)交到网络层,而这个接口函数就完成对帧类型的区分,再交到不同的协议处理程序...
  • 以太网帧类型总结

    万次阅读 2016-09-12 09:27:06
    EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要的。...
  • 以太网帧类型

    2013-01-11 19:20:35
    EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要的。...
  • :magnifying_glass_tilted_left: 适用于以太坊devp2p协议的Wireshark解剖器 此仓库包含一组用于以太坊的网络协议解析器,您可以将其加载到广泛... 在协议树中链接PING => PONG,以及FIND_NODE => NODES交互。 很多
  • 以太网帧类型速查

    2018-10-22 11:32:00
    EtherType :以太网类型字段及值EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段...
  • 太网帧类型

    2013-04-19 16:17:01
    EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要的。...
  • ARP协议与Ethernet MAC

    2020-05-14 18:59:06
    ARP协议:理解ARP的概念和作⽤ ARP协议各字段如图: MAC:理解以太⽹MAC MAC字段如图: 抓取ARP包:抓取并分析ARP请求与...协议类型:IPv4(0x0800) (即对应的类型码) 硬件size:6 协议size:4 操作码:repl
  • 以太网帧类型速查表

    2011-08-04 11:16:49
    EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要
  • EtherType :以太网类型字段及值 EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段...

空空如也

空空如也

1 2 3 4 5 6
收藏数 118
精华内容 47
关键字:

以太帧协议类型