def testCrossProtocolCalls(self):
    """Tests that passing in the wrong family returns EAFNOSUPPORT."""

    def CheckEAFNoSupport(function, *args):
      self.assertRaisesErrno(errno.EAFNOSUPPORT, function, *args)

    ipv6sockaddr = csocket.Sockaddr((net_test.IPV6_ADDR, 53))

    # In order to check that IPv6 socket calls return EAFNOSUPPORT when passed
    # IPv4 socket address structures, we need to pass down a socket address
    # length argument that's at least sizeof(sockaddr_in6). Otherwise, the calls
    # will fail immediately with EINVAL because the passed-in socket length is
    # too short. So create a sockaddr_in that's as long as a sockaddr_in6.
    ipv4sockaddr = csocket.Sockaddr((net_test.IPV4_ADDR, 53))
    ipv4sockaddr = csocket.SockaddrIn6(
        ipv4sockaddr.Pack() +
        "\x00" * (len(csocket.SockaddrIn6) - len(csocket.SockaddrIn)))

    s4 = net_test.IPv4PingSocket()
    s6 = net_test.IPv6PingSocket()

    # We can't just call s.connect(), s.bind() etc. with a tuple of the wrong
    # address family, because the Python implementation will just pass garbage
    # down to the kernel. So call the C functions directly.
    CheckEAFNoSupport(csocket.Bind, s4, ipv6sockaddr)
    CheckEAFNoSupport(csocket.Bind, s6, ipv4sockaddr)
    CheckEAFNoSupport(csocket.Connect, s4, ipv6sockaddr)
    CheckEAFNoSupport(csocket.Connect, s6, ipv4sockaddr)
    CheckEAFNoSupport(csocket.Sendmsg,
                      s4, ipv6sockaddr, net_test.IPV4_PING, None, 0)
    CheckEAFNoSupport(csocket.Sendmsg,
                      s6, ipv4sockaddr, net_test.IPV6_PING, None, 0)
Exemple #2
0
    def _Decode(self, command, msg, nla_type, nla_data):
        """Decodes netlink attributes to Python types."""
        if msg.family == AF_INET or msg.family == AF_INET6:
            if isinstance(msg, InetDiagReqV2):
                prefix = "INET_DIAG_REQ"
            else:
                prefix = "INET_DIAG"
            name = self._GetConstantName(__name__, nla_type, prefix)
        else:
            # Don't know what this is. Leave it as an integer.
            name = nla_type

        if name in [
                "INET_DIAG_SHUTDOWN", "INET_DIAG_TOS", "INET_DIAG_TCLASS",
                "INET_DIAG_SKV6ONLY"
        ]:
            data = ord(nla_data)
        elif name == "INET_DIAG_CONG":
            data = nla_data.strip("\x00")
        elif name == "INET_DIAG_MEMINFO":
            data = InetDiagMeminfo(nla_data)
        elif name == "INET_DIAG_INFO":
            # TODO: Catch the exception and try something else if it's not TCP.
            data = TcpInfo(nla_data)
        elif name == "INET_DIAG_SKMEMINFO":
            data = SkMeminfo(nla_data)
        elif name == "INET_DIAG_MARK":
            data = struct.unpack("=I", nla_data)[0]
        elif name == "INET_DIAG_REQ_BYTECODE":
            data = self.DecodeBytecode(nla_data)
        elif name in ["INET_DIAG_LOCALS", "INET_DIAG_PEERS"]:
            data = []
            while len(nla_data):
                # The SCTP diag code always appears to copy sizeof(sockaddr_storage)
                # bytes, but does so from a union sctp_addr which is at most as long
                # as a sockaddr_in6.
                addr, nla_data = cstruct.Read(nla_data,
                                              csocket.SockaddrStorage)
                if addr.family == AF_INET:
                    addr = csocket.SockaddrIn(addr.Pack())
                elif addr.family == AF_INET6:
                    addr = csocket.SockaddrIn6(addr.Pack())
                data.append(addr)
        else:
            data = nla_data

        return name, data