app-layer: add flow accessors for probing parsers

Probing parsers written in Rust cannot look into the Flow, which is
opaque to them.

Add SCFlowGetAppProtocolToClient() to get the protocol detected on
the to-client side, and SCAppLayerProtoDetectGetStreamDataSize() to
get the amount of stream data available for protocol detection in a
given direction.

These are needed by the IMAP probing parser to tell IMAP apart from
FTP on "USER CAPABILITY".

Ticket #8276
pull/16515/head
Giuseppe Longo 4 weeks ago
parent 9a37bb659b
commit 67f2f243f7

@ -1332,6 +1332,12 @@ extern "C" {
pp_max_depth: u16,
) -> ::std::os::raw::c_int;
}
extern "C" {
#[doc = " \\brief Get the size of the stream data available for protocol detection\n in the given direction, for use by probing parsers.\n\n \\retval bool false if the flow has no TCP session"]
pub fn SCAppLayerProtoDetectGetStreamDataSize(
f: *const Flow, direction: u8, size: *mut u32,
) -> bool;
}
extern "C" {
pub fn SCAppLayerRequestProtocolTLSUpgrade(f: *mut Flow) -> bool;
}
@ -1874,6 +1880,9 @@ extern "C" {
extern "C" {
pub fn SCFlowGetAppProtocol(f: *const Flow) -> AppProto;
}
extern "C" {
pub fn SCFlowGetAppProtocolToClient(f: *const Flow) -> AppProto;
}
#[doc = " \\brief Function type for flow initialization callbacks.\n\n Once registered with SCFlowRegisterInitCallback, this function will\n be called every time a flow is initialized, or in other words,\n every time Suricata picks up a flow.\n\n \\param tv The ThreadVars data structure for the thread creating the\n flow.\n \\param f The newly initialized flow.\n \\param p The packet related to creating the new flow.\n \\param user The user data provided during callback registration."]
pub type SCFlowInitCallbackFn = ::std::option::Option<
unsafe extern "C" fn(

@ -1668,6 +1668,17 @@ int SCAppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto,
SCReturnInt(r);
}
bool SCAppLayerProtoDetectGetStreamDataSize(const Flow *f, uint8_t direction, uint32_t *size)
{
TcpSession *ssn = (TcpSession *)f->protoctx;
if (f->proto != IPPROTO_TCP || ssn == NULL) {
return false;
}
TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
*size = StreamDataAvailableForProtoDetect(stream);
return true;
}
/***** Setup/General Registration *****/
int AppLayerProtoDetectSetup(void)

@ -93,6 +93,14 @@ int SCAppLayerProtoDetectPMRegisterPatternCIwPP(uint8_t ipproto, AppProto alprot
const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction,
ProbingParserFPtr PPFunc, uint16_t pp_min_depth, uint16_t pp_max_depth);
/**
* \brief Get the size of the stream data available for protocol detection
* in the given direction, for use by probing parsers.
*
* \retval bool false if the flow has no TCP session
*/
bool SCAppLayerProtoDetectGetStreamDataSize(const Flow *f, uint8_t direction, uint32_t *size);
/***** Setup/General Registration *****/
/**

@ -47,5 +47,6 @@ const uint8_t *SCFlowGetDestinationAddressAsRawPtr(const Flow *flow);
uint32_t SCFlowGetToServerPacketCount(const Flow *flow);
uint32_t SCFlowGetToClientPacketCount(const Flow *flow);
AppProto SCFlowGetAppProtocol(const Flow *f);
AppProto SCFlowGetAppProtocolToClient(const Flow *f);
#endif /* SURICATA_FLOW_BINDGEN_H */

@ -1290,6 +1290,11 @@ AppProto SCFlowGetAppProtocol(const Flow *f)
return f->alproto;
}
AppProto SCFlowGetAppProtocolToClient(const Flow *f)
{
return f->alproto_tc;
}
/**
* \brief Get flow destination port.
*

Loading…
Cancel
Save