/** * \brief This function is used to parse icmp_seq option passed via icmp_seq: keyword * * \param icmpseqstr Pointer to the user provided icmp_seq options * * \retval iseq pointer to DetectIcmpSeqData on success * \retval NULL on failure */ DetectIcmpSeqData *DetectIcmpSeqParse (char *icmpseqstr) { DetectIcmpSeqData *iseq = NULL; char *substr[3] = {NULL, NULL, NULL}; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; int i; const char *str_ptr; ret = pcre_exec(parse_regex, parse_regex_study, icmpseqstr, strlen(icmpseqstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret < 1 || ret > 4) { SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", icmpseqstr); goto error; } for (i = 1; i < ret; i++) { res = pcre_get_substring((char *)icmpseqstr, ov, MAX_SUBSTRINGS, i, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_get_substring failed"); goto error; } substr[i-1] = (char *)str_ptr; } iseq = SCMalloc(sizeof(DetectIcmpSeqData)); if (iseq == NULL) goto error; iseq->seq = 0; if (substr[0] != NULL && strlen(substr[0]) != 0) { if (substr[2] == NULL) { SCLogError(SC_ERR_MISSING_QUOTE,"Missing quote in input"); goto error; } } else { if (substr[2] != NULL) { SCLogError(SC_ERR_MISSING_QUOTE,"Missing quote in input"); goto error; } } uint16_t seq = 0; ByteExtractStringUint16(&seq, 10, 0, substr[1]); iseq->seq = htons(seq); for (i = 0; i < 3; i++) { if (substr[i] != NULL) SCFree(substr[i]); } return iseq; error: for (i = 0; i < 3; i++) { if (substr[i] != NULL) SCFree(substr[i]); } if (iseq != NULL) DetectIcmpSeqFree(iseq); return NULL; }
/** * \test DetectIcmpSeqParseTest03 is a test for setting an invalid icmp_seq value */ int DetectIcmpSeqParseTest03 (void) { DetectIcmpSeqData *iseq = NULL; iseq = DetectIcmpSeqParse("badc"); if (iseq != NULL) { DetectIcmpSeqFree(iseq); return 1; } return 0; }
/** * \test DetectIcmpSeqParseTest02 is a test for setting a valid icmp_seq value * with spaces all around */ int DetectIcmpSeqParseTest02 (void) { DetectIcmpSeqData *iseq = NULL; iseq = DetectIcmpSeqParse(" 300 "); if (iseq != NULL && iseq->seq == htons(300)) { DetectIcmpSeqFree(iseq); return 1; } return 0; }
/** * \brief this function is used to add the parsed icmp_seq data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param icmpseqstr pointer to the user provided icmp_seq option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectIcmpSeqSetup (DetectEngineCtx *de_ctx, Signature *s, char *icmpseqstr) { DetectIcmpSeqData *iseq = NULL; SigMatch *sm = NULL; iseq = DetectIcmpSeqParse(icmpseqstr); if (iseq == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_ICMP_SEQ; sm->ctx = (void *)iseq; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); return 0; error: if (iseq != NULL) DetectIcmpSeqFree(iseq); if (sm != NULL) SCFree(sm); return -1; }