jsommers / switchyard Goto Github PK
View Code? Open in Web Editor NEWSwitchyard is a Python 3-based framework for building networked system software.
Home Page: https://jsommers.github.io/switchyard/
License: GNU General Public License v3.0
Switchyard is a Python 3-based framework for building networked system software.
Home Page: https://jsommers.github.io/switchyard/
License: GNU General Public License v3.0
Would it be possible to allow initialization of packet headers with their attributes?
Right now it is a bit cumbersome that you have to create a default header first and then set its attributes.
For example, I would love to be able to do this:
import switchyard.lib.packet as packet
ip = packet.IPv4(srcip='0.0.0.1', dstip='10.1.1.4')
What is the rationale behind leaving out these attributes from __init__
?
When inserting a debugger() call into a user program, a Bdb exception occurs if the debugger is exited while the program still running. This is very likely because the debugger() call is implemented using the pdb module rather than by subclassing Bdb (or possibly subclassing Pdb). In any case, the additional exception is confusing and needs to be eliminated.
If one wants to create a new protocol and corresponding packet header, and if the header would normally appear as a layer 3 or 4 protocol, it's not possible to change EtherType or IPProtocol w/o going in and modifying switchyard.lib.packet.common directly since the relevant enumerations are constant once created.
To fix this, will probably need to subclass IntEnum and create an appropriate method for adding new values to the enumeration.
Note that this isn't a limitation for app layer protocols, since Switchyard has no notion of mappings from ports to applications, so there are no restrictions on ports (i.e., they're just ints, not a value from an enumeration).
Code to generate the error
from switchyard.lib.packet import *
icmptype = ICMPType.DestinationUnreachable
hdr = ICMP(icmptype=icmptype, icmpcode=ICMPTypeCodeMap[icmptype].NetworkUnreachable)
Error message:
ValueError('Invalid code 0 for type 8',)
def __init__(self, **kwargs):
for attrname, value in kwargs.items():
setattr(self, attrname, value)
In the code above, when iterating kwargs
, the sequence of its values being iterated could not be ensured. In the case of error, the icmpcode
is being set before icmptype
, which is not valid for the default EchoRequest
icmptype.
I know index based accessing of headers from packets is possible, but had you considered allowing access by header type?
For examples, right now to get the ARP header I can do pkt[1]
or pkt.get_header(Arp)
. What about allowing pkt[Arp]
?
Support for IPv6 is minimal through the framework. Some work on packet header classes has been done, but has been tested in only limited ways. Interface class doesn't support ip6 addresses, and doesn't presently support multiple addresses of any kind.
Looks like a gap in the linux subsystem. A workaround shouldn't be too painful.
No loss of precision due to float conversion.
When a test fails, particularly an output matching expectation, the diagnosis statement can be a bit convoluted and difficult to parse --- it should be improved. Here's an example of a packet output expectation failure, with a couple predicates and inexact matching. It should be easier for someone to read this and immediately pick out the main points.
You called send_packet and while the output port router-eth0 is ok, a inexact match of packet contents passed, but when comparing the packet you sent versus what I expected, the predicate (lambda pkt: pkt[-2].msgtype==4 and len(pkt[-1])==2) passed, the predicate (lambda pkt: set([a.network for a in pkt[-1]])=={IPv4Network("10.0.0.0/30"), IPv4Network("10.0.13.0/24")}) passed, and the predicate (lambda pkt: set([a.routerid for a in pkt[-1]])=={0,2}) failed. Packet field comparisons matched correctly: Ethernet 10:00:00:00:00:01->e0:00:00:00:00:00 IP | IPv4 10.0.0.1->10.0.0.2 OSPF | LSHeader LinkStateUpdate routerid: 13 areaid: 0 | LSUpdate seq 3 ttl 10: <router 0, 10.0.0.0/30>, <router 0, 10.0.13.0/24>..
Getting thrown into pdb when a test fails is a great feature, but I wish I could instead use a different python debugger.
For example, ipdb adds tab completion and a bunch of other goodies (by IPython). wdb is pretty sweet, allowing you to debug your python code in your browser. My favorite is probably pudb, which is a " full-screen, console-based visual debugger for Python."
I am not asking switchyard to provide support for any of these, but it would be really helpful if there was an easy way to swap in another debugger, maybe if there was some Debugger
base class that anyone could subclass.
I did a quick search of pdb
in the code and found a few places where it crops up, and would have to be extracted out of and abstracted away.
First off there is the switchyard/lib/debug.py, which has this pdb
specific line
pdb.Pdb(skip=['switchyard.lib.debug']).set_trace()
Then there is this monster block of code in switchyard/switch_test.py.
# patched-up post mortem pdb session to make sure
# that we start in the right place
p = pdb.Pdb(skip=['switchyard.lib.testing','switchyard.switchy_test'])
p.reset()
count = 0
xtb = tb
while xtb is not None:
count += 1
codestr = str(xtb.tb_frame.f_code)
syscode = ('switchyard/switchy_test.py' in codestr or 'switchyard/lib/testing.py' in codestr)
if not syscode:
break
xtb = xtb.tb_next
if xtb is None:
count -= 1
p.setup(None, tb)
for i in range(count):
p.onecmd('up')
p.cmdloop()
It does a lot of hairy things with pdb, that I am pretty sure not all of the other debuggers I mentioned support (but maybe I am wrong). Would it be possible there to do something a little dummer and still retain enough functionality?
pdb.run(debugstmt, globals={}, locals=xlocals)
import pdb
pdb.post_mortem()
When running in debian:jessie it won't load the libpcacp
library.
File "/switchyard/srpy.py", line 14, in <module>
from switchyard.lib.hostfirewall import Firewall
File "/switchyard/switchyard/lib/hostfirewall.py", line 7, in <module>
from switchyard.lib.common import log_warn, log_info, log_debug
File "/switchyard/switchyard/lib/common.py", line 10, in <module>
from switchyard.lib.pcapffi import pcap_devices
File "/switchyard/switchyard/lib/pcapffi.py", line 386, in <module>
_PcapFfi() # instantiate singleton
File "/switchyard/switchyard/lib/pcapffi.py", line 130, in __init__
self._libpcap = self._ffi.dlopen('libpcap.so')
File "/usr/local/lib/python3.4/site-packages/cffi/api.py", line 118, in dlopen
lib, function_cache = _make_ffi_library(self, name, flags)
File "/usr/local/lib/python3.4/site-packages/cffi/api.py", line 411, in _make_ffi_library
backendlib = _load_backend_lib(backend, libname, flags)
File "/usr/local/lib/python3.4/site-packages/cffi/api.py", line 400, in _load_backend_lib
return backend.load_library(name, flags)
OSError: cannot load library libpcap.so: libpcap.so: cannot open shared object file: No such file or directory
This is because it is looking for libcap.so
and in debian this library is called libcap.so.0.8
(when installed with apt-get install libpcap-dev
).
If I replace that line with self._ffi.dlopen('libpcap.so.0.8')
the library loads fine.
I am temporarily dealing with it by creating a symlink
$ ln -s /usr/lib/x86_64-linux-gnu/libpcap.so.0.8 /usr/lib/x86_64-linux-gnu/libpcap.so
Should there be a try...except...
there to look for multiple path libraries?
This is my first time dealing with C libraries, so maybe the problem isn't with switchyard but just with how I'm installing libpcap or linking it or something.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.