views:

35

answers:

2

I am having some problems using raw IPv6 sockets in python. I connect via:

    if self._socket != None:
        # Close out old socket first
        self._socket.close()
    self._socket = socket.socket(socket.AF_INET6, socket.SOCK_RAW)
    self._socket.bind((self._interface,0))
    self._socket.sendall(data)

where self._interface is my local address; specifically "fe80::fa1e:dfff:fed6:221d". When trying this, I get the following error:

  File "raw.py", line 164, in connect
    self._socket.bind((self._interface,0))
  File "<string>", line 1, in bind
socket.error: [Errno 49] Can't assign requested address

If I use my ipv6 localhost address for self._interface ("::1") I can actually bind the address, but can not send anything:

    self._socket.sendall(data)
  File "<string>", line 1, in sendall
socket.error: [Errno 39] Destination address required

Why would a raw socket need a destination address? Has anyone worked with raw IPv6 sockets in python, and can help me understand why this is happening?

A: 

I don't understand your combination of bind and sendall. In my understanding, bind is for server sockets and sendall requires a connection. Did you mean connect instead of bind?

Anyway, the IPv6 equivalent of INADDR_ANY is, according to the man page, IN6ADDR_ANY_INIT. Python does not define a constant for it, but this is the same as '::' (all zero).

This worked for me (as root):

>>> import socket
>>> s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_RAW)
>>> s.bind(('::', 0))

EDIT: Oops, I first did not saw that you actually managed to bind the socket to an address. However your second problem is obvious: You must first connect to some address before you can send data. Or use sendto with an address. This is not different from IPv4.

Bernd Petersohn
wuntee
ok. is it possible to create a raw packet and put it on the wire?
wuntee
@wuntee: I think you could use `sendto`: http://docs.python.org/library/socket.html#socket.socket.sendto
Bernd Petersohn
@wuntee: You may also be interested in http://stackoverflow.com/questions/1319261/sending-data-on-af-packet-socket
Bernd Petersohn
doesnt the sendto function require you to define a destination address - IP? if so, then I would not be able to define the IP layer in the packet...
wuntee
@wuntee: I think if you set the protocol to IPPROTO_RAW, you are assumed to provide the IP header. See http://lists.openwall.net/netdev/2009/01/15/168.
Bernd Petersohn
A: 

This code provides a raw socket with L2 access. Unfortunately OSX does not support the socket.PF_PACKET...

soc = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) #create the raw-socket
soc.bind(("lo0", 0))

soc.send(packet)
wuntee