关于使用 socket 构造 icmp 包报错 Permission denied 的问题 - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
bulay

关于使用 socket 构造 icmp 包报错 Permission denied 的问题

  •  
  •   bulay Apr 17, 2023 2260 views
    This topic created in 1147 days ago, the information mentioned may be changed or developed.

    背景: 接手别人的项目,添加子网时对子网所有地址进行 ping 测试


    构造子网地址和广播地址 socket 连接时,会报PermissionError: [Errno 13] Permission denied的错误.

    关于为什么要上子网地址和广播地址我也不清楚(代码专门拼接了这两个地址,这两者和对子网所有地址进行 ping 不是重复了吗)

    所有,子网地址和广播地址和应该怎么构造 icmp 的包和建立 socket 连接?

    Supplement 1    Apr 17, 2023

    ping普通地址无权限问题

    附一下代码

    def init_icmp_packet(sequence): # 把字节打包成二进制数据 data_type = 8 # ICMP Echo Request data_code = 0 # must be zero data_checksum = 0 # "...with value 0 substituted for this field..." data_ID = process_id # Identifier payload = b'abcdefghijklmnopqrstuvwabcdefghi' # data icmp_packet = struct.pack('>BBHHH32s', data_type, data_code, data_checksum, data_ID, sequence, payload) icmp_checksum = check_sum(icmp_packet) # 获取校验和 icmp_packet = struct.pack('>BBHHH32s', data_type, data_code, icmp_checksum, data_ID, sequence, payload) return icmp_packet def init_raw_socket(ip_addr, icmp_packet): raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1) # 服务端设置非阻塞 # raw_socket.setblocking(False) raw_socket.sendto(icmp_packet, (ip_addr, 1)) # 报错行 return raw_socket 
    Supplement 2    Apr 17, 2023

    问题已解决.附上解决后的代码:

    def init_raw_socket(ip_addr, icmp_packet): raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1) raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # 解决问题的代码,允许发送广播数据 # 服务端设置非阻塞 # raw_socket.setblocking(False) raw_socket.sendto(icmp_packet, (ip_addr, 1)) return raw_socket 

    关于setsockopt方法的用法及参数的含义参考这里

    11 replies    2023-04-18 17:10:49 +08:00
    keakon
        1
    keakon  
       Apr 17, 2023
    socket.SOCK_RAW 需要 root 权限,你加个 sudo 试试
    yougg
        2
    yougg  
       Apr 17, 2023
    artnowben
        3
    artnowben  
       Apr 17, 2023
    构建 icmp 报文请参考一下 测试仪项目 dperf https://github.com/baidu/dperf
    具体代码:
    1. raw socket 参考 https://github.com/pengjianzhang/tcping/blob/main/tcping.c
    2. icmp 封装参考 https://github.com/baidu/dperf/blob/main/src/icmp.c
    julyclyde
        4
    julyclyde  
       Apr 17, 2023
    建议还是先学学网络的基本原理,搞明白掩码到底是做啥用的
    再处理权限问题
    shxxy
        5
    shxxy  
       Apr 17, 2023
    楼上提到需要 root 权限,其实从内核 2.2 开始就可以单独设置这些权限。你可以用用 sudo setcap cap_net_raw+p PROGRAM 赋予你程序 socket_row 的能力
    julyclyde
        6
    julyclyde  
       Apr 17, 2023
    @qwq11 求教那个+p 是啥意思
    之前我看 man 的时候没明白
    shxxy
        7
    shxxy  
       Apr 17, 2023
    bulay
        8
    bulay  
    OP
       Apr 17, 2023
    @keakon
    @yougg
    @artnowben
    @julyclyde 感谢各位给出的建议,我按照各位的建议使用 root 权限启动,或者为程序添加 root 权限,问题并没有解决.
    我可能描述的不清楚,该程序 ping 普通地址是没问题的,不存在权限问题,但是 ping 子网地址和子网广播地址才会报权限问题.

    @qwq11 谢谢提醒,掩码什么作用我知道
    qbqbqbqb
        9
    qbqbqbqb  
       Apr 17, 2023
    子网地址是不能用作目标地址的

    广播地址可以,但是如果要用广播地址作为目标地址的话,需要用 setsockopt 给 socket 加上 SO_BROADCAST 属性
    bulay
        10
    bulay  
    OP
       Apr 17, 2023
    @qbqbqbqb 感谢大佬!就是这个问题. 另外,子网地址确实可以 ping 通.用 linux 的命令`ping -b`也是可以用子网地址作为目标地址的
    julyclyde
        11
    julyclyde  
       Apr 18, 2023
    你这个功能是新加的??
    我还以为接手的时候已经有这个了
    About     Help     Advertise     Blog     API     FAQ     Solana     3161 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 14:00 PVG 22:00 LAX 07:00 JFK 10:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86