def GetNet(self, query): """Expand a network token into a list of nacaddr.IPv4 objects. Args: query: Network definition token which may include comment text Raises: BadNetmaskTypeError: Results when an unknown netmask_type is specified. Acceptable values are 'cidr', 'netmask', and 'hostmask'. Returns: List of nacaddr.IPv4 objects Raises: UndefinedAddressError: for an undefined token value """ returnlist = [] data = [] token = '' data = query.split('#') # Get the token keyword and remove any comment token = data[0].split()[ 0] # Remove whitespace and cast from list to string if token not in self.networks: raise UndefinedAddressError('%s %s' % ('\nUNDEFINED:', str(token))) for next in self.networks[token].items: comment = '' if next.find('#') > -1: (net, comment) = next.split('#', 1) else: net = next try: net = net.strip() addr = nacaddr.IP(net) # we want to make sure that we're storing the network addresses # ie, FOO = 192.168.1.1/24 should actually return 192.168.1.0/24 if addr.ip != addr.network: addr = nacaddr.IP('%s/%d' % (addr.network, addr.prefixlen)) addr.text = comment.lstrip() addr.token = token returnlist.append(addr) except ValueError: # if net was something like 'FOO', or the name of another token which # needs to be dereferenced, nacaddr.IP() will return a ValueError returnlist.extend(self.GetNet(net)) for next in returnlist: next.parent_token = token return returnlist
def GetIpParents(self, query): """Return network tokens that contain IP in query. Args: query: an ip string ('10.1.1.1') or nacaddr.IP object """ base_parents = [] recursive_parents = [] # convert string to nacaddr, if arg is ipaddr then convert str() to nacaddr if type(query) != nacaddr.IPv4 and type(query) != nacaddr.IPv6: if query[:1].isdigit(): query = nacaddr.IP(query) # Get parent token for an IP if type(query) == nacaddr.IPv4 or type(query) == nacaddr.IPv6: for token in self.networks: for item in self.networks[token].items: item = item.split('#')[0].strip() if item[:1].isdigit() and nacaddr.IP(item).Contains(query): base_parents.append(token) # Get parent token for another token else: for token in self.networks: for item in self.networks[token].items: item = item.split('#')[0].strip() if item[:1].isalpha() and item == query: base_parents.append(token) # look for nested tokens for bp in base_parents: done = False for token in self.networks: if bp in self.networks[token].items: # ignore IPs, only look at token values if bp[:1].isalpha(): if bp not in recursive_parents: recursive_parents.append(bp) recursive_parents.extend(self.GetIpParents(bp)) done = True # if no nested tokens, just append value if not done: if bp[:1].isalpha() and bp not in recursive_parents: recursive_parents.append(bp) return sorted(list(set(recursive_parents)))
def __init__( self, pol, src='any', dst='any', sport='any', dport='any', proto='any', ): self.pol_obj = pol self.proto = proto # validate source port if sport == 'any': self.sport = sport else: self.sport = port.Port(sport) # validate destination port if dport == 'any': self.dport = dport else: self.dport = port.Port(dport) # validate source address if src == 'any': self.src = src else: try: self.src = nacaddr.IP(src) except ValueError: raise AddressError('bad source address: %s\n' % src) # validate destination address if dst == 'any': self.dst = dst else: try: self.dst = nacaddr.IP(dst) except ValueError: raise AddressError('bad destination address: %s\n' % dst) if type(self.pol_obj) is not policy.Policy: raise BadPolicy('Policy object is not valid.') self.matches = [] self.exact_matches = [] for header, terms in self.pol_obj.filters: filtername = header.target[0].options[0] for term in terms: possible = [] logging.debug('checking term: %s', term.name) if not self._AddrInside(self.src, term.source_address): logging.debug('srcaddr does not match') continue logging.debug('srcaddr matches: %s', self.src) if not self._AddrInside(self.dst, term.destination_address): logging.debug('dstaddr does not match') continue logging.debug('dstaddr matches: %s', self.dst) if (self.sport != 'any' and term.source_port and not self._PortInside(self.sport, term.source_port)): logging.debug('sport does not match') continue logging.debug('sport matches: %s', self.sport) if (self.dport != 'any' and term.destination_port and not self._PortInside( self.dport, term.destination_port)): logging.debug('dport does not match') continue logging.debug('dport matches: %s', self.dport) if (self.proto != 'any' and term.protocol and self.proto not in term.protocol): logging.debug('proto does not match') continue logging.debug('proto matches: %s', self.proto) if term.protocol_except and self.proto in term.protocol_except: logging.debug('protocol excepted by term, no match.') continue logging.debug('proto not excepted: %s', self.proto) if not term.action: # avoid any verbatim logging.debug('term had no action (verbatim?), no match.') continue logging.debug('term has an action') possible = self._PossibleMatch(term) self.matches.append( Match(filtername, term.name, possible, term.action, term.qos)) if possible: logging.debug( 'term has options: %s, not treating as exact match', possible) continue # if we get here then we have a match, and if the action isn't next and # there are no possibles, then this is a "definite" match and we needn't # look for any further matches (i.e. later terms may match, but since # we'll never get there we shouldn't report them) if 'next' not in term.action: self.exact_matches.append( Match(filtername, term.name, [], term.action, term.qos)) break