吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2715|回复: 5
收起左侧

[Python 转载] 计算机网络——小实验:解析IP、TCP、UDP数据报

  [复制链接]
dingallen216 发表于 2021-8-30 17:28
本帖最后由 dingallen216 于 2021-8-30 17:32 编辑

第一章链接:https://www.52pojie.cn/thread-1500148-1-1.html
第二章链接:https://www.52pojie.cn/thread-1500750-1-1.html
第三章链接:https://www.52pojie.cn/thread-1501401-1-1.html
第四章链接:https://www.52pojie.cn/thread-1502111-1-1.html

计算机网络概述、物理层、数据链路层、网络层的笔记都在上面这些内容里了,看到传输层和应用层的时候,全是些耳熟能详的内容,什么TCP三次握手,什么HTTP协议,干脆就放弃了做无用的笔记 。本文参考****的课程,做了一个解析IP、UDP、TCP数据报的小实验。本实验基于Python。



解析IP数据报

[Python] 纯文本查看 复制代码
# -*- encoding=utf-8 -*-

import struct
import socket

class IPParser:

    IP_HEADER_LENGTH = 20

    @classmethod
    def parse_ip_header(cls, ip_header):

        第一行 = struct.unpack('>BBH', ip_header[:4])
        第三行 = struct.unpack('>BBH', ip_header[8:12])
        第四行 = struct.unpack('>4s', ip_header[12:16])
        第五行 = struct.unpack('>4s', ip_header[16:20])

        IP版本 = 第一行[0] >> 4
        头部长度 = 第一行[0] & 15
        总长度 = 第一行[2]
        TTL = 第三行[0]
        协议 = 第三行[1]
        首部校验和 = 第三行[2]
        源IP地址 = socket.inet_ntoa(第四行[0])
        目的IP地址 = socket.inet_ntoa(第五行[0])

        return {
            'IP版本': IP版本,
            '头部长度': 头部长度,
            '总长度': 总长度,
            'TTL': TTL,
            '协议': 协议,
            '首部校验和': 首部校验和,
            '源IP地址': 源IP地址,
            '目的IP地址': 目的IP地址
        }

    @classmethod
    def parse(cls, packet):
        ip_header = packet[:20]
        return cls.parse_ip_header(ip_header)

易语言了都,属于是。应该不需要解说。



解析UDP、TCP数据报

[Python] 纯文本查看 复制代码
# -*- encoding=utf-8 -*-

import struct

class TransParser:
    IP_HEADER_OFFSET = 20
    UDP_HEADER_LENGTH = 8
    TCP_HEADER_LENGTH = 20


class UDPParser(TransParser):

    @classmethod
    def parse_udp_header(cls, udp_header):

        头 = struct.unpack('>HHHH', udp_header)
        源端口 = 头[0]
        目的端口 = 头[1]
        UDP长度 = 头[2]
        检验和 = 头[3]

        return {
            '源端口': 源端口,
            '目的端口': 目的端口,
            'UDP长度': UDP长度,
            '检验和': 检验和
        }

    @classmethod
    def parse(cls, packet):
        udp_header = packet[cls.IP_HEADER_OFFSET:cls.IP_HEADER_OFFSET + cls.UDP_HEADER_LENGTH]
        return cls.parse_udp_header(udp_header)


class TCPParser(TransParser):

    @classmethod
    def parse_tcp_header(cls, tcp_header):

        第一行 = struct.unpack('>HH', tcp_header[:4])
        第二行 = struct.unpack('>L', tcp_header[4:8])
        第三行 = struct.unpack('>L', tcp_header[8:12])
        第四行 = struct.unpack('>BBH', tcp_header[12:16])
        第五行 = struct.unpack('>HH', tcp_header[16:20])

        源端口 = 第一行[0]
        目的端口 = 第一行[1]
        序列号 = 第二行[0]
        确认号 = 第三行[0]
        数据偏移 = 第四行[0] >> 4
        flags = 第四行[1] & int('00111111',2)
        FIN = flags & 1
        SYN = (flags >> 1) & 1
        RST = (flags >> 2) & 1
        PSH = (flags >> 3) & 1
        ACK = (flags >> 4) & 1
        URG = (flags >> 5) & 1
        窗口大小 = 第四行[2]
        检验和 = 第五行[0]
        紧急指针 = 第五行[1]

        return {
            '源端口': 源端口,
            '目的端口': 目的端口,
            '序列号': 序列号,
            '确认号': 确认号,
            '数据偏移': 数据偏移,
            '标志位': {
                'FIN': FIN,
                'SYN': SYN,
                'RST': RST,
                'PSH': PSH,
                'ACK': ACK,
                'URG': URG
            },
            '窗口大小': 窗口大小,
            '检验和': 检验和,
            '紧急指针': 紧急指针
        }

    @classmethod
    def parse(cls, packet):
        tcp_header = packet[cls.IP_HEADER_OFFSET:cls.IP_HEADER_OFFSET + cls.TCP_HEADER_LENGTH]
        return cls.parse_tcp_header(tcp_header)



主逻辑(不必在意类名和其继承的类,这就是用于用于完成异步任务的,主逻辑就是process内的代码。需要注意的是,我们在运行时会给类传入一个packet,这就是我们通过监听捕获到的数据包)

[Python] 纯文本查看 复制代码
class ProcessTask(AsyncTask):

    def __init__(self, packet, *args, **kwargs):
        self.packet = packet
        super(ProcessTask, self).__init__(func=self.process, *args, **kwargs)

    def process(self):
        headers = {
            '网络层': None,
            '传输层': None
        }
        ip_header = IPParser.parse(self.packet)
        headers['网络层'] = ip_header
        if ip_header['协议'] == 17:
            udp_header = UDPParser.parse(self.packet)
            headers['传输层'] = udp_header
        elif ip_header['协议'] == 6:
            tcp_header = TCPParser.parse(self.packet)
            headers['传输层'] = tcp_header

        return headers



效果

图:IP数据报夹TCP数据报

图:IP数据报夹UDP数据报



总结:本文完成的解析数据报的方法就是取下头部,一个萝卜一个坑地将每个比特位的作用对应上其规则。IP协议是网络层的协议,而UDP和TCP是传输层的协议,所以想要拿到UDP和TCP数据,需要先把IP数据报的头部给摘了。可以看出这一过程在计算机内实现起来并不复杂,通过此方法,我们能剥下层层数据,解析出更高层次的协议内容。

免费评分

参与人数 6吾爱币 +8 热心值 +6 收起 理由
woyucheng + 1 + 1 谢谢@Thanks!
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
WSlibre + 1 + 1 我很赞同!
vividig + 1 我很赞同!
风来也999 + 1 我很赞同!
fu520 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

WSlibre 发表于 2021-8-30 20:24
谢谢分享
小朋友呢 发表于 2021-8-30 20:28
老铁这是看的哪位大神视频学的,可以推荐下吗
 楼主| dingallen216 发表于 2021-8-30 21:00
小朋友呢 发表于 2021-8-31 10:09

老铁前面的字被****号了
 楼主| dingallen216 发表于 2021-8-31 12:07
小朋友呢 发表于 2021-8-31 10:09
老铁前面的字被****号了

被屏蔽的是mu课网
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 13:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表