[pypy-svn] r76951 - in pypy/branch/rsocket-improvements/pypy: module/_socket module/_socket/test rlib

fijal at codespeak.net fijal at codespeak.net
Wed Sep 8 19:22:09 CEST 2010


Author: fijal
Date: Wed Sep  8 19:21:55 2010
New Revision: 76951

Modified:
   pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py
   pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py
   pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py
   pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py
   pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py
Log:
Implement AF_PACKET support. part 1 - interface name


Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py	(original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py	Wed Sep  8 19:21:55 2010
@@ -280,7 +280,7 @@
                             space.wrap(socktype),
                             space.wrap(protocol),
                             space.wrap(canonname),
-                            addr.as_object(space)])
+                            addr.as_object(-1, space)]) # -1 as per cpython
             for (family, socktype, protocol, canonname, addr) in lst]
     return space.newlist(lst1)
 getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, int, int, int, int]

Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py	(original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py	Wed Sep  8 19:21:55 2010
@@ -24,7 +24,7 @@
         try:
             sock, addr = self.accept(W_RSocket)
             return space.newtuple([space.wrap(sock),
-                                   addr.as_object(space)])
+                                   addr.as_object(sock.fd, space)])
         except SocketError, e:
             raise converted_error(space, e)
     accept_w.unwrap_spec = ['self', ObjSpace]
@@ -109,7 +109,7 @@
         """
         try:
             addr = self.getpeername()
-            return addr.as_object(space)
+            return addr.as_object(self.fd, space)
         except SocketError, e:
             raise converted_error(space, e)
     getpeername_w.unwrap_spec = ['self', ObjSpace]
@@ -122,7 +122,7 @@
         """
         try:
             addr = self.getsockname()
-            return addr.as_object(space)
+            return addr.as_object(self.fd, space)
         except SocketError, e:
             raise converted_error(space, e)
     getsockname_w.unwrap_spec = ['self', ObjSpace]
@@ -202,7 +202,7 @@
         try:
             data, addr = self.recvfrom(buffersize, flags)
             if addr:
-                w_addr = addr.as_object(space)
+                w_addr = addr.as_object(self.fd, space)
             else:
                 w_addr = space.w_None
             return space.newtuple([space.wrap(data), w_addr])
@@ -330,7 +330,7 @@
         try:
             readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags)
             if addr:
-                w_addr = addr.as_object(space)
+                w_addr = addr.as_object(self.fd, space)
             else:
                 w_addr = space.w_None
             return space.newtuple([space.wrap(readlgt), w_addr])

Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py	(original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py	Wed Sep  8 19:21:55 2010
@@ -2,6 +2,8 @@
 import sys
 import py
 from pypy.tool.udir import udir
+from pypy.rlib import rsocket
+from pypy.rpython.lltypesystem import lltype, rffi
 
 def setup_module(mod):
     mod.space = gettestobjspace(usemodules=['_socket', 'array'])
@@ -221,21 +223,35 @@
                         "(_socket, host, port): return _socket.getaddrinfo(host, port)")
     assert space.unwrap(w_l) == info
 
-def test_unknown_addr_as_object():
-    from pypy.rlib import rsocket
-    from pypy.rpython.lltypesystem import lltype, rffi
-    
+def test_unknown_addr_as_object():    
     c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw')
     c_addr.c_sa_data[0] = 'c'
     rffi.setintfield(c_addr, 'c_sa_family', 15)
     # XXX what size to pass here? for the purpose of this test it has
     #     to be short enough so we have some data, 1 sounds good enough
     #     + sizeof USHORT
-    w_obj = rsocket.Address(c_addr, 1 + 2).as_object(space)
+    w_obj = rsocket.Address(c_addr, 1 + 2).as_object(-1, space)
     assert space.is_true(space.isinstance(w_obj, space.w_tuple))
     assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15
     assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c'
 
+def test_addr_raw_packet():
+    if not hasattr(rsocket._c, 'sockaddr_ll'):
+        py.test.skip("posix specific test")
+    c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw')
+    addrlen = rffi.sizeof(rsocket._c.sockaddr_ll)
+    c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll)
+    rffi.setintfield(c_addr_ll, 'c_sll_ifindex', 1)
+    rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8)
+    rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET)
+    # fd needs to be somehow valid
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    fd = s.fileno()
+    w_obj = rsocket.make_address(c_addr, addrlen).as_object(fd, space)
+    assert space.is_true(space.eq(w_obj, space.newtuple([
+        space.wrap('lo'),
+        space.w_None])))
+
 def test_getnameinfo():
     host = "127.0.0.1"
     port = 25

Modified: pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py	(original)
+++ pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py	Wed Sep  8 19:21:55 2010
@@ -32,6 +32,9 @@
                 'arpa/inet.h',
                 'stdint.h', 
                 'errno.h',
+                'netpacket/packet.h',
+                'sys/ioctl.h',
+                'net/if.h',
                 )
     cond_includes = [('AF_NETLINK', 'linux/netlink.h')]
     libraries = ()
@@ -190,6 +193,8 @@
 FD_CONNECT_BIT FD_CLOSE_BIT
 WSA_IO_PENDING WSA_IO_INCOMPLETE WSA_INVALID_HANDLE
 WSA_INVALID_PARAMETER WSA_NOT_ENOUGH_MEMORY WSA_OPERATION_ABORTED
+
+SIOCGIFNAME
 '''.split()
 
 for name in constant_names:
@@ -309,6 +314,19 @@
                                             [('fd', socketfd_type),
                                              ('events', rffi.SHORT),
                                              ('revents', rffi.SHORT)])
+
+    CConfig.sockaddr_ll = platform.Struct('struct sockaddr_ll',
+                              [('sll_ifindex', rffi.INT),
+                               ('sll_protocol', rffi.INT),
+                               ('sll_pkttype', rffi.INT),
+                               ('sll_hatype', rffi.INT),
+                               ('sll_addr', rffi.CFixedArray(rffi.CHAR, 8)),
+                               ('sll_halen', rffi.INT)],
+                              )
+
+    CConfig.ifreq = platform.Struct('struct ifreq', [('ifr_ifindex', rffi.INT),
+                                 ('ifr_name', rffi.CFixedArray(rffi.CHAR, 8))])
+
 if _WIN32:
     CConfig.WSAEVENT = platform.SimpleType('WSAEVENT', rffi.VOIDP)
     CConfig.WSANETWORKEVENTS = platform.Struct(
@@ -408,6 +426,8 @@
 if _POSIX:
     nfds_t = cConfig.nfds_t
     pollfd = cConfig.pollfd
+    sockaddr_ll = cConfig.sockaddr_ll
+    ifreq = cConfig.ifreq
 if WIN32:
     WSAEVENT = cConfig.WSAEVENT
     WSANETWORKEVENTS = cConfig.WSANETWORKEVENTS
@@ -510,6 +530,8 @@
     socketpair_t = rffi.CArray(socketfd_type)
     socketpair = external('socketpair', [rffi.INT, rffi.INT, rffi.INT,
                           lltype.Ptr(socketpair_t)], rffi.INT)
+    ioctl = external('ioctl', [socketfd_type, rffi.INT, lltype.Ptr(ifreq)],
+                     rffi.INT)
 
 if _WIN32:
     ioctlsocket = external('ioctlsocket',

Modified: pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py	(original)
+++ pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py	Wed Sep  8 19:21:55 2010
@@ -6,8 +6,7 @@
 
 # Known missing features:
 #
-#   - support for non-Linux platforms
-#   - address families other than AF_INET, AF_INET6, AF_UNIX
+#   - address families other than AF_INET, AF_INET6, AF_UNIX, AF_PACKET
 #   - methods makefile(),
 #   - SSL
 #
@@ -109,7 +108,7 @@
         """
         keepalive_until_here(self)
 
-    def as_object(self, space):
+    def as_object(self, fd, space):
         """Convert the address to an app-level object."""
         # If we don't know the address family, don't raise an
         # exception -- return it as a tuple.
@@ -200,6 +199,31 @@
 
 # ____________________________________________________________
 
+class PacketAddress(Address):
+    family = AF_PACKET
+    struct = _c.sockaddr_ll
+    maxlen = minlen = sizeof(struct)
+
+    def get_ifname(self, fd):
+        a = self.lock(_c.sockaddr_ll)
+        p = lltype.malloc(_c.ifreq, flavor='raw')
+        rffi.setintfield(p, 'c_ifr_ifindex',
+                         rffi.getintfield(a, 'c_sll_ifindex'))
+        if (_c.ioctl(fd, _c.SIOCGIFNAME, p) == 0):
+            ifname = rffi.charp2str(p.c_ifr_name)
+        else:
+            ifname = ""
+        lltype.free(p, flavor='raw')
+        self.unlock()
+        return ifname
+
+    def get_protocol(self):
+        a = self.lock
+
+    def as_object(self, fd, space):
+        return space.newtuple([space.wrap(self.get_ifname(fd)),
+                               space.wrap(self.get_protocol())])
+
 class INETAddress(IPAddress):
     family = AF_INET
     struct = _c.sockaddr_in
@@ -228,7 +252,7 @@
                 self.get_host() == other.get_host() and
                 self.get_port() == other.get_port())
 
-    def as_object(self, space):
+    def as_object(self, fd, space):
         return space.newtuple([space.wrap(self.get_host()),
                                space.wrap(self.get_port())])
 
@@ -317,7 +341,7 @@
                 self.get_flowinfo() == other.get_flowinfo() and
                 self.get_scope_id() == other.get_scope_id())
 
-    def as_object(self, space):
+    def as_object(self, fd, space):
         return space.newtuple([space.wrap(self.get_host()),
                                space.wrap(self.get_port()),
                                space.wrap(self.get_flowinfo()),
@@ -421,7 +445,7 @@
             return (isinstance(other, UNIXAddress) and
                     self.get_path() == other.get_path())
 
-        def as_object(self, space):
+        def as_object(self, fd, space):
             return space.wrap(self.get_path())
 
         def from_object(space, w_address):
@@ -456,7 +480,7 @@
         def __repr__(self):
             return '<NETLINKAddress %r>' % (self.get_pid(), self.get_groups())
         
-        def as_object(self, space):
+        def as_object(self, fd, space):
             return space.newtuple([space.wrap(self.get_pid()),
                                    space.wrap(self.get_groups())])
 
@@ -613,7 +637,7 @@
 
     # convert an Address into an app-level object
     def addr_as_object(self, space, address):
-        return address.as_object(space)
+        return address.as_object(self.fd, space)
 
     # convert an app-level object into an Address
     # based on the current socket's family



More information about the Pypy-commit mailing list