tweak setup.py to work with multiple top-level files.
silence lots of warnings. add unicode box characters and --ascii, --unicode
This commit is contained in:
parent
4e8326ea6c
commit
23d27c8e72
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__pycache__
|
||||||
|
protocol.egg-info
|
13
constants.py
13
constants.py
@ -15,7 +15,7 @@
|
|||||||
# -> E-Mail: luis.mgarc@gmail.com #
|
# -> E-Mail: luis.mgarc@gmail.com #
|
||||||
# -> WWWW: http://www.luismg.com #
|
# -> WWWW: http://www.luismg.com #
|
||||||
# -> GitHub: https://github.com/luismartingarcia #
|
# -> GitHub: https://github.com/luismartingarcia #
|
||||||
# # #
|
# #
|
||||||
################################################################################
|
################################################################################
|
||||||
# #
|
# #
|
||||||
# This file is part of Protocol. #
|
# This file is part of Protocol. #
|
||||||
@ -52,18 +52,17 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Application name
|
# Application name
|
||||||
APPLICATION_NAME="Protocol"
|
APPLICATION_NAME = "Protocol"
|
||||||
|
|
||||||
# Current version
|
# Current version
|
||||||
APPLICATION_VERSION="0.1.0"
|
APPLICATION_VERSION = "0.1.0"
|
||||||
|
|
||||||
# Author
|
# Author
|
||||||
APPLICATION_AUTHOR="Luis MartinGarcia"
|
APPLICATION_AUTHOR = "Luis MartinGarcia"
|
||||||
|
|
||||||
# Author E-mail
|
# Author E-mail
|
||||||
APPLICATION_AUTHOR_EMAIL="luis.mgarc@gmail.com"
|
APPLICATION_AUTHOR_EMAIL = "luis.mgarc@gmail.com"
|
||||||
|
|
||||||
# Operation return codes
|
# Operation return codes
|
||||||
OP_SUCCESS = 0 # Function performed operation successfully
|
OP_SUCCESS = 0 # Function performed operation successfully
|
||||||
OP_FAILURE = -1 # Error encountered while performing operation
|
OP_FAILURE = -1 # Error encountered while performing operation
|
||||||
|
|
||||||
|
613
protocol
613
protocol
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
################################################################################
|
################################################################################
|
||||||
# ____ _ _ #
|
# ____ _ _ #
|
||||||
# | _ \ _ __ ___ | |_ ___ ___ ___ | | #
|
# | _ \ _ __ ___ | |_ ___ ___ ___ | | #
|
||||||
@ -60,7 +60,11 @@ import sys
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
# INTERNAL IMPORTS
|
# INTERNAL IMPORTS
|
||||||
from constants import *
|
from constants import (
|
||||||
|
APPLICATION_NAME, APPLICATION_VERSION,
|
||||||
|
APPLICATION_AUTHOR, APPLICATION_AUTHOR_EMAIL,
|
||||||
|
OP_FAILURE, OP_SUCCESS
|
||||||
|
)
|
||||||
import specs
|
import specs
|
||||||
|
|
||||||
|
|
||||||
@ -69,8 +73,9 @@ class ProtocolException(Exception):
|
|||||||
"""
|
"""
|
||||||
This class represents exceptions raised by the Protocol class
|
This class represents exceptions raised by the Protocol class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, errmsg):
|
def __init__(self, errmsg):
|
||||||
self.errmsg=errmsg
|
self.errmsg = errmsg
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.errmsg)
|
return str(self.errmsg)
|
||||||
@ -88,17 +93,33 @@ class Protocol():
|
|||||||
Class constructor.
|
Class constructor.
|
||||||
@param spec is the textual specification that describes the protocol.
|
@param spec is the textual specification that describes the protocol.
|
||||||
"""
|
"""
|
||||||
self.hdr_char_start="+" # Character for start of the border line
|
# unicode
|
||||||
self.hdr_char_end="+" # Character for end of the border line
|
self.u_top_hdr_char_start = "┌" # Character for start of the top border line
|
||||||
self.hdr_char_fill_odd="+" # Fill character for border odd positions
|
self.u_top_hdr_char_end = "┐" # Character for end of the top border line
|
||||||
self.hdr_char_fill_even="-" # Fill character for border even positions
|
self.u_bottom_hdr_char_start = "└" # Character for start of the bottom border line
|
||||||
self.hdr_char_sep="|" # Field separator character
|
self.u_bottom_hdr_char_end = "┘" # Character for end of the bottom border line
|
||||||
self.bits_per_line=32 # Number of bits per line
|
self.u_hdr_char_start = "├" # Character for start of the border line
|
||||||
self.do_print_top_tens=True # True: print top numbers for bit tens
|
self.u_hdr_char_end = "┤" # Character for end of the border line
|
||||||
self.do_print_top_units=True # True: print top numbers for bit units
|
self.u_hdr_char_fill = "─" # Fill character for border positions
|
||||||
self.field_list=[] # Header fields to be printed out
|
self.u_hdr_char_sep = "│" # Field separator character
|
||||||
self.parse_spec(spec) # Parse the received spec and populate self.field_list
|
self.u_hdr_connector_down = '┬'
|
||||||
|
self.u_hdr_connector_up = '┴'
|
||||||
|
self.u_hdr_connector_cross = '┼'
|
||||||
|
|
||||||
|
# ASCII
|
||||||
|
self.hdr_char_start = "+" # Character for start of the border line
|
||||||
|
self.hdr_char_end = "+" # Character for end of the border line
|
||||||
|
self.hdr_char_fill_odd = "+" # Fill character for border odd positions
|
||||||
|
self.hdr_char_fill_even = "-" # Fill character for border even positions
|
||||||
|
self.hdr_char_sep = "|" # Field separator character
|
||||||
|
|
||||||
|
self.bits_per_line = 32 # Number of bits per line
|
||||||
|
self.do_print_top_tens = True # True: print top numbers for bit tens
|
||||||
|
self.do_print_top_units = True # True: print top numbers for bit units
|
||||||
|
self.do_ascii = True # True: print ASCII box characters
|
||||||
|
self.do_unicode = False # False: print unicode box characters
|
||||||
|
self.field_list = [] # Header fields to be printed out
|
||||||
|
self.parse_spec(spec) # Parse the received spec and populate self.field_list
|
||||||
|
|
||||||
def parse_spec(self, spec):
|
def parse_spec(self, spec):
|
||||||
"""
|
"""
|
||||||
@ -110,62 +131,76 @@ class Protocol():
|
|||||||
@raise ProtocolException in case the supplied spec is not valid
|
@raise ProtocolException in case the supplied spec is not valid
|
||||||
"""
|
"""
|
||||||
if "?" in spec:
|
if "?" in spec:
|
||||||
parts=spec.split("?")
|
parts = spec.split("?")
|
||||||
fields=parts[0]
|
fields = parts[0]
|
||||||
opts=parts[1]
|
opts = parts[1]
|
||||||
if spec.count("?")>1:
|
if spec.count("?") > 1:
|
||||||
raise ProtocolException("FATAL: Character '?' may only be used as an option separator.")
|
raise ProtocolException(
|
||||||
|
"FATAL: Character '?' may only be used as an option separator."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
fields=spec
|
fields = spec
|
||||||
opts=None
|
opts = None
|
||||||
|
|
||||||
# Parse field spec
|
# Parse field spec
|
||||||
items=fields.split(",")
|
items = fields.split(",")
|
||||||
for item in items:
|
for item in items:
|
||||||
try:
|
try:
|
||||||
text, bits = item.split(":")
|
text, bits = item.split(":")
|
||||||
bits=int(bits)
|
bits = int(bits)
|
||||||
if bits<=0:
|
if bits <= 0:
|
||||||
raise ProtocolException("FATAL: Fields must be at least one bit long (%s)" %spec)
|
raise ProtocolException(
|
||||||
|
"FATAL: Fields must be at least one bit long (%s)" % spec
|
||||||
|
)
|
||||||
except ProtocolException:
|
except ProtocolException:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
raise ProtocolException("FATAL: Invalid field_list specification (%s)" %spec)
|
raise ProtocolException(
|
||||||
self.field_list.append({"text":text, "len":bits})
|
"FATAL: Invalid field_list specification (%s)" % spec
|
||||||
|
)
|
||||||
|
self.field_list.append({"text": text, "len": bits})
|
||||||
|
|
||||||
# Parse options
|
# Parse options
|
||||||
if opts is not None:
|
if opts is not None:
|
||||||
opts=opts.split(",")
|
opts = opts.split(",")
|
||||||
for opt in opts:
|
for opt in opts:
|
||||||
try:
|
try:
|
||||||
var, value = opt.split("=")
|
var, value = opt.split("=")
|
||||||
if var.lower()=="bits":
|
if var.lower() == "bits":
|
||||||
self.bits_per_line=int(value)
|
self.bits_per_line = int(value)
|
||||||
if self.bits_per_line<=0:
|
if self.bits_per_line <= 0:
|
||||||
raise ProtocolException("FATAL: Invalid value for 'bits' option (%s)" % value)
|
raise ProtocolException(
|
||||||
elif var.lower()=="numbers":
|
"FATAL: Invalid value for 'bits' option (%s)" % value
|
||||||
|
)
|
||||||
|
elif var.lower() == "numbers":
|
||||||
if value.lower() in ["0", "n", "no", "none", "false"]:
|
if value.lower() in ["0", "n", "no", "none", "false"]:
|
||||||
self.do_print_top_tens=False
|
self.do_print_top_tens = False
|
||||||
self.do_print_top_units=False
|
self.do_print_top_units = False
|
||||||
elif value.lower() in ["1", "y", "yes", "none", "true"]:
|
elif value.lower() in ["1", "y", "yes", "none", "true"]:
|
||||||
self.do_print_top_tens=True
|
self.do_print_top_tens = True
|
||||||
self.do_print_top_units=True
|
self.do_print_top_units = True
|
||||||
else:
|
else:
|
||||||
raise ProtocolException("FATAL: Invalid value for 'numbers' option (%s)" % value)
|
raise ProtocolException(
|
||||||
elif var.lower() in ["oddchar", "evenchar", "startchar", "endchar", "sepchar"]:
|
"FATAL: Invalid value for 'numbers' option (%s)" % value
|
||||||
if len(value)>1 or len(value)<=0:
|
)
|
||||||
raise ProtocolException("FATAL: Invalid value for '%s' option (%s)" % (var, value))
|
elif var.lower() in [
|
||||||
|
"oddchar", "evenchar", "startchar", "endchar", "sepchar"
|
||||||
|
]:
|
||||||
|
if len(value) > 1 or len(value) <= 0:
|
||||||
|
raise ProtocolException(
|
||||||
|
"FATAL: Invalid value for '%s' option (%s)" % (var, value)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if var.lower()=="oddchar":
|
if var.lower() == "oddchar":
|
||||||
self.hdr_char_fill_odd=value
|
self.hdr_char_fill_odd = value
|
||||||
elif var.lower()=="evenchar":
|
elif var.lower() == "evenchar":
|
||||||
self.hdr_char_fill_even=value
|
self.hdr_char_fill_even = value
|
||||||
elif var.lower()=="startchar":
|
elif var.lower() == "startchar":
|
||||||
self.hdr_char_start=value
|
self.hdr_char_start = value
|
||||||
elif var.lower()=="endchar":
|
elif var.lower() == "endchar":
|
||||||
self.hdr_char_end=value
|
self.hdr_char_end = value
|
||||||
elif var.lower()=="sepchar":
|
elif var.lower() == "sepchar":
|
||||||
self.hdr_char_sep=value
|
self.hdr_char_sep = value
|
||||||
except ProtocolException:
|
except ProtocolException:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
@ -173,7 +208,6 @@ class Protocol():
|
|||||||
|
|
||||||
return self.field_list
|
return self.field_list
|
||||||
|
|
||||||
|
|
||||||
def _get_top_numbers(self):
|
def _get_top_numbers(self):
|
||||||
"""
|
"""
|
||||||
@return a string representing the bit units and bit tens on top of the
|
@return a string representing the bit units and bit tens on top of the
|
||||||
@ -182,23 +216,22 @@ class Protocol():
|
|||||||
The returned string is not \n terminated, but it may contain a newline
|
The returned string is not \n terminated, but it may contain a newline
|
||||||
character in the middle.
|
character in the middle.
|
||||||
"""
|
"""
|
||||||
lines=["", ""]
|
lines = ["", ""]
|
||||||
if self.do_print_top_tens is True:
|
if self.do_print_top_tens is True:
|
||||||
for i in range(0, self.bits_per_line):
|
for i in range(0, self.bits_per_line):
|
||||||
if str(i)[-1:]=="0":
|
if str(i)[-1:] == "0":
|
||||||
lines[0]+=" %s" % str(i)[0]
|
lines[0] += " %s" % str(i)[0]
|
||||||
else:
|
else:
|
||||||
lines[0]+=" "
|
lines[0] += " "
|
||||||
lines[0]+="\n"
|
lines[0] += "\n"
|
||||||
if self.do_print_top_units is True:
|
if self.do_print_top_units is True:
|
||||||
for i in range(0, self.bits_per_line):
|
for i in range(0, self.bits_per_line):
|
||||||
lines[1]+=" %s" % str(i)[-1:]
|
lines[1] += " %s" % str(i)[-1:]
|
||||||
#lines[1]+="\n"
|
# lines[1] += "\n"
|
||||||
result = "".join(lines)
|
result = "".join(lines)
|
||||||
return result if len(result)>0 else None
|
return result if len(result) > 0 else None
|
||||||
|
|
||||||
|
def _get_horizontal(self, width=None, textline=None, fields=None, bottom=False, offset=0):
|
||||||
def _get_horizontal(self, width=None):
|
|
||||||
"""
|
"""
|
||||||
@return the horizontal border line that separates field rows.
|
@return the horizontal border line that separates field rows.
|
||||||
@param width controls how many field bits the line should cover. By
|
@param width controls how many field bits the line should cover. By
|
||||||
@ -206,23 +239,88 @@ class Protocol():
|
|||||||
the header.
|
the header.
|
||||||
"""
|
"""
|
||||||
if width is None:
|
if width is None:
|
||||||
width=self.bits_per_line
|
width = self.bits_per_line
|
||||||
if width<=0:
|
elif width <= 0:
|
||||||
return ""
|
return ""
|
||||||
else:
|
|
||||||
a="%s" % self.hdr_char_start
|
|
||||||
b=(self.hdr_char_fill_even+self.hdr_char_fill_odd)*(width-1)
|
|
||||||
c="%s%s" % (self.hdr_char_fill_even, self.hdr_char_end)
|
|
||||||
return a+b+c
|
|
||||||
|
|
||||||
|
# if above first text line then at the top
|
||||||
|
if textline == 1:
|
||||||
|
top = True
|
||||||
|
else:
|
||||||
|
top = False
|
||||||
|
|
||||||
|
# first character of the line
|
||||||
|
if self.do_unicode:
|
||||||
|
if top is True or offset > 0:
|
||||||
|
a = "%s" % self.u_top_hdr_char_start
|
||||||
|
elif bottom is True:
|
||||||
|
if width < self.bits_per_line:
|
||||||
|
a = "%s" % self.u_hdr_char_start
|
||||||
|
else:
|
||||||
|
a = "%s" % self.u_bottom_hdr_char_start
|
||||||
|
else:
|
||||||
|
a = "%s" % self.u_hdr_char_start
|
||||||
|
else:
|
||||||
|
a = "%s" % self.hdr_char_start
|
||||||
|
|
||||||
|
if self.do_unicode:
|
||||||
|
# create the baseline
|
||||||
|
chars = []
|
||||||
|
for i in range(2 * (width-1)):
|
||||||
|
chars.append(self.u_hdr_char_fill)
|
||||||
|
|
||||||
|
# look at fields to determine where up or down connections are made
|
||||||
|
start_above = set()
|
||||||
|
start_below = set()
|
||||||
|
for field in fields:
|
||||||
|
if field["start"] != 0:
|
||||||
|
if field["line"] == textline:
|
||||||
|
index = 2 * field["start"] - 1
|
||||||
|
if index < len(chars):
|
||||||
|
chars[index] = self.u_hdr_connector_down
|
||||||
|
start_above.add(field["start"])
|
||||||
|
# if field["line"] == textline - 1 and field["MF"] is False:
|
||||||
|
if field["line"] == textline - 1:
|
||||||
|
index = 2 * field["start"] - 1
|
||||||
|
if index < len(chars):
|
||||||
|
chars[index] = self.u_hdr_connector_up
|
||||||
|
start_below.add(field["start"])
|
||||||
|
|
||||||
|
# look for cross connectors
|
||||||
|
if top is False and bottom is False:
|
||||||
|
positions = start_above.intersection(start_below)
|
||||||
|
for position in positions:
|
||||||
|
chars[2 * position - 1] = self.u_hdr_connector_cross
|
||||||
|
|
||||||
|
b = "".join(chars)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# if ASCII, alternate +- characters between first and last
|
||||||
|
b = (self.hdr_char_fill_even+self.hdr_char_fill_odd)*(width-1)
|
||||||
|
|
||||||
|
# last character of the line
|
||||||
|
if self.do_unicode:
|
||||||
|
if top is True:
|
||||||
|
c = "%s%s" % (self.u_hdr_char_fill, self.u_top_hdr_char_end)
|
||||||
|
elif bottom is True:
|
||||||
|
c = "%s%s" % (self.u_hdr_char_fill, self.u_bottom_hdr_char_end)
|
||||||
|
else:
|
||||||
|
# if the field ends here and the next field spans, we need a corner
|
||||||
|
# TODO
|
||||||
|
c = "%s%s" % (self.u_hdr_char_fill, self.u_hdr_char_end)
|
||||||
|
else:
|
||||||
|
c = "%s%s" % (self.hdr_char_fill_even, self.hdr_char_end)
|
||||||
|
return a+b+c
|
||||||
|
|
||||||
def _get_separator(self, line_end=""):
|
def _get_separator(self, line_end=""):
|
||||||
"""
|
"""
|
||||||
@return a string containing a protocol field separator. Returned string
|
@return a string containing a protocol field separator. Returned string
|
||||||
is a single character and matches whatever is stored in self.hdr_char_sep
|
is a single character and matches whatever is stored in self.hdr_char_sep
|
||||||
"""
|
"""
|
||||||
return self.hdr_char_sep
|
if self.do_unicode:
|
||||||
|
return self.u_hdr_char_sep
|
||||||
|
else:
|
||||||
|
return self.hdr_char_sep
|
||||||
|
|
||||||
def _process_field_list(self):
|
def _process_field_list(self):
|
||||||
"""
|
"""
|
||||||
@ -231,36 +329,43 @@ class Protocol():
|
|||||||
protocol fields that span more than one line). This is just a helper
|
protocol fields that span more than one line). This is just a helper
|
||||||
function to make __str__()'s life easier.
|
function to make __str__()'s life easier.
|
||||||
"""
|
"""
|
||||||
new_fields=[]
|
new_fields = []
|
||||||
bits_in_line=0
|
bits_in_line = 0
|
||||||
i=0
|
i = 0
|
||||||
|
text_line = 1
|
||||||
while i < len(self.field_list):
|
while i < len(self.field_list):
|
||||||
# Extract all the info we need about the field
|
# Extract all the info we need about the field
|
||||||
field=self.field_list[i]
|
field = self.field_list[i]
|
||||||
field_text= field['text']
|
field_text = field['text']
|
||||||
field_len= field['len']
|
field['MF'] = False
|
||||||
field['MF']=False
|
|
||||||
|
|
||||||
available_in_line = self.bits_per_line - bits_in_line
|
available_in_line = self.bits_per_line - bits_in_line
|
||||||
|
|
||||||
# If we have enough space on this line to include the current field
|
# If we have enough space on this line to include the current field
|
||||||
# then just keep it as it is.
|
# then just keep it as it is.
|
||||||
if available_in_line >= field_len:
|
if available_in_line >= field['len']:
|
||||||
|
field['line'] = text_line
|
||||||
|
field['start'] = bits_in_line
|
||||||
|
bits_in_line += field['len']
|
||||||
|
field['end'] = bits_in_line - 1
|
||||||
new_fields.append(field)
|
new_fields.append(field)
|
||||||
bits_in_line+=field_len
|
i += 1
|
||||||
i+=1
|
if bits_in_line == self.bits_per_line:
|
||||||
if bits_in_line==self.bits_per_line:
|
bits_in_line = 0
|
||||||
bits_in_line=0
|
text_line += 1
|
||||||
# Otherwise, split the field into two parts, one blank and one with
|
# Otherwise, split the field into two parts, one blank and one with
|
||||||
# the actual field text
|
# the actual field text
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# Case 1: We have a field that is perfectly aligned and it
|
# Case 1: We have a field that is perfectly aligned and it
|
||||||
# has a length that is multiple of our line length
|
# has a length that is multiple of our line length
|
||||||
if bits_in_line==0 and field_len%self.bits_per_line==0:
|
if bits_in_line == 0 and field['len'] % self.bits_per_line == 0:
|
||||||
|
field['start'] = 0
|
||||||
|
field['end'] = self.bits_per_line - 1
|
||||||
|
field['line'] = text_line
|
||||||
|
text_line += 1
|
||||||
new_fields.append(field)
|
new_fields.append(field)
|
||||||
i+=1
|
i += 1
|
||||||
bits_in_line=0
|
|
||||||
|
|
||||||
# Case 2: We weren't that lucky and the field is either not
|
# Case 2: We weren't that lucky and the field is either not
|
||||||
# aligned or we can't print it using an exact number of full
|
# aligned or we can't print it using an exact number of full
|
||||||
@ -269,23 +374,31 @@ class Protocol():
|
|||||||
|
|
||||||
# If we have more space in the current line than in the next,
|
# If we have more space in the current line than in the next,
|
||||||
# then put the field text in this one
|
# then put the field text in this one
|
||||||
if available_in_line >= field_len-available_in_line:
|
if available_in_line >= field['len']-available_in_line:
|
||||||
new_field = {'text':field_text, 'len':available_in_line, "MF":True}
|
new_field = {
|
||||||
|
'text': field_text, 'len': available_in_line, "MF": True,
|
||||||
|
'start': bits_in_line, 'end': self.bits_per_line - 1,
|
||||||
|
'line': text_line,
|
||||||
|
}
|
||||||
new_fields.append(new_field)
|
new_fields.append(new_field)
|
||||||
field['text']=""
|
field['text'] = ""
|
||||||
field['len']=field_len-available_in_line
|
field['len'] = field['len']-available_in_line
|
||||||
field['MF']=False
|
field['MF'] = False
|
||||||
else:
|
else:
|
||||||
new_field = {'text':"", 'len':available_in_line, "MF":True}
|
new_field = {
|
||||||
|
'text': "", 'len': available_in_line, "MF": True,
|
||||||
|
'start': bits_in_line, 'end': self.bits_per_line - 1,
|
||||||
|
'line': text_line,
|
||||||
|
}
|
||||||
new_fields.append(new_field)
|
new_fields.append(new_field)
|
||||||
field['text']=field_text
|
field['text'] = field_text
|
||||||
field['len']=field_len-available_in_line
|
field['len'] = field['len']-available_in_line
|
||||||
field['MF']=False
|
field['MF'] = False
|
||||||
bits_in_line=0
|
bits_in_line = 0
|
||||||
|
text_line += 1
|
||||||
continue
|
continue
|
||||||
return new_fields
|
return new_fields
|
||||||
|
|
||||||
|
|
||||||
# Convert to string
|
# Convert to string
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
@ -300,54 +413,56 @@ class Protocol():
|
|||||||
# First of all, process our field list. This does some magic to make
|
# First of all, process our field list. This does some magic to make
|
||||||
# the algorithm work for fields that span more than one line
|
# the algorithm work for fields that span more than one line
|
||||||
proto_fields = self._process_field_list()
|
proto_fields = self._process_field_list()
|
||||||
lines=[]
|
lines = []
|
||||||
numbers=self._get_top_numbers()
|
numbers = self._get_top_numbers()
|
||||||
if numbers is not None:
|
if numbers is not None:
|
||||||
lines.append(numbers)
|
lines.append(numbers)
|
||||||
lines.append(self._get_horizontal())
|
textline = 1
|
||||||
|
lines.append(self._get_horizontal(textline=textline, fields=proto_fields))
|
||||||
|
|
||||||
# Print all protocol fields
|
# Print all protocol fields
|
||||||
bits_in_line=0
|
bits_in_line = 0
|
||||||
current_line=""
|
current_line = ""
|
||||||
fields_done=0
|
fields_done = 0
|
||||||
p=-1
|
p = -1
|
||||||
while p < len(proto_fields)-1:
|
while p < len(proto_fields)-1:
|
||||||
p+=1
|
p += 1
|
||||||
|
|
||||||
# Extract all the info we need about the field
|
# Extract all the info we need about the field
|
||||||
field = proto_fields[p]
|
field = proto_fields[p]
|
||||||
field_text= field['text']
|
field_text = field['text']
|
||||||
field_len= field['len']
|
field_len = field['len']
|
||||||
field_mf = field['MF'] is True # Field has more fragments
|
field_mf = field['MF'] is True # Field has more fragments
|
||||||
|
|
||||||
# If the field text is too long, we truncate it, and add a dot
|
# If the field text is too long, we truncate it, and add a dot
|
||||||
# at the end.
|
# at the end.
|
||||||
if len(field_text) > (field_len*2)-1:
|
if len(field_text) > (field_len*2)-1:
|
||||||
field_text=field_text[0:(field_len*2)-1]
|
field_text = field_text[0:(field_len*2)-1]
|
||||||
if len(field_text)>1:
|
if len(field_text) > 1:
|
||||||
field_text=field_text[0:-1]+"."
|
field_text = field_text[0:-1]+"."
|
||||||
|
|
||||||
# If we have space for the whole field in the current line, go
|
# If we have space for the whole field in the current line, go
|
||||||
# ahead and add it
|
# ahead and add it
|
||||||
if self.bits_per_line-bits_in_line >= field_len:
|
if self.bits_per_line-bits_in_line >= field_len:
|
||||||
# If this is the first thing we print on a line, add the
|
# If this is the first thing we print on a line, add the
|
||||||
# starting character
|
# starting character
|
||||||
if bits_in_line==0:
|
if bits_in_line == 0:
|
||||||
current_line+=self._get_separator()
|
current_line += self._get_separator()
|
||||||
|
|
||||||
# Add the whole field
|
# Add the whole field
|
||||||
current_line+=str.center(field_text, (field_len*2)-1)
|
current_line += str.center(field_text, (field_len*2)-1)
|
||||||
|
|
||||||
# Update counters
|
# Update counters
|
||||||
bits_in_line+=field_len
|
bits_in_line += field_len
|
||||||
fields_done+=1
|
fields_done += 1
|
||||||
|
|
||||||
# If this is the last character in the line, store the line
|
# If this is the last character in the line, store the line
|
||||||
if bits_in_line==self.bits_per_line:
|
if bits_in_line == self.bits_per_line:
|
||||||
current_line+=self._get_separator()
|
current_line += self._get_separator()
|
||||||
lines.append(current_line)
|
lines.append(current_line)
|
||||||
current_line=""
|
current_line = ""
|
||||||
bits_in_line=0
|
bits_in_line = 0
|
||||||
|
textline += 1
|
||||||
# When we have a fragmented field, we may need to suppress
|
# When we have a fragmented field, we may need to suppress
|
||||||
# the floor of the field, so the current line connects
|
# the floor of the field, so the current line connects
|
||||||
# with the one that follows. E.g.:
|
# with the one that follows. E.g.:
|
||||||
@ -360,9 +475,17 @@ class Protocol():
|
|||||||
if proto_fields[p+1]['len'] > self.bits_per_line - field_len:
|
if proto_fields[p+1]['len'] > self.bits_per_line - field_len:
|
||||||
|
|
||||||
# Print some +-+-+ to cover the previous field
|
# Print some +-+-+ to cover the previous field
|
||||||
line_left=self._get_horizontal(self.bits_per_line - field_len)
|
line_left = self._get_horizontal(
|
||||||
if len(line_left)==0:
|
self.bits_per_line - field_len,
|
||||||
line_left=self.hdr_char_start
|
textline=textline,
|
||||||
|
fields=proto_fields,
|
||||||
|
bottom=True
|
||||||
|
)
|
||||||
|
if len(line_left) == 0:
|
||||||
|
if self.do_unicode:
|
||||||
|
line_left = self.u_hdr_char_start
|
||||||
|
else:
|
||||||
|
line_left = self.hdr_char_start
|
||||||
|
|
||||||
# Now print some empty space to cover the part that
|
# Now print some empty space to cover the part that
|
||||||
# we can join with the field below.
|
# we can join with the field below.
|
||||||
@ -370,66 +493,107 @@ class Protocol():
|
|||||||
# line, then we need to print whitespace until the
|
# line, then we need to print whitespace until the
|
||||||
# end our line
|
# end our line
|
||||||
if proto_fields[p+1]['len'] >= self.bits_per_line:
|
if proto_fields[p+1]['len'] >= self.bits_per_line:
|
||||||
line_center=" "* ((2*(field_len)-1))
|
line_center = " " * ((2*(field_len)-1))
|
||||||
line_right=self.hdr_char_end
|
if self.do_unicode:
|
||||||
|
line_right = self.u_hdr_char_end
|
||||||
|
else:
|
||||||
|
line_right = self.hdr_char_end
|
||||||
# Case 2: the field in the next row is not big enough
|
# Case 2: the field in the next row is not big enough
|
||||||
# to cover all the space we'd like to join, so we
|
# to cover all the space we'd like to join, so we
|
||||||
# just print whitespace to cover as much as we can
|
# just print whitespace to cover as much as we can
|
||||||
else:
|
else:
|
||||||
line_center=" "* ((2*((proto_fields[p+1]['len']-(self.bits_per_line-field_len))))-1)
|
line_center = " " * (
|
||||||
line_right=self._get_horizontal(self.bits_per_line-proto_fields[p+1]['len'])
|
(2*((proto_fields[p+1]['len']-(self.bits_per_line-field_len))))-1
|
||||||
|
)
|
||||||
|
line_right = self._get_horizontal(
|
||||||
|
self.bits_per_line-proto_fields[p+1]['len'],
|
||||||
|
textline=textline,
|
||||||
|
fields=proto_fields,
|
||||||
|
offset=len(line_left) + len(line_center)
|
||||||
|
)
|
||||||
|
|
||||||
lines.append(line_left+line_center+line_right)
|
lines.append(line_left+line_center+line_right)
|
||||||
else:
|
else:
|
||||||
lines.append(self._get_horizontal())
|
lines.append(
|
||||||
|
self._get_horizontal(textline=textline, fields=proto_fields)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
lines.append(self._get_horizontal())
|
bottom = (p == len(proto_fields) - 1)
|
||||||
|
lines.append(
|
||||||
|
self._get_horizontal(textline=textline,
|
||||||
|
fields=proto_fields,
|
||||||
|
bottom=bottom)
|
||||||
|
)
|
||||||
|
|
||||||
# If this is not the last character of the line but we have no
|
# If this is not the last character of the line but we have no
|
||||||
# more fields to print, wrap up
|
# more fields to print, wrap up
|
||||||
elif fields_done==len(proto_fields):
|
elif fields_done == len(proto_fields):
|
||||||
current_line+=self._get_separator()
|
current_line += self._get_separator()
|
||||||
lines.append(current_line)
|
lines.append(current_line)
|
||||||
lines.append(self._get_horizontal(bits_in_line))
|
lines.append(
|
||||||
|
self._get_horizontal(
|
||||||
|
bits_in_line,
|
||||||
|
textline=textline,
|
||||||
|
fields=proto_fields,
|
||||||
|
bottom=True
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Add the separator character
|
# Add the separator character
|
||||||
current_line+=self.hdr_char_sep
|
if self.do_unicode:
|
||||||
|
current_line += self.u_hdr_char_sep
|
||||||
|
else:
|
||||||
|
current_line += self.hdr_char_sep
|
||||||
|
|
||||||
# We don't have enough space for the field on this line.
|
# We don't have enough space for the field on this line.
|
||||||
else:
|
else:
|
||||||
# Case 1: We are at the beginning of a new line and we need to
|
# Case 1: We are at the beginning of a new line and we need to
|
||||||
# span more than one line
|
# span more than one line
|
||||||
if bits_in_line==0:
|
if bits_in_line == 0:
|
||||||
# Case 1a: We have a multiple of the number of bits per line
|
# Case 1a: We have a multiple of the number of bits per line
|
||||||
if field_len%self.bits_per_line==0:
|
if field_len % self.bits_per_line == 0:
|
||||||
# Compute how many lines in total we need to print for this
|
# Compute how many lines in total we need to print for this
|
||||||
# big field.
|
# big field.
|
||||||
lines_to_print = int(((field_len/self.bits_per_line)*2)-1)
|
lines_to_print = int(((field_len/self.bits_per_line)*2)-1)
|
||||||
# We print the field text in the central line
|
# We print the field text in the central line
|
||||||
central_line=int(lines_to_print/2)
|
central_line = int(lines_to_print/2)
|
||||||
# Print all those lines
|
# Print all those lines
|
||||||
for i in range(0, lines_to_print):
|
for i in range(0, lines_to_print):
|
||||||
|
|
||||||
# Let's figure out which character we need to use
|
# Let's figure out which character we need to use
|
||||||
# to start and end the current line
|
# to start and end the current line
|
||||||
if i%2==1:
|
if i % 2 == 1:
|
||||||
start_line=self.hdr_char_start
|
if self.do_unicode:
|
||||||
end_line=self.hdr_char_end
|
start_line = self.u_hdr_char_start
|
||||||
|
end_line = self.u_hdr_char_end
|
||||||
|
else:
|
||||||
|
start_line = self.hdr_char_start
|
||||||
|
end_line = self.hdr_char_end
|
||||||
else:
|
else:
|
||||||
start_line=self.hdr_char_sep
|
if self.do_unicode:
|
||||||
end_line=self.hdr_char_sep
|
start_line = self.u_hdr_char_sep
|
||||||
|
end_line = self.u_hdr_char_sep
|
||||||
|
else:
|
||||||
|
start_line = self.hdr_char_sep
|
||||||
|
end_line = self.hdr_char_sep
|
||||||
|
|
||||||
# This is the line where we need to print the field
|
# This is the line where we need to print the field
|
||||||
# text.
|
# text.
|
||||||
if i == central_line:
|
if i == central_line:
|
||||||
lines.append(start_line + str.center(field_text, (self.bits_per_line*2)-1) + end_line)
|
lines.append(start_line + str.center(field_text, (self.bits_per_line*2)-1) + end_line)
|
||||||
|
textline += 1
|
||||||
# This is a line we need to leave blank
|
# This is a line we need to leave blank
|
||||||
else:
|
else:
|
||||||
lines.append(start_line + (" " * ((self.bits_per_line*2)-1)) + end_line)
|
lines.append(start_line + (" " * ((self.bits_per_line*2)-1)) + end_line)
|
||||||
# If we just added the last line, add a horizontal separator
|
# If we just added the last line, add a horizontal separator
|
||||||
if i==lines_to_print-1:
|
if i == lines_to_print-1:
|
||||||
lines.append(self._get_horizontal())
|
if p == len(proto_fields) - 1:
|
||||||
|
bottom = True
|
||||||
|
else:
|
||||||
|
bottom = False
|
||||||
|
lines.append(
|
||||||
|
self._get_horizontal(textline=textline, fields=proto_fields, bottom=bottom)
|
||||||
|
)
|
||||||
|
|
||||||
# Case 2: We are not at the beginning of the line and we need
|
# Case 2: We are not at the beginning of the line and we need
|
||||||
# to print something that does not fit in the current line
|
# to print something that does not fit in the current line
|
||||||
@ -439,7 +603,7 @@ class Protocol():
|
|||||||
# something spanning lines in a weird manner
|
# something spanning lines in a weird manner
|
||||||
assert(False)
|
assert(False)
|
||||||
|
|
||||||
result= "\n".join(lines)
|
result = "\n".join(lines)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -453,16 +617,18 @@ class Main():
|
|||||||
"""
|
"""
|
||||||
Class constructor. Nothing fancy.
|
Class constructor. Nothing fancy.
|
||||||
"""
|
"""
|
||||||
self.cmd_line_args=None # Copy of the user argv
|
self.cmd_line_args = None # Copy of the user argv
|
||||||
self.protocols=[] # List of protocols to print out
|
self.protocols = [] # List of protocols to print out
|
||||||
self.bits_per_line=None # Number of bits per line to print
|
self.bits_per_line = None # Number of bits per line to print
|
||||||
self.skip_numbers=None # True to avoid printing bit units and tens
|
self.skip_numbers = None # True to avoid printing bit units and tens
|
||||||
self.hdr_char_start=None # Character for start of the border line
|
self.hdr_char_start = None # Character for start of the border line
|
||||||
self.hdr_char_end=None # Character for end of the border line
|
self.hdr_char_end = None # Character for end of the border line
|
||||||
self.hdr_char_fill_odd=None # Fill character for border odd positions
|
self.hdr_char_fill_odd = None # Fill character for border odd positions
|
||||||
self.hdr_char_fill_even=None # Fill character for border even positions
|
self.hdr_char_fill_even = None # Fill character for border even positions
|
||||||
self.hdr_char_sep=None # Field separator character
|
self.hdr_char_sep = None # Field separator character
|
||||||
|
|
||||||
|
self.do_ascii = True # ASCII box characters
|
||||||
|
self.do_unicode = False # unicode box characters
|
||||||
|
|
||||||
def display_help(self):
|
def display_help(self):
|
||||||
"""
|
"""
|
||||||
@ -470,7 +636,9 @@ class Main():
|
|||||||
"""
|
"""
|
||||||
print("")
|
print("")
|
||||||
print("%s v%s" % (APPLICATION_NAME, APPLICATION_VERSION))
|
print("%s v%s" % (APPLICATION_NAME, APPLICATION_VERSION))
|
||||||
print("Copyright (C) %i, %s (%s)." % (max(2014, date.today().year), APPLICATION_AUTHOR, APPLICATION_AUTHOR_EMAIL))
|
print("Copyright (C) 2014-%i, %s (%s)." % (
|
||||||
|
date.today().year, APPLICATION_AUTHOR, APPLICATION_AUTHOR_EMAIL)
|
||||||
|
)
|
||||||
print("This software comes with ABSOLUTELY NO WARRANTY.")
|
print("This software comes with ABSOLUTELY NO WARRANTY.")
|
||||||
print("")
|
print("")
|
||||||
self.display_usage()
|
self.display_usage()
|
||||||
@ -478,10 +646,12 @@ class Main():
|
|||||||
print(" <protocol> : Name of an existing protocol")
|
print(" <protocol> : Name of an existing protocol")
|
||||||
print(" <spec> : Field by field specification of non-existing protocol")
|
print(" <spec> : Field by field specification of non-existing protocol")
|
||||||
print("OPTIONS:")
|
print("OPTIONS:")
|
||||||
|
print(" -a, --ascii : Use ASCII line characters (default)")
|
||||||
print(" -b, --bits <n> : Number of bits per line")
|
print(" -b, --bits <n> : Number of bits per line")
|
||||||
print(" -f, --file : Read specs from a text file")
|
print(" -f, --file : Read specs from a text file")
|
||||||
print(" -h, --help : Displays this help information")
|
print(" -h, --help : Displays this help information")
|
||||||
print(" -n, --no-numbers : Do not print bit numbers on top of the header")
|
print(" -n, --no-numbers : Do not print bit numbers on top of the header")
|
||||||
|
print(" -u, --unicode : Use Unicode box characters")
|
||||||
print(" -V, --version : Displays current version")
|
print(" -V, --version : Displays current version")
|
||||||
print(" --evenchar <char> : Character for the even positions of horizontal table borders")
|
print(" --evenchar <char> : Character for the even positions of horizontal table borders")
|
||||||
print(" --oddchar <char> : Character for the odd positions of horizontal table borders")
|
print(" --oddchar <char> : Character for the odd positions of horizontal table borders")
|
||||||
@ -489,21 +659,18 @@ class Main():
|
|||||||
print(" --endchar <char> : Character that ends horizontal table borders")
|
print(" --endchar <char> : Character that ends horizontal table borders")
|
||||||
print(" --sepchar <char> : Character that separates protocol fields")
|
print(" --sepchar <char> : Character that separates protocol fields")
|
||||||
|
|
||||||
|
|
||||||
def get_usage(self):
|
def get_usage(self):
|
||||||
"""
|
"""
|
||||||
@return a string containing application usage information
|
@return a string containing application usage information
|
||||||
"""
|
"""
|
||||||
return "Usage: %s {<protocol> or <spec>} [OPTIONS]" % self.cmd_line_args[0]
|
return "Usage: %s {<protocol> or <spec>} [OPTIONS]" % self.cmd_line_args[0]
|
||||||
|
|
||||||
|
|
||||||
def display_usage(self):
|
def display_usage(self):
|
||||||
"""
|
"""
|
||||||
Prints usage information to standard output
|
Prints usage information to standard output
|
||||||
"""
|
"""
|
||||||
print(self.get_usage())
|
print(self.get_usage())
|
||||||
|
|
||||||
|
|
||||||
def parse_config_file(self, filename):
|
def parse_config_file(self, filename):
|
||||||
"""
|
"""
|
||||||
This method parses the supplied configuration file and adds any protocols to our
|
This method parses the supplied configuration file and adds any protocols to our
|
||||||
@ -511,33 +678,32 @@ class Main():
|
|||||||
@return The number of protocols parsed
|
@return The number of protocols parsed
|
||||||
"""
|
"""
|
||||||
|
|
||||||
i=0
|
i = 0
|
||||||
# Read the contents of the whole file
|
# Read the contents of the whole file
|
||||||
try:
|
try:
|
||||||
f = open(filename)
|
with open(filename) as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
f.close()
|
f.close()
|
||||||
except:
|
except (FileNotFoundError, PermissionError, OSError):
|
||||||
print("Error while reading file %s. Please make sure it exists and it's readable." % filename)
|
print("Error while reading file %s. Please make sure it exists and it's readable." % filename)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Parse protocol specs, line by line
|
# Parse protocol specs, line by line
|
||||||
for line in lines:
|
for line in lines:
|
||||||
# Sanitize the line
|
# Sanitize the line
|
||||||
line=line.strip()
|
line = line.strip()
|
||||||
|
|
||||||
# If it starts with #, or is an empty line ignore it
|
# If it starts with #, or is an empty line ignore it
|
||||||
if line.startswith("#") or len(line)==0:
|
if line.startswith("#") or len(line) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If we have something else, treat it as a protocol spec
|
# If we have something else, treat it as a protocol spec
|
||||||
proto=Protocol(line)
|
proto = Protocol(line)
|
||||||
self.protocols.append(proto)
|
self.protocols.append(proto)
|
||||||
i+=1
|
i += 1
|
||||||
|
|
||||||
return i
|
return i
|
||||||
|
|
||||||
|
|
||||||
def parse_cmd_line_args(self, argv, is_config_file=False):
|
def parse_cmd_line_args(self, argv, is_config_file=False):
|
||||||
"""
|
"""
|
||||||
Parses command-line arguments and stores any relevant information
|
Parses command-line arguments and stores any relevant information
|
||||||
@ -545,7 +711,7 @@ class Main():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Store a reference to command line args for later use.
|
# Store a reference to command line args for later use.
|
||||||
if is_config_file==False:
|
if is_config_file is False:
|
||||||
self.cmd_line_args = argv
|
self.cmd_line_args = argv
|
||||||
|
|
||||||
# Check we have received enough command-line parameters
|
# Check we have received enough command-line parameters
|
||||||
@ -553,74 +719,84 @@ class Main():
|
|||||||
print(self.get_usage())
|
print(self.get_usage())
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
skip_arg=False
|
skip_arg = False
|
||||||
for i in range(1, len(argv)):
|
for i in range(1, len(argv)):
|
||||||
|
|
||||||
# Useful for args like -c <filename>. This avoids parsing the
|
# Useful for args like -c <filename>. This avoids parsing the
|
||||||
# filename as it if was a command-line flag.
|
# filename as it if was a command-line flag.
|
||||||
if skip_arg==True:
|
if skip_arg is True:
|
||||||
skip_arg=False
|
skip_arg = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Spec file
|
# Spec file
|
||||||
if argv[i]=="-f" or argv[i]=="--file":
|
if argv[i] == "-f" or argv[i] == "--file":
|
||||||
# Make sure we have an actual parameter after the flag
|
# Make sure we have an actual parameter after the flag
|
||||||
if (i+1)>=len(argv):
|
if (i+1) >= len(argv):
|
||||||
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
||||||
skip_arg=True
|
skip_arg = True
|
||||||
# Parse the config file
|
# Parse the config file
|
||||||
protos = self.parse_config_file(argv[i+1])
|
protos = self.parse_config_file(argv[i+1])
|
||||||
if protos <= 0:
|
if protos <= 0:
|
||||||
return OP_FAILURE, "No protocol specifications found in the supplied file (%s)" % argv[i+1]
|
return OP_FAILURE, "No protocol specifications found in the supplied file (%s)" % argv[i+1]
|
||||||
|
|
||||||
# Bits per line
|
# Bits per line
|
||||||
elif argv[i]=="-b" or argv[i]=="--bits":
|
elif argv[i] == "-b" or argv[i] == "--bits":
|
||||||
# Make sure we have an actual parameter after the flag
|
# Make sure we have an actual parameter after the flag
|
||||||
if (i+1)>=len(argv):
|
if (i+1) >= len(argv):
|
||||||
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
||||||
skip_arg=True
|
skip_arg = True
|
||||||
# Parse the config file
|
# Parse the config file
|
||||||
try:
|
try:
|
||||||
self.bits_per_line=int(argv[i+1])
|
self.bits_per_line = int(argv[i+1])
|
||||||
if self.bits_per_line<=0:
|
if self.bits_per_line <= 0:
|
||||||
return OP_FAILURE, "Invalid number of bits per line supplied (%s)" % argv[i+1]
|
return OP_FAILURE, "Invalid number of bits per line supplied (%s)" % argv[i+1]
|
||||||
except:
|
except:
|
||||||
return OP_FAILURE, "Invalid number of bits per line supplied (%s)" % argv[i+1]
|
return OP_FAILURE, "Invalid number of bits per line supplied (%s)" % argv[i+1]
|
||||||
|
|
||||||
# Avoid displaying numbers on top of the header
|
# Avoid displaying numbers on top of the header
|
||||||
elif argv[i]=="-n" or argv[i]=="--no-numbers":
|
elif argv[i] == "-n" or argv[i] == "--no-numbers":
|
||||||
self.skip_numbers=True
|
self.skip_numbers = True
|
||||||
|
|
||||||
|
# Use ASCII line characters
|
||||||
|
elif argv[i] == "-a" or argv[i] == "--ascii":
|
||||||
|
self.do_ascii = True
|
||||||
|
self.do_unicode = False
|
||||||
|
|
||||||
|
# Use Unicode box characters
|
||||||
|
elif argv[i] == "-u" or argv[i] == "--unicode":
|
||||||
|
self.do_ascii = False
|
||||||
|
self.do_unicode = True
|
||||||
|
|
||||||
# Character variations
|
# Character variations
|
||||||
elif argv[i] in ["--oddchar", "--evenchar", "--startchar", "--endchar", "--sepchar"]:
|
elif argv[i] in ["--oddchar", "--evenchar", "--startchar", "--endchar", "--sepchar"]:
|
||||||
# Make sure we have an actual parameter after the flag
|
# Make sure we have an actual parameter after the flag
|
||||||
if (i+1)>=len(argv):
|
if (i+1) >= len(argv):
|
||||||
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
return OP_FAILURE, "Expected parameter after %s\n%s" % (argv[i], self.get_usage())
|
||||||
skip_arg=True
|
skip_arg = True
|
||||||
|
|
||||||
# Make sure we got a single character, not more
|
# Make sure we got a single character, not more
|
||||||
if len(argv[i+1])!=1:
|
if len(argv[i+1]) != 1:
|
||||||
return OP_FAILURE, "A single character is expected after %s\n%s" % (argv[i], self.get_usage())
|
return OP_FAILURE, "A single character is expected after %s\n%s" % (argv[i], self.get_usage())
|
||||||
|
|
||||||
# Now let's store whatever character spec we got
|
# Now let's store whatever character spec we got
|
||||||
if argv[i]=="--oddchar":
|
if argv[i] == "--oddchar":
|
||||||
self.hdr_char_fill_odd=argv[i+1]
|
self.hdr_char_fill_odd = argv[i+1]
|
||||||
elif argv[i]=="--evenchar":
|
elif argv[i] == "--evenchar":
|
||||||
self.hdr_char_fill_even=argv[i+1]
|
self.hdr_char_fill_even = argv[i+1]
|
||||||
elif argv[i]=="--startchar":
|
elif argv[i] == "--startchar":
|
||||||
self.hdr_char_start=argv[i+1]
|
self.hdr_char_start = argv[i+1]
|
||||||
elif argv[i]=="--endchar":
|
elif argv[i] == "--endchar":
|
||||||
self.hdr_char_end=argv[i+1]
|
self.hdr_char_end = argv[i+1]
|
||||||
elif argv[i]=="--sepchar":
|
elif argv[i] == "--sepchar":
|
||||||
self.hdr_char_sep=argv[i+1]
|
self.hdr_char_sep = argv[i+1]
|
||||||
|
|
||||||
# Display help
|
# Display help
|
||||||
elif argv[i]=="-h" or argv[i]=="--help":
|
elif argv[i] == "-h" or argv[i] == "--help":
|
||||||
self.display_help()
|
self.display_help()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# Display version
|
# Display version
|
||||||
elif argv[i]=="-V" or argv[i]=="--version":
|
elif argv[i] == "-V" or argv[i] == "--version":
|
||||||
print("%s v%s" % (APPLICATION_NAME, APPLICATION_VERSION))
|
print("%s v%s" % (APPLICATION_NAME, APPLICATION_VERSION))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
@ -632,7 +808,7 @@ class Main():
|
|||||||
# Protocol name or protocol spec
|
# Protocol name or protocol spec
|
||||||
else:
|
else:
|
||||||
# If it contains ":" characters, we have a protocol spec
|
# If it contains ":" characters, we have a protocol spec
|
||||||
if argv[i].count(":")>0:
|
if argv[i].count(":") > 0:
|
||||||
spec = argv[i]
|
spec = argv[i]
|
||||||
# Otherwise, the user meant to display an existing protocol
|
# Otherwise, the user meant to display an existing protocol
|
||||||
else:
|
else:
|
||||||
@ -643,17 +819,17 @@ class Main():
|
|||||||
# we need to figure out which protocol the user meant.
|
# we need to figure out which protocol the user meant.
|
||||||
# If the specification is ambiguous, we will error
|
# If the specification is ambiguous, we will error
|
||||||
else:
|
else:
|
||||||
start_with_the_same=[]
|
start_with_the_same = []
|
||||||
for spec in specs.protocols:
|
for spec in specs.protocols:
|
||||||
if spec.startswith(argv[i]):
|
if spec.startswith(argv[i]):
|
||||||
start_with_the_same.append(spec)
|
start_with_the_same.append(spec)
|
||||||
# If we only have one entry, it means we got some
|
# If we only have one entry, it means we got some
|
||||||
# shortened version of the protocol name but no
|
# shortened version of the protocol name but no
|
||||||
# ambiguity. In that case, we will use the match.
|
# ambiguity. In that case, we will use the match.
|
||||||
if len(start_with_the_same)==1:
|
if len(start_with_the_same) == 1:
|
||||||
spec=specs.protocols[start_with_the_same[0]]
|
spec = specs.protocols[start_with_the_same[0]]
|
||||||
elif len(start_with_the_same)==0:
|
elif len(start_with_the_same) == 0:
|
||||||
print("ERROR: supplied protocol '%s' does not exist." % argv[i]);
|
print("ERROR: supplied protocol '%s' does not exist." % argv[i])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
print("Ambiguous protocol specifier '%s'. Did you mean any of these?" % argv[i])
|
print("Ambiguous protocol specifier '%s'. Did you mean any of these?" % argv[i])
|
||||||
@ -671,14 +847,12 @@ class Main():
|
|||||||
print("ERROR: %s" % str(e))
|
print("ERROR: %s" % str(e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(self.protocols)==0:
|
if len(self.protocols) == 0:
|
||||||
print("ERROR: Missing protocol")
|
print("ERROR: Missing protocol")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return OP_SUCCESS, None
|
return OP_SUCCESS, None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""
|
"""
|
||||||
This is Protocol's 'core' method: parses command line argument and prints
|
This is Protocol's 'core' method: parses command line argument and prints
|
||||||
@ -687,7 +861,7 @@ class Main():
|
|||||||
|
|
||||||
# Parse command-line arguments
|
# Parse command-line arguments
|
||||||
code, err = self.parse_cmd_line_args(sys.argv)
|
code, err = self.parse_cmd_line_args(sys.argv)
|
||||||
if code!=OP_SUCCESS:
|
if code != OP_SUCCESS:
|
||||||
print("ERROR: %s" % err)
|
print("ERROR: %s" % err)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@ -700,24 +874,29 @@ class Main():
|
|||||||
self.protocols[i].bits_per_line = self.bits_per_line
|
self.protocols[i].bits_per_line = self.bits_per_line
|
||||||
if self.skip_numbers is not None:
|
if self.skip_numbers is not None:
|
||||||
if self.skip_numbers is True:
|
if self.skip_numbers is True:
|
||||||
self.protocols[i].do_print_top_tens=False
|
self.protocols[i].do_print_top_tens = False
|
||||||
self.protocols[i].do_print_top_units=False
|
self.protocols[i].do_print_top_units = False
|
||||||
else:
|
else:
|
||||||
self.protocols[i].do_print_top_tens=True
|
self.protocols[i].do_print_top_tens = True
|
||||||
self.protocols[i].do_print_top_units=True
|
self.protocols[i].do_print_top_units = True
|
||||||
|
if self.do_unicode is True:
|
||||||
|
self.protocols[i].do_unicode = True
|
||||||
|
self.protocols[i].do_ascii = False
|
||||||
|
|
||||||
|
# override ASCII default characters, can't override unicode characters
|
||||||
if self.hdr_char_end is not None:
|
if self.hdr_char_end is not None:
|
||||||
self.protocols[i].hdr_char_end=self.hdr_char_end
|
self.protocols[i].hdr_char_end = self.hdr_char_end
|
||||||
if self.hdr_char_start is not None:
|
if self.hdr_char_start is not None:
|
||||||
self.protocols[i].hdr_char_start=self.hdr_char_start
|
self.protocols[i].hdr_char_start = self.hdr_char_start
|
||||||
if self.hdr_char_fill_even is not None:
|
if self.hdr_char_fill_even is not None:
|
||||||
self.protocols[i].hdr_char_fill_even=self.hdr_char_fill_even
|
self.protocols[i].hdr_char_fill_even = self.hdr_char_fill_even
|
||||||
if self.hdr_char_fill_odd is not None:
|
if self.hdr_char_fill_odd is not None:
|
||||||
self.protocols[i].hdr_char_fill_odd=self.hdr_char_fill_odd
|
self.protocols[i].hdr_char_fill_odd = self.hdr_char_fill_odd
|
||||||
if self.hdr_char_sep is not None:
|
if self.hdr_char_sep is not None:
|
||||||
self.protocols[i].hdr_char_sep=self.hdr_char_sep
|
self.protocols[i].hdr_char_sep = self.hdr_char_sep
|
||||||
|
|
||||||
print(self.protocols[i])
|
print(self.protocols[i])
|
||||||
if len(self.protocols)>1 and i!=len(self.protocols)-1:
|
if len(self.protocols) > 1 and i != len(self.protocols)-1:
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
13
setup.py
13
setup.py
@ -55,8 +55,11 @@
|
|||||||
# #
|
# #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
from distutils.core import setup, Extension
|
from distutils.core import setup
|
||||||
setup(name='protocol',
|
|
||||||
version='0.1',
|
setup(
|
||||||
scripts=['protocol', 'constants.py', 'specs.py']
|
name='protocol',
|
||||||
)
|
version='0.1',
|
||||||
|
scripts=['protocol'],
|
||||||
|
py_modules=[]
|
||||||
|
)
|
||||||
|
160
specs.py
160
specs.py
@ -65,7 +65,7 @@
|
|||||||
# + Payload +
|
# + Payload +
|
||||||
# | |
|
# | |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
ethernet="Destination Address:48,Source Address:48,EtherType:16,Payload:128?bits=48"
|
ethernet = "Destination Address:48,Source Address:48,EtherType:16,Payload:128?bits=48"
|
||||||
|
|
||||||
|
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
@ -79,7 +79,7 @@ ethernet="Destination Address:48,Source Address:48,EtherType:16,Payload:128?bits
|
|||||||
# + Payload +
|
# + Payload +
|
||||||
# | |
|
# | |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
dot1q="Destination Address:48,Source Address:48,TPID (0x8100):16,PCP:3,D:1,\
|
dot1q = "Destination Address:48,Source Address:48,TPID (0x8100):16,PCP:3,D:1,\
|
||||||
VLAN ID:12,EtherType:16,Payload:96?bits=48"
|
VLAN ID:12,EtherType:16,Payload:96?bits=48"
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ VLAN ID:12,EtherType:16,Payload:96?bits=48"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | data |
|
# | data |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
tcp="Source Port:16,Destination Port:16,Sequence Number:32,\
|
tcp = "Source Port:16,Destination Port:16,Sequence Number:32,\
|
||||||
Acknowledgment Number:32,Offset:4,Res.:4,Flags:8,Window:16,Checksum:16,\
|
Acknowledgment Number:32,Offset:4,Res.:4,Flags:8,Window:16,Checksum:16,\
|
||||||
Urgent Pointer:16,Options:24,Padding:8"
|
Urgent Pointer:16,Options:24,Padding:8"
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ Urgent Pointer:16,Options:24,Padding:8"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Length | Checksum |
|
# | Length | Checksum |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
udp="Source Port:16,Destination Port:16,Length:16,Checksum:16"
|
udp = "Source Port:16,Destination Port:16,Length:16,Checksum:16"
|
||||||
|
|
||||||
|
|
||||||
# 0 1 2 3
|
# 0 1 2 3
|
||||||
@ -130,7 +130,7 @@ udp="Source Port:16,Destination Port:16,Length:16,Checksum:16"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options | Padding |
|
# | Options | Padding |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
ip="Version:4,IHL:4,Type of Service:8,Total Length:16,Identification:16,\
|
ip = "Version:4,IHL:4,Type of Service:8,Total Length:16,Identification:16,\
|
||||||
Flags:3,Fragment Offset:13,Time to Live:8,Protocol:8,Header Checksum:16,\
|
Flags:3,Fragment Offset:13,Time to Live:8,Protocol:8,Header Checksum:16,\
|
||||||
Source Address:32,Destination Address:32,Options:24,Padding:8"
|
Source Address:32,Destination Address:32,Options:24,Padding:8"
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ Source Address:32,Destination Address:32,Options:24,Padding:8"
|
|||||||
# + +
|
# + +
|
||||||
# | |
|
# | |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
ipv6="Version:4,Traffic Class:8,Flow Label:20,Payload Length:16,Next Header:8,\
|
ipv6 = "Version:4,Traffic Class:8,Flow Label:20,Payload Length:16,Next Header:8,\
|
||||||
Hop Limit:8, Source Address:128, Destination Address:128"
|
Hop Limit:8, Source Address:128, Destination Address:128"
|
||||||
|
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ Hop Limit:8, Source Address:128, Destination Address:128"
|
|||||||
# + Message Body +
|
# + Message Body +
|
||||||
# | |
|
# | |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp="Type:8,Code:8,Checksum:16,Message Body:64"
|
icmp = "Type:8,Code:8,Checksum:16,Message Body:64"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv4 Destination Unreachable Message
|
# ICMPv4 Destination Unreachable Message
|
||||||
@ -184,7 +184,7 @@ icmp="Type:8,Code:8,Checksum:16,Message Body:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Internet Header + 64 bits of Original Data Datagram |
|
# | Internet Header + 64 bits of Original Data Datagram |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_destination="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits\
|
icmp_destination = "Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits\
|
||||||
of Original Data Datagram:64"
|
of Original Data Datagram:64"
|
||||||
|
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ icmp_destination="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Internet Header + 64 bits of Original Data Datagram |
|
# | Internet Header + 64 bits of Original Data Datagram |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_time="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
icmp_time = "Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
||||||
Original Data Datagram:64"
|
Original Data Datagram:64"
|
||||||
|
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ icmp_time="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Internet Header + 64 bits of Original Data Datagram |
|
# | Internet Header + 64 bits of Original Data Datagram |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_parameter="Type:8,Code:8,Checksum:16,Pointer:8,Unused:24,Internet Header\
|
icmp_parameter = "Type:8,Code:8,Checksum:16,Pointer:8,Unused:24,Internet Header\
|
||||||
+ 64 bits of Original Data Datagram:64"
|
+ 64 bits of Original Data Datagram:64"
|
||||||
|
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ icmp_parameter="Type:8,Code:8,Checksum:16,Pointer:8,Unused:24,Internet Header\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Internet Header + 64 bits of Original Data Datagram |
|
# | Internet Header + 64 bits of Original Data Datagram |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_source="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
icmp_source = "Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
||||||
Original Data Datagram:64"
|
Original Data Datagram:64"
|
||||||
|
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ icmp_source="Type:8,Code:8,Checksum:16,Unused:32,Internet Header + 64 bits of\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Internet Header + 64 bits of Original Data Datagram |
|
# | Internet Header + 64 bits of Original Data Datagram |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_redirect="Type:8,Code:8,Checksum:16,Gateway Internet Address:32,Internet\
|
icmp_redirect = "Type:8,Code:8,Checksum:16,Gateway Internet Address:32,Internet\
|
||||||
Header + 64 bits of Original Data Datagram:64"
|
Header + 64 bits of Original Data Datagram:64"
|
||||||
|
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ icmp_redirect="Type:8,Code:8,Checksum:16,Gateway Internet Address:32,Internet\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Data ...
|
# | Data ...
|
||||||
# +-+-+-+-+-
|
# +-+-+-+-+-
|
||||||
icmp_echo="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
icmp_echo = "Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv4 Timestamp or Timestamp Reply Message
|
# ICMPv4 Timestamp or Timestamp Reply Message
|
||||||
@ -277,7 +277,7 @@ icmp_echo="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Transmit Timestamp |
|
# | Transmit Timestamp |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_timestamp="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,\
|
icmp_timestamp = "Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,\
|
||||||
Originate Timestamp:32,Receive Timestamp:32,Transmit Timestamp:32"
|
Originate Timestamp:32,Receive Timestamp:32,Transmit Timestamp:32"
|
||||||
|
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ Originate Timestamp:32,Receive Timestamp:32,Transmit Timestamp:32"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Identifier | Sequence Number |
|
# | Identifier | Sequence Number |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
icmp_information="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16"
|
icmp_information = "Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv6 General Format
|
# ICMPv6 General Format
|
||||||
@ -303,7 +303,7 @@ icmp_information="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16"
|
|||||||
# | |
|
# | |
|
||||||
# + Message Body +
|
# + Message Body +
|
||||||
# | |
|
# | |
|
||||||
icmpv6="Type:8,Code:8,Checksum:16,Message Body:64"
|
icmpv6 = "Type:8,Code:8,Checksum:16,Message Body:64"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv6 Destination Unreachable Message
|
# ICMPv6 Destination Unreachable Message
|
||||||
@ -318,7 +318,7 @@ icmpv6="Type:8,Code:8,Checksum:16,Message Body:64"
|
|||||||
# | Invoking packet data (without exceeding minimum IPv6 MTU) |
|
# | Invoking packet data (without exceeding minimum IPv6 MTU) |
|
||||||
# + as possible without the ICMPv6 packet +
|
# + as possible without the ICMPv6 packet +
|
||||||
# | exceeding the minimum IPv6 MTU [IPv6] |
|
# | exceeding the minimum IPv6 MTU [IPv6] |
|
||||||
icmpv6_destination="Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data\
|
icmpv6_destination = "Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data\
|
||||||
(without exceeding minimum IPv6 MTU):64"
|
(without exceeding minimum IPv6 MTU):64"
|
||||||
|
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ icmpv6_destination="Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data\
|
|||||||
# | As much of invoking packet |
|
# | As much of invoking packet |
|
||||||
# + as possible without the ICMPv6 packet +
|
# + as possible without the ICMPv6 packet +
|
||||||
# | exceeding the minimum IPv6 MTU [IPv6] |
|
# | exceeding the minimum IPv6 MTU [IPv6] |
|
||||||
icmpv6_big="Type:8,Code:8,Checksum:16,MTU:32,Invoking packet data (without\
|
icmpv6_big = "Type:8,Code:8,Checksum:16,MTU:32,Invoking packet data (without\
|
||||||
exceeding minimum IPv6 MTU):64"
|
exceeding minimum IPv6 MTU):64"
|
||||||
|
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ icmpv6_big="Type:8,Code:8,Checksum:16,MTU:32,Invoking packet data (without\
|
|||||||
# | As much of invoking packet |
|
# | As much of invoking packet |
|
||||||
# + as possible without the ICMPv6 packet +
|
# + as possible without the ICMPv6 packet +
|
||||||
# | exceeding the minimum IPv6 MTU [IPv6] |
|
# | exceeding the minimum IPv6 MTU [IPv6] |
|
||||||
icmpv6_time="Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data (without\
|
icmpv6_time = "Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data (without\
|
||||||
exceeding minimum IPv6 MTU):64"
|
exceeding minimum IPv6 MTU):64"
|
||||||
|
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ icmpv6_time="Type:8,Code:8,Checksum:16,Unused:32,Invoking packet data (without\
|
|||||||
# | As much of invoking packet |
|
# | As much of invoking packet |
|
||||||
# + as possible without the ICMPv6 packet +
|
# + as possible without the ICMPv6 packet +
|
||||||
# | exceeding the minimum IPv6 MTU [IPv6] |
|
# | exceeding the minimum IPv6 MTU [IPv6] |
|
||||||
icmpv6_parameter="Type:8,Code:8,Checksum:16,Pointer:32,Invoking packet data\
|
icmpv6_parameter = "Type:8,Code:8,Checksum:16,Pointer:32,Invoking packet data\
|
||||||
(without exceeding minimum IPv6 MTU):64"
|
(without exceeding minimum IPv6 MTU):64"
|
||||||
|
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ icmpv6_parameter="Type:8,Code:8,Checksum:16,Pointer:32,Invoking packet data\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Data ...
|
# | Data ...
|
||||||
# +-+-+-+-+-
|
# +-+-+-+-+-
|
||||||
icmpv6_echo="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
icmpv6_echo = "Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv6 Router Solicitation Message Format
|
# ICMPv6 Router Solicitation Message Format
|
||||||
@ -395,7 +395,7 @@ icmpv6_echo="Type:8,Code:8,Checksum:16,Identifier:16,Sequence Number:16,Data:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options ...
|
# | Options ...
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-
|
# +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
icmpv6_rsol="Type:8,Code:8,Checksum:16,Reserved:32,Options:64"
|
icmpv6_rsol = "Type:8,Code:8,Checksum:16,Reserved:32,Options:64"
|
||||||
|
|
||||||
|
|
||||||
# ICMPv6 Router Advertisement Message Format
|
# ICMPv6 Router Advertisement Message Format
|
||||||
@ -413,7 +413,7 @@ icmpv6_rsol="Type:8,Code:8,Checksum:16,Reserved:32,Options:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options ...
|
# | Options ...
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-
|
# +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
icmpv6_radv="Type:8,Code:8,Checksum:16,Cur Hop Limit:8,M:1,O:1,Reserved:6,\
|
icmpv6_radv = "Type:8,Code:8,Checksum:16,Cur Hop Limit:8,M:1,O:1,Reserved:6,\
|
||||||
Router Lifetime:16,Reachable Time:32,Retransmission Timer:32,Options:64"
|
Router Lifetime:16,Reachable Time:32,Retransmission Timer:32,Options:64"
|
||||||
|
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ Router Lifetime:16,Reachable Time:32,Retransmission Timer:32,Options:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options ...
|
# | Options ...
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-
|
# +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
icmpv6_nsol="Type:8,Code:8,Checksum:16,Reserved:32,Target Address:128,\
|
icmpv6_nsol = "Type:8,Code:8,Checksum:16,Reserved:32,Target Address:128,\
|
||||||
Options:64"
|
Options:64"
|
||||||
|
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ Options:64"
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options ...
|
# | Options ...
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-
|
# +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
icmpv6_nadv="Type:8,Code:8,Checksum:16,R:1,S:1,O:1,Reserved:29,Target\
|
icmpv6_nadv = "Type:8,Code:8,Checksum:16,R:1,S:1,O:1,Reserved:29,Target\
|
||||||
Address:128,Options:64"
|
Address:128,Options:64"
|
||||||
|
|
||||||
|
|
||||||
@ -490,30 +490,30 @@ icmpv6_nadv="Type:8,Code:8,Checksum:16,R:1,S:1,O:1,Reserved:29,Target\
|
|||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
# | Options ...
|
# | Options ...
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-
|
# +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
icmpv6_redirect="Type:8,Code:8,Checksum:16,Reserved:32,Target Address:128,\
|
icmpv6_redirect = "Type:8,Code:8,Checksum:16,Reserved:32,Target Address:128,\
|
||||||
Destination Address:128,Options:64"
|
Destination Address:128,Options:64"
|
||||||
|
|
||||||
dhcp = "Opcode:8,Hardware Type: 8,HW Addr Len:8,Hop Count:8,Transaction ID:32,Number of Seconds:16,Flags:16,Client IP Addr:32,Your IP Addr: 32,Server IP Addr:32,Gateway IP Addr:32,Client Hardware Addr:128,Server Host Name:512,Boot Filename:1024"
|
dhcp = "Opcode:8,Hardware Type: 8,HW Addr Len:8,Hop Count:8,Transaction ID:32,Number of Seconds:16,Flags:16,Client IP Addr:32,Your IP Addr: 32,Server IP Addr:32,Gateway IP Addr:32,Client Hardware Addr:128,Server Host Name:512,Boot Filename:1024"
|
||||||
|
|
||||||
modbus_tcp="Transaction ID:16,Protocol ID:16,Length:16,Address:8,Function Code:8,Data:64"
|
modbus_tcp = "Transaction ID:16,Protocol ID:16,Length:16,Address:8,Function Code:8,Data:64"
|
||||||
|
|
||||||
profinet_rt="Frame ID:16,User Data:80,Cycle Counter:16,Data Status:8,Transfer Status:8"
|
profinet_rt = "Frame ID:16,User Data:80,Cycle Counter:16,Data Status:8,Transfer Status:8"
|
||||||
|
|
||||||
dnp3="Start:16,Length:8,Control:8,Destination Address:16,Source Address:16,CRC:16,User Data 1:128,CRC 1:16,User Data 2:112,CRC 2:16"
|
dnp3 = "Start:16,Length:8,Control:8,Destination Address:16,Source Address:16,CRC:16,User Data 1:128,CRC 1:16,User Data 2:112,CRC 2:16"
|
||||||
|
|
||||||
tsap="Type:8,Slot:5,Rack:3?bits=16"
|
tsap = "Type:8,Slot:5,Rack:3?bits=16"
|
||||||
|
|
||||||
cotp_cr="Length:8,PDU Type:8, Destination Reference:16, Source Reference:16,Class/Options:8,Param. Code:8,Param. Length:8,Param.:88"
|
cotp_cr = "Length:8,PDU Type:8, Destination Reference:16, Source Reference:16,Class/Options:8,Param. Code:8,Param. Length:8,Param.:88"
|
||||||
|
|
||||||
cotp_dt="Length:8,PDU Type:8,Num. & LDU:8?bits=24"
|
cotp_dt = "Length:8,PDU Type:8,Num. & LDU:8?bits=24"
|
||||||
|
|
||||||
cotp_dr="Length:8,PDU Type:8, Destination Reference:16, Source Reference:16,Cause:8"
|
cotp_dr = "Length:8,PDU Type:8, Destination Reference:16, Source Reference:16,Cause:8"
|
||||||
|
|
||||||
s7_header="Protocol ID:8,ROSCTR:8,Reserved:16,Request ID:16,Parameter Length:16,Data Length:16,Error Code (only ROSCTR 3):16,Function Code:8,Item Count:8?bits=16"
|
s7_header = "Protocol ID:8,ROSCTR:8,Reserved:16,Request ID:16,Parameter Length:16,Data Length:16,Error Code (only ROSCTR 3):16,Function Code:8,Item Count:8?bits=16"
|
||||||
|
|
||||||
s7_item="Var Type:8,Var Length:8,Syntax ID:8,Transport Size:8,Length:16,DB Number:16,Area:8,Address:24"
|
s7_item = "Var Type:8,Var Length:8,Syntax ID:8,Transport Size:8,Length:16,DB Number:16,Area:8,Address:24"
|
||||||
|
|
||||||
s7_data="Return Code:8,Transport Size:8,Data Length:16"
|
s7_data = "Return Code:8,Transport Size:8,Data Length:16"
|
||||||
|
|
||||||
# 0 1
|
# 0 1
|
||||||
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
@ -534,7 +534,7 @@ s7_data="Return Code:8,Transport Size:8,Data Length:16"
|
|||||||
# * *
|
# * *
|
||||||
# | |
|
# | |
|
||||||
# *-------------------------------*
|
# *-------------------------------*
|
||||||
example="Field4:4,Field4:4,Field8:8,Field16:16,Field32:32,Field64:64?bits=16,\
|
example = "Field4:4,Field4:4,Field8:8,Field16:16,Field32:32,Field64:64?bits=16,\
|
||||||
numbers=y,startchar=*,endchar=*,evenchar=-,oddchar=-,sepchar=|"
|
numbers=y,startchar=*,endchar=*,evenchar=-,oddchar=-,sepchar=|"
|
||||||
|
|
||||||
|
|
||||||
@ -713,7 +713,7 @@ numbers=y,startchar=*,endchar=*,evenchar=-,oddchar=-,sepchar=|"
|
|||||||
# + +
|
# + +
|
||||||
# | |
|
# | |
|
||||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
test="Field_1:1,Field_4:4,Field_7:7,Field_10:10,Field_13:13,Field_16:16,\
|
test = "Field_1:1,Field_4:4,Field_7:7,Field_10:10,Field_13:13,Field_16:16,\
|
||||||
Field_19:19,Field_22:22,Field_25:25,Field_28:28,Field_31:31,Field_34:34,\
|
Field_19:19,Field_22:22,Field_25:25,Field_28:28,Field_31:31,Field_34:34,\
|
||||||
Field_37:37,Field_40:40,Field_43:43,Field_46:46,Field_49:49,Field_52:52,\
|
Field_37:37,Field_40:40,Field_43:43,Field_46:46,Field_49:49,Field_52:52,\
|
||||||
Field_55:55,Field_58:58,Field_61:61,Field_64:64,Field_67:67,Field_70:70,\
|
Field_55:55,Field_58:58,Field_61:61,Field_64:64,Field_67:67,Field_70:70,\
|
||||||
@ -724,45 +724,45 @@ Field_124:124,Field_127:127"
|
|||||||
|
|
||||||
|
|
||||||
# Dictionary of specs
|
# Dictionary of specs
|
||||||
protocols={"ethernet":ethernet,
|
protocols = {
|
||||||
"8021q":dot1q,
|
"ethernet": ethernet,
|
||||||
"dot1q":dot1q,
|
"8021q": dot1q,
|
||||||
"tcp":tcp,
|
"dot1q": dot1q,
|
||||||
"udp":udp,
|
"tcp": tcp,
|
||||||
"ip":ip,
|
"udp": udp,
|
||||||
"ipv6":ipv6,
|
"ip": ip,
|
||||||
"icmp":icmp,
|
"ipv6": ipv6,
|
||||||
"icmp-destination":icmp_destination,
|
"icmp": icmp,
|
||||||
"icmp-time":icmp_time,
|
"icmp-destination": icmp_destination,
|
||||||
"icmp-parameter":icmp_parameter,
|
"icmp-time": icmp_time,
|
||||||
"icmp-source":icmp_source,
|
"icmp-parameter": icmp_parameter,
|
||||||
"icmp-redirect":icmp_redirect,
|
"icmp-source": icmp_source,
|
||||||
"icmp-echo":icmp_echo,
|
"icmp-redirect": icmp_redirect,
|
||||||
"icmp-timestamp":icmp_timestamp,
|
"icmp-echo": icmp_echo,
|
||||||
"icmp-information":icmp_information,
|
"icmp-timestamp": icmp_timestamp,
|
||||||
"icmpv6":icmpv6,
|
"icmp-information": icmp_information,
|
||||||
"icmpv6-destination":icmpv6_destination,
|
"icmpv6": icmpv6,
|
||||||
"icmpv6-big":icmpv6_big,
|
"icmpv6-destination": icmpv6_destination,
|
||||||
"icmpv6-time":icmpv6_time,
|
"icmpv6-big": icmpv6_big,
|
||||||
"icmpv6-parameter":icmpv6_parameter,
|
"icmpv6-time": icmpv6_time,
|
||||||
"icmpv6-echo":icmpv6_echo,
|
"icmpv6-parameter": icmpv6_parameter,
|
||||||
"icmpv6-rsol":icmpv6_rsol,
|
"icmpv6-echo": icmpv6_echo,
|
||||||
"icmpv6-radv":icmpv6_radv,
|
"icmpv6-rsol": icmpv6_rsol,
|
||||||
"icmpv6-nsol":icmpv6_nsol,
|
"icmpv6-radv": icmpv6_radv,
|
||||||
"icmpv6-nadv":icmpv6_nadv,
|
"icmpv6-nsol": icmpv6_nsol,
|
||||||
"icmpv6-redirect":icmpv6_redirect,
|
"icmpv6-nadv": icmpv6_nadv,
|
||||||
"dhcp": dhcp,
|
"icmpv6-redirect": icmpv6_redirect,
|
||||||
"modbus_tcp":modbus_tcp,
|
"dhcp": dhcp,
|
||||||
"profinet_rt":profinet_rt,
|
"modbus_tcp": modbus_tcp,
|
||||||
"tsap":tsap,
|
"profinet_rt": profinet_rt,
|
||||||
"dnp3":dnp3,
|
"tsap": tsap,
|
||||||
"s7_header":s7_header,
|
"dnp3": dnp3,
|
||||||
"s7_item":s7_item,
|
"s7_header": s7_header,
|
||||||
"s7_data":s7_data,
|
"s7_item": s7_item,
|
||||||
"cotp_cr":cotp_cr,
|
"s7_data": s7_data,
|
||||||
"cotp_dt":cotp_dt,
|
"cotp_cr": cotp_cr,
|
||||||
"cotp_dr":cotp_dr,
|
"cotp_dt": cotp_dt,
|
||||||
"example":example,
|
"cotp_dr": cotp_dr,
|
||||||
"test":test
|
"example": example,
|
||||||
}
|
"test": test
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user