python - 在发送多播 IPv6 时使用 SOCK_STREAM 或 SOCK_RAW

标签 python sockets networking ipv6 multicast

大家好,我有个问题,我似乎找不到关于在多播上发送原始数据包的文档,所有示例、解决方案和文档都以 UDP 用法为中心。

我以此为例:http://svn.python.org/projects/stackless/trunk/Demo/sockets/mcast.py

优化代码时,我只关心发送部分,如下所示:

import time
import struct
import socket
import sys

MYPORT = 8123
MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
MYTTL = 1 # Increase to reach other networks
group = MYGROUP_6

if "-s" in sys.argv[1:]:
    sender(group)
addrinfo = socket.getaddrinfo(group, None)[0]

s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)

# Set Time-to-live (optional)
ttl_bin = struct.pack('@i', MYTTL)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)

while True:
    data = repr(time.time())
    s.sendto(data + '\0', (addrinfo[4][0], MYPORT))
    time.sleep(1)

现在在多播中发送一个 UDP。我想要的是转换

s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)

进入

s = socket(AF_PACKET, SOCK_RAW, IPPROTO_ICMPV6)

或至少将 socket.SOCK_DGRAM 更改为 socket.SOCK_STREAM 以发送 TCP 数据包。

我的目标是发送一个 ICMPv6 数据包,希望我可以发送原始数据包,因为我使用 VLANS 但是当我更改 SOCK_DGRAM 时,我会收到这样的错误:

Traceback (most recent call last):
  File "/root/PycharmProjects/SlaacSecuritySolutionv3/ClassS3/SendTest.py", line 20, in <module>
    s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 92] Protocol not available

当我将 socket.socket 更改为 socket.AF_PACKET, socket.SOCK_RAW 时也是如此

请帮忙,我被困在这里好几天了

最佳答案

#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Imports
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

import sys
import time
import socket
import select
import struct
import select
import time
from impacket import ImpactDecoder, ImpactPacket, IP6, ICMP6, version
from impacket import ImpactPacket
from netaddr import *

#~ Definitions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

maddr = ('ff12::4242', 4242)

def ipv6Multicast(host='::1', maddr=maddr):
    haddr = socket.getaddrinfo(host, maddr[1], socket.AF_INET6, socket.IPPROTO_TCP)[0][-1]
    maddr = socket.getaddrinfo(maddr[0], maddr[1], socket.AF_INET6, socket.IPPROTO_TCP)[0][-1]

    sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6)
    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 5)

    ifn = struct.pack("I", haddr[3])
    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifn)

    group = socket.inet_pton(socket.AF_INET6, maddr[0]) + ifn
    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)

    #sock.bind(haddr)
    sock.setblocking(False)

    return sock, maddr

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~ Main
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if __name__=='__main__':
    # change host to use your IPv6 address...eth
    sock, maddr = ipv6Multicast(host='fe80::20c:29ff:fe23:8450')

    # send initial message
    msg = 'IPv6 multicast recipie'
    eth = ImpactPacket.Ethernet() 
    print maddr
    while 1:
         sock.sendto(eth.get_packet(),("ff12::4242",0))
         time.sleep(1

这是我将 IPv6 ICMPv6 数据包发送到网络的解决方案,我使用 impacket 构建数据包,但还没有数据。

如果执行它将发送格式错误的 ICMPv6 数据包

关于python - 在发送多播 IPv6 时使用 SOCK_STREAM 或 SOCK_RAW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28525124/

相关文章:

python - Python PIL 有抗锯齿方法吗?

networking - 有没有办法在不加密的情况下避免 MITM 攻击?

java - 在 Java 中重用 ObjectOutputStreams

python - reshape 图像数组

python - 我可以使用 gimp 命令编写独立的 python 脚本吗?

python - 计算机之间的套接字

sockets - 如何在 swift 中明确地从 NSInputStream 中读取数据?

linux - 有什么方法可以在不断开连接的情况下远程移除和插入网络模块?

python - 在一列字符串中搜索多个子串并返回子串类别

linux - 用于非阻塞、面向行的套接字 I/O 的 C++ 库?