#include "util-memcmp.h"
#include "util-random.h"
+#include "util-validate.h"
//#define PRINT
}
}
+static int Setup(Flow *f, HtpState *hstate)
+{
+ /* store flow ref in state so callbacks can access it */
+ hstate->f = f;
+
+ HTPCfgRec *htp_cfg_rec = &cfglist;
+ htp_cfg_t *htp = cfglist.cfg; /* Default to the global HTP config */
+ void *user_data = NULL;
+
+ if (FLOW_IS_IPV4(f)) {
+ SCLogDebug("Looking up HTP config for ipv4 %08x", *GET_IPV4_DST_ADDR_PTR(f));
+ (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)GET_IPV4_DST_ADDR_PTR(f), cfgtree, &user_data);
+ }
+ else if (FLOW_IS_IPV6(f)) {
+ SCLogDebug("Looking up HTP config for ipv6");
+ (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)GET_IPV6_DST_ADDR(f), cfgtree, &user_data);
+ }
+ else {
+ SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown address family, bug!");
+ goto error;
+ }
+
+ if (user_data != NULL) {
+ htp_cfg_rec = user_data;
+ htp = htp_cfg_rec->cfg;
+ SCLogDebug("LIBHTP using config: %p", htp);
+ } else {
+ SCLogDebug("Using default HTP config: %p", htp);
+ }
+
+ if (NULL == htp) {
+#ifdef DEBUG_VALIDATION
+ BUG_ON(htp == NULL);
+#endif
+ /* should never happen if HTPConfigure is properly invoked */
+ goto error;
+ }
+
+ hstate->connp = htp_connp_create(htp);
+ if (hstate->connp == NULL) {
+ goto error;
+ }
+
+ hstate->conn = htp_connp_get_connection(hstate->connp);
+
+ htp_connp_set_user_data(hstate->connp, (void *)hstate);
+ hstate->cfg = htp_cfg_rec;
+
+ SCLogDebug("New hstate->connp %p", hstate->connp);
+
+ htp_connp_open(hstate->connp, NULL, f->sp, NULL, f->dp, &f->startts);
+
+ return 0;
+error:
+ return -1;
+}
+
/**
* \brief Function to handle the reassembled data from client and feed it to
* the HTP library to process it.
int r = -1;
int ret = 1;
- //PrintRawDataFp(stdout, input, input_len);
-
HtpState *hstate = (HtpState *)htp_state;
- hstate->f = f;
/* On the first invocation, create the connection parser structure to
* be used by HTP library. This is looked up via IP in the radix
* tree. Failing that, the default HTP config is used.
*/
if (NULL == hstate->conn) {
- HTPCfgRec *htp_cfg_rec = &cfglist;
- htp_cfg_t *htp = cfglist.cfg; /* Default to the global HTP config */
- void *user_data = NULL;
-
- if (FLOW_IS_IPV4(f)) {
- SCLogDebug("Looking up HTP config for ipv4 %08x", *GET_IPV4_DST_ADDR_PTR(f));
- (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)GET_IPV4_DST_ADDR_PTR(f), cfgtree, &user_data);
- }
- else if (FLOW_IS_IPV6(f)) {
- SCLogDebug("Looking up HTP config for ipv6");
- (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)GET_IPV6_DST_ADDR(f), cfgtree, &user_data);
- }
- else {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown address family, bug!");
- goto error;
- }
-
- if (user_data != NULL) {
- htp_cfg_rec = user_data;
- htp = htp_cfg_rec->cfg;
- SCLogDebug("LIBHTP using config: %p", htp);
- } else {
- SCLogDebug("Using default HTP config: %p", htp);
- }
-
- if (NULL == htp) {
-#ifdef DEBUG_VALIDATION
- BUG_ON(htp == NULL);
-#endif
- /* should never happen if HTPConfigure is properly invoked */
+ if (Setup(f, hstate) != 0) {
goto error;
}
-
- hstate->connp = htp_connp_create(htp);
- if (hstate->connp == NULL) {
- goto error;
- }
-
- hstate->conn = htp_connp_get_connection(hstate->connp);
-
- htp_connp_set_user_data(hstate->connp, (void *)hstate);
- hstate->cfg = htp_cfg_rec;
-
- SCLogDebug("New hstate->connp %p", hstate->connp);
}
-
- /* the code block above should make sure connp is never NULL here */
-#ifdef DEBUG_VALIDATION
- BUG_ON(hstate->connp == NULL);
-#endif
+ DEBUG_VALIDATE_BUG_ON(hstate->connp == NULL);
/* Unset the body inspection (the callback should
* reactivate it if necessary) */
hstate->flags &=~ HTP_FLAG_NEW_BODY_SET;
- /* Open the HTTP connection on receiving the first request */
- if (!(hstate->flags & HTP_FLAG_STATE_OPEN)) {
- SCLogDebug("opening htp handle at %p", hstate->connp);
-
- htp_connp_open(hstate->connp, NULL, f->sp, NULL, f->dp, &f->startts);
- hstate->flags |= HTP_FLAG_STATE_OPEN;
- } else {
- SCLogDebug("using existing htp handle at %p", hstate->connp);
- }
-
htp_time_t ts = { f->lastts.tv_sec, f->lastts.tv_usec };
/* pass the new data to the htp parser */
if (input_len > 0) {
int ret = 1;
HtpState *hstate = (HtpState *)htp_state;
- hstate->f = f;
- if (hstate->connp == NULL) {
- SCLogDebug("HTP state has no connp");
- /* till we have the new libhtp changes that allow response first,
- * let's take response in first. */
- //BUG_ON(1);
- SCReturnInt(-1);
+ /* On the first invocation, create the connection parser structure to
+ * be used by HTP library. This is looked up via IP in the radix
+ * tree. Failing that, the default HTP config is used.
+ */
+ if (NULL == hstate->conn) {
+ if (Setup(f, hstate) != 0) {
+ goto error;
+ }
}
+ DEBUG_VALIDATE_BUG_ON(hstate->connp == NULL);
/* Unset the body inspection (the callback should
* reactivate it if necessary) */
SCLogDebug("hstate->connp %p", hstate->connp);
SCReturnInt(ret);
+error:
+ SCReturnInt(-1);
}
/**
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOCLIENT,
HTPHandleResponseData);
SC_ATOMIC_INIT(htp_config_flags);
- AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOSERVER);
+ AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP,
+ ALPROTO_HTTP, STREAM_TOSERVER|STREAM_TOCLIENT);
HTPConfigure();
} else {
SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
- FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
- FAIL_IF(f.alproto != ALPROTO_FAILED);
- FAIL_IF(f.alproto_ts != ALPROTO_FAILED);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
- FAIL_IF(!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
+ FAIL_IF((ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ p->tcph->th_ack = htonl(1 + sizeof(request));
+ p->tcph->th_seq = htonl(328);
+ p->tcph->th_flags = TH_PUSH | TH_ACK;
+ p->flowflags = FLOW_PKT_TOCLIENT;
+ p->payload_len = 0;
+ p->payload = NULL;
+ FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF((ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+
TEST_END;
PASS;
}