#!/usr/bin/env python3 import argparse from enum import Enum import sys import xml.sax class ParserState(Enum): NOOP = 0 DISCARD = 1 CAPTURE = 2 class IPDisallowedHandler(xml.sax.ContentHandler): TRANSITIONS = { "address": ParserState.CAPTURE, "source": ParserState.CAPTURE, "destination": ParserState.CAPTURE, "global": ParserState.CAPTURE, } def __init__(self): self._reset() def _reset(self): self._state = ParserState.NOOP self._address = None self._source = None self._destination = None self._global = None self._content = "" def _processElement(self, name): pass def startElement(self, name, attrs): if name == "record": self._state = ParserState.DISCARD return if self._state == ParserState.NOOP: return self._state = self.TRANSITIONS.get(name, ParserState.DISCARD) def endElement(self, name): if name == "record": if self._address is not None: self._processElement() self._reset() if self._state == ParserState.NOOP: return if self._content == "": return self._content = self._content.strip() if name == "address": self._address = self._content.split(", ") if name == "source": self._source = self._content == "True" if name == "destination": self._destination = self._content == "True" if name == "global": self._global = self._content == "True" self._content = "" self._state = ParserState.DISCARD def characters(self, content): if self._state != ParserState.CAPTURE: return self._content += content class IPDisallowedInboundHandler(IPDisallowedHandler): def _processElement(self): if not self._source: for address in self._address: print(address) class IPDisallowedOutboundHandler(IPDisallowedHandler): def _processElement(self): # Document states: # > If the value of "Destination" is FALSE, the values of # > "Forwardable" and "Globally Reachable" must also be false. # So, `self._destination == False` implies `self._global == # False.` For this reason, it's enough to test for # `self._global == False`. if not self._global: for address in self._address: print(address) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("direction", choices=["inbound", "outbound"]) args = parser.parse_args() if args.direction == "inbound": handler = IPDisallowedInboundHandler() else: handler = IPDisallowedOutboundHandler() xml.sax.parse(sys.stdin, handler)