1# Copyright 2016 - The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import collections 16import copy 17import ipaddress 18 19 20class Subnet(object): 21 """Configs for a subnet on the dhcp server. 22 23 Attributes: 24 network: ipaddress.IPv4Network, the network that this subnet is in. 25 start: ipaddress.IPv4Address, the start ip address. 26 end: ipaddress.IPv4Address, the end ip address. 27 router: The router to give to all hosts in this subnet. 28 lease: The lease time of all hosts in this subnet. 29 """ 30 31 def __init__(self, 32 subnet, 33 start=None, 34 end=None, 35 router=None, 36 lease_time=None): 37 """ 38 Args: 39 subnet_address: ipaddress.IPv4Network, The network that this 40 subnet is. 41 start: ipaddress.IPv4Address, The start of the address range to 42 give hosts in this subnet. If not given then the first ip in 43 the network is used. 44 end: ipaddress.IPv4Address, The end of the address range to give 45 hosts. If not given then the last ip in the network is used. 46 router: ipaddress.IPv4Address, The router hosts should use in this 47 subnet. If not given the first ip in the network is used. 48 lease_time: int, The amount of lease time in seconds 49 hosts in this subnet have. 50 """ 51 self.network = subnet 52 53 if start: 54 self.start = start 55 else: 56 self.start = self.network[2] 57 58 if not self.start in self.network: 59 raise ValueError('The start range is not in the subnet.') 60 if self.start.is_reserved: 61 raise ValueError('The start of the range cannot be reserved.') 62 63 if end: 64 self.end = end 65 else: 66 self.end = self.network[-2] 67 68 if not self.end in self.network: 69 raise ValueError('The end range is not in the subnet.') 70 if self.end.is_reserved: 71 raise ValueError('The end of the range cannot be reserved.') 72 if self.end < self.start: 73 raise ValueError( 74 'The end must be an address larger than the start.') 75 76 if router: 77 if router >= self.start and router <= self.end: 78 raise ValueError('Router must not be in pool range.') 79 if not router in self.network: 80 raise ValueError('Router must be in the given subnet.') 81 82 self.router = router 83 else: 84 # TODO: Use some more clever logic so that we don't have to search 85 # every host potentially. 86 self.router = None 87 for host in self.network.hosts(): 88 if host < self.start or host > self.end: 89 self.router = host 90 break 91 92 if not self.router: 93 raise ValueError('No useable host found.') 94 95 self.lease_time = lease_time 96 97 98class StaticMapping(object): 99 """Represents a static dhcp host. 100 101 Attributes: 102 identifier: How id of the host (usually the mac addres 103 e.g. 00:11:22:33:44:55). 104 address: ipaddress.IPv4Address, The ipv4 address to give the host. 105 lease_time: How long to give a lease to this host. 106 """ 107 108 def __init__(self, identifier, address, lease_time=None): 109 self.identifier = identifier 110 self.ipv4_address = address 111 self.lease_time = lease_time 112 113 114class DhcpConfig(object): 115 """The configs for a dhcp server. 116 117 Attributes: 118 subnets: A list of all subnets for the dhcp server to create. 119 static_mappings: A list of static host addresses. 120 default_lease_time: The default time for a lease. 121 max_lease_time: The max time to allow a lease. 122 """ 123 124 def __init__(self, 125 subnets=None, 126 static_mappings=None, 127 default_lease_time=600, 128 max_lease_time=7200): 129 self.subnets = copy.deepcopy(subnets) if subnets else [] 130 self.static_mappings = (copy.deepcopy(static_mappings) 131 if static_mappings else []) 132 self.default_lease_time = default_lease_time 133 self.max_lease_time = max_lease_time 134