Example #1
0
 def setUp(self):
     self._tap0 = Tap()
     self._tap1 = Tap()
     self._tap2 = Tap()
     self._bridge0 = Bridge('src-')
     self._bridge1 = Bridge('target-')
     self._bridge2 = Bridge('target2-')
     self._devices = [self._tap0, self._tap1, self._tap2,
                      self._bridge0, self._bridge1, self._bridge2]
     # If setUp raise, teardown is not called, so we should either succeed,
     # or fail without leaving junk around.
     cleanup = []
     try:
         for iface in self._devices:
             iface.addDevice()
             cleanup.append(iface)
         self._bridge0.addIf(self._tap0.devName)
         self._bridge1.addIf(self._tap1.devName)
         self._bridge2.addIf(self._tap2.devName)
     except:
         t, v, tb = sys.exc_info()
         for iface in cleanup:
             try:
                 iface.delDevice()
             except Exception:
                 self.log.exception("Error removing device %s" % iface)
         six.reraise(t, v, tb)
Example #2
0
 def setUp(self):
     self._tap0 = Tap()
     self._tap1 = Tap()
     self._tap2 = Tap()
     self._bridge0 = Bridge('src-')
     self._bridge1 = Bridge('target-')
     self._bridge2 = Bridge('target2-')
     self._devices = [
         self._tap0, self._tap1, self._tap2, self._bridge0, self._bridge1,
         self._bridge2
     ]
     # If setUp raise, teardown is not called, so we should either succeed,
     # or fail without leaving junk around.
     cleanup = []
     try:
         for iface in self._devices:
             iface.addDevice()
             cleanup.append(iface)
         self._bridge0.addIf(self._tap0.devName)
         self._bridge1.addIf(self._tap1.devName)
         self._bridge2.addIf(self._tap2.devName)
     except:
         t, v, tb = sys.exc_info()
         for iface in cleanup:
             try:
                 iface.delDevice()
             except Exception:
                 self.log.exception("Error removing device %s" % iface)
         six.reraise(t, v, tb)
Example #3
0
class TestPortMirror(TestCaseBase):

    """
    Tests port mirroring of IP traffic between two bridges.

    This test brings up two tap devices and attaches every device to a
    separate bridge. Then mirroring of IP packets between the two bridges is
    enabled. If sent through _tap0 the packet _ICMP arrives on _tap1 the test
    succeeds. The tap devices are needed because the tc filter rules only
    become active when the bridge is ready, and the bridge only becomes ready
    when it is attached to an active device.
    """

    #  [ Ethernet ]
    #  dst       = 00:1c:c0:d0:44:dc
    #  src       = 00:21:5c:4d:42:75
    #  type      = IPv4
    #     [ IP ]
    #     version   = 4L
    #     ihl       = 5L
    #     tos       = 0x0
    #     len       = 33
    #     id        = 1
    #     flags     =
    #     frag      = 0L
    #     ttl       = 64
    #     proto     = icmp
    #     chksum    = 0xf953
    #     src       = 192.168.0.52
    #     dst       = 192.168.0.3
    #     \options   \
    #        [ ICMP ]
    #        type      = echo-request
    #        code      = 0
    #        chksum    = 0x2875
    #        id        = 0x0
    #        seq       = 0x0
    #           [ Raw ]
    #           load      = '\x01#Eg\x89'
    _ICMP = unhexlify(
        '001cc0d044dc''00215c4d4275''0800'  # Ethernet
        '45000021000100004001f953''c0a80034''c0a80003'  # IP
        '080028750000000'  # ICMP
        '00123456789')  # Payload

    @ValidateRunningAsRoot
    @requires_tc
    @requires_tun
    def setUp(self):
        self._tap0 = Tap()
        self._tap1 = Tap()
        self._tap2 = Tap()
        self._bridge0 = Bridge('src-')
        self._bridge1 = Bridge('target-')
        self._bridge2 = Bridge('target2-')
        self._devices = [self._tap0, self._tap1, self._tap2,
                         self._bridge0, self._bridge1, self._bridge2]
        # If setUp raise, teardown is not called, so we should either succeed,
        # or fail without leaving junk around.
        cleanup = []
        try:
            for iface in self._devices:
                iface.addDevice()
                cleanup.append(iface)
            self._bridge0.addIf(self._tap0.devName)
            self._bridge1.addIf(self._tap1.devName)
            self._bridge2.addIf(self._tap2.devName)
        except:
            t, v, tb = sys.exc_info()
            for iface in cleanup:
                try:
                    iface.delDevice()
                except Exception:
                    self.log.exception("Error removing device %s" % iface)
            six.reraise(t, v, tb)

    def tearDown(self):
        failed = False
        for iface in self._devices:
            try:
                iface.delDevice()
            except Exception:
                self.log.exception("Error removing device %s" % iface)
                failed = True
        if failed:
            raise RuntimeError("Error tearing down interfaces")

    def _sendPing(self):
        self._tap1.startListener(self._ICMP)
        self._tap0.writeToDevice(self._ICMP)
        # Attention: sleep is bad programming practice! Never use it for
        # synchronization in productive code!
        time.sleep(0.1)
        if self._tap1.isListenerAlive():
            self._tap1.stopListener()
            return False
        else:
            return True

    def testMirroring(self):
        tc.setPortMirroring(self._bridge0.devName, self._bridge1.devName)
        self.assertTrue(self._sendPing(), "Bridge received no mirrored ping "
                        "requests.")

        tc.unsetPortMirroring(self._bridge0.devName, self._bridge1.devName)
        self.assertFalse(self._sendPing(), "Bridge received mirrored ping "
                         "requests, but mirroring is unset.")

    def testMirroringWithDistraction(self):
        "setting another mirror action should not obstract the first one"
        tc.setPortMirroring(self._bridge0.devName, self._bridge2.devName)
        self.testMirroring()
        tc.unsetPortMirroring(self._bridge0.devName, self._bridge2.devName)
Example #4
0
class TestPortMirror(TestCaseBase):
    """
    Tests port mirroring of IP traffic between two bridges.

    This test brings up two tap devices and attaches every device to a
    separate bridge. Then mirroring of IP packets between the two bridges is
    enabled. If sent through _tap0 the packet _ICMP arrives on _tap1 the test
    succeeds. The tap devices are needed because the tc filter rules only
    become active when the bridge is ready, and the bridge only becomes ready
    when it is attached to an active device.
    """

    #  [ Ethernet ]
    #  dst       = 00:1c:c0:d0:44:dc
    #  src       = 00:21:5c:4d:42:75
    #  type      = IPv4
    #     [ IP ]
    #     version   = 4L
    #     ihl       = 5L
    #     tos       = 0x0
    #     len       = 33
    #     id        = 1
    #     flags     =
    #     frag      = 0L
    #     ttl       = 64
    #     proto     = icmp
    #     chksum    = 0xf953
    #     src       = 192.168.0.52
    #     dst       = 192.168.0.3
    #     \options   \
    #        [ ICMP ]
    #        type      = echo-request
    #        code      = 0
    #        chksum    = 0x2875
    #        id        = 0x0
    #        seq       = 0x0
    #           [ Raw ]
    #           load      = '\x01#Eg\x89'
    _ICMP = unhexlify('001cc0d044dc'
                      '00215c4d4275'
                      '0800'  # Ethernet
                      '45000021000100004001f953'
                      'c0a80034'
                      'c0a80003'  # IP
                      '080028750000000'  # ICMP
                      '00123456789')  # Payload

    @ValidateRunningAsRoot
    @requires_tc
    @requires_tun
    def setUp(self):
        self._tap0 = Tap()
        self._tap1 = Tap()
        self._tap2 = Tap()
        self._bridge0 = Bridge('src-')
        self._bridge1 = Bridge('target-')
        self._bridge2 = Bridge('target2-')
        self._devices = [
            self._tap0, self._tap1, self._tap2, self._bridge0, self._bridge1,
            self._bridge2
        ]
        # If setUp raise, teardown is not called, so we should either succeed,
        # or fail without leaving junk around.
        cleanup = []
        try:
            for iface in self._devices:
                iface.addDevice()
                cleanup.append(iface)
            self._bridge0.addIf(self._tap0.devName)
            self._bridge1.addIf(self._tap1.devName)
            self._bridge2.addIf(self._tap2.devName)
        except:
            t, v, tb = sys.exc_info()
            for iface in cleanup:
                try:
                    iface.delDevice()
                except Exception:
                    self.log.exception("Error removing device %s" % iface)
            six.reraise(t, v, tb)

    def tearDown(self):
        failed = False
        for iface in self._devices:
            try:
                iface.delDevice()
            except Exception:
                self.log.exception("Error removing device %s" % iface)
                failed = True
        if failed:
            raise RuntimeError("Error tearing down interfaces")

    def _sendPing(self):
        self._tap1.startListener(self._ICMP)
        self._tap0.writeToDevice(self._ICMP)
        # Attention: sleep is bad programming practice! Never use it for
        # synchronization in productive code!
        time.sleep(0.1)
        if self._tap1.isListenerAlive():
            self._tap1.stopListener()
            return False
        else:
            return True

    def testMirroring(self):
        tc.setPortMirroring(self._bridge0.devName, self._bridge1.devName)
        self.assertTrue(self._sendPing(), "Bridge received no mirrored ping "
                        "requests.")

        tc.unsetPortMirroring(self._bridge0.devName, self._bridge1.devName)
        self.assertFalse(
            self._sendPing(), "Bridge received mirrored ping "
            "requests, but mirroring is unset.")

    def testMirroringWithDistraction(self):
        "setting another mirror action should not obstract the first one"
        tc.setPortMirroring(self._bridge0.devName, self._bridge2.devName)
        self.testMirroring()
        tc.unsetPortMirroring(self._bridge0.devName, self._bridge2.devName)