From 552660e9dba43218ebd5bc0a572bd71a4668dcbe Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Thu, 29 Mar 2018 00:12:37 -0400 Subject: [PATCH] sample NAT router (no peers) --- samples/NATRouter.py | 139 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 samples/NATRouter.py diff --git a/samples/NATRouter.py b/samples/NATRouter.py new file mode 100755 index 0000000..fa9b70c --- /dev/null +++ b/samples/NATRouter.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python + +""" +This sample application presents itself as a router between an "inside" network +that sits behind a NAT and a "global" network of other NAT router peers. + +$ python NATRouter.py addr1 port1 net1 addr2 port2 net2 + + addr1 - local address like 192.168.1.10/24 + port1 - local port + net1 - local network number + addr2 - global address like 201.1.1.1:47809 + port2 - local mapped port + net2 - global network number + +The sample addresses are like running BR1 from Figure J-8, Clause J.7.5. +""" + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger +from bacpypes.consolelogging import ArgumentParser + +from bacpypes.core import run +from bacpypes.comm import bind + +from bacpypes.pdu import Address +from bacpypes.netservice import NetworkServiceAccessPoint, NetworkServiceElement +from bacpypes.bvllservice import BIPBBMD, BIPNAT, AnnexJCodec, UDPMultiplexer + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + +# +# NATRouter +# + +@bacpypes_debugging +class NATRouter: + + def __init__(self, addr1, port1, net1, addr2, port2, net2): + if _debug: NATRouter._debug("__init__ %r %r %r %r %r %r", addr1, port1, net1, addr2, port2, net2) + + # a network service access point will be needed + self.nsap = NetworkServiceAccessPoint() + + # give the NSAP a generic network layer service element + self.nse = NetworkServiceElement() + bind(self.nse, self.nsap) + + #== First stack + + # local address + local_addr = Address("{}:{}".format(addr1, port1)) + + # create a BBMD stack + self.s1_bip = BIPBBMD(local_addr) + self.s1_annexj = AnnexJCodec() + self.s1_mux = UDPMultiplexer(local_addr) + + # bind the bottom layers + bind(self.s1_bip, self.s1_annexj, self.s1_mux.annexJ) + + # bind the BIP stack to the local network + self.nsap.bind(self.s1_bip, net1, addr1) + + #== Second stack + + # global address + global_addr = Address(addr2) + nat_addr = Address("{}:{}".format(addr1, port2)) + + # create a NAT stack + self.s2_bip = BIPNAT(global_addr) + self.s2_annexj = AnnexJCodec() + self.s2_mux = UDPMultiplexer(nat_addr) + + # bind the bottom layers + bind(self.s2_bip, self.s2_annexj, self.s2_mux.annexJ) + + # bind the BIP stack to the global network + self.nsap.bind(self.s2_bip, net2) + +# +# __main__ +# + +def main(): + # parse the command line arguments + parser = ArgumentParser(description=__doc__) + + # add an argument for local address + parser.add_argument('addr1', type=str, + help='address of first network', + ) + + # add an argument for local port + parser.add_argument('port1', type=int, + help='port number of local network', + ) + + # add an argument for interval + parser.add_argument('net1', type=int, + help='network number of local network', + ) + + # add an argument for interval + parser.add_argument('addr2', type=str, + help='address of global network (outside NAT)', + ) + + # add an argument for local port + parser.add_argument('port2', type=int, + help='port number of global forwarded port', + ) + + # add an argument for interval + parser.add_argument('net2', type=int, + help='network number of global network', + ) + + # now parse the arguments + args = parser.parse_args() + + if _debug: _log.debug("initialization") + if _debug: _log.debug(" - args: %r", args) + + # create the router + router = NATRouter(args.addr1, args.port1, args.net1, args.addr2, args.port2, args.net2) + if _debug: _log.debug(" - router: %r", router) + + _log.debug("running") + + run() + + _log.debug("fini") + + +if __name__ == "__main__": + main()