Tea9源码网 - 免费分享精品源码、教程、软件|全网干货资源收集,免费下载。

计算机网络——小实验:解析IP、TCP、UDP数据报

发布:吾爱破解论坛2021-9-1 14:22分类: 技术教程 标签: Python 计算机网络 UDP数据报 解析IP TCP

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



解析IP数据报

# -*- 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数据报
# -*- 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,这就是我们通过监听捕获到的数据包)
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数据报夹UDP数据报

图:IP数据报夹UDP数据报

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

温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,谢谢合作!

已有 2502 人阅读