Files
firegex-traffic-viewer/fgex-lib/firegex/nfproxy/models/tcp.py

81 lines
3.0 KiB
Python
Raw Normal View History

2025-03-03 20:25:36 +01:00
from firegex.nfproxy.internals.data import DataStreamCtx
2025-03-03 21:15:49 +01:00
from firegex.nfproxy.internals.exceptions import NotReadyToRun, StreamFullDrop, StreamFullReject
from firegex.nfproxy.internals.models import FullStreamAction
2025-03-03 20:25:36 +01:00
2025-03-03 21:15:49 +01:00
class InternalTCPStream:
2025-03-03 20:25:36 +01:00
def __init__(self,
2025-03-03 21:15:49 +01:00
data: bytes,
2025-03-03 20:25:36 +01:00
is_ipv6: bool,
):
2025-03-03 23:55:24 +01:00
self.data = bytes(data)
2025-03-03 20:25:36 +01:00
self.__is_ipv6 = bool(is_ipv6)
2025-03-03 21:15:49 +01:00
self.__total_stream_size = len(data)
2025-03-03 20:25:36 +01:00
@property
def is_ipv6(self) -> bool:
return self.__is_ipv6
2025-03-03 21:15:49 +01:00
@property
def total_stream_size(self) -> int:
return self.__total_stream_size
def _push_new_data(self, data: bytes):
2025-03-03 23:55:24 +01:00
self.data += data
2025-03-03 21:15:49 +01:00
self.__total_stream_size += len(data)
2025-03-03 20:25:36 +01:00
@classmethod
2025-03-03 21:15:49 +01:00
def _fetch_packet(cls, internal_data:DataStreamCtx, is_input:bool=False):
2025-03-03 20:25:36 +01:00
if internal_data.current_pkt is None or internal_data.current_pkt.is_tcp is False:
raise NotReadyToRun()
2025-03-03 21:15:49 +01:00
if internal_data.current_pkt.is_input != is_input:
raise NotReadyToRun()
datahandler: TCPInputStream = internal_data.data_handler_context.get(cls, None)
if datahandler is None:
datahandler = cls(internal_data.current_pkt.data, internal_data.current_pkt.is_ipv6)
internal_data.data_handler_context[cls] = datahandler
else:
if datahandler.total_stream_size+len(internal_data.current_pkt.data) > internal_data.stream_max_size:
match internal_data.full_stream_action:
case FullStreamAction.FLUSH:
datahandler = cls(internal_data.current_pkt.data, internal_data.current_pkt.is_ipv6)
internal_data.data_handler_context[cls] = datahandler
case FullStreamAction.REJECT:
raise StreamFullReject()
case FullStreamAction.DROP:
raise StreamFullDrop()
case FullStreamAction.ACCEPT:
raise NotReadyToRun()
else:
datahandler._push_new_data(internal_data.current_pkt.data)
return datahandler
2025-03-03 20:25:36 +01:00
2025-03-03 21:15:49 +01:00
class TCPInputStream(InternalTCPStream):
2025-03-03 20:25:36 +01:00
"""
This datamodel will assemble the TCP input stream from the client sent data.
The function that use this data model will be handled when:
- The packet is TCP
- At least 1 packet has been sent
- A new client packet has been received
"""
@classmethod
def _fetch_packet(cls, internal_data:DataStreamCtx):
2025-03-03 21:15:49 +01:00
return super()._fetch_packet(internal_data, is_input=True)
2025-03-03 20:25:36 +01:00
TCPClientStream = TCPInputStream
class TCPOutputStream:
"""
This datamodel will assemble the TCP output stream from the server sent data.
The function that use this data model will be handled when:
- The packet is TCP
- At least 1 packet has been sent
- A new server packet has been sent
"""
@classmethod
def _fetch_packet(cls, internal_data:DataStreamCtx):
2025-03-03 21:15:49 +01:00
return super()._fetch_packet(internal_data, is_input=False)
2025-03-03 20:25:36 +01:00
TCPServerStream = TCPOutputStream