首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

不使用原始套接字发送udp请求后,如何从端口读取ICMP响应

在不使用原始套接字发送UDP请求后,从端口读取ICMP响应会遇到一些挑战,因为ICMP协议通常用于网络诊断和错误报告,而不是用于常规的数据传输。ICMP响应通常是由网络设备(如路由器)在检测到某些网络问题时生成的,例如目标不可达、超时等。

基础概念

ICMP(Internet Control Message Protocol):是一种网络层协议,用于发送错误消息和操作信息。它通常用于诊断网络连接问题。

原始套接字:允许应用程序发送和接收原始IP数据包,包括ICMP包。使用原始套接字可以直接处理ICMP协议。

为什么不能直接从端口读取ICMP响应

  1. 协议层不同:UDP是传输层协议,而ICMP是网络层协议。操作系统通常不会将ICMP响应转发到发送UDP请求的应用程序端口。
  2. 防火墙和安全策略:许多防火墙和安全策略会阻止ICMP响应到达非特权端口,以防止潜在的安全风险。

解决方案

使用原始套接字

虽然题目要求不使用原始套接字,但为了完整性,这里简要说明如何使用原始套接字来处理ICMP响应:

代码语言:txt
复制
import socket
import struct
import time

ICMP_ECHO_REQUEST = 8

def checksum(source_string):
    sum = 0
    count_to = (len(source_string) // 2) * 2
    count = 0

    while count < count_to:
        this_val = source_string[count + 1] * 256 + source_string[count]
        sum = sum + this_val
        sum = sum & 0xffffffff
        count = count + 2

    if count_to < len(source_string):
        sum = sum + source_string[len(source_string) - 1]
        sum = sum & 0xffffffff

    sum = (sum >> 16) + (sum & 0xffff)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xffff
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer

def send_one_ping(sock, dest_addr, id):
    packet = struct.pack('!BBHHH', ICMP_ECHO_REQUEST, 0, 0, id, 1)
    checksum_value = checksum(packet)
    packet = struct.pack('!BBHHH', ICMP_ECHO_REQUEST, 0, checksum_value, id, 1)
    sock.sendto(packet, (dest_addr, 1))

def receive_one_ping(sock, id, timeout):
    time_left = timeout
    while True:
        start_time = time.time()
        readable = select.select([sock], [], [], time_left)
        time_spent = time.time() - start_time
        if not readable[0]:  # Timeout
            return None

        time_received = time.time()
        recv_packet, addr = sock.recvfrom(1024)
        icmp_header = recv_packet[20:28]
        type, code, checksum, packet_id, sequence = struct.unpack('!BBHHH', icmp_header)
        if packet_id == id:
            return time_received - start_time

        time_left -= time_spent
        if time_left <= 0:
            return None

def do_one(dest_addr, timeout):
    icmp = socket.getprotobyname("icmp")
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    except PermissionError:
        print("Permission denied. You need to run this script as root.")
        return

    my_id = os.getpid() & 0xFFFF
    send_one_ping(sock, dest_addr, my_id)
    delay = receive_one_ping(sock, my_id, timeout)
    sock.close()
    return delay

# Example usage
import os
import select

dest_addr = "8.8.8.8"  # Google's public DNS server
timeout = 1

delay = do_one(dest_addr, timeout)
if delay is not None:
    print(f"Reply from {dest_addr}: time={delay:.3f}ms")
else:
    print("Request timed out.")

使用现有的库

如果不允许使用原始套接字,可以考虑使用现有的库,如ping3,它封装了ICMP请求的处理:

代码语言:txt
复制
from ping3 import ping, verbose_ping

# Simple ping
response_time = ping("8.8.8.8")
print(f"Response time: {response_time} ms")

# Verbose ping with more details
verbose_ping("8.8.8.8", count=4)

应用场景

  • 网络诊断:检查网络连接是否正常。
  • 延迟测量:测量数据包从发送端到接收端的往返时间。

注意事项

  • 权限问题:在某些操作系统上,使用原始套接字需要root权限。
  • 安全性:处理ICMP包时要小心,避免引入安全漏洞。

通过上述方法,可以在不使用原始套接字的情况下,有效地处理ICMP响应。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

《Python黑帽子》:原始套接字和流量嗅探

在本文中,我们将使用原始套接字来访问诸如IP 和ICMP 头等底层的网络信息。在下面的例子中,我们只对IP 层和更高层感兴趣,因此我们不会去解码以太网头中的信息。...当你发送一个UDP 数据包到主机的某个关闭的UDP 端口上时,目标主机通常会返回一个ICMP 包指示目标端口不可达。...这样的ICMP 信息意味着目标主机是存活的,因为我们可以假设如果没有接收到发送的UDP 数据的任何响应,目标主机应该不存在。...挑选一个不太可能被使用的UDP 端口来确保这种方式的有效性是必要的,为了达到最大范围的覆盖度,我们可以查探多个端口以避免正好将数据发送到活动的UDP 服务上。 为什么使用UDP 呢?...在第一个例子中,我们只需设置原始套接字嗅探器,读取一个数据包,然后退出即可。 首先,我们通过构建套接字对象对网络接口上的数据包嗅探进行必要的参数设置①。

1.3K20

Go 语言网络编程系列(一)—— Socket 编程入门:Dial 函数及其使用

从服务端来看,代码编写分为以下几个步骤: 建立并绑定 Socket:首先服务端使用 socket() 函数建立网络套接字,然后使用 bind() 函数为套接字绑定指定的 IP 和端口; 监听请求:接下来...,服务端使用 listen() 函数监听客户端对绑定 IP 和端口的请求; 接收连接:如果有请求过来,并通过三次握手成功建立连接,则使用 accept() 函数接收并处理该连接; 处理请求与发送响应:服务端通过...read() 函数从上述已建立连接读取客户端发送的请求数据,经过处理后再通过 write() 函数将响应数据发送给客户端 从客户端来看,代码编写分为以下几个步骤: 建立 Socket:客户端同样使用...socket()函数建立网络套接字; 建立连接:建立连接:然后调用 connect() 函数传入 IP 和端口号建立与指定服务端网络程序的连接; 发送请求与接收响应:连接建立成功后,客户端就可以通过 write...() 函数向服务端发送数据,并使用 read() 函数从服务端接收响应。

7.5K30
  • 八股文!!

    Fragment offset:某个分片位于原始报文中的偏移,重组报文时使用 TTL:分片生命周期 Protocol:上层协议标识(TCP/UDP/ICMP等) 校验和:针对IP首部的累加校验和 源IP...IP分片:链路不同,MTU也不同,IP会将数据包以路径MTU分片后发包,到达目的IP后重组,分片增加了出现问题的几率 4 ICMP协议 ICMP协议报文头格式 ICMP协议的作用 ICMP协议的使用...ICMP的应用—ping程序 Ping程序提供网络层到某台主机的路由是否可达 发送方组ICMP回显请求报文,标识符字段填写进程ID,序号字段从0开始,发送回显请求报文时序号递增,并在选项数据中保存发送的时间...traceroute利用udp模块组成udp数据包,并将目的端口号设置为不可能的端口号,依次将IP数据报包头的ttl字段从1递增,traceroute依据返回的ICMP报文是端口不可达或请求超时来判断是否结束...另一端write该套接字时将会被响应一个rst报文,再次写入时触发sigpipe信号(信号默认动作是结束进程,即使捕捉该异常,write也会得到sigpipe错误)由此也可得知对端状态变更 如果另一端不主动写入

    1K11

    你说UDP是无连接的,那么UDP connect 有啥用?

    如果我们不进行 connect 操作,建立(UDP 套接字——目的地址 + 端口)之间的映射关系,操作系统内核就没有办法把 ICMP 不可达的信息和 UDP 套接字进行关联,也就没有办法将 ICMP 信息通知给应用程序...如果我们进行了 connect 操作,帮助操作系统内核从容建立了(UDP 套接字——目的地址 + 端口)之间的映射关系,当收到一个 ICMP 不可达报文时,操作系统内核可以从映射表中找出是哪个 UDP...套接字;14-18 行创建 IPv4 地址,绑定到 ANY 和对应端口;20 行绑定 UDP 套接字和 IPv4 地址;27 行为该程序注册一个信号处理函数,以响应 Ctrl+C 信号量操作;32-37...套接字;12-16 行创建了一个 IPv4 地址,绑定到指定端口和 IP;20-22 行调用 connect 将 UDP 套接字和 IPv4 地址进行了“绑定”;27-46 行是程序的主体,读取标准输入字符串后...因为如果不使用 connect 方式,每次发送报文都会需要这样的过程:连接套接字→发送报文→断开套接字→连接套接字→发送报文→断开套接字 →………而如果使用 connect 方式,就会变成下面这样:连接套接字

    7020

    CSAPP 网络编程 笔记

    典型:多个描述字多路复用,比如交互式输入和网络套接字。 出现粘包如何处理? UDP与原始套接口 UDP协议中发送数据大于缓冲区大小,系统如何处理,说明理由。...UDP采用循环服务器的工作方式,它仅有的单个套接口用于接收所有到达的数据报,并发回所有的响应,UDP套接口有一个接收缓冲区用于存放到来的数据报。...如何避免UDP协议下客户端将非服务端发送的应答,误认为是服务器应答? 通过 recvfrom 里返回的 IP 与端口区分 使用 connect 简述ping程序的功能与实现原理。...利用原始套接口发送 icmp 回射请求,等待对方的应答,应答中包含请求的标识符、序列号、时间戳 简述traceroute程序的功能与实现原理。...首先发送 ttl 为1的 udp 数据报,然后逐次递增ttl,确定下一跳的路由。 当 icmp 报文到达目标主机时,目标主机返送一个 icmp 错误,显示端口不可达。

    58030

    TCPIP协议族

    其关键问题是确定数据包从源端到目的端如何选择路由。...在TCP/IP协议栈中,源端口号和目的端口号分别与源IP地址和目的IP地址组成套接字(socket),唯一的确定一条TCP连接。...套接字(socket)分为源套接字和目的套接字: 源套接字:源端口号+源IP地址; 目的套接字:目的端口号+目的IP地址; 源套接字和目的套接字用于唯一的确定一条TCP连接。...目的主机B收到请求报文后,将其中的主机A的IP地址与MAC地址的映射存到自己的ARP高速缓存中,并把自己的IP地址到MAC地址的映射作为响应发回主机A。...ICMP还定义了源抑制(source quench)报文。当路由器的缓冲区满后,送入的报文被丢弃,此时路由器向发送报文的主机发送源抑制报文,要求降低发送速率。

    80920

    网络嗅探器

    原理:   通常的套接字程序只能响应与自己MAC地址相匹配的 或者是 广播形式发出的数据帧,对于其他形式的数据帧网络接口采取的动作是直接丢弃   为了使网卡接收所有经过他的封包,要将其设置成混杂模式,通过原始套接字来实现...设置混杂模式:   创建原始套接字,   绑定到一个明确的本地地址,   向套接字发送SIO_RCVALL控制命令,   接收所有的IP包 代码实现步骤:   1 创建原始套接字   2 绑定到明确地址...主程序代码如下: void main() { //创建原始套接字 SOCKET sRaw = socket(AF_INET,SOCK_RAW,IPPROTO_IP); //获取本地...: break; case IPPROTO_ICMP: break; } } 解析TCP头代码如下:取出端口号,输出 void DecodeTCPPacket...: break; case IPPROTO_ICMP: break; } } void main() { // 创建原始套节字 SOCKET

    2K100

    应用层

    传输的步骤(特点): UDP套接字指定了应用所在的一个端节点(end point) 在发送数据报时,采用创建好的本地套接字(标示 ID),就不必在发送每个报文中指明自己所采用的 ip和port...但是在发送报文时,必须要指定对方的ip和udp port(另外一个段节点) 套接字(Socket) 进程向套接字发送报文或从套接字接收报文 套接字 门户 发送进程将报文推出门户,发送进程依赖于传输层设施在另外一侧的...方式的大致模式 广告公司从站点获得信息 Web缓存(代理服务器) 目标:不访问原始服务器,就满足客户的请求 操作: 用户设置浏览器: 通 过缓存访问Web 浏览器将所有的HTTP 请求发给缓存...允许用户用目录来组织 报文 允许用户读取报文组件 IMAP在会话过程中保留 用户状态: 目录名、报文ID与目录名 之间映射 DNS Email DNS P2P应用 CDN TCP套接字...(Socket)编程 UDP套接字编程

    10310

    原始套接字和流量嗅探

    ---- 原始套接字和流量嗅探 前言 《Python黑帽子:黑客与渗透测试编程之道》的读书笔记,会包括书中源码,并自己将其中一些改写成Python3版本。...书是比较老了,anyway,还是本很好的书 本篇是第3章原始套接字和流量嗅探 1、Windows和Linux上的包嗅探 为了多平台使用,先创建SOCKET,再判断平台 windows允许嗅探所有协议 linux...coding:utf8 -*- import socket import os # 监听主机,即监听那个网络接口,下面的为我的kali的ip host = "10.10.10.145" # 创建原始套接字...sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) #raw的中文是生的意思,大概就是原始套接字的意思吧...层 如果要主机发现,关闭的端口会对UDP包返回一个ICMP端口不可达的响应,以此判断主机是否存活,所以需要解码ICMP #!

    1.8K20

    计网之网络应用

    每个字段如何描述 字段的语义(semantics) 字段中信息的含义 规则(rules) 进程何时发送/响应信息 进程如何发送/响应信息 网络应用对传输服务的需求 数据丢失(data...,用于数据缓存和请求响应代理 用户向设定浏览器通过缓存进行Web访问 浏览器向缓存/代理服务器发送所有的HTTP请求 若请求对象在代理服务器缓存中,缓存返回对象 否则,缓存服务器向原始服务器发送...SOCK_DGRAM , 数据报套接字 Data GRAM ,面向UDP SOCK_RAW , 原始套接字 面向网络层IP/ICMP/IGMP......,saddrlen); recv函数从TCP连接的另一端接收数据,或从调用了connect函数的UDP客户端套接字接收服务器发来的数据 recvform函数用于从UDP服务器端套接字与未调用connect...IP和端口号 listen 设置TCP套接字为监听模式,同时设置请求队列大小 accept 接收/提取一个连接请求,创建新套接字(建立连接通道) send 发送数据(TCP套接字/连接模式的C端UDP

    31831

    Python socket 模块的使用

    先看一段创建服务器端的代码 import socket #定义服务器端启动后要绑定的ip和端口 ip_port = ('127.0.0.1',9999) # 创建socket对象并指定连接的网络类型和传输协议...  socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过...socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。...其中data是包含接收数据的字符串,address是发送数据的套接字地址。 sk.send(string[,flag])   将string中的数据发送到连接的套接字。...因为udp协议本身就比tcp协议的步骤要少(不需要三次握手),所以如果我们选择使用udp协议来写程序步骤也会简化不少 import socket #指定要绑定的ip和端口 ip_port = ('127.0.0.1

    1.2K20

    python学习----------so

    服务器根据地址类型,socket类型,协议创建socket 服务器为socket绑定ip和端口 服务器监听端口号请求,随时准备客户端发来的连接请求 客户端创建socket 客户端打开socket,根据服务器...  socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过...socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。...其中data是包含接收数据的字符串,address是发送数据的套接字地址。 sk.send(string[,flag])   将string中的数据发送到连接的套接字。...该函数主要用于UDP协议。 sk.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。

    1K10

    SeedLab——Packet Sniffing and Spoofing Lab

    通常情况下,应用程序使用高级套接字(如TCP套接字或UDP套接字)进行网络通信,这些套接字封装了底层的网络协议细节,提供了简化的接口供应用程序使用。...然而,使用原始套接字,应用程序可以绕过这些封装,直接访问和操作网络协议栈中的原始数据。...当使用原始套接字发送IP数据包时,操作系统会负责处理IP头部的构建和校验和计算。我们只需要构造IP数据包的内容,将其传递给操作系统,并通过原始套接字发送即可。...Q F 为什么时原始套接字需要root权限? 通过原始套接字,可以直接访问和操作网络层的数据包,包括构造和发送自定义的网络数据包。所有会存在潜在的安全风险,因此必须要root权限。...如果没有root权限,在创建原始套接字过程就会失败了。 Task 2.3: Sniff and then Spoof 编写一个程序能够响应ICMP ECHO,伪造ICMP Reply。

    99010

    网络协议:一文搞懂Socket套接字

    2、数据报套接字(SOCK_DGRAM) 提供了一种无连接的服务,通信双方不需要建立任何显式连接,数据可以发送到指定的套接字,并且可以从指定的套接字接收数据。...数据报套接字使用UDP进行数据的传输。由于数据包套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。...3、原始套接字(SOCK_RAW) 与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的 IP 数据包,而流套接字只能读取 TCP 的数据,数据报套接字只能读取...1、Demo 服务端 服务端的 Socket Demo 流程思路: 创建 ServerSocket 对象,绑定监听端口; 通过 accept() 方法监听客户端请求; 链接建立后,通过输入流读取客户端发送的请求信息...; 连接建立后,通过输出流向服务器端发送请求信息; 通过输入流获取服务器响应的信息; 关闭相关资源。

    2.7K21

    python资源库——socket网络编

    sockket简介 socekt又称为‘套接字’,用于描述IP和地址端口,是一个通信链路的句柄,应用程序通常通过套接字向网络发出请求或者应答网络请求。...socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过...socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。...通常是一个元组(ipaddr,port) sk.fileno() 套接字的文件描述符 socket编程思路 TCP服务端 创建套接字,绑定套接字到本地IP与端口 开始监听连接 进入循环,不断接受客户端的连接请求...然后接收传来的数据,并发送给对方数据 传输完毕后,关闭套接字 TCP客户端 创建套接字,连接远端地址 连接后发送数据和接收数据 传输完毕后,关闭套接字 server端: import socket ip_port

    90110

    Golang中用到的的Websocket库

    这些套接字提供双向、可靠、有序和不重复的数据流,没有记录边界。 原始套接字(或原始 IP 套接字)通常在路由器和其他网络设备中可用。...套接字通信 每个网络套接字都由地址标识,地址是传输协议、IP 地址和端口号的三元组。主机之间的通信主要有两种协议:TCP 和 UDP。...建立连接后,客户端和服务器开始交换数据:客户端通过 TCPConn 对象向服务器发送请求,服务器解析请求并发送响应,TCPConn 对象接收来自服务器的响应。...= nil { // handle error } 连接到 UDP 套接字 与 TCP 套接字相反,使用 UDP 套接字,客户端只向服务器发送数据报。...将此用作Sec-WebSocket-Accept响应标头的值。 传输数据帧 握手成功完成后,应用程序可以从客户端读取数据和向客户端写入数据。

    2K20

    17 . Go之网络编程

    Socket又称“套接字”,应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机的进程间可以通讯 类似于操作系统将复杂丑陋的控制计算机硬件的操作封装成统一简单的接口,只需要使用者学会如何操作系统就可以简单快速的操作计算机硬件...建立并绑定 Socket:首先服务端使用 socket() 函数建立网络套接字,然后使用 bind() 函数为套接字绑定指定的 IP 和端口; // 2....处理请求与发送响应:服务端通过 read() 函数从上述已建立连接读取客户端发送的请求数据,经过处理后再通过 write() 函数将响应数据发送给客户端。...从客户端来看,代码编写分为以下几个步骤 // 1 . 建立 Socket:客户端同样使用 socket()函数建立网络套接字; // 2 ....发送请求与接收响应:连接建立成功后,客户端就可以通过 write() 函数向服务端发送数据,并使用 read() 函数从服务端接收响应。

    1K50

    【在Linux世界中追寻伟大的One Piece】网络命令|验证UDP

    当您执行ping命令时,它会向指定的主机发送一系列的ICMP回显请求(echo request)消息,并等待接收ICMP回显响应(echo reply)消息。...SOCKET:表示一个套接字描述符,用于在网络中唯一标识一个套接字。 sockaddr_in:IPv4地址结构体,用于存储IP地址和端口号等信息。 socket():创建一个新的套接字。...bind():将套接字与本地地址绑定。 listen():将套接字设置为监听模式,等待客户端的连接请求。...accept():接受客户端的连接请求,并返回一个新的套接字描述符,用于与客户端 进行通信。...成功调用该函数后,Winsock库的状态会被初始化,应用程序就可以使用 Winsock提供的一系列套接字服务,如地址家族识别、地址转换、名字查询和连接控制等。

    9210

    Socket套接字(网络编程万字总结-附代码)

    2.2 数据报套接字:使用传输层UDP协议 UDP,即User Datagram Protocol(用户数据报协议),传输层协议。...2.3 原始套接字 原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。...三、UDP数据报套接字编程 对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。...3.1 Java数据报套接字通信模型 java中使用UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用 DatagramPacket 作为发送或接收的UDP数据报。...TCP连接,所以是给接收方使用 输出流:同理,所以是给发送方使用 4.4 TCP中的长短连接 TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接: 短连接:每次接收到数据并返回响应后

    77220

    一文总结计算机网络

    工作流程: 从网卡读取自己的MAC地址—>发送RARP请求的广播数据包—>RARP服务器收到请求,为其分配IP地址,并将RARP回应发送给该机器—>该机器收到IP地址后,使用IP地址进行通信 ICMP...使用场景 1、需要频繁交互的场景使用长连接,如即时通信工具(微信/QQ,QQ也有UDP),相反则使用短连接,比如普通的web网站,只有当浏览器发起请求时才会建立连接,服务器返回响应后,连接立即断开。...糊涂窗口综合证:TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报为40字节的的话)...为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。...*连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发 给客户端,一旦客户端确认了此描述,双方就正式建立连接。

    64720
    领券