Python网络程序设计 | 使用标准库socket编写网络嗅探器程序

编写程序,监听本机收到的所有网络数据,解析每个数据的MAC、IP、ICMP、TCP、UDP协议头信息,同时记录不同IP地址发来数据的次数(www.erLong.net)。60秒后停止监听,输出不同IP地址发来数据的次数。如果需要查看其他协议头的信息,可以把代码中注释掉的print语句解除注释,然后重新运行程序观察结果。

请参考TCP/IP协议数据封装过程再结合各协议的头部信息组织格式来理解代码中的解包过程。

01

实现代码

importsocket

importctypes

fromtime importsleep

fromstruct importunpack

fromthreading importThread

# 记录每个IP地址发来信息的次数

activeDegree = dict

# eth_addr是使用lambda表达式定义的MAC地址格式转换函数

# 返回6组十六进制数

eth_addr = lambdaa: ( ':'.join([ '{:02x}']* 6)).format(*a)

defparse_mac(buffer):

# 处理头部获取MAC信息,使用struct进行反序列化

# 关注微信公众号“Python小屋”,发送消息“历史文章”可以找到struct的相关文章

eth_protocol = socket.ntohs(unpack( '!6s6sH', buffer)[ 2])

msg = f'Destination MAC: {eth_addr(buffer[ 0: 6])} ' \

+ f',Source MAC: {eth_addr(buffer[ 6: 12])} ' \

+ f',Protocol: {eth_protocol}'

returnmsg

defparse_ip(buffer):

# 解析IP头

iph = unpack( '!BBHHHBBH4s4s', buffer)

version_ihl = iph[ 0]

version = version_ihl >> 4

ihl = version_ihl & 0xF

iph_length = ihl * 4

ttl, protocol = iph[ 5], iph[ 6]

s_addr = socket.inet_ntoa(iph[ 8])

d_addr = socket.inet_ntoa(iph[ 9])

msg = f'IP => Version: {version}, Header Length: {iph_length},' \

+ f'TTL: {ttl}, Protocol: {protocol}, Source IP: {s_addr},' \

+ f'Destination IP: {d_addr}'

returniph_length, protocol, msg

defparse_tcp(buffer):

# 解析TCP协议头

tcph = unpack( '!HHLLBBHHH', buffer)

s_port, d_port, seq, ack, doff_reserved = tcph[: 5]

tcph_length = doff_reserved >> 4

msg = f'TCP => Source Port: {s_port}, Dest Port: {d_port}' \

+ f',Sequence Number: {seq},Acknowledgement Number: {ack}' \

+ f',TCP header length: {tcph_length}'

returnmsg

defparse_udp(buffer):

# 解析UDP协议头

udph = unpack( '!HHHH', buffer)

s_port, d_port, length, checksum = udph

msg = f'UDP => Source Port: {s_port}, Dest Port: {d_port}' \

+ f',Length: {length},CheckSum: {checksum}'

returnmsg

# ICMP结构体

classICMP(ctypes.Structure):

# ICMP协议各字段

_fields_ = [( 'type', ctypes.c_ubyte),

( 'code', ctypes.c_ubyte),

( 'checksum', ctypes.c_ushort),

( 'unused', ctypes.c_ushort),

( 'next_hop_mtu', ctypes.c_ushort)]

def__new__(self, socket_buffer):

returnself.from_buffer_copy(socket_buffer)

def__init__(self, socket_buffer):

pass

defparse_icmp(buffer):

# 解析ICMP协议头

icmp_header = ICMP(buffer)

msg = f'ICMP => Type: {icmp_header.type},' \

+ f'Code: {icmp_header.code},CheckSum: {icmp_header.checksum}'

returnmsg

defmain:

# 获取本地计算机所有IP地址

HOST = socket.gethostbyname_ex(socket.gethostname)[ 2]

# 创建原始套接字,Windows之外的系统,要把IPPROTO_IP替换为IPPROTO_ICMP

sock = socket.socket(socket.AF_INET, socket.SOCK_RAW,

socket.IPPROTO_IP)

sock.bind((HOST[ -1], 0))

# 设置包含IP头

sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# 开启混杂模式,接收所有包,需要以管理员权限运行程序

sock.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

print( '开始监听...')

whileflag:

# 接收一个数据包

data, (host, port) = sock.recvfrom( 65565)

# 解析MAC信息

mac_len = 14

mac_info = parse_mac(data[:mac_len])

# print(mac_info)

# IP头部基本长度为20字节,最大可能长度为60字节

ip_len, protocol, ip_info = parse_ip(data[: 20])

# print(ip_info)

# IP头部中的协议为1表示ICMP,2表示IGMP,6表示TCP

# 8表示EGP,17表示UDP,41表示IPv6,89表示OSPF

ifprotocol == 6:

# TCP协议头部基本长度为20字节,最大可能长度为60字节

tcp_info = parse_tcp(data[ip_len:ip_len+ 20])

payload = data[start+ 20:]

# print(tcp_info)

elifprotocol == 17:

# UDP协议头部基本长度为8字节

start = mac_len+ip_len

udp_info = parse_udp(data[start:start+ 8])

payload = data[start+ 8:]

# print(udp_info)

elifprotocol == 1:

icmp_part = data[ip_len:ip_len+ctypes.sizeof(ICMP)]

icmp_info = parse_icmp(icmp_part)

payload = data[ip_len+ctypes.sizeof(ICMP):]

# print(icmp_info)

# 统计不同IP地址发来数据的次数

activeDegree[host] = activeDegree.get(host, 0) + 1

# 如果想看本次嗅探到的具体数据,可以删除下面一行代码的len函数

print(len(payload), (host, port))

# 关闭混杂模式,关闭套接字

sock.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

sock.close

# 创建线程,60秒后结束线程停止嗅探

flag = True

t = Thread(target=main)

t.start

sleep( 60)

flag = False

t.join

print( '监听结束...')

# 输出每个IP地址发来数据包的次数

foritem inactiveDegree.items:

print(item)

02

参考书籍

Python网络程序设计(微课版)

作者:董付国

定价:59.80元

内容简介

本书分为5章,主要内容如下:第1章快速介绍Python 开发环境搭建、Python 编码规范、常用数据类型、运算符、内置函数、程序控制结构、函数定义和类定义等基础语法知识;第2章讲解多线程编程模块threading 和多进程编程multiprocessing 、subprocess 在不同领域的应用,以及扩展库psutil 在进程管理方面的应用;第3章讲解基于TCP/UDP/SSL 等网络协议的套接字编程以及端口扫描器、嗅探器与网络抓包、网络管理等内容;第4章讲解使用标准库urllib 、re 和扩展库requests 、bs4 、scrapy 、selenium 、MechanicalSoup 编写网络爬虫程序的有关内容和实战案例;第5章讲解email 、smtplib 、poplib 、imaplib 等标准库在构造/解析、发送、接收和处理电子邮件方面的应用。

作者简介

董付国

山东工商学院副教授,先后出版17本Python系列教材,多次获得校级教学优秀效果一等奖,长期维护微信公众号“Python小屋”免费分享1000多篇Python技术文章和超过500节微课视频。

本书特色

本书可以作为计算机科学与技术、网络工程、软件工程以及相关专业研究生、本科生、专科生的教材(专科生可以根据学时情况和培养目标选讲一部分内容),也可以作为网络应用开发工程师、网络运维工程师和爱好者的自学用书,第5章内容尤其对于办公文秘人员也大有益。

编辑推荐

讲解Python语言在多线程/多进程编程、TCP/UDP套接字编程、网络管理与运维、网络爬虫、电子邮件客户端编程等领域的应用。

全书包含91个例题、60段演示性代码、223道习题、20小时微课视频,微信公众号“Python小屋”1200篇原创技术文章可供扩展阅读。

为用书教师免费提供教学大纲、授课计划与学时分配表、课件、源码、教案、微课视频、习题答案、题库等全套教学资源,支持多种方式与作者实时交流。

【京东购书链接】 扫描查看或购买

03

精彩推荐

  • 考研计算机 │ 《计算机组成原理》典型真题详解!

  • 机器学习案例 | 通过EBG学习概念cup

  • Oracle数据库 | Oracle并发与一致性(附实例)

  • Oracle数据库 | Oracle备份实例

  • CCF CSP-J/S第一轮认证知识点:计算机系统结构基本常识

  • 机器学习案例 | 泰坦尼克号生存预测——逻辑回归

  • CCF CSP-J/S第一轮认证知识点:计算机语言与算法

  • Oracle数据库系统管理与运维 | 项目案例

  • Oracle数据库系统管理与运维 | 数据库进程

  • Python课程思政 | “七一讲话”词云图

  • Oracle数据库系统管理与运维 | Oracle体系结构

  • Oracle数据库系统的发展史

  • 人工智能 | 知识图谱案例解析

主营产品:中空玻璃设备,玻璃陶瓷加工设备,燃煤锅炉,燃气锅炉,电热锅炉,锅炉熔炉及配件,干燥设备,设备及组件