kifurushi: a little python library for your protocol implementation
Kifurushi makes it simple to implement a network protocol.
This article aims to talk about my latest work in the python landscape. It is oriented for network protocol implementors.
During my daily work, I see a lot of stuff related to the DNS protocol. I’m not working directly on it, but this caught my curiosity, and I started to study it. And the best way to learn is to.. practice! So I start interacted with the protocol using the excellent scapy library. It is a library implementing many network protocols and help you experiment as much as you like. I wanted to start a simple DNS client with it and.. I thought it might be too much to import such a big library to handle only one protocol. May be this is what library authors like does who did h2 or aioquic also think to not use this awesome library (or may be they don’t know it at all). Anyway, It would be glad to just use the scapy ability to forge packets without importing the huge protocol library. This is where the idea of kifurushi comes from.
You can install kifurushi using the pip command.
pip install kifurushi
You can also use an alternative python dependency manager like poetry. If you don’t know it, I have a nice introduction about it here.
poetry add kifurushi
The usage is pretty simple. Here is an example of a simple packet class created with kifurushi
- You create a new protocol by inheriting the Packet class. In this example, the protocol Disney has three fields.
- A two-bytes integer field called mickey whose default value is 2.
- A one byte integer field called minnie whose default value is 3. You notice the hex keyword set to true. It is to tell that we prefer the hexadecimal representation when displaying this field information.
- The last field is a four-byte field. It is slightly different from the first two (notice the Enum in the class name) . It takes a third mandatory argument which is an enum, or a dict mapping values to a literal representation easier to remember for the user.
- The list of all fields is available here.
Now let’s show a more complete example where we use our class to send and receive data from network (which is the main goal of this library).
We will assume in the following example that we have an hypothetical server called disney-stuff.com listening on port 14006 capable of understanding the Disney protocol.
- You can set packet attributes using the field name like on line 26.
- To get the binary representation of a packet, you use its raw property (line 28).
- To get a packet instance from raw bytes, we use the from_bytes class method (line 30).
See you soon for a next article, stay safe. 😁
If you like my article and want to continue learning with me, don’t hesitate to follow me here and subscribe to my newsletter 😉