def calc_dhcp_range_start(ip, prefix, start):
    """calucale a good dhcp range start"""
    ip_int = int(ipaddress.IPv4Address(ip))
    netmask_int = int(
        ipaddress.IPv4Address(network_util.ipv4_prefix_to_netmask(prefix)))
    start_int = int(ipaddress.IPv4Address(start))
    return start_int - (ip_int & netmask_int)
    def write_interface_v4_alias(self, intf, alias, count, settings):
        """
        Write an IPv4 alias interface
        """
        file = self.network_file

        file.write("\n")
        file.write("config interface '%s'\n" % (intf['logical_name']+"4"+"_"+str(count)))
        if intf.get('is_bridge'):
            # https://wiki.openwrt.org/doc/uci/network#aliasesthe_new_way
            # documentation says to use "br-" plus logical name
            file.write("\toption ifname '%s'\n" % ("br-"+intf['ifname']))
        else:
            file.write("\toption ifname '%s'\n" % intf['ifname'])
        file.write("\toption proto 'static'\n")
        file.write("\toption ipaddr '%s'\n" % alias.get('v4Address'))
        file.write("\toption netmask '%s'\n" % network_util.ipv4_prefix_to_netmask(alias.get('v4Prefix')))
    def write_interface_v4_config(self, intf, settings):
        """
        Writes the actual IPv4 configuration options for an interface
        This is a separate function because depending on the configuration this may be written in different locations
        """
        file = self.network_file

        if intf.get('v4ConfigType') == "DHCP":
            if not intf.get('wan'):
                raise Exception('Invalid v4ConfigType: Can not use DHCP on non-WAN interfaces')
            file.write("\toption proto 'dhcp'\n")
        elif intf.get('v4ConfigType') == "STATIC":
            file.write("\toption proto 'static'\n")
            file.write("\toption force_link '0'\n")
            file.write("\toption ipaddr '%s'\n" % intf.get('v4StaticAddress'))
            file.write("\toption netmask '%s'\n" % network_util.ipv4_prefix_to_netmask(intf.get('v4StaticPrefix')))
            if intf.get('wan') and intf.get('v4StaticGateway') != None:
                file.write("\toption gateway '%s'\n" % intf.get('v4StaticGateway'))
        elif intf.get('v4ConfigType') == "PPPOE":
            if not intf.get('wan'):
                raise Exception('Invalid v4ConfigType: Can not use PPPOE on non-WAN interfaces')
            file.write("\toption proto 'pppoe'\n")
            # FIXME
            # If its PPPoE the "netfilterDev" is the actual device that netfilter rules should match on
            # In this case we need to set 'netfilterDev' to 'pppX' so subsequent modules know the proper
            # netfilter device to use
            # intf['netfilterDev'] = ppp0

        elif intf.get('v4ConfigType') == "DISABLED":
            # This needs to be written for addressless bridges
            file.write("\toption proto 'none'\n")
            file.write("\toption auto '1'\n")

        if intf.get('wan') and intf.get('v4ConfigType') != "DISABLED":
            file.write("\toption ip4table 'wan.%d'\n" % intf.get('interfaceId'))

        return
    def write_dhcp_file(self, settings, prefix=""):
        """writes prefix/etc/config/dhcp"""
        filename = prefix + self.dhcp_filename
        file_dir = os.path.dirname(filename)
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)

        system = settings.get('system')
        dns = settings.get('dns')
        dhcp = settings.get('dhcp')

        file = open(filename, "w+")
        file.write("## Auto Generated\n")
        file.write("## DO NOT EDIT. Changes will be overwritten.\n")
        file.write("\n")
        file.write("config dnsmasq\n")

        interfaces = settings['network']['interfaces']

        ## Only enable dns reserver for static Ethernet or PPPoE interfaces,
        ## if those interfaces are enabled.
        dnsmasq_dns_server_template = "\tlist server '{dns_resolver_address}@{device}'\n"
        for intf in interfaces:
            if intf.get('enabled') == True and intf.get(
                    'configType'
            ) == 'ADDRESSED' and intf.get('wan') is True and intf.get(
                    'v4ConfigType') == 'STATIC':
                if intf.get('v4StaticDNS1') != None:
                    file.write(
                        DhcpManager.dnsmasq_dns_server_template.format(
                            dns_resolver_address=intf.get('v4StaticDNS1'),
                            device=intf.get('device')))
                if intf.get('v4StaticDNS2') != None:
                    file.write(
                        DhcpManager.dnsmasq_dns_server_template.format(
                            dns_resolver_address=intf.get('v4StaticDNS2'),
                            device=intf.get('device')))

            if intf.get('enabled') == True and intf.get(
                    'configType'
            ) == 'ADDRESSED' and intf.get('wan') is True and intf.get(
                    'v4ConfigType'
            ) == 'PPPOE' and intf.get('v4PPPoEUsePeerDNS') is False:
                if intf.get('v4PPPoEDNS1') != None:
                    file.write(
                        DhcpManager.dnsmasq_dns_server_template.format(
                            dns_resolver_address=intf.get('v4PPPoEDNS1'),
                            device=intf.get('device')))
                if intf.get('v4PPPoEDNS2') != None:
                    file.write(
                        DhcpManager.dnsmasq_dns_server_template.format(
                            dns_resolver_address=intf.get('v4PPPoEDNS2'),
                            device=intf.get('device')))

        if dns.get('localServers') != None:
            for local_server in dns.get('localServers'):
                file.write("\tlist server '/%s/%s'\n" %
                           (local_server.get('domain'),
                            local_server.get('localServer')))

        if system.get('domainName') != None:
            file.write("\toption domain '%s'\n" % system.get('domainName'))

        file.write("\toption expandhosts '1'\n")
        file.write("\toption nonegcache '0'\n")
        if dhcp.get('dhcpAuthoritative') is True:
            file.write("\toption authoritative '1'\n")
        else:
            file.write("\toption authoritative '0'\n")

        file.write("\tlist interface '*'\n")
        file.write("\toption localise_queries '1'\n")
        file.write("\toption nohosts '1'\n")
        file.write("\toption domainneeded '0'\n")
        file.write("\toption boguspriv '0'\n")
        file.write("\toption filterwin2k '0'\n")
        file.write("\toption readethers '0'\n")
        file.write("\toption rebind_protection '0'\n")
        file.write("\toption rebind_localhost '0'\n")
        file.write("\toption nonwildcard '0'\n")
        file.write("\toption localservice '0'\n")
        file.write("\toption dhcpleasemax '5000'\n")
        file.write("\toption dnsforwardmax '512'\n")
        file.write("\toption leasefile '/tmp/dhcp.leases'\n")
        file.write("\toption resolvfile '/tmp/resolv.conf.auto'\n")
        file.write("\tlist addnhosts '/tmp/hosts.untangle'\n")

        file.write("\n")

        dhcpv6_in_use = False

        # If relay is enabled on a WAN intf. then we need to adjust LAN intf config appropriately
        dhcpv6_relay_enabled = False
        for intf in interfaces:
            if intf.get('v6RelayEnabled'):
                dhcpv6_relay_enabled = True

        for intf in interfaces:
            if intf.get('configType') == 'ADDRESSED':
                interface_name = network_util.get_interface_name(
                    settings, intf, "ipv4")

                file.write("config dhcp '%s'\n" % interface_name)
                if intf.get('dhcpEnabled') is True:
                    if intf.get('v4ConfigType') != 'DISABLED':
                        file.write("\toption interface '%s'\n" %
                                   interface_name)
                        file.write("\toption force 1\n")
                        file.write(
                            "\toption start '%d'\n" %
                            calc_dhcp_range_start(intf.get('v4StaticAddress'),
                                                  intf.get('v4StaticPrefix'),
                                                  intf.get('dhcpRangeStart')))
                        file.write(
                            "\toption limit '%d'\n" %
                            calc_dhcp_range_limit(intf.get('dhcpRangeStart'),
                                                  intf.get('dhcpRangeEnd')))

                        if intf.get('dhcpLeaseDuration') != None and intf.get(
                                'dhcpLeaseDuration') != 0:
                            file.write("\toption leasetime '%d'\n" %
                                       intf.get('dhcpLeaseDuration'))
                        else:
                            file.write("\toption leasetime '3600'\n")

                        if intf.get(
                                'dhcpGatewayOverride') != None and intf.get(
                                    'dhcpGatewayOverride') != "" and intf.get(
                                        'dhcpGatewayOverride') != 0:
                            file.write("\tlist dhcp_option '3,%s'\n" %
                                       intf.get('dhcpGatewayOverride'))
                        else:
                            file.write("\tlist dhcp_option '3,%s'\n" %
                                       intf.get('v4StaticAddress'))

                        if intf.get('dhcpPrefixOverride') != None and intf.get(
                                'dhcpPrefixOverride') != "" and intf.get(
                                    'dhcpPrefixOverride') != 0:
                            file.write("\tlist dhcp_option '1,%s'\n" %
                                       network_util.ipv4_prefix_to_netmask(
                                           intf.get('dhcpPrefixOverride')))
                        else:
                            file.write("\tlist dhcp_option '1,%s'\n" %
                                       network_util.ipv4_prefix_to_netmask(
                                           intf.get('v4StaticPrefix')))

                        if intf.get('dhcpDNSOverride') != None and intf.get(
                                'dhcpDNSOverride') != "":
                            dns_servers = intf.get('dhcpDNSOverride')
                        else:
                            dns_servers = intf.get('v4StaticAddress')

                        file.write("\tlist dhcp_option '6,%s'\n" % dns_servers)

                        if intf.get('dhcpOptions') != None:
                            for dhcp_option in intf.get('dhcpOptions'):
                                if dhcp_option.get(
                                        'enabled'
                                ) is None or not dhcp_option.get('enabled'):
                                    continue
                                file.write("\tlist dhcp_option '%s'\n" %
                                           dhcp_option.get('value'))

                    if intf.get('v6ConfigType') != 'DISABLED':
                        dhcpv6_in_use = True
                        if dhcpv6_relay_enabled:
                            write_relay_options(file, intf.get('wan'))
                        else:
                            file.write("\toption dhcpv6 'server'\n")
                            file.write("\toption ra 'server'\n")

                    file.write("\n")
                else:
                    file.write("\toption interface '%s'\n" % interface_name)
                    # Only add relay options to interfaces that have IPv6 enabled, or if they are a WAN with relay enabled
                    if (intf.get('wan') is False
                            and intf.get('v6ConfigType') is not None
                            and intf.get('v6ConfigType') != 'DISABLED'
                            and dhcpv6_relay_enabled
                        ) or intf.get('v6RelayEnabled'):
                        write_relay_options(file, intf.get('wan'))
                    else:
                        file.write("\toption ignore '1'\n")
                    file.write("\n")

        if dhcpv6_in_use is True:
            file.write("config odhcpd 'odhcpd'\n")
            file.write("\toption maindhcp '0'\n")
            file.write("\toption leasefile '/tmp/hosts/odhcpd'\n")
            file.write("\toption leasetrigger '/usr/sbin/odhcpd-update'\n")
            file.write("\toption loglevel '4'\n")
            file.write("\n")

        if dns.get('staticEntries') != None:
            for entry in dns.get('staticEntries'):
                if entry.get('name') != None and entry.get('address') != None:
                    file.write("config 'domain'\n")
                    file.write("\toption name '%s'\n" % entry.get('name'))
                    file.write("\toption ip '%s'\n" % entry.get('address'))
                    file.write("\n")

        if dhcp.get('staticDhcpEntries') != None:
            for entry in dhcp.get('staticDhcpEntries'):
                if entry.get('macAddress') != None and entry.get(
                        'address') != None:
                    file.write("config 'host'\n")
                    file.write("\toption ip '%s'\n" % entry.get('address'))
                    file.write("\toption mac '%s'\n" % entry.get('macAddress'))
                    file.write("\n")

        file.flush()
        file.close()

        print("%s: Wrote %s" % (self.__class__.__name__, filename))
Exemple #5
0
    def write_dhcp_file(self, settings, prefix=""):
        filename = prefix + self.dhcp_filename
        file_dir = os.path.dirname(filename)
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)

        system = settings.get('system')
        dns = settings.get('dns')
        dhcp = settings.get('dhcp')

        self.network_file = open(filename, "w+")
        file = self.network_file
        file.write("## Auto Generated\n")
        file.write("## DO NOT EDIT. Changes will be overwritten.\n")
        file.write("\n")
        file.write("config dnsmasq\n")

        interfaces = settings['network']['interfaces']
        for intf in interfaces:
            if intf.get('configType') == 'ADDRESSED' and intf.get(
                    'wan') == True and intf.get('v4ConfigType') == 'STATIC':
                if intf.get('v4StaticDNS1') != None:
                    file.write("\tlist server '%s'\n" %
                               intf.get('v4StaticDNS1'))
                if intf.get('v4StaticDNS2') != None:
                    file.write("\tlist server '%s'\n" %
                               intf.get('v4StaticDNS2'))

            if intf.get('configType') == 'ADDRESSED' and intf.get(
                    'wan') == True and intf.get(
                        'v4ConfigType') == 'PPPOE' and intf.get(
                            'v4PPPoEUsePeerDNS') == False:
                if intf.get('v4PPPoEDNS1') != None:
                    file.write("\tlist server '%s'\n" %
                               intf.get('v4PPPoEDNS1'))
                if intf.get('v4PPPoEDNS2') != None:
                    file.write("\tlist server '%s'\n" %
                               intf.get('v4PPPoEDNS2'))

        if dns.get('localServers') != None:
            for local_server in dns.get('localServers'):
                file.write("\tlist server '/%s/%s'\n" %
                           (local_server.get('domain'),
                            local_server.get('localServer')))

        if system.get('domainName') != None:
            file.write("\toption domain '%s'\n" % system.get('domainName'))

        file.write("\toption expandhosts '1'\n")
        file.write("\toption nonegcache '0'\n")
        if dhcp.get('dhcpAuthoritative') == True:
            file.write("\toption authoritative '1'\n")
        else:
            file.write("\toption authoritative '0'\n")

        file.write("\tlist interface '*'\n")
        file.write("\toption localise_queries '1'\n")
        file.write("\toption nohosts '1'\n")
        file.write("\toption domainneeded '0'\n")
        file.write("\toption boguspriv '0'\n")
        file.write("\toption filterwin2k '0'\n")
        file.write("\toption readethers '0'\n")
        file.write("\toption rebind_protection '0'\n")
        file.write("\toption rebind_localhost '0'\n")
        file.write("\toption nonwildcard '0'\n")
        file.write("\toption localservice '0'\n")
        file.write("\toption dhcpleasemax '5000'\n")
        file.write("\toption leasefile '/tmp/dhcp.leases'\n")
        file.write("\toption resolvfile '/tmp/resolv.conf.auto'\n")
        file.write("\tlist addnhosts '/tmp/hosts.untangle'\n")

        file.write("\n")

        for intf in interfaces:
            if intf.get('configType') == 'ADDRESSED':
                if intf.get('is_bridge'):
                    interface_name = "b_" + intf.get('name') + "4"
                else:
                    interface_name = intf.get('name') + "4"

                file.write("config dhcp '%s'\n" % interface_name)
                if intf.get('dhcpEnabled') == True:
                    file.write("\toption interface '%s'\n" % interface_name)
                    file.write(
                        "\toption start '%d'\n" %
                        calc_dhcp_range_start(intf.get('v4StaticAddress'),
                                              intf.get('v4StaticPrefix'),
                                              intf.get('dhcpRangeStart')))
                    file.write("\toption limit '%d'\n" % calc_dhcp_range_limit(
                        intf.get('dhcpRangeStart'), intf.get('dhcpRangeEnd')))

                    if intf.get('dhcpLeaseDuration') != None and intf.get(
                            'dhcpLeaseDuration') != 0:
                        file.write("\toption leasetime '%d'\n" %
                                   intf.get('dhcpLeaseDuration'))
                    else:
                        file.write("\toption leasetime '3600'\n")

                    file.write("\toption dhcpv6 'server'\n")
                    file.write("\toption ra 'server'\n")

                    if intf.get('v4DhcpGatewayOverride') != None and intf.get(
                            'v4DhcpGatewayOverride') != "":
                        file.write("\tlist dhcp_option '3,%s'\n" %
                                   intf.get('v4DhcpGatewayOverride'))
                    else:
                        file.write("\tlist dhcp_option '3,%s'\n" %
                                   intf.get('v4StaticAddress'))

                    if intf.get('v4DhcpPrefixOverride') != None and intf.get(
                            'v4DhcpPrefixOverride') != "":
                        file.write("\tlist dhcp_option '1,%s'\n" %
                                   network_util.ipv4_prefix_to_netmask(
                                       intf.get('v4DhcpPrefixOverride')))
                    else:
                        file.write("\tlist dhcp_option '1,%s'\n" %
                                   network_util.ipv4_prefix_to_netmask(
                                       intf.get('v4StaticPrefix')))

                    if intf.get('v4DhcpDNS1Override') != None and intf.get(
                            'v4DhcpDNS1Override') != "":
                        DNSServers = intf.get('v4DhcpDNS1Override')
                    else:
                        DNSServers = intf.get('v4StaticAddress')

                    if intf.get('v4DhcpDNS2Override') != None and intf.get(
                            'v4DhcpDNS2Override') != "":
                        DNSServers = DNSServers + "," + intf.get(
                            'v4DhcpDNS2Override')

                    file.write("\tlist dhcp_option '6,%s'\n" % DNSServers)

                    if intf.get('dhcpOptions') != None:
                        for dhcpOption in intf.get('dhcpOptions'):
                            if dhcpOption.get(
                                    'enabled'
                            ) == None or not dhcpOption.get('enabled'):
                                continue
                            file.write("\tlist dhcp_option '%s'\n" %
                                       dhcpOption.get('value'))

                    file.write("\n")
                else:
                    file.write("\toption interface '%s'\n" % interface_name)
                    file.write("\toption ignore '1'\n")
                    file.write("\n")

        file.write("config odhcpd 'odhcpd'\n")
        file.write("\toption maindhcp '0'\n")
        file.write("\toption leasefile '/tmp/hosts/odhcpd'\n")
        file.write("\toption leasetrigger '/usr/sbin/odhcpd-update'\n")
        file.write("\toption loglevel '4'\n")
        file.write("\n")

        if dns.get('staticEntries') != None:
            for entry in dns.get('staticEntries'):
                if entry.get('name') != None and entry.get('address') != None:
                    file.write("config 'domain'\n")
                    file.write("\toption name '%s'\n" % entry.get('name'))
                    file.write("\toption ip '%s'\n" % entry.get('address'))
                    file.write("\n")

        if dhcp.get('staticDhcpEntries') != None:
            for entry in dhcp.get('staticDhcpEntries'):
                if entry.get('macAddress') != None and entry.get(
                        'address') != None:
                    file.write("config 'host'\n")
                    file.write("\toption ip '%s'\n" % entry.get('address'))
                    file.write("\toption mac '%s'\n" % entry.get('macAddress'))
                    file.write("\n")

        file.flush()
        file.close()

        print("%s: Wrote %s" % (self.__class__.__name__, filename))