mirror of https://github.com/dirtbags/netarch.git
Add xmodem example
This commit is contained in:
parent
8cd7cb0bdc
commit
6a1cbaec73
|
@ -11,6 +11,9 @@ and room to grow these explorations into full-blown decoders.
|
|||
Get going
|
||||
=========
|
||||
|
||||
Documentation sucks, sorry.
|
||||
The way we go about things is to copy `dumbdecode.py` to a new file,
|
||||
Documentation doesn't exist. Sorry.
|
||||
The way we go about things is to copy [dumbdecode](examples/dumbdecode.py) to a new file,
|
||||
and start hacking onto it.
|
||||
|
||||
You may find the [example xmodem decoder](examples/xmodem.py) to be helpful!
|
||||
It illustrates a fair amount of what the library provides.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#! /usr/bin/python3
|
||||
|
||||
import netarch
|
||||
import sys
|
||||
|
||||
class DumbPacket(netarch.Packet):
|
||||
def parse(self, data):
|
||||
|
@ -10,4 +9,4 @@ class DumbPacket(netarch.Packet):
|
|||
class DumbSession(netarch.Session):
|
||||
Packet = DumbPacket
|
||||
|
||||
netarch.main(DumbSession, sys.argv[1:])
|
||||
netarch.main(DumbSession)
|
Binary file not shown.
|
@ -0,0 +1,45 @@
|
|||
#! /usr/bin/python3
|
||||
|
||||
import netarch
|
||||
|
||||
class XmodemPacket(netarch.Packet):
|
||||
def parse(self, data):
|
||||
datastream = netarch.Unpacker(data)
|
||||
self.opcode = datastream.uint8()
|
||||
self.payload = datastream.buf
|
||||
|
||||
def opcode_1(self):
|
||||
"Xfer"
|
||||
datastream = netarch.Unpacker(self.payload)
|
||||
self["seq"] = datastream.uint8()
|
||||
self["~seq"] = datastream.uint8()
|
||||
|
||||
assert self["seq"] == 255 - self["~seq"]
|
||||
assert len(datastream.buf) == 0x81
|
||||
|
||||
self["checksum"] = datastream.uint8(pos=-1)
|
||||
self.payload = datastream.buf
|
||||
|
||||
def opcode_4(self):
|
||||
"EOT"
|
||||
|
||||
def opcode_6(self):
|
||||
"ACK"
|
||||
|
||||
def opcode_21(self):
|
||||
"Begin transmission?"
|
||||
|
||||
class XmodemSession(netarch.Session):
|
||||
Packet = XmodemPacket
|
||||
|
||||
def process(self, packet):
|
||||
packet.show()
|
||||
|
||||
if packet.opcode == 21:
|
||||
# Open a new file for output
|
||||
self.out = self.open_out("data.bin")
|
||||
elif packet.opcode == 1:
|
||||
self.out.write(bytes(packet.payload))
|
||||
|
||||
|
||||
netarch.main(XmodemSession)
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
import binascii
|
||||
import struct
|
||||
import sys
|
||||
from . import ip
|
||||
|
||||
from .unpack import Unpacker
|
||||
|
||||
|
||||
def cstring(buf):
|
||||
|
@ -180,8 +181,10 @@ def _registry(encoding):
|
|||
|
||||
codecs.register(_registry)
|
||||
|
||||
def main(session, pcaps):
|
||||
def main(session, pcaps=None):
|
||||
s = None
|
||||
if not pcaps:
|
||||
pcaps = sys.argv[1:]
|
||||
reseq = ip.Dispatch(*pcaps)
|
||||
for _, d in reseq:
|
||||
srv, first, chunk = d
|
||||
|
|
|
@ -39,7 +39,7 @@ class Unpacker:
|
|||
self.endian = endian
|
||||
self.buf = buf
|
||||
|
||||
def uint(self, size, endian=None):
|
||||
def uint(self, size, pos=0, endian=None):
|
||||
endian = endian or self.endian
|
||||
if size not in (8, 16, 32, 64):
|
||||
# XXX: I'm pretty sure this can be done, but I don't want to code it up right now.
|
||||
|
@ -53,20 +53,22 @@ class Unpacker:
|
|||
r = (1, 0, 3, 2, 5, 4, 7, 6)[:noctets]
|
||||
else:
|
||||
raise ValueError("Unsupported byte order")
|
||||
pull, self.buf = self.buf[:noctets], self.buf[noctets:]
|
||||
if pos < 0:
|
||||
pos += len(self.buf)
|
||||
pull, self.buf = self.buf[pos:pos+noctets], self.buf[:pos] + self.buf[pos+noctets:]
|
||||
acc = 0
|
||||
for i in r:
|
||||
acc = (acc << 8) | pull[i]
|
||||
return acc
|
||||
|
||||
def uint8(self):
|
||||
return self.uint(8)
|
||||
def uint16(self, endian=None):
|
||||
return self.uint(16, endian)
|
||||
def uint32(self, endian=None):
|
||||
return self.uint(32, endian)
|
||||
def uint64(self, endian=None):
|
||||
return self.uint(64, endian)
|
||||
def uint8(self, pos=0):
|
||||
return self.uint(8, pos)
|
||||
def uint16(self, pos=0, endian=None):
|
||||
return self.uint(16, pos, endian)
|
||||
def uint32(self, pos=0, endian=None):
|
||||
return self.uint(32, pos, endian)
|
||||
def uint64(self, pos=0, endian=None):
|
||||
return self.uint(64, pos, endian)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
|
2
setup.py
2
setup.py
|
@ -38,7 +38,7 @@ setup(
|
|||
# For a discussion on single-sourcing the version across setup.py and the
|
||||
# project code, see
|
||||
# https://packaging.python.org/en/latest/single_source_version.html
|
||||
version='1.0.1', # Required
|
||||
version='2.1.0', # Required
|
||||
|
||||
# This is a one-line description or tagline of what your project does. This
|
||||
# corresponds to the "Summary" metadata field:
|
||||
|
|
Loading…
Reference in New Issue