diff --git a/src/Makefile.am b/src/Makefile.am index 4e4a76dba1..cd716c7e58 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,8 @@ detect-engine-siggroup.c detect-engine-siggroup.h \ detect-engine-mpm.c detect-engine-mpm.h \ detect-engine-iponly.c detect-engine-iponly.h \ detect-parse.c detect-parse.h \ +detect-ack.c detect-ack.h \ +detect-seq.c detect-seq.h \ detect-content.c detect-content.h \ detect-uricontent.c detect-uricontent.h \ detect-flowbits.c detect-flowbits.h \ diff --git a/src/detect-ack.c b/src/detect-ack.c new file mode 100644 index 0000000000..99104d78a9 --- /dev/null +++ b/src/detect-ack.c @@ -0,0 +1,314 @@ +/* Copyright (c) 2009 Open Information Security Foundation */ + +/** + * \file + * \author Brian Rectanus + * + * Implements the "ack" keyword. + */ + +#include "eidps-common.h" +#include "debug.h" +#include "decode.h" +#include "detect.h" + +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" + +#include "detect-ack.h" + +#include "util-byte.h" +#include "util-unittest.h" + +static int DetectAckSetup(DetectEngineCtx *, Signature *s, SigMatch *m, + char *sidstr); +static int DetectAckMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Packet *p, Signature *s, SigMatch *m); +static void DetectAckRegisterTests(void); +static void DetectAckFree(void *ptr); + + +void DetectAckRegister(void) { + sigmatch_table[DETECT_ACK].name = "ack"; + sigmatch_table[DETECT_ACK].Match = DetectAckMatch; + sigmatch_table[DETECT_ACK].Setup = DetectAckSetup; + sigmatch_table[DETECT_ACK].Free = DetectAckFree; + sigmatch_table[DETECT_ACK].RegisterTests = DetectAckRegisterTests; +} + +/** + * \internal + * \brief This function is used to match packets with a given Ack number + * + * \param t pointer to thread vars + * \param det_ctx pointer to the pattern matcher thread + * \param p pointer to the current packet + * \param m pointer to the sigmatch that we will cast into DetectAckData + * + * \retval 0 no match + * \retval 1 match + */ +static int DetectAckMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Packet *p, Signature *s, SigMatch *m) +{ + uint32_t *data = (uint32_t *)m->ctx; + + /* This is only needed on TCP packets */ + if (IPPROTO_TCP != p->proto) { + return 0; + } + + return (*data == TCP_GET_ACK(p)) ? 1 : 0; +} + +/** + * \internal + * \brief this function is used to add the ack option into the signature + * + * \param de_ctx pointer to the Detection Engine Context + * \param s pointer to the Current Signature + * \param m pointer to the Current SigMatch + * \param optstr pointer to the user provided options + * + * \retval 0 on Success + * \retval -1 on Failure + */ +static int DetectAckSetup(DetectEngineCtx *de_ctx, Signature *s, + SigMatch *m, char *optstr) +{ + uint32_t *data = malloc(sizeof(uint32_t)); + SigMatch *sm = NULL; + + //printf("DetectAckSetup: \'%s\'\n", optstr); + + data = malloc(sizeof(uint32_t)); + if (data == NULL) { + printf("DetectAckSetup: malloc failed\n"); + goto error; + } + + sm = SigMatchAlloc(); + if (sm == NULL) { + goto error; + } + + sm->type = DETECT_ACK; + + if (-1 == ByteExtractStringUint32(data, 10, 0, optstr)) { + goto error; + } + sm->ctx = (void *)data; + + SigMatchAppend(s, m, sm); + + return 0; + +error: + if (data) free(data); + return -1; + +} + +/** + * \internal + * \brief this function will free memory associated with ack option + * + * \param data pointer to ack configuration data + */ +static void DetectAckFree(void *ptr) +{ + uint32_t *data = (uint32_t *)ptr; + free(data); +} + + +#ifdef UNITTESTS +/** + * \internal + * \brief This test tests sameip success and failure. + */ +static int DetectAckSigTest01Real(int mpm_type) +{ + uint8_t *buf = (uint8_t *)""; + uint16_t buflen = strlen((char *)buf); + Packet p[3]; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx; + int result = 0; + uint8_t tcp_hdr0[] = { + 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, + 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, + 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, + 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, + 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02 + }; + uint8_t tcp_hdr1[] = { + 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, + 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, + 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, + 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, + 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02 + }; + + memset(&th_v, 0, sizeof(th_v)); + + /* TCP w/ack=42 */ + memset(&p[0], 0, sizeof(p[0])); + p[0].src.family = AF_INET; + p[0].dst.family = AF_INET; + p[0].payload = buf; + p[0].payload_len = buflen; + p[0].proto = IPPROTO_TCP; + p[0].tcph = (TCPHdr *)tcp_hdr0; + p[0].tcph->th_ack = htonl(42); + + /* TCP w/ack=100 */ + memset(&p[1], 0, sizeof(p[1])); + p[1].src.family = AF_INET; + p[1].dst.family = AF_INET; + p[1].payload = buf; + p[1].payload_len = buflen; + p[1].proto = IPPROTO_TCP; + p[1].tcph = (TCPHdr *)tcp_hdr1; + p[1].tcph->th_ack = htonl(100); + + /* ICMP */ + memset(&p[2], 0, sizeof(p[2])); + p[2].src.family = AF_INET; + p[2].dst.family = AF_INET; + p[2].payload = buf; + p[2].payload_len = buflen; + p[2].proto = IPPROTO_ICMP; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + /* These three are crammed in here as there is no Parse */ + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing ack\";ack:foo;sid:1;)") != NULL) + { + printf("invalid ack accepted: "); + goto end; + } + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing ack\";ack:9999999999;sid:1;)") != NULL) + { + printf("overflowing ack accepted: "); + goto end; + } + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing ack\";ack:-100;sid:1;)") != NULL) + { + printf("negative ack accepted: "); + goto end; + } + + de_ctx->sig_list = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing ack\";sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + de_ctx->sig_list->next = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing ack\";ack:42;sid:2;)"); + if (de_ctx->sig_list->next == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + PatternMatchPrepare(mpm_ctx, mpm_type); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[0]); + if (PacketAlertCheck(&p[0], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[0], 2) == 0) { + printf("sid 2 did not alert, but should have: "); + goto cleanup; + } + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[1]); + if (PacketAlertCheck(&p[1], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[1], 2) != 0) { + printf("sid 2 alerted, but should not have: "); + goto cleanup; + } + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[1]); + if (PacketAlertCheck(&p[2], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[2], 2) != 0) { + printf("sid 2 alerted, but should not have: "); + goto cleanup; + } + + result = 1; + +cleanup: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + PatternMatchDestroy(mpm_ctx); + DetectEngineCtxFree(de_ctx); + +end: + return result; +} + +/** + * \test DetectAckSigTest01B2g tests sameip under B2g MPM + */ +static int DetectAckSigTest01B2g(void) +{ + return DetectAckSigTest01Real(MPM_B2G); +} + +/** + * \test DetectAckSigTest01B2g tests sameip under B3g MPM + */ +static int DetectAckSigTest01B3g(void) +{ + return DetectAckSigTest01Real(MPM_B3G); +} + +/** + * \test DetectAckSigTest01B2g tests sameip under WuManber MPM + */ +static int DetectAckSigTest01Wm(void) +{ + return DetectAckSigTest01Real(MPM_WUMANBER); +} + +#endif /* UNITTESTS */ + +/** + * \internal + * \brief This function registers unit tests for DetectAck + */ +static void DetectAckRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectAckSigTest01B2g", DetectAckSigTest01B2g, 1); + UtRegisterTest("DetectAckSigTest01B3g", DetectAckSigTest01B3g, 1); + UtRegisterTest("DetectAckSigTest01Wm", DetectAckSigTest01Wm, 1); +#endif /* UNITTESTS */ +} + diff --git a/src/detect-ack.h b/src/detect-ack.h new file mode 100644 index 0000000000..76512a109e --- /dev/null +++ b/src/detect-ack.h @@ -0,0 +1,10 @@ +#ifndef __DETECT_ACK_H__ +#define __DETECT_ACK_H__ + +/** + * \brief Registration function for ack: keyword + */ +void DetectAckRegister(void); + +#endif /* __DETECT_ACK_H__ */ + diff --git a/src/detect-seq.c b/src/detect-seq.c new file mode 100644 index 0000000000..ad524e6291 --- /dev/null +++ b/src/detect-seq.c @@ -0,0 +1,314 @@ +/* Copyright (c) 2009 Open Information Security Foundation */ + +/** + * \file + * \author Brian Rectanus + * + * Implements the "seq" keyword. + */ + +#include "eidps-common.h" +#include "debug.h" +#include "decode.h" +#include "detect.h" + +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" + +#include "detect-seq.h" + +#include "util-byte.h" +#include "util-unittest.h" + +static int DetectSeqSetup(DetectEngineCtx *, Signature *s, SigMatch *m, + char *sidstr); +static int DetectSeqMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Packet *p, Signature *s, SigMatch *m); +static void DetectSeqRegisterTests(void); +static void DetectSeqFree(void *ptr); + + +void DetectSeqRegister(void) { + sigmatch_table[DETECT_SEQ].name = "seq"; + sigmatch_table[DETECT_SEQ].Match = DetectSeqMatch; + sigmatch_table[DETECT_SEQ].Setup = DetectSeqSetup; + sigmatch_table[DETECT_SEQ].Free = DetectSeqFree; + sigmatch_table[DETECT_SEQ].RegisterTests = DetectSeqRegisterTests; +} + +/** + * \internal + * \brief This function is used to match packets with a given Seq number + * + * \param t pointer to thread vars + * \param det_ctx pointer to the pattern matcher thread + * \param p pointer to the current packet + * \param m pointer to the sigmatch that we will cast into DetectSeqData + * + * \retval 0 no match + * \retval 1 match + */ +static int DetectSeqMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Packet *p, Signature *s, SigMatch *m) +{ + uint32_t *data = (uint32_t *)m->ctx; + + /* This is only needed on TCP packets */ + if (IPPROTO_TCP != p->proto) { + return 0; + } + + return (*data == TCP_GET_SEQ(p)) ? 1 : 0; +} + +/** + * \internal + * \brief this function is used to add the seq option into the signature + * + * \param de_ctx pointer to the Detection Engine Context + * \param s pointer to the Current Signature + * \param m pointer to the Current SigMatch + * \param optstr pointer to the user provided options + * + * \retval 0 on Success + * \retval -1 on Failure + */ +static int DetectSeqSetup (DetectEngineCtx *de_ctx, Signature *s, + SigMatch *m, char *optstr) +{ + uint32_t *data = malloc(sizeof(uint32_t)); + SigMatch *sm = NULL; + + //printf("DetectSeqSetup: \'%s\'\n", optstr); + + data = malloc(sizeof(uint32_t)); + if (data == NULL) { + printf("DetectSeqSetup: malloc failed\n"); + goto error; + } + + sm = SigMatchAlloc(); + if (sm == NULL) { + goto error; + } + + sm->type = DETECT_SEQ; + + if (-1 == ByteExtractStringUint32(data, 10, 0, optstr)) { + goto error; + } + sm->ctx = (void *)data; + + SigMatchAppend(s, m, sm); + + return 0; + +error: + if (data) free(data); + return -1; + +} + +/** + * \internal + * \brief this function will free memory associated with seq option + * + * \param data pointer to seq configuration data + */ +static void DetectSeqFree(void *ptr) +{ + uint32_t *data = (uint32_t *)ptr; + free(data); +} + + +#ifdef UNITTESTS +/** + * \internal + * \brief This test tests sameip success and failure. + */ +static int DetectSeqSigTest01Real(int mpm_type) +{ + uint8_t *buf = (uint8_t *)""; + uint16_t buflen = strlen((char *)buf); + Packet p[3]; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx; + int result = 0; + uint8_t tcp_hdr0[] = { + 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, + 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, + 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, + 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, + 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02 + }; + uint8_t tcp_hdr1[] = { + 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, + 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, + 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, + 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, + 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02 + }; + + memset(&th_v, 0, sizeof(th_v)); + + /* TCP w/seq=42 */ + memset(&p[0], 0, sizeof(p[0])); + p[0].src.family = AF_INET; + p[0].dst.family = AF_INET; + p[0].payload = buf; + p[0].payload_len = buflen; + p[0].proto = IPPROTO_TCP; + p[0].tcph = (TCPHdr *)tcp_hdr0; + p[0].tcph->th_seq = htonl(42); + + /* TCP w/seq=100 */ + memset(&p[1], 0, sizeof(p[1])); + p[1].src.family = AF_INET; + p[1].dst.family = AF_INET; + p[1].payload = buf; + p[1].payload_len = buflen; + p[1].proto = IPPROTO_TCP; + p[1].tcph = (TCPHdr *)tcp_hdr1; + p[1].tcph->th_seq = htonl(100); + + /* ICMP */ + memset(&p[2], 0, sizeof(p[2])); + p[2].src.family = AF_INET; + p[2].dst.family = AF_INET; + p[2].payload = buf; + p[2].payload_len = buflen; + p[2].proto = IPPROTO_ICMP; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + /* These three are crammed in here as there is no Parse */ + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing seq\";seq:foo;sid:1;)") != NULL) + { + printf("invalid seq accepted: "); + goto end; + } + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing seq\";seq:9999999999;sid:1;)") != NULL) + { + printf("overflowing seq accepted: "); + goto end; + } + if (SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing seq\";seq:-100;sid:1;)") != NULL) + { + printf("negative seq accepted: "); + goto end; + } + + de_ctx->sig_list = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing seq\";sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + de_ctx->sig_list->next = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing seq\";seq:42;sid:2;)"); + if (de_ctx->sig_list->next == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + PatternMatchPrepare(mpm_ctx, mpm_type); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[0]); + if (PacketAlertCheck(&p[0], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[0], 2) == 0) { + printf("sid 2 did not alert, but should have: "); + goto cleanup; + } + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[1]); + if (PacketAlertCheck(&p[1], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[1], 2) != 0) { + printf("sid 2 alerted, but should not have: "); + goto cleanup; + } + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[1]); + if (PacketAlertCheck(&p[2], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[2], 2) != 0) { + printf("sid 2 alerted, but should not have: "); + goto cleanup; + } + + result = 1; + +cleanup: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + PatternMatchDestroy(mpm_ctx); + DetectEngineCtxFree(de_ctx); + +end: + return result; +} + +/** + * \test DetectSeqSigTest01B2g tests sameip under B2g MPM + */ +static int DetectSeqSigTest01B2g(void) +{ + return DetectSeqSigTest01Real(MPM_B2G); +} + +/** + * \test DetectSeqSigTest01B2g tests sameip under B3g MPM + */ +static int DetectSeqSigTest01B3g(void) +{ + return DetectSeqSigTest01Real(MPM_B3G); +} + +/** + * \test DetectSeqSigTest01B2g tests sameip under WuManber MPM + */ +static int DetectSeqSigTest01Wm(void) +{ + return DetectSeqSigTest01Real(MPM_WUMANBER); +} + +#endif /* UNITTESTS */ + +/** + * \internal + * \brief This function registers unit tests for DetectSeq + */ +static void DetectSeqRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectSeqSigTest01B2g", DetectSeqSigTest01B2g, 1); + UtRegisterTest("DetectSeqSigTest01B3g", DetectSeqSigTest01B3g, 1); + UtRegisterTest("DetectSeqSigTest01Wm", DetectSeqSigTest01Wm, 1); +#endif /* UNITTESTS */ +} + diff --git a/src/detect-seq.h b/src/detect-seq.h new file mode 100644 index 0000000000..7623c75c97 --- /dev/null +++ b/src/detect-seq.h @@ -0,0 +1,8 @@ +#ifndef __DETECT_SEQ_H__ +#define __DETECT_SEQ_H__ + +/* prototypes */ +void DetectSeqRegister(void); + +#endif /* __DETECT_SEQ_H__ */ + diff --git a/src/detect.c b/src/detect.c index 1068ff88ca..e642d017c8 100644 --- a/src/detect.c +++ b/src/detect.c @@ -22,6 +22,8 @@ #include "detect-flags.h" #include "detect-fragbits.h" #include "detect-gid.h" +#include "detect-ack.h" +#include "detect-seq.h" #include "detect-content.h" #include "detect-uricontent.h" #include "detect-pcre.h" @@ -2571,6 +2573,8 @@ void SigTableSetup(void) { DetectThresholdRegister(); DetectMetadataRegister(); DetectMsgRegister(); + DetectAckRegister(); + DetectSeqRegister(); DetectContentRegister(); DetectUricontentRegister(); DetectPcreRegister(); diff --git a/src/detect.h b/src/detect.h index 6ec782e3e4..1bb97c44df 100644 --- a/src/detect.h +++ b/src/detect.h @@ -402,6 +402,8 @@ enum { DETECT_CONTENT, /* 8 */ DETECT_URICONTENT, /* 9 */ DETECT_PCRE, /* 10 */ + DETECT_ACK, + DETECT_SEQ, DETECT_DEPTH, DETECT_DISTANCE, DETECT_WITHIN, diff --git a/src/util-byte.c b/src/util-byte.c index 086a008b3c..d903811a44 100644 --- a/src/util-byte.c +++ b/src/util-byte.c @@ -2,6 +2,8 @@ #include "util-byte.h" #include "util-unittest.h" +/** \todo: Remove the fprintf errors in favor of logging */ + int ByteExtract(uint64_t *res, int e, uint16_t len, const uint8_t *bytes) { uint64_t b = 0; @@ -27,7 +29,6 @@ int ByteExtract(uint64_t *res, int e, uint16_t len, const uint8_t *bytes) *res |= (b << ((i & 7) << 3)); - //printf("ByteExtractUint64: %016" PRIx64 "/%016" PRIx64 "\n", (b << ((i & 7) << 3)), *res); } return len; @@ -110,9 +111,8 @@ int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) */ char strbuf[24]; -//printf("ByteExtractString(%p,%d,%d,\"%s\")", res, base, len, str); if (len > 23) { - printf("ByteExtractString: len too large (23 max)\n"); + fprintf(stderr, "ByteExtractString: len too large (23 max)\n"); return -1; } @@ -127,10 +127,10 @@ int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) *res = strtoull(ptr, &endptr, base); if (errno == ERANGE) { - printf("ByteExtractString: Numeric value out of range.\n"); + fprintf(stderr, "ByteExtractString: Numeric value out of range\n"); return -1; } else if (endptr == str) { - printf("ByteExtractString: Invalid numeric value.\n"); + fprintf(stderr, "ByteExtractString: Invalid numeric value\n"); return -1; } /* This will interfere with some rules that do not know the length @@ -138,13 +138,11 @@ int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) */ #if 0 else if (len && *endptr != '\0') { - printf("ByteExtractString: Extra characters following numeric value.\n"); + fprintf(stderr, "ByteExtractString: Extra characters following numeric value\n"); return -1; } #endif - //printf("ByteExtractString: Extracted base %d: 0x%" PRIx64 "\n", base, *res); - return (endptr - ptr); } @@ -166,7 +164,7 @@ inline int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const *res = (uint32_t)i64; if ((uint64_t)(*res) != i64) { - printf("ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (uint64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); return -1; } @@ -186,7 +184,7 @@ inline int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const *res = (uint16_t)i64; if ((uint64_t)(*res) != i64) { - printf("ByteExtractStringUint16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (uint64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringUint16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); return -1; } @@ -206,7 +204,7 @@ inline int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const ch *res = (uint8_t)i64; if ((uint64_t)(*res) != i64) { - printf("ByteExtractStringUint8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (uint64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringUint8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); return -1; } @@ -228,7 +226,7 @@ int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *st char strbuf[24]; if (len > 23) { - printf("ByteExtractStringSigned: len too large (23 max)\n"); + fprintf(stderr, "ByteExtractStringSigned: len too large (23 max)\n"); return -1; } @@ -243,10 +241,10 @@ int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *st *res = strtoll(ptr, &endptr, base); if (errno == ERANGE) { - printf("ByteExtractStringSigned: Numeric value out of range.\n"); + fprintf(stderr, "ByteExtractStringSigned: Numeric value out of range\n"); return -1; } else if (endptr == str) { - printf("ByteExtractStringSigned: Invalid numeric value.\n"); + fprintf(stderr, "ByteExtractStringSigned: Invalid numeric value\n"); return -1; } /* This will interfere with some rules that do not know the length @@ -254,12 +252,12 @@ int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *st */ #if 0 else if (len && *endptr != '\0') { - printf("ByteExtractStringSigned: Extra characters following numeric value.\n"); + fprintf(stderr, "ByteExtractStringSigned: Extra characters following numeric value\n"); return -1; } #endif - //printf("ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res); + //fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res); return (endptr - ptr); } @@ -282,7 +280,7 @@ inline int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const ch *res = (int32_t)i64; if ((int64_t)(*res) != i64) { - printf("ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (int64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; } @@ -302,7 +300,7 @@ inline int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const ch *res = (int16_t)i64; if ((int64_t)(*res) != i64) { - printf("ByteExtractStringInt16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (int64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringInt16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; } @@ -322,7 +320,7 @@ inline int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *res = (int8_t)i64; if ((int64_t)(*res) != i64) { - printf("ByteExtractStringInt8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ").", (int64_t)(*res), i64); + fprintf(stderr, "ByteExtractStringInt8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; }