计算机网络——小实验:解析IP、TCP、UDP数据报
本帖最后由 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数据报
# -*- 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)
第四行 = struct.unpack('>4s', ip_header)
第五行 = struct.unpack('>4s', ip_header)
IP版本 = 第一行 >> 4
头部长度 = 第一行 & 15
总长度 = 第一行
TTL = 第三行
协议 = 第三行
首部校验和 = 第三行
源IP地址 = socket.inet_ntoa(第四行)
目的IP地址 = socket.inet_ntoa(第五行)
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)
源端口 = 头
目的端口 = 头
UDP长度 = 头
检验和 = 头
return {
'源端口': 源端口,
'目的端口': 目的端口,
'UDP长度': UDP长度,
'检验和': 检验和
}
@classmethod
def parse(cls, packet):
udp_header = packet
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)
第三行 = struct.unpack('>L', tcp_header)
第四行 = struct.unpack('>BBH', tcp_header)
第五行 = struct.unpack('>HH', tcp_header)
源端口 = 第一行
目的端口 = 第一行
序列号 = 第二行
确认号 = 第三行
数据偏移 = 第四行 >> 4
flags = 第四行 & 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
窗口大小 = 第四行
检验和 = 第五行
紧急指针 = 第五行
return {
'源端口': 源端口,
'目的端口': 目的端口,
'序列号': 序列号,
'确认号': 确认号,
'数据偏移': 数据偏移,
'标志位': {
'FIN': FIN,
'SYN': SYN,
'RST': RST,
'PSH': PSH,
'ACK': ACK,
'URG': URG
},
'窗口大小': 窗口大小,
'检验和': 检验和,
'紧急指针': 紧急指针
}
@classmethod
def parse(cls, packet):
tcp_header = packet
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
效果
https://pic1.zhimg.com/80/v2-f8d8f7f00ebeeb2320281ce6cea6088f_720w.png图:IP数据报夹TCP数据报
https://pic1.zhimg.com/80/v2-e0e89eda561b73ebea7d6db172246eef_720w.png图:IP数据报夹UDP数据报
总结:本文完成的解析数据报的方法就是取下头部,一个萝卜一个坑地将每个比特位的作用对应上其规则。IP协议是网络层的协议,而UDP和TCP是传输层的协议,所以想要拿到UDP和TCP数据,需要先把IP数据报的头部给摘了。可以看出这一过程在计算机内实现起来并不复杂,通过此方法,我们能剥下层层数据,解析出更高层次的协议内容。 谢谢分享 老铁这是看的哪位大神视频学的,可以推荐下吗 小朋友呢 发表于 2021-8-30 20:28
老铁这是看的哪位大神视频学的,可以推荐下吗
***** 咚咚锵 dingallen216 发表于 2021-8-30 21:00
***** 咚咚锵
老铁前面的字被****号了 小朋友呢 发表于 2021-8-31 10:09
老铁前面的字被****号了
被屏蔽的是mu课网
页:
[1]