MCPcopy Create free account
hub / github.com/USArmyResearchLab/Dshell / reassemble

Method reassemble

dshell/core.py:1732–1815  ·  view source on GitHub ↗

Rebuild the data string from the current list of data packets For each packet, the TCP sequence number is checked. If overlapping or padding is disallowed, it will raise a SequenceNumberError exception if a respective event occurs. Args: allow_p

(self, allow_padding=True, allow_overlap=True, padding=b'\x00')

Source from the content-addressed store, hash-verified

1730 # TODO: Merge this in with the add_packet() logic, however I am unsure how using acknowledge numbers
1731 # works if we are only looking at one side.
1732 def reassemble(self, allow_padding=True, allow_overlap=True, padding=b'\x00'):
1733 """
1734 Rebuild the data string from the current list of data packets
1735 For each packet, the TCP sequence number is checked.
1736
1737 If overlapping or padding is disallowed, it will raise a
1738 SequenceNumberError exception if a respective event occurs.
1739
1740 Args:
1741 allow_padding (bool): If data is missing and allow_padding = True
1742 (default: True), then the padding argument
1743 will be used to fill the gaps.
1744 allow_overlap (bool): If data is overlapping, the new data is
1745 used if the allow_overlap argument is True
1746 (default). Otherwise, the earliest data is
1747 kept.
1748 padding: Byte character(s) to use to fill in missing data. Used
1749 in conjunction with allow_padding (default: b'\\\\x00')
1750 """
1751 data = b""
1752 unacknowledged_data = []
1753 acknowledged_data = {}
1754 for pkt in self.packets:
1755 if not pkt.sequence_number:
1756 # if there are no sequence numbers (i.e. not TCP), just rebuild
1757 # in chronological order
1758 data += pkt.data
1759 continue
1760
1761 if pkt.data:
1762 if pkt.sequence_number in acknowledged_data:
1763 continue
1764 unacknowledged_data.append(pkt)
1765
1766 elif pkt.tcp_flags and pkt.tcp_flags & tcp.TH_ACK:
1767 ackpkt = pkt
1768 for i, datapkt in enumerate(unacknowledged_data):
1769 if (datapkt.ack_number == ackpkt.sequence_number
1770 and ackpkt.ack_number == (datapkt.sequence_number + len(datapkt.data))):
1771 # if the seq/ack numbers align, this is the data packet
1772 # we want
1773 # TODO confirm this logic is correct
1774 acknowledged_data[datapkt.sequence_number] = datapkt.data
1775 unacknowledged_data.pop(i)
1776 break
1777
1778 if not acknowledged_data and not unacknowledged_data:
1779 # For non-sequential protocols, just return what we have
1780 self.__data_bytes = data
1781
1782 else:
1783 # Create a list of each segment of the complete data. Use
1784 # acknowledged data first, and then try to fill in the blanks with
1785 # unacknowledged data.
1786 segments = acknowledged_data.copy()
1787 for pkt in reversed(unacknowledged_data):
1788 if pkt.sequence_number in segments: continue
1789 segments[pkt.sequence_number] = pkt.data

Callers 2

connection_handlerMethod · 0.80
connection_handlerMethod · 0.80

Calls 1

SequenceNumberErrorClass · 0.85

Tested by

no test coverage detected