Exemple #1
0
    def __calculate_mask(self) -> None:
        """
        Calculates the mask from the instance var self.__mask

        If the mask is a literal mask (i.e. '255.255.255.0'), the try case is concerned.
        If instead, the user gave the mask length, we make sure to raise an AttributeError to switch to the
        except case to do proper testing.

        :raises:
            IncorrectMaskException: if the mask is wrongly formed (byte != 0 after byte < 255) or if the mask contains a
                byte that cannot be used in a mask.
        """

        try:
            # The mask is given by its literal
            temp = self.__mask.split('.')
            if len(temp) == 1:
                # If the mask is given by its length
                # Use AttributeError raise to switch to the except case
                raise AttributeError()

            length = 0

            for byte in range(4):
                concerned = int(temp[byte])
                # We check that the byte is in the awaited bytes list
                if concerned in Utils.mask_allowed_bytes:
                    # If mask contains a 0, we check that each next byte
                    # contains only a 0, else we raise an IncorrectMaskException
                    if concerned < 255:
                        for i in range(1, 4 - byte):
                            b = temp[byte + i]
                            if b != '0':
                                raise IncorrectMaskException(
                                    is_out_allowed=False,
                                    value=b,
                                    extra=byte + i)

                    length += Utils.switch_length(concerned, index=True)
                else:
                    raise IncorrectMaskException(is_out_allowed=True,
                                                 value=concerned)

            # Stock the length
            self.__mask_length = length
            self.__mask = FourBytesLiteral().set_from_string_literal(
                ".".join(temp))

        except AttributeError:
            # The mask is given by its length
            self.__mask_length = int(self.__mask)
            self.__mask = FourBytesLiteral().set_from_string_literal(
                Utils.mask_length_to_literal(self.__mask_length))

        finally:
            self.__addresses = 2**(32 - self.__mask_length) - 2
    def __build_subnets(self) -> None:
        start_ip = self.network_range['start']

        for i in range(len(self.__subnets_sizes)):
            machines_bits = self.__submasks_machine_bits[i]
            mask_literal = FourBytesLiteral().set_eval(Utils.mask_length_to_literal(32 - machines_bits))

            result = IPv4Network().init_from_fbl(start_ip, mask_literal)
            self.__subnets.append(result)
            start_ip = Utils.ip_after(result.network_range['end'])
Exemple #3
0
        def check_ip_availability(subnet_inst_, ip_):
            """
            Checks if an IP is available

            This function is a suicider: it will die if any of the tests fail. It will either raise
            nettools.core.errors.IPOffNetworkRangeException or rth.core.errors.IPAlreadyAttributed

            Args:
                subnet_inst_: The subnetwork instance
                ip_: The IP that has to be checked
            """

            # Checking that ip is effectively in range of the subnet
            if isinstance(ip_, str):
                ip_ = FourBytesLiteral().set_from_string_literal(ip_)

            mask = FourBytesLiteral().set_from_string_literal(
                Utils.mask_length_to_literal(subnet_inst_.mask_length))
            inst = IPv4Network().init_from_fbl(ip_, mask)

            if inst.address_type != 1:
                # means the address is either a network or a broadcast address
                raise IPOffNetworkRangeException(str(ip))

            # then we check that ip is not used by any of the current routers
            routers = subnet_inst_.routers
            for r in routers:
                if str(routers[r]) == str(ip_):
                    raise IPAlreadyAttributed(name, ip_,
                                              self.uid_to_name('router', r),
                                              str(router_name))
    def __display_subnets(self, advanced=False) -> None:
        if not self.__activated:
            return

        occupied, graph, t = self.__build_graph()

        literal_ip = Utils.to_literal(self.ip)
        literal_netr = Utils.netr_to_literal(self.__total_network_range)

        print(self.lang_dict['network'])
        if advanced is True:
            print(self.lang_dict['cidr_adv'].format(literal_ip, self.mask_length))
        else:
            print(self.lang_dict['cidr'].format(literal_ip, self.mask_length))
        print("{} - {}".format(literal_netr['start'], literal_netr['end']))
        if advanced is True:
            print(self.lang_dict['addr_avail_advanced'].format(occupied, self.addresses))
        else:
            print(self.lang_dict['addr_avail'].format(self.addresses))
        print('')
        print(self.lang_dict['utils'].format(len(self.__subnets), t))

        for i in range(len(self.__subnets)):
            literal_sub_netr = self.__subnets[i].displayable_network_range

            if advanced:
                print(self.lang_dict['sub_addr_advanced'].format(literal_sub_netr['start'],
                                                                 literal_sub_netr['end'],
                                                                 2 ** self.__submasks_machine_bits[i] - 2,
                                                                 self.__subnets_sizes[i]))
            else:
                print(self.lang_dict['sub_addr'].format(literal_sub_netr['start'],
                                                        literal_sub_netr['end'],
                                                        2 ** self.__submasks_machine_bits[i] - 2))

        if advanced:
            print('')
            print(self.lang_dict['net_usage'])
            print(graph)
Exemple #5
0
    def display_type(self, display=False) -> None:
        if display is True:
            self._display()
        elif display is False:
            if self.address_type == 0:
                machine_type = self.lang_dict['addr_types']['net']
            elif self.address_type == 1:
                machine_type = self.lang_dict['addr_types']['mac']
            elif self.address_type == 2:
                machine_type = self.lang_dict['addr_types']['bct']
            else:
                machine_type = None

            temp = Utils.netr_to_literal(self.network_range)
            temp['address_type'] = machine_type
            print(temp)
Exemple #6
0
    def network_raw_output(self):
        """
        Returns a raw output of the local network
        """

        final = {'subnets': {}, 'routers': {}}

        for sid in self.subnetworks:
            subnet = self.subnetworks[sid]['instance']

            displayable_connected_routers = subnet.routers.copy()
            for i in displayable_connected_routers:
                displayable_connected_routers[i] = str(
                    displayable_connected_routers[i])

            final['subnets'][sid] = {
                'id': subnet.uid,
                'name': subnet.name,
                'connected_routers': displayable_connected_routers,
                'range': Utils.netr_to_literal(subnet.network_range),
                'mask': subnet.mask_length
            }

        for rid in self.routers:
            router = self.routers[rid]

            displayable_connected_subnets = router.connected_networks.copy()
            for i in displayable_connected_subnets:
                displayable_connected_subnets[i] = str(
                    displayable_connected_subnets[i])

            final['routers'][rid] = {
                'id': router.uid,
                'name': router.name,
                'connected_subnets': displayable_connected_subnets,
                'internet': router.internet
            }

        return final
Exemple #7
0
 def displayable_network_range(self):
     return Utils.netr_to_literal(self.__network_range)
Exemple #8
0
 def display_range(self, display=False) -> None:
     if display is True:
         self._display()
     else:
         print(Utils.netr_to_literal(self.network_range))
Exemple #9
0
    def connect_router_to_networks(self, router_name, subnets_ips):
        """
        Connects a router to a set of subnetworks

        Args:
            router_name: The name of the router
            subnets_ips: The list of subnetworks with the corresponding IP to assign the router to.
            Format is {SUBNET_NAME: IP, ...}
        """
        def check_ip_availability(subnet_inst_, ip_):
            """
            Checks if an IP is available

            This function is a suicider: it will die if any of the tests fail. It will either raise
            nettools.core.errors.IPOffNetworkRangeException or rth.core.errors.IPAlreadyAttributed

            Args:
                subnet_inst_: The subnetwork instance
                ip_: The IP that has to be checked
            """

            # Checking that ip is effectively in range of the subnet
            if isinstance(ip_, str):
                ip_ = FourBytesLiteral().set_from_string_literal(ip_)

            mask = FourBytesLiteral().set_from_string_literal(
                Utils.mask_length_to_literal(subnet_inst_.mask_length))
            inst = IPv4Network().init_from_fbl(ip_, mask)

            if inst.address_type != 1:
                # means the address is either a network or a broadcast address
                raise IPOffNetworkRangeException(str(ip))

            # then we check that ip is not used by any of the current routers
            routers = subnet_inst_.routers
            for r in routers:
                if str(routers[r]) == str(ip_):
                    raise IPAlreadyAttributed(name, ip_,
                                              self.uid_to_name('router', r),
                                              str(router_name))

        router_uid = self.name_to_uid('router', router_name)

        for name in subnets_ips:
            subnet_uid = self.name_to_uid('subnet', name)
            subnet_inst = self.subnetworks[subnet_uid]['instance']
            router_inst = self.routers[router_uid]

            subnet_ip = subnets_ips[name]

            # we want to attribute a "personalised" IP
            if subnet_ip:
                check_ip_availability(subnet_inst, subnet_ip)
                ip = subnet_ip
            # we will let the program set it for us
            else:

                ip = subnet_inst.network_range['end']
                while True:
                    ip = Utils.ip_before(ip)
                    try:
                        check_ip_availability(subnet_inst, ip)
                        break
                    except IPAlreadyAttributed:
                        continue

            subnet_inst.connect(router_uid, ip)
            router_inst.connect(subnet_uid, ip)

            self.subnetworks[subnet_uid]['instance'] = subnet_inst
            self.routers[router_uid] = router_inst
Exemple #10
0
    def create_network(self, ip, mask_length, name=None):
        """
        Creates a virtual subnetwork

        Args:
            ip: The given IP
            mask_length: The network mask length of the subnetwork
            name: The eventual name of the subnetwork

        """

        uid = len(self.subnetworks)

        # Name correspondency
        if name:
            result = self.is_name_existing('subnet', name)
            if result:
                raise NameAlreadyExists(name)
        else:
            name = f"<Untitled Network#ID:{uid}>"

        current = self.Network(ip, mask_length, uid, name)
        current_netr = Utils.netr_to_literal(current.network_range)

        if self.ranges:
            for sid in self.subnetworks:
                subnet = self.subnetworks[sid]['instance']
                subnetr = Utils.netr_to_literal(subnet.network_range)

                overlap = False
                if current.mask_length == subnet.mask_length:
                    # Masks are equal
                    if current_netr['start'] == subnetr['start']:
                        overlap = True
                else:
                    if current.mask_length < subnet.mask_length:
                        # New network mask is bigger, check if the existing subnetwork is inside
                        big = current_netr['start'].split('.')
                        small = subnetr['start']
                    else:
                        # New network is smaller that existing subnetwork, check if it is inside
                        small = current_netr['start']
                        big = subnetr['start'].split('.')

                    if current.mask_length <= 8:
                        if int(big[0]) <= int(small.split('.')[0]):
                            overlap = True
                    elif 8 < current.mask_length <= 16:
                        if small.startswith(f"{big[0]}") and int(
                                big[1]) <= int(small.split('.')[1]):
                            overlap = True
                    elif 16 < current.mask_length <= 24:
                        if small.startswith(f"{big[0]}.{big[1]}") and int(
                                big[2]) <= int(small.split('.')[2]):
                            overlap = True
                    elif 24 < current.mask_length <= 32:
                        if int(big[3]) <= int(small.split('.')[3]):
                            overlap = True

                if overlap:
                    raise OverlappingError(current_netr, subnetr)

        self.subnetworks[uid] = {
            'instance': current,
            'range': current.network_range
        }

        # adding to network ranges
        self.ranges.append(current.network_range)
        # also adding name if defined
        if name:
            self.subnets_names.append(name)

        return uid