网络安全项目实战(三)--报文检测

news2024/11/23 12:06:38

6. TCP/IP协议栈及以太网帧

  • 目标
    • 了解TCP/IP协议栈的组织结构
    • 掌握以太网帧的数据格式定义
    • 能应用编码实现以太网帧的解析方法

6.1. TCP/IP 协议栈

TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网络层(Network)和链路层(Link)四层。如下图所示(该图出自[TCPIP])。

两台计算机通过TCP/IP协议通讯的过程如下所示(该图出自[TCPIP])。 

传输层及其以下的机制由内核提供,应用层由用户进程提供(后面将介绍如何使用socket API编写应用程序),应用程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示(该图出自[TCPIP])。 

不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。我们在pcap文件中,所得到的package data数据就是一个以太网帧, 因此对“package data”的解析就是解析一个以太网帧

 

6.2. 以太网(RFC 894)帧格式

以太网的帧格式如下所示(该图出自[TCPIP]):

  • 源地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的。用ifconfig命令看一下,“HWaddr 00:15:F2:14:9E:3F”部分就是硬件地址。
  • 目的地址, 意义同源地址
  • 协议字段有三种值,分别对应IP、ARP、RARP。帧末尾是CRC校验码。

    以太网帧中的数据长度规定最小46字节,最大1500字节。

    ARP和RARP数据包的长度不够46字节,要在后面补填充位。

    最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU,如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation)。

    ifconfig命令的输出中也有“MTU:1500”。

    注意,MTU这个概念指数据帧中有效载荷的最大长度,不包括帧首部的长度。

 

6.3. 以太网栈头部

 // /usr/include/linux/if_ether.h 

struct ethhdr {
    unsigned char    h_dest[ETH_ALEN];    /* 目标mac地址    */
    unsigned char    h_source[ETH_ALEN];    /* 源mac地址    */
    __be16        h_proto;        /* 以太网类型    */
} __attribute__((packed));

6.4. 以太网帧解析代码

一下为以太网帧的核心解析代码


    MAC_FRM_HDR *mac_hdr; //define a Ethernet frame header  
    IP_HDR *ip_hdr;       //define a IP header  
    char *tmp1, *tmp2;  
    int AND_LOGIC = 0xFF;  

    mac_hdr = buf;  //buf is what we got from the socket program  
    ip_hdr = buf + sizeof(MAC_FRM_HDR);  
    //udp_hdr = buf + sizeof(MAC_FRM_HDR) + sizeof(IP_HDR); //if we want to analyses the UDP/TCP  

    tmp1 = mac_hdr->src_addr;  
    tmp2 = mac_hdr->dest_addr;  
    /* print the MAC addresses of source and receiving host */  
    printf("MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X==>" "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",  
                tmp1[0]&AND_LOGIC, tmp1[1]&AND_LOGIC, tmp1[2]&AND_LOGIC,tmp1[3]&AND_LOGIC,  
                tmp1[4]&AND_LOGIC, tmp1[5]&AND_LOGIC,  
                tmp2[0]&AND_LOGIC, tmp2[1]&AND_LOGIC, tmp2[2]&AND_LOGIC,tmp2[3]&AND_LOGIC,  
                tmp2[4]&AND_LOGIC, tmp2[5]&AND_LOGIC);  

    tmp1 = (char*)&ip_hdr->ip_src;  
    tmp2 = (char*)&ip_hdr->ip_dest;  
    /* print the IP addresses of source and receiving host */  
    printf("IP: %d.%d.%d.%d => %d.%d.%d.%d",  
                 tmp1[0]&AND_LOGIC, tmp1[1]&AND_LOGIC, tmp1[2]&AND_LOGIC,tmp1[3]&AND_LOGIC,  
                 tmp2[0]&AND_LOGIC, tmp2[1]&AND_LOGIC, tmp2[2]&AND_LOGIC,tmp2[3]&AND_LOGIC);  
    /* print the IP protocol which was used by the socket communication */  
    switch(ip_hdr->ip_protocol) {  
             case IPPROTO_ICMP: LOGI("ICMP"); break;  
             case IPPROTO_IGMP: LOGI("IGMP"); break;  
             case IPPROTO_IPIP: LOGI("IPIP"); break;  
             case IPPROTO_TCP:  
         case IPPROTO_UDP:  
                                LOGI("Protocol: %s", ip_hdr->ip_protocol == IPPROTO_TCP ? "TCP" : "UDP");  
                                LOGI("Source port: %u, destination port: %u", udp_hdr->s_port, udp_hdr->d_port);  
                                break;  
             case IPPROTO_RAW: LOGI("RAW"); break;  
             default: printf("Unknown, please query in inclued/linux/in.h\n"); break;  
    }  

7. IP 报文

  • 目标
    • 了解IP报文的组织结构
    • 掌握IP报文的分析方法。

7.1. IP数据报格式

IP数据报的格式如下(这里只讨论IPv4)(该图出自[TCPIP]):

 

  • 版本:IP报文版本号 IPV4:4,IPV6:6

  • 首部长度:IP header 长度,是4字节的整数倍, 没有选项,则一般为5(5x32bit=20B)

  • 8位服务类型:一般没有使用,详细参考RFC
  • 总长度:header+数据 总长度
  • 16位标识:IP 报文的唯一id,分片报文的id 相同,便于进行重组。
  • 3位标志:标明是否分片。是一个3位的控制字段,包含:
    • 保留位:1位
    • 不分段位:1位,取值:0(允许数据报分段)、1(数据报不能分段)
    • 更多段位:1位,取值:0(数据包后面没有包,该包为最后的包)、1(数据包后面有更多的包)
Bit 0: reserved, must be zero
Bit 1: (DF) 0 = May Fragment,  1 = Don't Fragment.
Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.

          0   1   2
        +---+---+---+
        |   | D | M |
        | 0 | F | F |
        +---+---+---+
  • 13位片偏移:参考下图。如果是第一片取值为0,第二片取值175,以此类推。

  • TTL:生存时间,即路由器的跳数,每经过一个路由器,该TTL 减一,因此路由器需要重新计算IP报文的校验和。
  • 8位协议:ICMP:1,TCP:6,UDP:17,其他的自行百度
  • 首部校验和:IP header校验和,接收端收到报文进行计算如果校验和错误,直接丢弃。
  • 源IP地址:无须解释
  • 目的IP地址:无须解释
  • 选项:这个一般也没有使用。详细参考RFC
  • 数据:上层的报文,如TCP 报文、UDP报文等。

7.2. IP报文头部

IP头部,总长度20字节


 // /usr/include/linux/ip.h
struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,     //首部长度
        version:4;    //版本 
 #elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,    //版本
          ihl:4;          //首部长度
 #else
 #error    "Please fix <asm/byteorder.h>"
 #endif
    __u8    tos;      //服务类型
    __be16    tot_len;    //总长度
    __be16    id;         //标志
    __be16    frag_off;   //分片偏移
    __u8    ttl;         //生存时间
    __u8    protocol;     //协议
    __sum16    check;         //检验和
    __be32    saddr;      //源IP地址
    __be32    daddr;      //目的IP地址
    /*The options start here. */
};

关于协议类型定义

 // /usr/include/linux/netinet/in.h

/* Standard well-defined IP protocols.  */
enum
  {
    IPPROTO_IP = 0,       /* Dummy protocol for TCP.  */
#define IPPROTO_IP        IPPROTO_IP
    IPPROTO_ICMP = 1,       /* Internet Control Message Protocol.  */
#define IPPROTO_ICMP        IPPROTO_ICMP
    IPPROTO_IGMP = 2,       /* Internet Group Management Protocol. */
#define IPPROTO_IGMP        IPPROTO_IGMP
    IPPROTO_IPIP = 4,       /* IPIP tunnels (older KA9Q tunnels use 94).  */
#define IPPROTO_IPIP        IPPROTO_IPIP
    IPPROTO_TCP = 6,       /* Transmission Control Protocol.  */
#define IPPROTO_TCP        IPPROTO_TCP
    IPPROTO_EGP = 8,       /* Exterior Gateway Protocol.  */
#define IPPROTO_EGP        IPPROTO_EGP
    IPPROTO_PUP = 12,       /* PUP protocol.  */
#define IPPROTO_PUP        IPPROTO_PUP
    IPPROTO_UDP = 17,       /* User Datagram Protocol.  */
.....

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1308811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Python监控服务器在线状态

前言 在公司内网有一台服务器&#xff0c;有动态的公网IP&#xff0c;使用DDNS对外提供服务&#xff0c;但是会因为停电、服务器卡死等原因导致服务器离线。服务器离线后无法及时获知&#xff0c;因此需要实现在服务器离线的时候能够发送消息到手机上。 思路梳理 公司办理的…

第31期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

CSS特效029:超逼真的3D篮球弹跳,含挤压弹起模态

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…

【云原生kubernets】Service 的功能与应用

一、Service介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。为了解决这个问题&#xff0c;kubernetes提供了Service资…

nestjs守卫/全局守卫校验jwt

一、守卫 目标 部分接口需要用户登录后才可以访问&#xff0c;用户登录后可以颁发 jwt_token 给前端&#xff0c;前端在调用需要鉴权的接口&#xff0c;需要在请求头添加 jwt_token&#xff0c;后端校验通过才能继续访问&#xff0c;否则返回403无权访问 创建守卫 anth 安装…

【期末复习向】常见的激活函数

激活函数是非线性的函数&#xff0c;使用它的原因就是因为线性函数无论叠加多少层&#xff0c;最终带来的变化都是线性的组合&#xff0c;一般也只能用于线性分类&#xff0c;如经典的多层感知机。但是如果加上非线性的变换&#xff0c;根据通用近似定理&#xff0c;就可使得神…

python+pytest接口自动化(15)-日志管理模块loguru简介

python自带日志管理模块logging&#xff0c;使用时可进行模块化配置&#xff0c; 但logging配置起来比较繁琐&#xff0c;且在多进行多线程等场景下使用时&#xff0c;如果不经过特殊处理&#xff0c;则容易出现日志丢失或记录错乱的情况。 python中有一个用起来非常简便的第…

鸿蒙开发组件之DatePicker

一、功能 DatePicker是鸿蒙开发中的日期组件&#xff0c;主要用来日期的选择。样式如下 二、初始化一个DatePicker DatePicker({start:new Date(1970-01-01),end: new Date(2035-12-31)})当然我们的start和end参数是可选的&#xff0c;不必须传递&#xff0c;所以初始化也可以…

【动态规划】06路径问题_不同路径II_C++(medium)

题目链接&#xff1a;leetcode不同路径II 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求在考虑网格中有障碍物的情况下&#xff0c;从左上角到右下角将会有多少条不同的路径…

【ARM Trace32(劳特巴赫) 使用介绍 14 -- Go.direct 介绍】

请阅读【Trace32 ARM 专栏导读】 文章目录 Trace32 Go.directGo配合程序断点使用Go 配合读写断点使用Go 快速回到上一层函数 System.Mode Go Trace32 Go.direct TRACE32调试过程中&#xff0c;会经常对芯片/内核进行控制&#xff0c;比如全速运行、暂停、单步等等。这篇文章先…

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 执行Nacos中的startup.cmd的时候出现闪退,于是在该脚本的最后一行添加pause,查看因为什么原因闪退 出现的bug如下所示:Error:Unable to access jarfile xxxx\target\nacos-server.jar 截图如下所示: 查看内部文件夹,…

德语 Alt 代码表

德语的 Alt 代码表&#xff0c;请参考下图。 输入方法就是按住 Alt 键不松开&#xff0c;然后在小键盘上输入字符&#xff0c;松开 Alt 键&#xff0c;计算机就能输出上面的字符了。 德语 Alt 代码表 - 系统容器 - iSharkFly德语的 Alt 代码表&#xff0c;请参考下图。 输入方…

c语言为什么要引入数据类型

大家好&#xff0c;今天给大家介绍c语言为什么要引入数据类型&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 在本人看来,C语言引入数据类型的原因主要有以下几点&#xff1a; 数…

消息中间件比较

那都有哪些中间件可供选择呢。其实现在主流的消息中间件就4种&#xff1a;kafka、ActiveMQ、RocketMQ、RabbitMQ 下面我们来看一下&#xff0c;他们之间有什么区别&#xff0c;他们分别应该用于什么场景 ActiveMQ 我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件&…

集群监控Zabbix和Prometheus

文章目录 一、Zabbix入门概述1、Zabbix概述2、Zabbix 基础架构3、Zabbix部署3.1 前提环境准备3.2 安装Zabbix3.3 配置Zabbix3.4 启动停止Zabbix 二、Zabbix的使用与集成1、Zabbix常用术语2、Zabbix实战2.1 创建Host2.2 创建监控项&#xff08;Items&#xff09;2.3 创建触发器&…

寻找最大整数 C语言xdoj51

问题描述 从键盘输入四个整数&#xff0c;找出其中的最大值并将其输出。 输入说明 输入4个整数&#xff0c;用空格分隔 输出说明 输出值最大的一个整数 输入样例 25 99 -46 0 输出样例 99 #include <stdio.h>//寻找最大整数 int main() {int i, a[4]…

5 转向事件驱动的架构

文章目录 核心概念消息代理事件和消息了解事件异步消息通信响应式系统 事件驱动的利弊消息传递模式发布—订阅工作队列过滤器数据持久性 消息传递代理协议、标准和工具AMQP和RabbitMQ基本概念交换类型和路由消息确认和拒绝 设置RabbitMQ安装RabbitMQRabbitMQ管理界面 Spring AM…

Unity_FairyGUI发布导入Unity编辑器资源报错

Unity_FairyGUI发布导入Unity编辑器资源报错 报错&#xff1a; FairyGUI: settings for Assets/UI/XMUI/XMSubway_atlas0.png is wrong! Correct values are: (Generate Mip Mapsunchecked) UnityEngine.Debug:LogWarning (object) FairyGUI.UIPackage:LoadAtlas (FairyGUI.P…

用Go汇编实现一个快速排序算法

本代码全网首发&#xff0c;使用Go plan9 windows arm64汇编&#xff0c;实现基础版快速排序算法。 未引入随机因子的快速排序的普通Go代码长这样。 func QuickSort(arr []int) {if len(arr) < 1 {return}base, l, r : arr[0], 0, len(arr)-1for i : 1; i < r; {if arr…

UI设计中的2.5D插画是什么?

2.5d插画&#xff0c;你可能第一时间会想2D应该是平面的&#xff0c;3D是立体的&#xff0c;介于2D和3D之间&#xff0c;那么它就是在平面上面看立体的2.5D透视原理图像&#xff0c;就是物体的正面、光面和暗面三面组成&#xff0c;也算是伪3D。 首先&#xff0c;设计师需要设…