网络工程师这一行,理解报文封装过程是很重要的一步,对我们来说,报文是很抽象的内容,所以我们需要借助一些工具(如wireshark)去抓包并且使用其自带的模板将二进制信息转换成我们能读懂的信息。
但是我们该如何自己制作报文并且将它发送出去呢?这就需要借助一些计算机语言来实现了。
在python中,有现成的scapy库能帮我们实现这一需求,scapy能封装、发送、捕获、读取报文,也能用来查询一些本机网络信息,还是很强大的。
我这里只是列举几个自己做的小实验,更多内容,可以看官网的手册
Welcome to Scapy’s documentation!
https://scapy.readthedocs.io/en/latest/
或者一些网上大佬分享的中文文档,如:
Scapy介绍官方文档翻译
https://www.ctolib.com/docs-scapy-doc-c-Introduction.html
我做了两个实验:
第一个实验:用scapy列举自己的网卡,然后将选中的网卡信息列举出来,如,ip、mac等。
#! /usr/bin/python3.6# -*- coding: utf-8 -*-from scapy.all import *import easygui# 调用scapy和easygui,# scapy用于查询设备网络信息,# easygui用于提供简单的ui界面if_list_name_list = []# 创建一个网卡名称列表,用于在easygui中列举网卡if_list = get_windows_if_list()# 获取windows的接口列表,每个接口信息包含在字典中,其格式为:# {'name': '网卡名称', 'win_index': 3, 'description': '描述', 'guid': 'xxx', # 'mac': 'xxx', 'ipv4_metric': 5, 'ipv6_metric': 0, 'ips': ['ipv6', 'ipv4']}for i in if_list: print(i) if_list_name_list.append(i['name']) # 将网卡逐条加入网卡名称列表the_if_name = easygui.choicebox(msg='请选择网卡:', title='提示', choices=if_list_name_list)# 弹出提示窗,会让我们根据网卡名称选择指定网卡the_if_index = if_list_name_list.index(the_if_name)# 获取接口序号if len(if_list[the_if_index]['ips']) == 1: the_if_ip = if_list[the_if_index]['ips'][0]else: the_if_ip = if_list[the_if_index]['ips'][1]the_if_mac = if_list[the_if_index]['mac']# 因为scapy会同时显示ipv4和ipv6,但是如果网卡ipv6被关闭的话,又仅会显示一个ip# 所以咱们在这先判断下ips的长度(这样省事...)# 这里是在读取选中网卡的ip和mac信息easygui.msgbox(msg='设备ip为'+the_if_ip+',设备mac为'+the_if_mac, title='提示')# 弹窗显示选中网卡的ip和mac信息
验证:
第二个实验:用scapy构造“正常”的arp报文,这里只是举个栗子,实际上scapy功能远远不止于此。这里我的终端ip为10.1.11.51/24,网关的ip为10.1.11.1/24
#! /usr/bin/python3.6# -*- coding: utf-8 -*-from scapy.all import *from scapy.layers.l2 import Ether, ARP# 调用scapy# scapy用于网络编程ping_packet = Ether(dst='FF:FF:FF:FF:FF:FF')/ARP(op=1, pdst='10.1.11.1')# 构造ARP报文,还需要对以太帧头Ether进行构造,dst是目的mac,src是源mac# ARP报头信息中,hwsrc是源mac,psrc是源ip,hwdst是目的mac,默认是全0,pdst是目的ipping_packet.show()# 查看发送报文的字段信息send_arp = srp(ping_packet)print('测试:', send_arp)# 发送前边构造好的arp报文,并接收相应的响应报文# 打印发送和接收的报文信息print(send_arp[0].res)# 打印接收到的arp相应报文字段信息
验证:
arp响应报文头部信息:
[(FF:FF:FF:FF:FF:FF type=ARP |>>, 94:e6:f7:xx:xx:xx src=f0:63:f9:xx:xx:xx type=ARP |'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>>)]