stackforge 0.6.5__tar.gz → 0.6.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stackforge-0.6.5 → stackforge-0.6.6}/Cargo.lock +3 -3
- {stackforge-0.6.5 → stackforge-0.6.6}/Cargo.toml +1 -1
- {stackforge-0.6.5 → stackforge-0.6.6}/PKG-INFO +20 -6
- {stackforge-0.6.5 → stackforge-0.6.6}/README.md +19 -5
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/mod.rs +41 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/table.rs +24 -7
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/tcp_state.rs +26 -3
- {stackforge-0.6.5 → stackforge-0.6.6}/src/lib.rs +28 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.github/workflows/release.yml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.github/workflows/test.yml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.gitignore +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.pre-commit-config.yaml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/.python-version +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/CLAUDE.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/CODE_OF_CONDUCT.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/CONTRIBUTING.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/LICENSE +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/cliff.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/cog.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-automata/Cargo.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-automata/src/lib.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/Cargo.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/.DS_Store +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/error.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/config.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/error.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/icmp_state.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/key.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/spill.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/state.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/tcp_reassembly.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/udp_state.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/arp.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/bindings.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/bitmap.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/edns.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/header.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/query.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/rdata.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/rr.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/svcb.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/types.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/control.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/data.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/ie.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/management.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/radiotap.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/security.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/types.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/beacon.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/command.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/crc.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/security.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/types.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ethernet.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/field.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/field_ext.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ftp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ftp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/generic/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/generic/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/detection.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/request.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/response.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/frames.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/hpack.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/checksum.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/error.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/extensions.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/types.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmpv6/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmpv6/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/imap/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/imap/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/checksum.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/fragmentation.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/header.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/options.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/protocol.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/routing.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/ttl.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/ext_headers.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/l2tp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/l2tp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/crc.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqtt/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqtt/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqttsn/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqttsn/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/neighbor.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/pop3/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/pop3/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/frames.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/headers.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/varint.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/raw.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/smtp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/smtp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ssh/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ssh/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/stack.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/checksum.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/flags.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/header.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/options.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/services.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tftp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tftp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/cert.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_aead.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_block.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_stream.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/compression.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/groups.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hash.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hkdf_tls13.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hmac_tls.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/prf.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/suites.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/common.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/key_share.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/signature_algorithms.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/sni.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/supported_versions.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/certificate.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/client_hello.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/finished.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/key_exchange.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/server_hello.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/keyexchange/ecdhe.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/keyexchange/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/record.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/session.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/handshake.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/record.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/types.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/checksum.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/zwave/builder.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/zwave/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/lib.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/packet.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/reader.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/writer.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/bits.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/checksum.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/compare.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/hex.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/padding.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/random.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/pyproject.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/python/stackforge/__init__.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/python/stackforge/custom.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/rust-toolchain.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/rustfmt.toml +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/arp.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/arp_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ethernet_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/icmp_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ipv4_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/mod.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ssh_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/tcp_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/tls_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/udp_compat.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dns.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dot11.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dot15d4.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ethernet.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/field.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ftp.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/http.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/http2.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/icmpv6.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/imap.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ipv6.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/layer.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/main.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/modbus.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/mqtt.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/packet.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/pop3.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/quic.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/smtp.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ssh.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/tftp.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/tls.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/util.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/zwave.rs +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/__init__.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/conftest.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_arp_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_checksums_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_edge_cases_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_ethernet_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_icmp_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_ipv4_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_pcap_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_stacking_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_tcp_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_udp_compat.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_uts_integration.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_core.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_custom.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dns.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dot11.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dot15d4.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_flow.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ftp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_http.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_icmpv6.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_imap.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ipv6.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_l2tp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_max_packet_flow_len.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_modbus.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_mqtt.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_mqttsn.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pcap.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pcapng.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pop3.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_quic.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_smtp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ssh.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_streaming_flows.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_tftp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_tls.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_udp_icmp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_ftp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_http.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_http2.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_imap.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_ipv6.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_l2tp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_modbus.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_mqtt.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_mqttsn.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_pop3.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_quic.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_smtp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_tftp.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_zwave.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_zwave.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http2_h2c.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_chunk.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed-brotli.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed-zstd.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_content_length.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_head.pcapng +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_tcp_psh.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/ssh_ed25519.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/PCAP.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/smallFlows.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/test.pcap +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/scripts/compare_packets.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/scripts/generate_scapy_fixtures.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns_dnssec.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns_edns0.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dot11.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dot15d4.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/fields.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/ftp.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/http.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/http2.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/imap.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet6 copy.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet6.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/l2.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/l2tp.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/modbus.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/mqtt.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/mqttsn.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/pop3.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/quic.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/smtp.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/ssh.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tftp.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/__init__.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/cert.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/example_client.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/example_server.py +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/README.md +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/ca_cert.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/ca_key.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/cli_cert.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/cli_key.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_cert.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_cert_ed25519.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_key.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_key_ed25519.pem +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/sslv2.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tls.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tls13.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tlsclientserver.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/zwave.uts +0 -0
- {stackforge-0.6.5 → stackforge-0.6.6}/uv.lock +0 -0
|
@@ -1074,7 +1074,7 @@ dependencies = [
|
|
|
1074
1074
|
|
|
1075
1075
|
[[package]]
|
|
1076
1076
|
name = "stackforge"
|
|
1077
|
-
version = "0.6.
|
|
1077
|
+
version = "0.6.6"
|
|
1078
1078
|
dependencies = [
|
|
1079
1079
|
"pyo3",
|
|
1080
1080
|
"stackforge-automata",
|
|
@@ -1083,7 +1083,7 @@ dependencies = [
|
|
|
1083
1083
|
|
|
1084
1084
|
[[package]]
|
|
1085
1085
|
name = "stackforge-automata"
|
|
1086
|
-
version = "0.6.
|
|
1086
|
+
version = "0.6.6"
|
|
1087
1087
|
dependencies = [
|
|
1088
1088
|
"bytes",
|
|
1089
1089
|
"stackforge-core",
|
|
@@ -1091,7 +1091,7 @@ dependencies = [
|
|
|
1091
1091
|
|
|
1092
1092
|
[[package]]
|
|
1093
1093
|
name = "stackforge-core"
|
|
1094
|
-
version = "0.6.
|
|
1094
|
+
version = "0.6.6"
|
|
1095
1095
|
dependencies = [
|
|
1096
1096
|
"aes",
|
|
1097
1097
|
"aes-gcm",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stackforge
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.6
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Intended Audience :: System Administrators
|
|
@@ -359,17 +359,29 @@ Enable verbose mode to see progress feedback on stderr during extraction:
|
|
|
359
359
|
```python
|
|
360
360
|
# Quick verbose flag on the function call
|
|
361
361
|
conversations = extract_flows("capture.pcap", verbose=True)
|
|
362
|
-
# [stackforge] Opening capture file: capture.pcap
|
|
363
|
-
# [stackforge] Starting streaming flow extraction...
|
|
364
|
-
# [stackforge] Processed 10000 packets (342 flows so far)
|
|
365
|
-
# [stackforge] Processed 20000 packets (587 flows so far)
|
|
366
|
-
# [stackforge] Flow extraction complete: 612 conversations
|
|
367
362
|
|
|
368
363
|
# Or via FlowConfig
|
|
369
364
|
config = FlowConfig(verbose=True)
|
|
370
365
|
conversations = extract_flows("capture.pcap", config=config)
|
|
371
366
|
```
|
|
372
367
|
|
|
368
|
+
Verbose output shows real-time progress with processing rate, memory usage, ETA, and spill stats:
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
[+] stackforge flow extraction engine
|
|
372
|
+
[+] File: capture.pcap (2.3 GB)
|
|
373
|
+
[+] Mode: streaming (packets read from disk on-the-fly)
|
|
374
|
+
[+] Memory budget: 1.00 GB
|
|
375
|
+
[+] Processing...
|
|
376
|
+
|
|
377
|
+
[1m 23s] 100,000 pkts | 1,234 flows | 85,432/s (avg 72,150/s) | mem ~45.2 MB
|
|
378
|
+
[2m 48s] 200,000 pkts | 2,567 flows | 78,901/s (avg 71,428/s) | mem ~89.1 MB | 3 spills
|
|
379
|
+
|
|
380
|
+
[+] Finalizing (sorting 88,254 flows)...
|
|
381
|
+
[+] Complete: 88,254 flows extracted
|
|
382
|
+
[+] Wall time: 1h 12m
|
|
383
|
+
```
|
|
384
|
+
|
|
373
385
|
Customize timeouts, buffer limits, and memory budget with `FlowConfig`:
|
|
374
386
|
|
|
375
387
|
```python
|
|
@@ -389,6 +401,8 @@ For large captures, set a memory budget so reassembly buffers automatically spil
|
|
|
389
401
|
config = FlowConfig(
|
|
390
402
|
memory_budget=256 * 1024 * 1024, # 256 MB RAM budget
|
|
391
403
|
spill_dir="/tmp/stackforge-spill", # optional custom spill directory
|
|
404
|
+
store_packet_indices=False, # save ~8 bytes/pkt on large captures
|
|
405
|
+
progress_interval=500_000, # report every 500K packets (default: 100K)
|
|
392
406
|
)
|
|
393
407
|
conversations = extract_flows("large_capture.pcapng", config=config)
|
|
394
408
|
```
|
|
@@ -335,17 +335,29 @@ Enable verbose mode to see progress feedback on stderr during extraction:
|
|
|
335
335
|
```python
|
|
336
336
|
# Quick verbose flag on the function call
|
|
337
337
|
conversations = extract_flows("capture.pcap", verbose=True)
|
|
338
|
-
# [stackforge] Opening capture file: capture.pcap
|
|
339
|
-
# [stackforge] Starting streaming flow extraction...
|
|
340
|
-
# [stackforge] Processed 10000 packets (342 flows so far)
|
|
341
|
-
# [stackforge] Processed 20000 packets (587 flows so far)
|
|
342
|
-
# [stackforge] Flow extraction complete: 612 conversations
|
|
343
338
|
|
|
344
339
|
# Or via FlowConfig
|
|
345
340
|
config = FlowConfig(verbose=True)
|
|
346
341
|
conversations = extract_flows("capture.pcap", config=config)
|
|
347
342
|
```
|
|
348
343
|
|
|
344
|
+
Verbose output shows real-time progress with processing rate, memory usage, ETA, and spill stats:
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
[+] stackforge flow extraction engine
|
|
348
|
+
[+] File: capture.pcap (2.3 GB)
|
|
349
|
+
[+] Mode: streaming (packets read from disk on-the-fly)
|
|
350
|
+
[+] Memory budget: 1.00 GB
|
|
351
|
+
[+] Processing...
|
|
352
|
+
|
|
353
|
+
[1m 23s] 100,000 pkts | 1,234 flows | 85,432/s (avg 72,150/s) | mem ~45.2 MB
|
|
354
|
+
[2m 48s] 200,000 pkts | 2,567 flows | 78,901/s (avg 71,428/s) | mem ~89.1 MB | 3 spills
|
|
355
|
+
|
|
356
|
+
[+] Finalizing (sorting 88,254 flows)...
|
|
357
|
+
[+] Complete: 88,254 flows extracted
|
|
358
|
+
[+] Wall time: 1h 12m
|
|
359
|
+
```
|
|
360
|
+
|
|
349
361
|
Customize timeouts, buffer limits, and memory budget with `FlowConfig`:
|
|
350
362
|
|
|
351
363
|
```python
|
|
@@ -365,6 +377,8 @@ For large captures, set a memory budget so reassembly buffers automatically spil
|
|
|
365
377
|
config = FlowConfig(
|
|
366
378
|
memory_budget=256 * 1024 * 1024, # 256 MB RAM budget
|
|
367
379
|
spill_dir="/tmp/stackforge-spill", # optional custom spill directory
|
|
380
|
+
store_packet_indices=False, # save ~8 bytes/pkt on large captures
|
|
381
|
+
progress_interval=500_000, # report every 500K packets (default: 100K)
|
|
368
382
|
)
|
|
369
383
|
conversations = extract_flows("large_capture.pcapng", config=config)
|
|
370
384
|
```
|
|
@@ -174,6 +174,18 @@ pub fn extract_flows_with_config(
|
|
|
174
174
|
format_duration(elapsed),
|
|
175
175
|
format_count(rate as usize)
|
|
176
176
|
);
|
|
177
|
+
|
|
178
|
+
let (total_drops, flows_with_drops) = count_dropped_segments(&conversations);
|
|
179
|
+
if total_drops > 0 {
|
|
180
|
+
eprintln!(
|
|
181
|
+
"[!] Warning: {} TCP segments dropped across {} flows (buffer/fragment limits exceeded)",
|
|
182
|
+
format_count(total_drops as usize),
|
|
183
|
+
format_count(flows_with_drops),
|
|
184
|
+
);
|
|
185
|
+
eprintln!(
|
|
186
|
+
"[!] Tip: increase max_reassembly_buffer or max_ooo_fragments to capture more data"
|
|
187
|
+
);
|
|
188
|
+
}
|
|
177
189
|
eprintln!();
|
|
178
190
|
}
|
|
179
191
|
Ok(conversations)
|
|
@@ -265,11 +277,40 @@ where
|
|
|
265
277
|
format_count(conversations.len())
|
|
266
278
|
);
|
|
267
279
|
eprintln!("[+] Wall time: {}", format_duration(elapsed));
|
|
280
|
+
|
|
281
|
+
// Report reassembly drops
|
|
282
|
+
let (total_drops, flows_with_drops) = count_dropped_segments(&conversations);
|
|
283
|
+
if total_drops > 0 {
|
|
284
|
+
eprintln!(
|
|
285
|
+
"[!] Warning: {} TCP segments dropped across {} flows (buffer/fragment limits exceeded)",
|
|
286
|
+
format_count(total_drops as usize),
|
|
287
|
+
format_count(flows_with_drops),
|
|
288
|
+
);
|
|
289
|
+
eprintln!(
|
|
290
|
+
"[!] Tip: increase max_reassembly_buffer or max_ooo_fragments to capture more data"
|
|
291
|
+
);
|
|
292
|
+
}
|
|
268
293
|
eprintln!();
|
|
269
294
|
}
|
|
270
295
|
Ok(conversations)
|
|
271
296
|
}
|
|
272
297
|
|
|
298
|
+
/// Count total dropped TCP segments across all conversations.
|
|
299
|
+
fn count_dropped_segments(conversations: &[ConversationState]) -> (u64, usize) {
|
|
300
|
+
let mut total_drops: u64 = 0;
|
|
301
|
+
let mut flows_with_drops: usize = 0;
|
|
302
|
+
for conv in conversations {
|
|
303
|
+
if let ProtocolState::Tcp(ref tcp) = conv.protocol_state {
|
|
304
|
+
let drops = tcp.total_dropped_segments();
|
|
305
|
+
if drops > 0 {
|
|
306
|
+
total_drops += drops;
|
|
307
|
+
flows_with_drops += 1;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
(total_drops, flows_with_drops)
|
|
312
|
+
}
|
|
313
|
+
|
|
273
314
|
/// Extract flows directly from a capture file (PCAP or PcapNG).
|
|
274
315
|
///
|
|
275
316
|
/// Streams packets from disk — never loads the entire file into memory.
|
|
@@ -160,20 +160,31 @@ impl ConversationTable {
|
|
|
160
160
|
|
|
161
161
|
/// Spill reassembly buffers to disk until under budget.
|
|
162
162
|
///
|
|
163
|
-
///
|
|
164
|
-
///
|
|
163
|
+
/// Two limits prevent runaway iteration:
|
|
164
|
+
/// - `max_spills`: stop after spilling this many buffers (actual work done)
|
|
165
|
+
/// - `max_skip`: stop after skipping this many already-spilled/non-TCP entries
|
|
166
|
+
/// without finding anything to free (avoids scanning the entire table when
|
|
167
|
+
/// most flows are already on disk)
|
|
165
168
|
fn maybe_spill(&self) {
|
|
166
|
-
let mut
|
|
167
|
-
let
|
|
169
|
+
let mut spills = 0;
|
|
170
|
+
let max_spills = 64;
|
|
171
|
+
let mut consecutive_skips = 0;
|
|
172
|
+
let max_skip = 512;
|
|
173
|
+
|
|
168
174
|
for mut entry in self.conversations.iter_mut() {
|
|
169
|
-
if !self.memory_tracker.is_over_budget() ||
|
|
175
|
+
if !self.memory_tracker.is_over_budget() || spills >= max_spills {
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
if consecutive_skips >= max_skip {
|
|
179
|
+
// Most nearby entries are already spilled — stop scanning
|
|
170
180
|
break;
|
|
171
181
|
}
|
|
172
|
-
|
|
182
|
+
|
|
173
183
|
if let ProtocolState::Tcp(ref mut tcp_state) = entry.value_mut().protocol_state {
|
|
174
|
-
//
|
|
184
|
+
// Skip buffers already on disk
|
|
175
185
|
if tcp_state.reassembler_fwd.is_spilled() && tcp_state.reassembler_rev.is_spilled()
|
|
176
186
|
{
|
|
187
|
+
consecutive_skips += 1;
|
|
177
188
|
continue;
|
|
178
189
|
}
|
|
179
190
|
let freed_fwd = tcp_state
|
|
@@ -189,7 +200,13 @@ impl ConversationTable {
|
|
|
189
200
|
self.memory_tracker.subtract(total_freed);
|
|
190
201
|
self.spill_count
|
|
191
202
|
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
203
|
+
spills += 1;
|
|
204
|
+
consecutive_skips = 0; // Reset — we found something useful
|
|
205
|
+
} else {
|
|
206
|
+
consecutive_skips += 1;
|
|
192
207
|
}
|
|
208
|
+
} else {
|
|
209
|
+
consecutive_skips += 1;
|
|
193
210
|
}
|
|
194
211
|
}
|
|
195
212
|
}
|
|
@@ -104,6 +104,10 @@ pub struct TcpConversationState {
|
|
|
104
104
|
pub reassembler_fwd: TcpReassembler,
|
|
105
105
|
/// Stream reassembly for reverse direction.
|
|
106
106
|
pub reassembler_rev: TcpReassembler,
|
|
107
|
+
/// Number of forward segments dropped due to buffer/fragment limits.
|
|
108
|
+
pub dropped_segments_fwd: u64,
|
|
109
|
+
/// Number of reverse segments dropped due to buffer/fragment limits.
|
|
110
|
+
pub dropped_segments_rev: u64,
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
impl TcpConversationState {
|
|
@@ -115,9 +119,17 @@ impl TcpConversationState {
|
|
|
115
119
|
reverse_endpoint: TcpEndpointState::new(),
|
|
116
120
|
reassembler_fwd: TcpReassembler::new(),
|
|
117
121
|
reassembler_rev: TcpReassembler::new(),
|
|
122
|
+
dropped_segments_fwd: 0,
|
|
123
|
+
dropped_segments_rev: 0,
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
126
|
|
|
127
|
+
/// Total dropped segments across both directions.
|
|
128
|
+
#[must_use]
|
|
129
|
+
pub fn total_dropped_segments(&self) -> u64 {
|
|
130
|
+
self.dropped_segments_fwd + self.dropped_segments_rev
|
|
131
|
+
}
|
|
132
|
+
|
|
121
133
|
/// Process a TCP packet, updating connection state and reassembly buffers.
|
|
122
134
|
///
|
|
123
135
|
/// `direction` indicates whether this packet is Forward (`addr_a` → `addr_b`)
|
|
@@ -219,9 +231,20 @@ impl TcpConversationState {
|
|
|
219
231
|
|
|
220
232
|
// Process payload through reassembler
|
|
221
233
|
if !payload.is_empty() {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
234
|
+
if let Err(e) = reassembler.process_segment(seq, payload, config) {
|
|
235
|
+
// Buffer full or too many fragments — track the drop
|
|
236
|
+
match direction {
|
|
237
|
+
FlowDirection::Forward => self.dropped_segments_fwd += 1,
|
|
238
|
+
FlowDirection::Reverse => self.dropped_segments_rev += 1,
|
|
239
|
+
}
|
|
240
|
+
// Log once at thresholds to avoid flooding stderr
|
|
241
|
+
let total = self.dropped_segments_fwd + self.dropped_segments_rev;
|
|
242
|
+
if total == 1 || total.is_power_of_two() {
|
|
243
|
+
eprintln!(
|
|
244
|
+
"[!] stackforge: TCP reassembly dropped segment ({e}), {total} total drops for this flow"
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
225
248
|
}
|
|
226
249
|
|
|
227
250
|
if flags.fin {
|
|
@@ -4254,6 +4254,34 @@ impl PyConversation {
|
|
|
4254
4254
|
}
|
|
4255
4255
|
}
|
|
4256
4256
|
|
|
4257
|
+
/// Number of TCP segments dropped due to reassembly buffer/fragment limits.
|
|
4258
|
+
/// Returns 0 for non-TCP flows.
|
|
4259
|
+
#[getter]
|
|
4260
|
+
fn dropped_segments(&self) -> u64 {
|
|
4261
|
+
match &self.inner.protocol_state {
|
|
4262
|
+
stackforge_core::ProtocolState::Tcp(tcp) => tcp.total_dropped_segments(),
|
|
4263
|
+
_ => 0,
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
|
|
4267
|
+
/// Number of forward-direction TCP segments dropped.
|
|
4268
|
+
#[getter]
|
|
4269
|
+
fn dropped_segments_fwd(&self) -> u64 {
|
|
4270
|
+
match &self.inner.protocol_state {
|
|
4271
|
+
stackforge_core::ProtocolState::Tcp(tcp) => tcp.dropped_segments_fwd,
|
|
4272
|
+
_ => 0,
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
|
|
4276
|
+
/// Number of reverse-direction TCP segments dropped.
|
|
4277
|
+
#[getter]
|
|
4278
|
+
fn dropped_segments_rev(&self) -> u64 {
|
|
4279
|
+
match &self.inner.protocol_state {
|
|
4280
|
+
stackforge_core::ProtocolState::Tcp(tcp) => tcp.dropped_segments_rev,
|
|
4281
|
+
_ => 0,
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
|
|
4257
4285
|
/// Z-Wave home ID, or None for non-Z-Wave flows.
|
|
4258
4286
|
#[getter]
|
|
4259
4287
|
fn zwave_home_id(&self) -> Option<u32> {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/fragmentation.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|