Exemplo n.º 1
0
  def CheckRawGrePacket(self, version, netid, routing_mode, dstaddr):
    s = self.BuildSocket(version, net_test.RawGRESocket, netid, routing_mode)

    inner_version = {4: 6, 6: 4}[version]
    inner_src = self.MyAddress(inner_version, netid)
    inner_dst = self.GetRemoteAddress(inner_version)
    inner = str(packets.UDP(inner_version, inner_src, inner_dst, sport=None)[1])

    ethertype = {4: net_test.ETH_P_IP, 6: net_test.ETH_P_IPV6}[inner_version]
    # A GRE header can be as simple as two zero bytes and the ethertype.
    packet = struct.pack("!i", ethertype) + inner
    myaddr = self.MyAddress(version, netid)

    s.sendto(packet, (dstaddr, IPPROTO_GRE))
    desc, expected = packets.GRE(version, myaddr, dstaddr, ethertype, inner)
    msg = "Raw IPv%d GRE with inner IPv%d UDP: expected %s on %s" % (
        version, inner_version, desc, self.GetInterfaceName(netid))
    self.ExpectPacketOn(netid, msg, expected)
Exemplo n.º 2
0
  def CheckUDPPacket(self, version, netid, routing_mode, dstaddr):
    s = self.BuildSocket(version, net_test.UDPSocket, netid, routing_mode)

    if version == 6 and dstaddr.startswith("::ffff"):
      version = 4
    myaddr = self.MyAddress(version, netid)
    desc, expected = packets.UDP(version, myaddr, dstaddr, sport=None)
    msg = "IPv%s UDP %%s: expected %s on %s" % (
        version, desc, self.GetInterfaceName(netid))

    s.sendto(UDP_PAYLOAD, (dstaddr, 53))
    self.ExpectPacketOn(netid, msg % "sendto", expected)

    # IP_UNICAST_IF doesn't seem to work on connected sockets, so no TCP.
    if routing_mode != "ucast_oif":
      s.connect((dstaddr, 53))
      s.send(UDP_PAYLOAD)
      self.ExpectPacketOn(netid, msg % "connect/send", expected)
      s.close()
Exemplo n.º 3
0
    def CheckRemarking(self, version, use_connect):
        # Remarking or resetting UNICAST_IF on connected sockets does not work.
        if use_connect:
            modes = ["oif"]
        else:
            modes = ["mark", "oif"]
            if HAVE_UNICAST_IF:
                modes += ["ucast_oif"]

        for mode in modes:
            s = net_test.UDPSocket(self.GetProtocolFamily(version))

            # Figure out what packets to expect.
            unspec = {4: "0.0.0.0", 6: "::"}[version]
            sport = packets.RandomPort()
            s.bind((unspec, sport))
            dstaddr = {4: self.IPV4_ADDR, 6: self.IPV6_ADDR}[version]
            desc, expected = packets.UDP(version, unspec, dstaddr, sport)

            # If we're testing connected sockets, connect the socket on the first
            # netid now.
            if use_connect:
                netid = self.tuns.keys()[0]
                self.SelectInterface(s, netid, mode)
                s.connect((dstaddr, 53))
                expected.src = self.MyAddress(version, netid)

            # For each netid, select that network without closing the socket, and
            # check that the packets sent on that socket go out on the right network.
            for netid in self.tuns:
                self.SelectInterface(s, netid, mode)
                if not use_connect:
                    expected.src = self.MyAddress(version, netid)
                s.sendto(UDP_PAYLOAD, (dstaddr, 53))
                connected_str = "Connected" if use_connect else "Unconnected"
                msg = "%s UDPv%d socket remarked using %s: expecting %s on %s" % (
                    connected_str, version, mode, desc,
                    self.GetInterfaceName(netid))
                self.ExpectPacketOn(netid, msg, expected)
                self.SelectInterface(s, None, mode)
Exemplo n.º 4
0
    def testOnlinkCommunication(self):
        """Checks that on-link communication goes direct and not through routers."""
        for netid in self.tuns:
            # Send a UDP packet to a random on-link destination.
            s = net_test.UDPSocket(AF_INET6)
            iface = self.GetInterfaceName(netid)
            self.BindToDevice(s, iface)
            # dstaddr can never be our address because GetRandomDestination only fills
            # in the lower 32 bits, but our address has 0xff in the byte before that
            # (since it's constructed from the EUI-64 and so has ff:fe in the middle).
            dstaddr = self.GetRandomDestination(self.IPv6Prefix(netid))
            s.sendto(UDP_PAYLOAD, (dstaddr, 53))

            # Expect an NS for that destination on the interface.
            myaddr = self.MyAddress(6, netid)
            mymac = self.MyMacAddress(netid)
            desc, expected = packets.NS(myaddr, dstaddr, mymac)
            msg = "Sending UDP packet to on-link destination: expecting %s" % desc
            time.sleep(
                0.0001)  # Required to make the test work on kernel 3.1(!)
            self.ExpectPacketOn(netid, msg, expected)

            # Send an NA.
            tgtmac = "02:00:00:00:%02x:99" % netid
            _, reply = packets.NA(dstaddr, myaddr, tgtmac)
            # Don't use ReceivePacketOn, since that uses the router's MAC address as
            # the source. Instead, construct our own Ethernet header with source
            # MAC of tgtmac.
            reply = scapy.Ether(src=tgtmac, dst=mymac) / reply
            self.ReceiveEtherPacketOn(netid, reply)

            # Expect the kernel to send the original UDP packet now that the ND cache
            # entry has been populated.
            sport = s.getsockname()[1]
            desc, expected = packets.UDP(6, myaddr, dstaddr, sport=sport)
            msg = "After NA response, expecting %s" % desc
            self.ExpectPacketOn(netid, msg, expected)
Exemplo n.º 5
0
  def CheckRemarking(self, version, use_connect):
    modes = ["mark", "oif", "uid"]
    # Setting UNICAST_IF on connected sockets does not work.
    if not use_connect and HAVE_UNICAST_IF:
      modes += ["ucast_oif"]

    for mode in modes:
      s = net_test.UDPSocket(self.GetProtocolFamily(version))

      # Figure out what packets to expect.
      sport = net_test.BindRandomPort(version, s)
      dstaddr = {4: self.IPV4_ADDR, 6: self.IPV6_ADDR}[version]
      unspec = {4: "0.0.0.0", 6: "::"}[version]  # Placeholder.
      desc, expected = packets.UDP(version, unspec, dstaddr, sport)

      # If we're testing connected sockets, connect the socket on the first
      # netid now.
      if use_connect:
        netid = self.tuns.keys()[0]
        self.SelectInterface(s, netid, mode)
        s.connect((dstaddr, 53))
        expected.src = self.MyAddress(version, netid)

      # For each netid, select that network without closing the socket, and
      # check that the packets sent on that socket go out on the right network.
      #
      # For connected sockets, routing is cached in the socket's destination
      # cache entry. In this case, we check that just re-selecting the netid
      # (except via SO_BINDTODEVICE) does not change routing, but that
      # subsequently invalidating the destination cache entry does. Arguably
      # this is a bug in the kernel because re-selecting the netid should cause
      # routing to change. But it is a convenient way to check that
      # InvalidateDstCache actually works.
      prevnetid = None
      for netid in self.tuns:
        self.SelectInterface(s, netid, mode)
        if not use_connect:
          expected.src = self.MyAddress(version, netid)

        def ExpectSendUsesNetid(netid):
          connected_str = "Connected" if use_connect else "Unconnected"
          msg = "%s UDPv%d socket remarked using %s: expecting %s on %s" % (
              connected_str, version, mode, desc, self.GetInterfaceName(netid))
          if use_connect:
            s.send(UDP_PAYLOAD)
          else:
            s.sendto(UDP_PAYLOAD, (dstaddr, 53))
          self.ExpectPacketOn(netid, msg, expected)

        if use_connect and mode in ["mark", "uid", "ucast_oif"]:
          # If we have a destination cache entry, packets are not rerouted...
          if prevnetid:
            ExpectSendUsesNetid(prevnetid)
            # ... until we invalidate it.
            self.InvalidateDstCache(version, dstaddr, prevnetid)
          ExpectSendUsesNetid(netid)
        else:
          ExpectSendUsesNetid(netid)

        self.SelectInterface(s, None, mode)
        prevnetid = netid
Exemplo n.º 6
0
    def _TestSocketPolicy(self, version):
        # Open a UDP socket and connect it.
        family = net_test.GetAddressFamily(version)
        s = socket(family, SOCK_DGRAM, 0)
        netid = self.RandomNetid()
        self.SelectInterface(s, netid, "mark")

        remotesockaddr = self.GetRemoteSocketAddress(version)
        s.connect((remotesockaddr, 53))
        saddr, sport = s.getsockname()[:2]
        daddr, dport = s.getpeername()[:2]
        if version == 5:
            saddr = saddr.replace("::ffff:", "")
            daddr = daddr.replace("::ffff:", "")

        reqid = 0

        desc, pkt = packets.UDP(version, saddr, daddr, sport=sport)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after socket, expected %s" % desc,
                            pkt)

        # Using IPv4 XFRM on a dual-stack socket requires setting an AF_INET policy
        # that's written in terms of IPv4 addresses.
        xfrm_version = 4 if version == 5 else version
        xfrm_family = net_test.GetAddressFamily(xfrm_version)
        xfrm_base.ApplySocketPolicy(s, xfrm_family, xfrm.XFRM_POLICY_OUT,
                                    TEST_SPI, reqid, None)

        # Because the policy has level set to "require" (the default), attempting
        # to send a packet results in an error, because there is no SA that
        # matches the socket policy we set.
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remotesockaddr, 53))

        # Adding a matching SA causes the packet to go out encrypted. The SA's
        # SPI must match the one in our template, and the destination address must
        # match the packet's destination address (in tunnel mode, it has to match
        # the tunnel destination).
        self.CreateNewSa(net_test.GetWildcardAddress(xfrm_version),
                         self.GetRemoteAddress(xfrm_version), TEST_SPI, reqid,
                         None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        expected_length = xfrm_base.GetEspPacketLength(
            xfrm.XFRM_MODE_TRANSPORT, version, False, net_test.UDP_PAYLOAD,
            xfrm_base._ALGO_HMAC_SHA1, xfrm_base._ALGO_CBC_AES_256)
        self._ExpectEspPacketOn(netid, TEST_SPI, 1, expected_length, None,
                                None)

        # Sending to another destination doesn't work: again, no matching SA.
        remoteaddr2 = self.GetOtherRemoteSocketAddress(version)
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remoteaddr2, 53))

        # Sending on another socket without the policy applied results in an
        # unencrypted packet going out.
        s2 = socket(family, SOCK_DGRAM, 0)
        self.SelectInterface(s2, netid, "mark")
        s2.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        pkts = self.ReadAllPacketsOn(netid)
        self.assertEquals(1, len(pkts))
        packet = pkts[0]

        protocol = packet.nh if version == 6 else packet.proto
        self.assertEquals(IPPROTO_UDP, protocol)

        # Deleting the SA causes the first socket to return errors again.
        self.xfrm.DeleteSaInfo(self.GetRemoteAddress(xfrm_version), TEST_SPI,
                               IPPROTO_ESP)
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remotesockaddr, 53))

        # Clear the socket policy and expect a cleartext packet.
        xfrm_base.SetPolicySockopt(s, family, None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after clear, expected %s" % desc, pkt)

        # Clearing the policy twice is safe.
        xfrm_base.SetPolicySockopt(s, family, None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after clear 2, expected %s" % desc,
                            pkt)

        # Clearing if a policy was never set is safe.
        s = socket(AF_INET6, SOCK_DGRAM, 0)
        xfrm_base.SetPolicySockopt(s, family, None)