办个网站卖什么好处,微信公众号登录入口在哪里,沈阳网站制作哪家好,单页面网站 wordpressScrapy IP()类 编程指南#xff08;基础#xff09;
IP简介
工欲善其事#xff0c;必先利其器#xff0c;在聊Scapy IP类时#xff0c;我们先要了解IP是什么。 IP指的是Internet Protocol#xff08;互联网协议#xff09;的数据包。Internet Protocol是互联网上用于在…Scrapy IP()类 编程指南基础
IP简介
工欲善其事必先利其器在聊Scapy IP类时我们先要了解IP是什么。 IP指的是Internet Protocol互联网协议的数据包。Internet Protocol是互联网上用于在网络中传输数据的一种协议。在TCP/IP协议族中IP层负责数据包的路由和寻址确保数据能够在网络中正确传递。
IP协议定义了一种在网络中唯一标识设备主机或路由器的方式并提供了一种将数据分割成小的数据包进行传输的机制。每个数据包都包含源和目标设备的IP地址以便路由器能够正确地将数据包从源传输到目标。
IP协议又分为IPv4、IPv6两个版本IPv6可以理解为IPv4的升级版但它们又有所不同它的出现是为了解决IPv4地址即将耗尽的问题日后也会详细说明IPv6今天我们主要的对象就是IPv4。
在IPv4协议中IP地址主要被分为五个类别通常称为IP地址的分类。这些分类是基于地址的网络部分的位数以及主机部分的位数。这五个主要的IP地址分类是A类、B类、C类、D类和E类。
类A地址 范围1.0.0.0 到 126.255.255.255特点第一个字节8位用于网络部分剩余的三个字节24位用于主机部分。可用网络2^7 - 2 126因为0和127保留作为特殊用途。 类B地址 范围128.0.0.0 到 191.255.255.255特点前两个字节16位用于网络部分后两个字节16位用于主机部分。可用网络2^14 - 2 16,382 类C地址 范围192.0.0.0 到 223.255.255.255特点前三个字节24位用于网络部分最后一个字节8位用于主机部分。可用网络2^21 - 2 2,097,150 类D地址 范围224.0.0.0 到 239.255.255.255特点用于多播Multicast通信不分配给单个主机或网络。 类E地址 范围240.0.0.0 到 255.255.255.255特点保留作为将来使用的实验和开发。
IP报文头
在Scapy中IP报文头与IP()类直接相关。IP()类用于创建和处理IPv4报文头它是Scapy中用于构建IPv4数据包的类。使用IP()类我们可以轻松地定义IPv4数据包的各种属性如源地址、目标地址、协议类型等。 版本Version
占4位。指定IP协议的版本IPv4的版本号为4。
头部长度IHL - Internet Header Length
占4位。指定IPv4头部的长度以32位字4字节为单位。由于IPv4头部中最少有20字节因此该字段的值至少为5表示20字节。
服务类型Type of Service - TOS
占8位。用于指定服务质量包括优先级、延迟、吞吐量和可靠性。
总长度Total Length
占16位。指定整个IPv4数据包的长度包括头部和数据。最大长度为65,535字节。
标识Identification
占16位。用于将相关的数据包片段组合成完整的数据包。
标志位Flags
占3位。包含“不分片Don’t Fragment”和“更多片段More Fragments”标志。
片偏移Fragment Offset
占13位。指定数据包片段在原始数据包中的偏移量。
生存时间Time to Live - TTL
占8位。限制数据包在网络中的生存时间每经过一个路由器该字段值减一。当TTL为0时数据包被丢弃。
协议Protocol
占8位。指定上层协议例如TCP6、UDP17、ICMP1等。
头部校验和Header Checksum
占16位。
用于检测IPv4头部的错误主要是检测在传输过程中头部信息是否损坏。
源地址Source Address
占32位。
指定数据包的源IP地址。
目标地址Destination Address
占32位。
指定数据包的目标IP地址。
选项Options
可选字段用于提供一些额外的信息。通常很少被使用因为IPv4头部本身已经包含了足够的信息。
Scapy IP()使用
而在Scapy中IP报文头与IP()类直接相关。IP()类用于创建和处理IPv4报文头它是Scapy中用于构建IPv4数据包的类。
以下是IP()类的一些常用属性
src指定源IP地址。
#两种方式指定
IP(srcx.x.x.x)#构造函数指定ip_packet IP() #构造空参数
ip_packet.src x.x.x.x #成员属性指定dst指定目标IP地址
#两种方式指定
IP(dstx.x.x.x)#构造函数指定ip_packet IP() #构造空参数
ip_packet.dst x.x.x.x #成员属性指定proto指定上层协议例如TCP、UDP等。
#两种方式指定
IP(protoTCP)#构造函数指定ip_packet IP() #构造空参数
ip_packet.proto TCP #成员属性指定ttl设置Time-to-Live值。
#两种方式指定
IP(ttl5)#构造函数指定ip_packet IP() #构造空参数
ip_packet.ttl 5 #成员属性指定tos设置Type of Service值。
#两种方式指定
IP(tos0b10101010)#构造函数指定ip_packet IP() #构造空参数
ip_packet.tos 0b10101010 #成员属性指定ihl设置IP报文头长度通常不需要手动设置。
#两种方式指定
IP(ihl5)#构造函数指定ip_packet IP() #构造空参数
ip_packet.ihl 20 #成员属性指定flags设置IP标志位。
#两种方式指定
IP(flagsMF)#构造函数指定ip_packet IP() #构造空参数
ip_packet.src MF#成员属性指定options设置IP报文头的选项字段。
#两种方式指定
IP(options[(1, 1, b\x01)])#构造函数指定ip_packet IP() #构造空参数
ip_packet.src [(1, 1, b\x01)] #成员属性指定Scapy IP() 实战使用
IP有这么多头部字节我们用的最多也就是src源地址和dst目的地址它们决定着我们的数据包由谁发起又要发送到哪里。现在我们使用Scapy来构造一个IP头。
from scapy.layers.inet import IP, ICMP
from scapy.sendrecv import sr1# 创建一个包含IP和ICMP协议的数据包也就是ping包
ip_packet IP(dst192.168.30.55) / ICMP()# 发送数据包并等待响应
response sr1(ip_packet)# 打印响应信息
response.show() 如果我将src源IP地址修改在发送,再来查看结果
from scapy.layers.inet import IP, ICMP
from scapy.sendrecv import sr1ip_packet.src 123.123.222.111send_ip sr1(ip_packet) 这里可能有人就有疑问了源IP我明明已经修改为123.123.222.111,为什么还会有响应包这里就牵扯到交换机的原理以及ARP的知识了。
交换机是一个二层设备为什么说它是二层设备呢因为交换机的基础功能就是处理OSI网络模型中的第二层数据链路层在数据链路层来说它更关心是MAC物理地址的交换它在工作过程中维护一张关键的表格。
MAC地址表
它是一个用于存储设备MAC地址与物理端口对应关系的表格。当交换机收到一个帧数据包时它会查看帧中的目标MAC地址并将这个MAC地址与接收到帧的端口进行关联更新MAC地址表。这样交换机就知道将数据帧发送到哪个端口以便正确地转发数据。
MAC地址就是设备的独特标签IP地址是用于在网络中找该设备的逻辑地址而怎么通过设备的逻辑地址去找到这台设备呢这就要通过ARP协议来解决了。ARP协议可以帮助你根据一个逻辑地址找到具体设备的物理设备以便进行直接通信。在主机系统一般都会存在一个ARP表作用如下
ARP表
它用于存储IP地址与对应的MAC地址之间的映射关系。当设备需要与网络中的其他设备通信时它首先会查看自己的ARP表。如果在ARP表中找不到目标设备的IP地址对应的MAC地址设备就会发起ARP请求请求网络中其他设备告知它目标设备的MAC地址。
因为我们没有构造二层Ether包所以这个数据包的mac地址会以默认接口的MAC地址认作缺省值默认属性进行发送当这个包经过交换机时交换机会读取该数据包的目的MAC信息发现目的MAC信息全为F就为广播包他就会向所有端口发送ARP广播报文询问谁是192.168.30.55找到相应的接口进行二层转发当数据包到达目的后目标主机会先检查数据包的源MAC地址并在本机的ARP表中查找对应的MAC与IP绑定关系完成接收后目标主机会根据请求包中的源IP、源MAC构造一个响应包发给源主机
这就解释了为什么我随便设置的Ip还能得到响应报文的问题。 最后给出一个由ScapyIP()类编写的超级Ping工具
# codingutf-8Author: 迪奥布斯
create time : 2024/1/27
超级pingimport re
import timefrom scapy.config import conf
from scapy.layers.inet import IP, ICMP
from scapy.sendrecv import sr, sr1ips []def order_ip(ip):ip_source, ip_num ip.rsplit(., 1)start, end ip_num.split(-)if start end:tmp startstart endend tmpip_list [ip_source . str(num) for num in range(int(start), int(end))]return ip_listdef num_ip(ip):b ip.split(,)a set(b)return list(a)def ip_run(ip):return [ip]def check_ip_format(ip):patterns {ipv4: (re.compile(r^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$), ip_run),ip_range: (re.compile(r^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}-(25[1-5]|2[0-4]\d|1\d\d|[1-9]?\d)$),order_ip),multiple_ips: (re.compile(r(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}-(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)|(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})(?:,(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}-(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)|(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))*$), num_ip),}matched Falsefor pattern_type, (pattern, fun) in patterns.items():if pattern.match(ip):ips.append(fun(ip))matched Truebreakif not matched:print(输入的IP无效请重新输入)exit()def send_icmp(ip, interface):# 构建 ICMP 请求包ping_pkt IP(dstip) / ICMP(id1000)try:# 发送 ICMP 请求并等待响应 ntime.sleep(0.5)start_time time.time()ip_response sr1(ping_pkt, timeout1, verboseFalse, ifaceinterface)end_time time.time()if ip_response is not None:ttl_sys {255: Ulinx系统(交换机、路由器),128: Windos系统,64: MacOS/Linux}for ttl_num, sys_name in ttl_sys.items():if ip_response[IP].ttl ttl_num:sys sys_nameprint(f{ip_response[IP].src} --- 可达{ip_response[IP].ttl} --- 跳数它是{sys}花费 {(end_time - start_time) * 1000:0.1f} 毫秒)else:print(f{ip} --- 无响应)except Exception as e:print(f发生错误: {e})exit()def start_main(ip, num, interface):check_ip_format(ip)if len(ips[0]) 2:a num * len(ips[0])b a - numwhile not a b:send_icmp(ips[0][0], interface)a - 1elif len(ips[0]) 2:a num * len(ips[0])for ip_num in ips[0]:b a - numwhile not a b:send_icmp(ip_num, interface)a - 1def tiShi():print(* * 80)print(目前可以实现功能多IP范围ping主机判断主机系统)print(IP输入格式为)print(单个IP192.168.0.1)print(范围IP:192.168.0.1-255)print(多个IP192.168.0.1192.168.0.2)print(ping的次数默认为4次)print(指定网卡接口不指定为默认网卡)print(指定接口为网卡名称,例如windows的网卡名称“以太网”或“以太网1linux的网卡名”eth0“或”ens0“)print(* * 80)def user_input():tiShi()while True:target_ip input(请输入你要ping的ip:)target_num input(请输入要ping的次数:).strip()if not target_num or not target_num.isdigit():ai 4print(f输入为空设置默认值为: {ai}, end)else:try:ai int(target_num)print(f转换后的整数值为: {ai}, end)except ValueError:print(输入无效无法转换为整数。, end)print(target_num)target_interface input(请输入网卡名称:)if target_interface :target_interface conf.ifaceprint(输入为空为默认网卡:, conf.iface.name)start_main(target_ip, ai, target_interface)if __name__ __main__:user_input()