/** * \brief Returns the TV for the calling thread. * * \retval tv Pointer to the ThreadVars instance for the calling thread; * NULL on no match */ ThreadVars *TmThreadsGetCallingThread(void) { pthread_t self = pthread_self(); ThreadVars *tv = NULL; int i = 0; SCMutexLock(&tv_root_lock); for (i = 0; i < TVT_MAX; i++) { tv = tv_root[i]; while (tv) { if (pthread_equal(self, tv->t)) { SCMutexUnlock(&tv_root_lock); return tv; } tv = tv->next; } } SCMutexUnlock(&tv_root_lock); return NULL; }
TmEcode ReceiveNFQThreadDeinit(ThreadVars *t, void *data) { NFQThreadVars *ntv = (NFQThreadVars *)data; NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); if (ntv->data != NULL) { SCFree(ntv->data); ntv->data = NULL; } ntv->datalen = 0; NFQDestroyQueue(nq); SCMutexLock(&nfq_init_lock); if (--receive_queue_num == 0) { // No more active queues, we may now free global contexts SCFree(g_nfq_t); SCFree(g_nfq_q); } SCMutexUnlock(&nfq_init_lock); return TM_ECODE_OK; }
/** * \brief Write buffer to log file. * \retval 0 on failure; otherwise, the return value of fwrite (number of * characters successfully written). */ static int SCLogFileWrite(const char *buffer, int buffer_len, LogFileCtx *log_ctx) { SCMutexLock(&log_ctx->fp_mutex); int ret = 0; #ifdef BUILD_WITH_UNIXSOCKET if (log_ctx->is_sock) { ret = SCLogFileWriteSocket(buffer, buffer_len, log_ctx); } else #endif { /* Check for rotation. */ if (log_ctx->rotation_flag) { log_ctx->rotation_flag = 0; SCConfLogReopen(log_ctx); } if (log_ctx->flags & LOGFILE_ROTATE_INTERVAL) { time_t now = time(NULL); if (now >= log_ctx->rotate_time) { SCConfLogReopen(log_ctx); log_ctx->rotate_time = now + log_ctx->rotate_interval; } } if (log_ctx->fp) { clearerr(log_ctx->fp); ret = fwrite(buffer, buffer_len, 1, log_ctx->fp); fflush(log_ctx->fp); } } SCMutexUnlock(&log_ctx->fp_mutex); return ret; }
int PoolThreadGrow(PoolThread *pt, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)) { void *ptmp; size_t newsize; PoolThreadElement *e = NULL; if (pt == NULL || pt->array == NULL) { SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); return -1; } newsize = pt->size + 1; SCLogDebug("newsize %lu", newsize); ptmp = SCRealloc(pt->array, (newsize * sizeof(PoolThreadElement))); if (ptmp == NULL) { SCFree(pt->array); pt->array = NULL; SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); return -1; } pt->array = ptmp; pt->size = newsize; e = &pt->array[newsize - 1]; memset(e, 0x00, sizeof(*e)); SCMutexInit(&e->lock, NULL); SCMutexLock(&e->lock); e->pool = PoolInit(size, prealloc_size, elt_size, Alloc, Init, InitData, Cleanup, Free); SCMutexUnlock(&e->lock); if (e->pool == NULL) { SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); return -1; } return (int)(newsize - 1); }
TmEcode ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) { SCMutexLock(&nfq_init_lock); #ifndef OS_WIN32 sigset_t sigs; sigfillset(&sigs); pthread_sigmask(SIG_BLOCK, &sigs, NULL); #endif /* OS_WIN32 */ NFQThreadVars *ntv = (NFQThreadVars *) initdata; /* store the ThreadVars pointer in our NFQ thread context * as we will need it in our callback function */ ntv->tv = tv; int r = NFQInitThread(ntv, (max_pending_packets * NFQ_BURST_FACTOR)); if (r < 0) { SCLogError(SC_ERR_NFQ_THREAD_INIT, "nfq thread failed to initialize"); SCMutexUnlock(&nfq_init_lock); exit(EXIT_FAILURE); } #define T_DATA_SIZE 70000 ntv->data = SCMalloc(T_DATA_SIZE); if (ntv->data == NULL) { SCMutexUnlock(&nfq_init_lock); return TM_ECODE_FAILED; } ntv->datalen = T_DATA_SIZE; #undef T_DATA_SIZE *data = (void *)ntv; SCMutexUnlock(&nfq_init_lock); return TM_ECODE_OK; }
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) { char *js_s = json_dumps(js, JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| #ifdef JSON_ESCAPE_SLASH JSON_ESCAPE_SLASH #else 0 #endif ); if (unlikely(js_s == NULL)) return TM_ECODE_OK; SCMutexLock(&file_ctx->fp_mutex); if (json_out == ALERT_SYSLOG) { syslog(alert_syslog_level, "%s", js_s); } else if (json_out == ALERT_FILE) { MemBufferWriteString(buffer, "%s\n", js_s); (void)MemBufferPrintToFPAsString(buffer, file_ctx->fp); fflush(file_ctx->fp); } SCMutexUnlock(&file_ctx->fp_mutex); free(js_s); return 0; }
/** * \brief bypass callback function for NFQ * * \param p a Packet to use information from to trigger bypass * \return 1 if bypass is successful, 0 if not */ static int NFQBypassCallback(Packet *p) { if (IS_TUNNEL_PKT(p)) { /* real tunnels may have multiple flows inside them, so bypass can't * work for those. Rebuilt packets from IP fragments are fine. */ if (p->flags & PKT_REBUILT_FRAGMENT) { Packet *tp = p->root ? p->root : p; SCMutexLock(&tp->tunnel_mutex); tp->nfq_v.mark = (nfq_config.bypass_mark & nfq_config.bypass_mask) | (tp->nfq_v.mark & ~nfq_config.bypass_mask); tp->flags |= PKT_MARK_MODIFIED; SCMutexUnlock(&tp->tunnel_mutex); return 1; } return 0; } else { /* coverity[missing_lock] */ p->nfq_v.mark = (nfq_config.bypass_mark & nfq_config.bypass_mask) | (p->nfq_v.mark & ~nfq_config.bypass_mask); p->flags |= PKT_MARK_MODIFIED; } return 1; }
int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { Unified2AlertThread *aun = (Unified2AlertThread *)data; Unified2AlertFileHeader hdr; AlertIPv4Unified2 *phdr = (AlertIPv4Unified2 *)(aun->data + sizeof(Unified2AlertFileHeader)); AlertIPv4Unified2 gphdr; PacketAlert *pa; int offset, length; int ret; unsigned int event_id; if (p->alerts.cnt == 0) return 0; length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv4Unified2)); offset = length; memset(aun->data, 0, aun->datalen); hdr.type = htonl(UNIFIED2_IDS_EVENT_TYPE); hdr.length = htonl(sizeof(AlertIPv4Unified2)); /* fill the gphdr structure with the data of the packet */ memset(&gphdr, 0, sizeof(gphdr)); gphdr.sensor_id = htonl(sensor_id); gphdr.event_id = 0; gphdr.event_second = htonl(p->ts.tv_sec); gphdr.event_microsecond = htonl(p->ts.tv_usec); gphdr.src_ip = p->ip4h->s_ip_src.s_addr; gphdr.dst_ip = p->ip4h->s_ip_dst.s_addr; gphdr.protocol = IPV4_GET_RAW_IPPROTO(p->ip4h); if(p->action & ACTION_DROP) gphdr.packet_action = UNIFIED2_BLOCKED_FLAG; else gphdr.packet_action = 0; /* TODO inverse order if needed, this should be done on a * alert basis */ switch(gphdr.protocol) { case IPPROTO_ICMP: if(p->icmpv4h) { gphdr.sp = htons(p->icmpv4h->type); gphdr.dp = htons(p->icmpv4h->code); } break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: gphdr.sp = htons(p->sp); gphdr.dp = htons(p->dp); break; default: gphdr.sp = 0; gphdr.dp = 0; break; } uint16_t i = 0; for (; i < p->alerts.cnt + 1; i++) { if (i < p->alerts.cnt) pa = &p->alerts.alerts[i]; else { if (!(p->flags & PKT_HAS_TAG)) break; pa = PacketAlertGetTag(); } if (unlikely(pa->s == NULL)) continue; /* reset length and offset */ aun->offset = offset; aun->length = length; memset(aun->data + aun->offset, 0, aun->datalen - aun->offset); /* copy the part common to all alerts */ memcpy(aun->data, &hdr, sizeof(hdr)); memcpy(phdr, &gphdr, sizeof(gphdr)); /* fill the hdr structure with the alert data */ event_id = htonl(SC_ATOMIC_ADD(unified2_event_id, 1)); phdr->event_id = event_id; phdr->generator_id = htonl(pa->s->gid); phdr->signature_id = htonl(pa->s->id); phdr->signature_revision = htonl(pa->s->rev); phdr->classification_id = htonl(pa->s->class); phdr->priority_id = htonl(pa->s->prio); /* check and enforce the filesize limit */ SCMutexLock(&aun->file_ctx->fp_mutex); if ((aun->file_ctx->size_current + length) > aun->file_ctx->size_limit) { if (Unified2AlertRotateFile(tv,aun) < 0) { aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } } if (Unified2Write(aun) != 1) { aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } memset(aun->data, 0, aun->length); aun->length = 0; aun->offset = 0; /* Write the alert (it doesn't lock inside, since we * already locked here for rotation check) */ int stream = (gphdr.protocol == IPPROTO_TCP) ? (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; ret = Unified2PacketTypeAlert(aun, p, event_id, stream); if (ret != 1) { aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } fflush(aun->file_ctx->fp); aun->file_ctx->alerts++; SCMutexUnlock(&aun->file_ctx->fp_mutex); } return 0; }
/** * \brief Function to fill unified2 ipv6 ids type format into the file. * * \param t Thread Variable containing input/output queue, cpu affinity etc. * \param p Packet struct used to decide for ipv4 or ipv6 * \param data Unified2 thread data. * \param pq Packet queue * * \retval 0 on succces * \retval -1 on failure */ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq) { Unified2AlertThread *aun = (Unified2AlertThread *)data; Unified2AlertFileHeader hdr; AlertIPv6Unified2 *phdr = (AlertIPv6Unified2 *)(aun->data + sizeof(Unified2AlertFileHeader)); AlertIPv6Unified2 gphdr; PacketAlert *pa; int offset, length; int ret; unsigned int event_id; if (p->alerts.cnt == 0) return 0; length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv6Unified2)); offset = length; memset(aun->data, 0, aun->datalen); hdr.type = htonl(UNIFIED2_IDS_EVENT_IPV6_TYPE); hdr.length = htonl(sizeof(AlertIPv6Unified2)); /* fill the gphdr structure with the data of the packet */ memset(&gphdr, 0, sizeof(gphdr)); /* FIXME this need to be copied for each alert */ gphdr.sensor_id = htonl(sensor_id); gphdr.event_second = htonl(p->ts.tv_sec); gphdr.event_microsecond = htonl(p->ts.tv_usec); gphdr.src_ip = *(struct in6_addr*)GET_IPV6_SRC_ADDR(p); gphdr.dst_ip = *(struct in6_addr*)GET_IPV6_DST_ADDR(p); gphdr.protocol = p->proto; if(p->action & ACTION_DROP) gphdr.packet_action = UNIFIED2_BLOCKED_FLAG; else gphdr.packet_action = 0; switch(gphdr.protocol) { case IPPROTO_ICMPV6: if(p->icmpv6h) { gphdr.sp = htons(p->icmpv6h->type); gphdr.dp = htons(p->icmpv6h->code); } else { gphdr.sp = 0; gphdr.dp = 0; } break; case IPPROTO_ICMP: if(p->icmpv4h) { gphdr.sp = htons(p->icmpv4h->type); gphdr.dp = htons(p->icmpv4h->code); } else { gphdr.sp = 0; gphdr.dp = 0; } break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: gphdr.sp = htons(p->sp); gphdr.dp = htons(p->dp); break; default: gphdr.sp = 0; gphdr.dp = 0; break; } uint16_t i = 0; for (; i < p->alerts.cnt + 1; i++) { if (i < p->alerts.cnt) pa = &p->alerts.alerts[i]; else { if (!(p->flags & PKT_HAS_TAG)) break; pa = PacketAlertGetTag(); } if (unlikely(pa->s == NULL)) continue; /* reset length and offset */ aun->offset = offset; aun->length = length; memset(aun->data + aun->offset, 0, aun->datalen - aun->offset); /* copy the part common to all alerts */ memcpy(aun->data, &hdr, sizeof(hdr)); memcpy(phdr, &gphdr, sizeof(gphdr)); /* fill the header structure with the data of the alert */ event_id = htonl(SC_ATOMIC_ADD(unified2_event_id, 1)); phdr->event_id = event_id; phdr->generator_id = htonl(pa->s->gid); phdr->signature_id = htonl(pa->s->id); phdr->signature_revision = htonl(pa->s->rev); phdr->classification_id = htonl(pa->s->class); phdr->priority_id = htonl(pa->s->prio); SCMutexLock(&aun->file_ctx->fp_mutex); if ((aun->file_ctx->size_current + length) > aun->file_ctx->size_limit) { if (Unified2AlertRotateFile(t,aun) < 0) { aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } } if (Unified2Write(aun) != 1) { aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } memset(aun->data, 0, aun->length); aun->length = 0; aun->offset = 0; /* stream flag based on state match, but only for TCP */ int stream = (gphdr.protocol == IPPROTO_TCP) ? (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; ret = Unified2PacketTypeAlert(aun, p, phdr->event_id, stream); if (ret != 1) { SCLogError(SC_ERR_FWRITE, "Error: fwrite failed: %s", strerror(errno)); aun->file_ctx->alerts += i; SCMutexUnlock(&aun->file_ctx->fp_mutex); return -1; } fflush(aun->file_ctx->fp); aun->file_ctx->alerts++; SCMutexUnlock(&aun->file_ctx->fp_mutex); } return 0; }
/** * \test Test a valid dce_iface entry for a bind and bind_ack */ static int DetectSslStateTest07(void) { uint8_t chello_buf[] = { 0x80, 0x67, 0x01, 0x03, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, 0x00, 0x00, 0x39, 0x00, 0x00, 0x38, 0x00, 0x00, 0x35, 0x00, 0x00, 0x33, 0x00, 0x00, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x16, 0x00, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x15, 0x00, 0x00, 0x12, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0xa8, 0xb8, 0x93, 0xbb, 0x90, 0xe9, 0x2a, 0xa2, 0x4d, 0x6d, 0xcc, 0x1c, 0xe7, 0x2a, 0x80, 0x21 }; uint32_t chello_buf_len = sizeof(chello_buf); uint8_t shello_buf[] = { 0x16, 0x03, 0x00, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x00, 0x44, 0x4c, 0x94, 0x8f, 0xfe, 0x81, 0xed, 0x93, 0x65, 0x02, 0x88, 0xa3, 0xf8, 0xeb, 0x63, 0x86, 0x0e, 0x2c, 0xf6, 0x8d, 0xd0, 0x0f, 0x2c, 0x2a, 0xd6, 0x4f, 0xcd, 0x2d, 0x3c, 0x16, 0xd7, 0xd6, 0x20, 0xa0, 0xfb, 0x60, 0x86, 0x3d, 0x1e, 0x76, 0xf3, 0x30, 0xfe, 0x0b, 0x01, 0xfd, 0x1a, 0x01, 0xed, 0x95, 0xf6, 0x7b, 0x8e, 0xc0, 0xd4, 0x27, 0xbf, 0xf0, 0x6e, 0xc7, 0x56, 0xb1, 0x47, 0xce, 0x98, 0x00, 0x35, 0x00, 0x16, 0x03, 0x00, 0x03, 0x44, 0x0b, 0x00, 0x03, 0x40, 0x00, 0x03, 0x3d, 0x00, 0x03, 0x3a, 0x30, 0x82, 0x03, 0x36, 0x30, 0x82, 0x02, 0x9f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x58, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0c, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x44, 0x65, 0x73, 0x65, 0x72, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, 0x2c, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0c, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, 0x20, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0f, 0x63, 0x61, 0x40, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x33, 0x30, 0x33, 0x30, 0x35, 0x31, 0x36, 0x34, 0x37, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x33, 0x30, 0x33, 0x31, 0x36, 0x34, 0x37, 0x34, 0x35, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x58, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0c, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x44, 0x65, 0x73, 0x65, 0x72, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, 0x2c, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x57, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x77, 0x77, 0x77, 0x40, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa4, 0x6e, 0x53, 0x14, 0x0a, 0xde, 0x2c, 0xe3, 0x60, 0x55, 0x9a, 0xf2, 0x42, 0xa6, 0xaf, 0x47, 0x12, 0x2f, 0x17, 0xce, 0xfa, 0xba, 0xdc, 0x4e, 0x63, 0x56, 0x34, 0xb9, 0xba, 0x73, 0x4b, 0x78, 0x44, 0x3d, 0xc6, 0x6c, 0x69, 0xa4, 0x25, 0xb3, 0x61, 0x02, 0x9d, 0x09, 0x04, 0x3f, 0x72, 0x3d, 0xd8, 0x27, 0xd3, 0xb0, 0x5a, 0x45, 0x77, 0xb7, 0x36, 0xe4, 0x26, 0x23, 0xcc, 0x12, 0xb8, 0xae, 0xde, 0xa7, 0xb6, 0x3a, 0x82, 0x3c, 0x7c, 0x24, 0x59, 0x0a, 0xf8, 0x96, 0x43, 0x8b, 0xa3, 0x29, 0x36, 0x3f, 0x91, 0x7f, 0x5d, 0xc7, 0x23, 0x94, 0x29, 0x7f, 0x0a, 0xce, 0x0a, 0xbd, 0x8d, 0x9b, 0x2f, 0x19, 0x17, 0xaa, 0xd5, 0x8e, 0xec, 0x66, 0xa2, 0x37, 0xeb, 0x3f, 0x57, 0x53, 0x3c, 0xf2, 0xaa, 0xbb, 0x79, 0x19, 0x4b, 0x90, 0x7e, 0xa7, 0xa3, 0x99, 0xfe, 0x84, 0x4c, 0x89, 0xf0, 0x3d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x14, 0x30, 0x12, 0x81, 0x10, 0x77, 0x77, 0x77, 0x40, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x30, 0x3a, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x2d, 0x16, 0x2b, 0x6d, 0x6f, 0x64, 0x5f, 0x73, 0x73, 0x6c, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xae, 0x79, 0x79, 0x22, 0x90, 0x75, 0xfd, 0xa6, 0xd5, 0xc4, 0xb8, 0xc4, 0x99, 0x4e, 0x1c, 0x05, 0x7c, 0x91, 0x59, 0xbe, 0x89, 0x0d, 0x3d, 0xc6, 0x8c, 0xa3, 0xcf, 0xf6, 0xba, 0x23, 0xdf, 0xb8, 0xae, 0x44, 0x68, 0x8a, 0x8f, 0xb9, 0x8b, 0xcb, 0x12, 0xda, 0xe6, 0xa2, 0xca, 0xa5, 0xa6, 0x55, 0xd9, 0xd2, 0xa1, 0xad, 0xba, 0x9b, 0x2c, 0x44, 0x95, 0x1d, 0x4a, 0x90, 0x59, 0x7f, 0x83, 0xae, 0x81, 0x5e, 0x3f, 0x92, 0xe0, 0x14, 0x41, 0x82, 0x4e, 0x7f, 0x53, 0xfd, 0x10, 0x23, 0xeb, 0x8a, 0xeb, 0xe9, 0x92, 0xea, 0x61, 0xf2, 0x8e, 0x19, 0xa1, 0xd3, 0x49, 0xc0, 0x84, 0x34, 0x1e, 0x2e, 0x6e, 0xf6, 0x98, 0xe2, 0x87, 0x53, 0xd6, 0x55, 0xd9, 0x1a, 0x8a, 0x92, 0x5c, 0xad, 0xdc, 0x1e, 0x1c, 0x30, 0xa7, 0x65, 0x9d, 0xc2, 0x4f, 0x60, 0xd2, 0x6f, 0xdb, 0xe0, 0x9f, 0x9e, 0xbc, 0x41, 0x16, 0x03, 0x00, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00 }; uint32_t shello_buf_len = sizeof(shello_buf); uint8_t client_change_cipher_spec_buf[] = { 0x16, 0x03, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x80, 0x65, 0x51, 0x2d, 0xa6, 0xd4, 0xa7, 0x38, 0xdf, 0xac, 0x79, 0x1f, 0x0b, 0xd9, 0xb2, 0x61, 0x7d, 0x73, 0x88, 0x32, 0xd9, 0xf2, 0x62, 0x3a, 0x8b, 0x11, 0x04, 0x75, 0xca, 0x42, 0xff, 0x4e, 0xd9, 0xcc, 0xb9, 0xfa, 0x86, 0xf3, 0x16, 0x2f, 0x09, 0x73, 0x51, 0x66, 0xaa, 0x29, 0xcd, 0x80, 0x61, 0x0f, 0xe8, 0x13, 0xce, 0x5b, 0x8e, 0x0a, 0x23, 0xf8, 0x91, 0x5e, 0x5f, 0x54, 0x70, 0x80, 0x8e, 0x7b, 0x28, 0xef, 0xb6, 0x69, 0xb2, 0x59, 0x85, 0x74, 0x98, 0xe2, 0x7e, 0xd8, 0xcc, 0x76, 0x80, 0xe1, 0xb6, 0x45, 0x4d, 0xc7, 0xcd, 0x84, 0xce, 0xb4, 0x52, 0x79, 0x74, 0xcd, 0xe6, 0xd7, 0xd1, 0x9c, 0xad, 0xef, 0x63, 0x6c, 0x0f, 0xf7, 0x05, 0xe4, 0x4d, 0x1a, 0xd3, 0xcb, 0x9c, 0xd2, 0x51, 0xb5, 0x61, 0xcb, 0xff, 0x7c, 0xee, 0xc7, 0xbc, 0x5e, 0x15, 0xa3, 0xf2, 0x52, 0x0f, 0xbb, 0x32, 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03, 0x00, 0x00, 0x40, 0xa9, 0xd8, 0xd7, 0x35, 0xbc, 0x39, 0x56, 0x98, 0xad, 0x87, 0x61, 0x2a, 0xc4, 0x8f, 0xcc, 0x03, 0xcb, 0x93, 0x80, 0x81, 0xb0, 0x4a, 0xc4, 0xd2, 0x09, 0x71, 0x3e, 0x90, 0x3c, 0x8d, 0xe0, 0x95, 0x44, 0xfe, 0x56, 0xd1, 0x7e, 0x88, 0xe2, 0x48, 0xfd, 0x76, 0x70, 0x76, 0xe2, 0xcd, 0x06, 0xd0, 0xf3, 0x9d, 0x13, 0x79, 0x67, 0x1e, 0x37, 0xf6, 0x98, 0xbe, 0x59, 0x18, 0x4c, 0xfc, 0x75, 0x56 }; uint32_t client_change_cipher_spec_buf_len = sizeof(client_change_cipher_spec_buf); uint8_t server_change_cipher_spec_buf[] = { 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03, 0x00, 0x00, 0x40, 0xce, 0x7c, 0x92, 0x43, 0x59, 0xcc, 0x3d, 0x90, 0x91, 0x9c, 0x58, 0xf0, 0x7a, 0xce, 0xae, 0x0d, 0x08, 0xe0, 0x76, 0xb4, 0x86, 0xb1, 0x15, 0x5b, 0x32, 0xb8, 0x77, 0x53, 0xe7, 0xa6, 0xf9, 0xd0, 0x95, 0x5f, 0xaa, 0x07, 0xc3, 0x96, 0x7c, 0xc9, 0x88, 0xc2, 0x7a, 0x20, 0x89, 0x4f, 0xeb, 0xeb, 0xb6, 0x19, 0xef, 0xaa, 0x27, 0x73, 0x9d, 0xa6, 0xb4, 0x9f, 0xeb, 0x34, 0xe2, 0x4d, 0x9f, 0x6b }; uint32_t server_change_cipher_spec_buf_len = sizeof(server_change_cipher_spec_buf); uint8_t toserver_app_data_buf[] = { 0x17, 0x03, 0x00, 0x01, 0xb0, 0x4a, 0xc3, 0x3e, 0x9d, 0x77, 0x78, 0x01, 0x2c, 0xb4, 0xbc, 0x4c, 0x9a, 0x84, 0xd7, 0xb9, 0x90, 0x0c, 0x21, 0x10, 0xf0, 0xfa, 0x00, 0x7c, 0x16, 0xbb, 0x77, 0xfb, 0x72, 0x42, 0x4f, 0xad, 0x50, 0x4a, 0xd0, 0xaa, 0x6f, 0xaa, 0x44, 0x6c, 0x62, 0x94, 0x1b, 0xc5, 0xfe, 0xe9, 0x1c, 0x5e, 0xde, 0x85, 0x0b, 0x0e, 0x05, 0xe4, 0x18, 0x6e, 0xd2, 0xd3, 0xb5, 0x20, 0xab, 0x81, 0xfd, 0x18, 0x9a, 0x73, 0xb8, 0xd7, 0xef, 0xc3, 0xdd, 0x74, 0xd7, 0x9c, 0x1e, 0x6f, 0x21, 0x6d, 0xf8, 0x24, 0xca, 0x3c, 0x70, 0x78, 0x36, 0x12, 0x7a, 0x8a, 0x9c, 0xac, 0x4e, 0x1c, 0xa8, 0xfb, 0x27, 0x30, 0xba, 0x9a, 0xf4, 0x2f, 0x0a, 0xab, 0x80, 0x6a, 0xa1, 0x60, 0x74, 0xf0, 0xe3, 0x91, 0x84, 0xe7, 0x90, 0x88, 0xcc, 0xf0, 0x95, 0x7b, 0x0a, 0x22, 0xf2, 0xf9, 0x27, 0xe0, 0xdd, 0x38, 0x0c, 0xfd, 0xe9, 0x03, 0x71, 0xdc, 0x70, 0xa4, 0x6e, 0xdf, 0xe3, 0x72, 0x9e, 0xa1, 0xf0, 0xc9, 0x00, 0xd6, 0x03, 0x55, 0x6a, 0x67, 0x5d, 0x9c, 0xb8, 0x75, 0x01, 0xb0, 0x01, 0x9f, 0xe6, 0xd2, 0x44, 0x18, 0xbc, 0xca, 0x7a, 0x10, 0x39, 0xa6, 0xcf, 0x15, 0xc7, 0xf5, 0x35, 0xd4, 0xb3, 0x6d, 0x91, 0x23, 0x84, 0x99, 0xba, 0xb0, 0x7e, 0xd0, 0xc9, 0x4c, 0xbf, 0x3f, 0x33, 0x68, 0x37, 0xb7, 0x7d, 0x44, 0xb0, 0x0b, 0x2c, 0x0f, 0xd0, 0x75, 0xa2, 0x6b, 0x5b, 0xe1, 0x9f, 0xd4, 0x69, 0x9a, 0x14, 0xc8, 0x29, 0xb7, 0xd9, 0x10, 0xbb, 0x99, 0x30, 0x9a, 0xfb, 0xcc, 0x13, 0x1f, 0x76, 0x4e, 0xe6, 0xdf, 0x14, 0xaa, 0xd5, 0x60, 0xbf, 0x91, 0x49, 0x0d, 0x64, 0x42, 0x29, 0xa8, 0x64, 0x27, 0xd4, 0x5e, 0x1b, 0x18, 0x03, 0xa8, 0x73, 0xd6, 0x05, 0x6e, 0xf7, 0x50, 0xb0, 0x09, 0x6b, 0x69, 0x7a, 0x12, 0x28, 0x58, 0xef, 0x5a, 0x86, 0x11, 0xde, 0x71, 0x71, 0x9f, 0xca, 0xbd, 0x79, 0x2a, 0xc2, 0xe5, 0x9b, 0x5e, 0x32, 0xe7, 0xcb, 0x97, 0x6e, 0xa0, 0xea, 0xa4, 0xa4, 0x6a, 0x32, 0xf9, 0x37, 0x39, 0xd8, 0x37, 0x6d, 0x63, 0xf3, 0x08, 0x1c, 0xdd, 0x06, 0xdd, 0x2c, 0x2b, 0x9f, 0x04, 0x88, 0x5f, 0x36, 0x42, 0xc1, 0xb1, 0xc7, 0xe8, 0x2d, 0x5d, 0xa4, 0x6c, 0xe5, 0x60, 0x94, 0xae, 0xd0, 0x90, 0x1e, 0x88, 0xa0, 0x87, 0x52, 0xfb, 0xed, 0x97, 0xa5, 0x25, 0x5a, 0xb7, 0x55, 0xc5, 0x13, 0x07, 0x85, 0x27, 0x40, 0xed, 0xb8, 0xa0, 0x26, 0x13, 0x44, 0x0c, 0xfc, 0xcc, 0x5a, 0x09, 0xe5, 0x44, 0xb5, 0x63, 0xa1, 0x43, 0x51, 0x23, 0x4f, 0x17, 0x21, 0x89, 0x2e, 0x58, 0xfd, 0xf9, 0x63, 0x74, 0x04, 0x70, 0x1e, 0x7d, 0xd0, 0x66, 0xba, 0x40, 0x5e, 0x45, 0xdc, 0x39, 0x7c, 0x53, 0x0f, 0xa8, 0x38, 0xb2, 0x13, 0x99, 0x27, 0xd9, 0x4a, 0x51, 0xe9, 0x9f, 0x2a, 0x92, 0xbb, 0x9c, 0x90, 0xab, 0xfd, 0xf1, 0xb7, 0x40, 0x05, 0xa9, 0x7a, 0x20, 0x63, 0x36, 0xc1, 0xef, 0xb9, 0xad, 0xa2, 0xe0, 0x1d, 0x20, 0x4f, 0xb2, 0x34, 0xbd, 0xea, 0x07, 0xac, 0x21, 0xce, 0xf6, 0x8a, 0xa2, 0x9e, 0xcd, 0xfa }; uint32_t toserver_app_data_buf_len = sizeof(toserver_app_data_buf); int result = 0; Signature *s = NULL; ThreadVars th_v; Packet *p = NULL; Flow f; TcpSession ssn; DetectEngineThreadCtx *det_ctx = NULL; DetectEngineCtx *de_ctx = NULL; SSLState *ssl_state = NULL; int r = 0; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; p->flow = &f; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; f.alproto = ALPROTO_TLS; StreamTcpInitConfig(TRUE); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " "(msg:\"ssl state\"; ssl_state:client_hello; " "sid:1;)"); if (s == NULL) goto end; s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " "(msg:\"ssl state\"; " "ssl_state:client_hello | server_hello; " "sid:2;)"); if (s == NULL) goto end; s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " "(msg:\"ssl state\"; " "ssl_state:client_hello | server_hello | " "client_keyx; sid:3;)"); if (s == NULL) goto end; s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " "(msg:\"ssl state\"; " "ssl_state:client_hello | server_hello | " "client_keyx | server_keyx; sid:4;)"); if (s == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER | STREAM_START, chello_buf, chello_buf_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); ssl_state = f.alstate; if (ssl_state == NULL) { printf("no ssl state: "); goto end; } /* do detect */ p->alerts.cnt = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!PacketAlertCheck(p, 1)) goto end; if (PacketAlertCheck(p, 2)) goto end; if (PacketAlertCheck(p, 3)) goto end; if (PacketAlertCheck(p, 4)) goto end; SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, shello_buf, shello_buf_len); if (r != 0) { printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ p->alerts.cnt = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) goto end; if (!PacketAlertCheck(p, 2)) goto end; if (PacketAlertCheck(p, 3)) goto end; if (PacketAlertCheck(p, 4)) goto end; SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, client_change_cipher_spec_buf, client_change_cipher_spec_buf_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ p->alerts.cnt = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) goto end; if (PacketAlertCheck(p, 2)) goto end; if (!PacketAlertCheck(p, 3)) goto end; if (PacketAlertCheck(p, 4)) goto end; SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, server_change_cipher_spec_buf, server_change_cipher_spec_buf_len); if (r != 0) { printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ p->alerts.cnt = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) goto end; if (PacketAlertCheck(p, 2)) goto end; if (PacketAlertCheck(p, 3)) goto end; if (PacketAlertCheck(p, 4)) goto end; SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, toserver_app_data_buf, toserver_app_data_buf_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ p->alerts.cnt = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) goto end; if (PacketAlertCheck(p, 2)) goto end; if (PacketAlertCheck(p, 3)) goto end; if (PacketAlertCheck(p, 4)) goto end; result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** \test Check the signature working to alert when http_cookie is not present */ static int DetectHttpCookieSigTest07(void) { int result = 0; Flow f; uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" "Cookie: dummy\r\n\r\n"; uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" "\"HTTP cookie\"; content:!\"dummy\"; " "http_cookie; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); http_state = f.alstate; if (http_state == NULL) { printf("no http state: "); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { goto end; } result = 1; end: if (det_ctx != NULL) { DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); } if (de_ctx != NULL) { SigGroupCleanup(de_ctx); DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); UTHFreePackets(&p, 1); return result; }
void TmqhOutputPacketpool(ThreadVars *t, Packet *p) { bool proot = false; SCEnter(); SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false"); if (IS_TUNNEL_PKT(p)) { SCLogDebug("Packet %p is a tunnel packet: %s", p,p->root ? "upper layer" : "tunnel root"); /* get a lock to access root packet fields */ SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; SCMutexLock(m); if (IS_TUNNEL_ROOT_PKT(p)) { SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE"); const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p); SCLogDebug("root pkt: outstanding %u", outstanding); if (outstanding == 0) { SCLogDebug("no tunnel packets outstanding, no more tunnel " "packet(s) depending on this root"); /* if this packet is the root and there are no * more tunnel packets to consider * * return it to the pool */ } else { SCLogDebug("tunnel root Packet %p: outstanding > 0, so " "packets are still depending on this root, setting " "SET_TUNNEL_PKT_VERDICTED", p); /* if this is the root and there are more tunnel * packets, return this to the pool. It's still referenced * by the tunnel packets, and we will return it * when we handle them */ SET_TUNNEL_PKT_VERDICTED(p); PACKET_PROFILING_END(p); SCMutexUnlock(m); SCReturn; } } else { SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt"); TUNNEL_INCR_PKT_RTV_NOLOCK(p); const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p); SCLogDebug("tunnel pkt: outstanding %u", outstanding); /* all tunnel packets are processed except us. Root already * processed. So return tunnel pkt and root packet to the * pool. */ if (outstanding == 0 && p->root && IS_TUNNEL_PKT_VERDICTED(p->root)) { SCLogDebug("root verdicted == true && no outstanding"); /* handle freeing the root as well*/ SCLogDebug("setting proot = 1 for root pkt, p->root %p " "(tunnel packet %p)", p->root, p); proot = true; /* fall through */ } else { /* root not ready yet, or not the last tunnel packet, * so get rid of the tunnel pkt only */ SCLogDebug("NOT IS_TUNNEL_PKT_VERDICTED (%s) || " "outstanding > 0 (%u)", (p->root && IS_TUNNEL_PKT_VERDICTED(p->root)) ? "true" : "false", outstanding); /* fall through */ } } SCMutexUnlock(m); SCLogDebug("tunnel stuff done, move on (proot %d)", proot); } /* we're done with the tunnel root now as well */ if (proot == true) { SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false"); PACKET_RELEASE_REFS(p->root); p->root->ReleasePacket(p->root); p->root = NULL; } PACKET_PROFILING_END(p); PACKET_RELEASE_REFS(p); p->ReleasePacket(p); SCReturn; }
/** * \brief Init function for ReceivePcap. * * This is a setup function for recieving packets * via libpcap. There are two versions of this function * depending on the major version of libpcap used. * For versions prior to 1.x we use open_pcap_live, * for versions 1.x and greater we use pcap_create + pcap_activate. * * \param tv pointer to ThreadVars * \param initdata pointer to the interface passed from the user * \param data pointer gets populated with PcapThreadVars * * \todo Create a general pcap setup function. */ TmEcode ReceivePcapThreadInit(ThreadVars *tv, const void *initdata, void **data) { SCEnter(); PcapIfaceConfig *pcapconfig = (PcapIfaceConfig *)initdata; if (initdata == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); SCReturnInt(TM_ECODE_FAILED); } PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); if (unlikely(ptv == NULL)) { pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } memset(ptv, 0, sizeof(PcapThreadVars)); ptv->tv = tv; ptv->livedev = LiveGetDevice(pcapconfig->iface); if (ptv->livedev == NULL) { SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); SCFree(ptv); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("using interface %s", (char *)pcapconfig->iface); if (LiveGetOffload() == 0) { (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1); } else { DisableIfaceOffloading(ptv->livedev, 1, 1); } ptv->checksum_mode = pcapconfig->checksum_mode; if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { SCLogInfo("Running in 'auto' checksum mode. Detection of interface state will require " xstr(CHECKSUM_SAMPLE_COUNT) " packets."); } /* XXX create a general pcap setup function */ char errbuf[PCAP_ERRBUF_SIZE]; ptv->pcap_handle = pcap_create((char *)pcapconfig->iface, errbuf); if (ptv->pcap_handle == NULL) { if (strlen(errbuf)) { SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s, error %s", (char *)pcapconfig->iface, errbuf); } else { SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s", (char *)pcapconfig->iface); } SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } if (pcapconfig->snaplen == 0) { /* We set snaplen if we can get the MTU */ ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface); } else { ptv->pcap_snaplen = pcapconfig->snaplen; } if (ptv->pcap_snaplen > 0) { /* set Snaplen. Must be called before pcap_activate */ int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen); if (pcap_set_snaplen_r != 0) { SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } SCLogInfo("Set snaplen to %d for '%s'", ptv->pcap_snaplen, pcapconfig->iface); } /* set Promisc, and Timeout. Must be called before pcap_activate */ int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, pcapconfig->promisc); //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_promisc_r); if (pcap_set_promisc_r != 0) { SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle,LIBPCAP_COPYWAIT); //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_timeout_r); if (pcap_set_timeout_r != 0) { SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } #ifdef HAVE_PCAP_SET_BUFF ptv->pcap_buffer_size = pcapconfig->buffer_size; if (ptv->pcap_buffer_size >= 0 && ptv->pcap_buffer_size <= INT_MAX) { if (ptv->pcap_buffer_size > 0) SCLogInfo("Going to use pcap buffer size of %" PRId32 "", ptv->pcap_buffer_size); int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,ptv->pcap_buffer_size); //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_buffer_size_r); if (pcap_set_buffer_size_r != 0) { SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } } #endif /* HAVE_PCAP_SET_BUFF */ /* activate the handle */ int pcap_activate_r = pcap_activate(ptv->pcap_handle); //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_activate_r); if (pcap_activate_r != 0) { SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle)); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_FAILED); } else { ptv->pcap_state = PCAP_STATE_UP; } /* set bpf filter if we have one */ if (pcapconfig->bpf_filter) { SCMutexLock(&pcap_bpf_compile_lock); ptv->bpf_filter = pcapconfig->bpf_filter; if (pcap_compile(ptv->pcap_handle,&ptv->filter,(char *)ptv->bpf_filter,1,0) < 0) { SCLogError(SC_ERR_BPF, "bpf compilation error %s", pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } if (pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { SCLogError(SC_ERR_BPF, "could not set bpf filter %s", pcap_geterr(ptv->pcap_handle)); SCMutexUnlock(&pcap_bpf_compile_lock); SCFree(ptv); pcapconfig->DerefFunc(pcapconfig); return TM_ECODE_FAILED; } SCMutexUnlock(&pcap_bpf_compile_lock); } /* no offloading supported at all */ (void)GetIfaceOffloading(pcapconfig->iface, 1, 1); ptv->datalink = pcap_datalink(ptv->pcap_handle); pcapconfig->DerefFunc(pcapconfig); ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", ptv->tv); ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", ptv->tv); ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops", ptv->tv); *data = (void *)ptv; SCReturnInt(TM_ECODE_OK); }
static int ProfilingGenericTicksTest01(void) { #define TEST_RUNS 1024 uint64_t ticks_start = 0; uint64_t ticks_end = 0; void *ptr[TEST_RUNS]; int i; ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { ptr[i] = SCMalloc(1024); } ticks_end = UtilCpuGetTicks(); printf("malloc(1024) %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCFree(ptr[i]); } ticks_end = UtilCpuGetTicks(); printf("SCFree(1024) %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); SCMutex m[TEST_RUNS]; ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCMutexInit(&m[i], NULL); } ticks_end = UtilCpuGetTicks(); printf("SCMutexInit() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCMutexLock(&m[i]); } ticks_end = UtilCpuGetTicks(); printf("SCMutexLock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCMutexUnlock(&m[i]); } ticks_end = UtilCpuGetTicks(); printf("SCMutexUnlock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCMutexDestroy(&m[i]); } ticks_end = UtilCpuGetTicks(); printf("SCMutexDestroy() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); SCSpinlock s[TEST_RUNS]; ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCSpinInit(&s[i], 0); } ticks_end = UtilCpuGetTicks(); printf("SCSpinInit() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCSpinLock(&s[i]); } ticks_end = UtilCpuGetTicks(); printf("SCSpinLock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCSpinUnlock(&s[i]); } ticks_end = UtilCpuGetTicks(); printf("SCSpinUnlock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SCSpinDestroy(&s[i]); } ticks_end = UtilCpuGetTicks(); printf("SCSpinDestroy() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); SC_ATOMIC_DECL_AND_INIT(unsigned int, test); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { (void) SC_ATOMIC_ADD(test,1); } ticks_end = UtilCpuGetTicks(); printf("SC_ATOMIC_ADD %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); ticks_start = UtilCpuGetTicks(); for (i = 0; i < TEST_RUNS; i++) { SC_ATOMIC_CAS(&test,i,i+1); } ticks_end = UtilCpuGetTicks(); printf("SC_ATOMIC_CAS %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); return 1; }
void HostLock(Host *h) { SCMutexLock(&h->m); }
int LogStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) { SCEnter(); LogStatsLogThread *aft = (LogStatsLogThread *)thread_data; struct timeval tval; struct tm *tms; gettimeofday(&tval, NULL); struct tm local_tm; tms = SCLocalTime(tval.tv_sec, &local_tm); /* Calculate the Engine uptime */ int up_time = (int)difftime(tval.tv_sec, st->start_time); int sec = up_time % 60; // Seconds in a minute int in_min = up_time / 60; int min = in_min % 60; // Minutes in a hour int in_hours = in_min / 60; int hours = in_hours % 24; // Hours in a day int days = in_hours / 24; MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); MemBufferWriteString(aft->buffer, "Date: %" PRId32 "/%" PRId32 "/%04d -- " "%02d:%02d:%02d (uptime: %"PRId32"d, %02dh %02dm %02ds)\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour, tms->tm_min, tms->tm_sec, days, hours, min, sec); MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); MemBufferWriteString(aft->buffer, "%-25s | %-25s | %-s\n", "Counter", "TM Name", "Value"); MemBufferWriteString(aft->buffer, "----------------------------------------------" "---------------------\n"); /* global stats */ uint32_t u = 0; if (aft->statslog_ctx->flags & LOG_STATS_TOTALS) { for (u = 0; u < st->nstats; u++) { if (st->stats[u].name == NULL) continue; char line[1024]; size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", st->stats[u].name, st->stats[u].tm_name, st->stats[u].value); /* since we can have many threads, the buffer might not be big enough. * Expand if necessary. */ if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); } MemBufferWriteString(aft->buffer, "%s", line); } } /* per thread stats */ if (st->tstats != NULL && aft->statslog_ctx->flags & LOG_STATS_THREADS) { /* for each thread (store) */ uint32_t x; for (x = 0; x < st->ntstats; x++) { uint32_t offset = x * st->nstats; /* for each counter */ for (u = offset; u < (offset + st->nstats); u++) { if (st->tstats[u].name == NULL) continue; char line[1024]; size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", st->tstats[u].name, st->tstats[u].tm_name, st->tstats[u].value); /* since we can have many threads, the buffer might not be big enough. * Expand if necessary. */ if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); } MemBufferWriteString(aft->buffer, "%s", line); } } } SCMutexLock(&aft->statslog_ctx->file_ctx->fp_mutex); aft->statslog_ctx->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), aft->statslog_ctx->file_ctx); SCMutexUnlock(&aft->statslog_ctx->file_ctx->fp_mutex); MemBufferReset(aft->buffer); SCReturnInt(0); }
static inline void IPFWMutexLock(IPFWQueueVars *nq) { if (nq->use_mutex) SCMutexLock(&nq->socket_lock); }
/** * \brief Log the dropped packets in netfilter format when engine is running * in inline mode * * \param tv Pointer the current thread variables * \param p Pointer the packet which is being logged * \param data Pointer to the droplog struct * * \return return TM_EODE_OK on success */ static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) { LogDropLogThread *dlt = (LogDropLogThread *)data; uint16_t proto = 0; char timebuf[64]; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); SCMutexLock(&dlt->file_ctx->fp_mutex); if (dlt->file_ctx->rotation_flag) { dlt->file_ctx->rotation_flag = 0; if (SCConfLogReopen(dlt->file_ctx) != 0) { /* Rotation failed, error already logged. */ SCMutexUnlock(&dlt->file_ctx->fp_mutex); return TM_ECODE_FAILED; } } char srcip[46] = ""; char dstip[46] = ""; if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, 16); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, 16); fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16" " "TOS=0x%02"PRIu8" TTL=%"PRIu8" ID=%"PRIu16"", timebuf, srcip, dstip, IPV4_GET_IPLEN(p), IPV4_GET_IPTOS(p), IPV4_GET_IPTTL(p), IPV4_GET_IPID(p)); proto = IPV4_GET_IPPROTO(p); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16"" " TC=%"PRIu32" HOPLIMIT=%"PRIu8" FLOWLBL=%"PRIu32"", timebuf, srcip, dstip, IPV6_GET_PLEN(p), IPV6_GET_CLASS(p), IPV6_GET_HLIM(p), IPV6_GET_FLOW(p)); proto = IPV6_GET_L4PROTO(p); } if (SCProtoNameValid(proto) == TRUE) { fprintf(dlt->file_ctx->fp, " PROTO=%s",known_proto[proto]); } else { fprintf(dlt->file_ctx->fp, " PROTO=%03"PRIu16"",proto); } switch (proto) { case IPPROTO_TCP: if (PKT_IS_TCP(p)) { fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" " "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"", GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : ""); fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : ""); fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"", TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p)); } break; case IPPROTO_UDP: if (PKT_IS_UDP(p)) { fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16"" " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_GET_LEN(p)); } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p), ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p)); } else if (PKT_IS_ICMPV6(p)) { fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); } break; default: fprintf(dlt->file_ctx->fp," Unknown protocol"); } fprintf(dlt->file_ctx->fp,"\n"); fflush(dlt->file_ctx->fp); dlt->drop_cnt++; SCMutexUnlock(&dlt->file_ctx->fp_mutex); return TM_ECODE_OK; }
static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipproto) { SCEnter(); LogHttpLogThread *aft = (LogHttpLogThread *)data; LogHttpFileCtx *hlog = aft->httplog_ctx; char timebuf[64]; size_t idx = 0; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } /* check if we have HTTP state or not */ FLOWLOCK_WRLOCK(p->flow); /* WRITE lock before we updated flow logged id */ uint16_t proto = AppLayerGetProtoFromPacket(p); if (proto != ALPROTO_HTTP) goto end; int r = AppLayerTransactionGetLoggedId(p->flow); if (r < 0) { goto end; } size_t logged = (size_t)r; r = HtpTransactionGetLoggableId(p->flow); if (r < 0) { goto end; } size_t loggable = (size_t)r; /* nothing to do */ if (logged >= loggable) { goto end; } HtpState *htp_state = (HtpState *)AppLayerGetProtoStateFromPacket(p); if (htp_state == NULL) { SCLogDebug("no http state, so no request logging"); goto end; } if (htp_state->connp == NULL || htp_state->connp->conn == NULL) goto end; htp_tx_t *tx = NULL; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; Port sp, dp; if ((PKT_IS_TOSERVER(p))) { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: goto end; } sp = p->sp; dp = p->dp; } else { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); break; default: goto end; } sp = p->dp; dp = p->sp; } for (idx = logged; idx < loggable; idx++) { tx = list_get(htp_state->connp->conn->transactions, idx); if (tx == NULL) { SCLogDebug("tx is NULL not logging !!"); continue; } SCLogDebug("got a HTTP request and now logging !!"); /* reset */ MemBufferReset(aft->buffer); if (hlog->flags & LOG_HTTP_CUSTOM) { LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp); } else { /* time */ MemBufferWriteString(aft->buffer, "%s ", timebuf); /* hostname */ if (tx->parsed_uri != NULL && tx->parsed_uri->hostname != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->parsed_uri->hostname), bstr_len(tx->parsed_uri->hostname)); } else { MemBufferWriteString(aft->buffer, "<hostname unknown>"); } MemBufferWriteString(aft->buffer, " [**] "); /* uri */ if (tx->request_uri != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); } MemBufferWriteString(aft->buffer, " [**] "); /* user agent */ htp_header_t *h_user_agent = NULL; if (tx->request_headers != NULL) { h_user_agent = table_getc(tx->request_headers, "user-agent"); } if (h_user_agent != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_user_agent->value), bstr_len(h_user_agent->value)); } else { MemBufferWriteString(aft->buffer, "<useragent unknown>"); } if (hlog->flags & LOG_HTTP_EXTENDED) { LogHttpLogExtended(aft, tx); } /* ip/tcp header info */ MemBufferWriteString(aft->buffer, " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", srcip, sp, dstip, dp); } aft->uri_cnt ++; SCMutexLock(&hlog->file_ctx->fp_mutex); MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); fflush(hlog->file_ctx->fp); SCMutexUnlock(&hlog->file_ctx->fp_mutex); AppLayerTransactionUpdateLoggedId(p->flow); } end: FLOWLOCK_UNLOCK(p->flow); SCReturnInt(TM_ECODE_OK); }
/** * \test Check the signature working to alert against set-cookie */ static int DetectHttpCookieSigTest08(void) { int result = 0; Flow f; uint8_t httpbuf_request[] = "GET / HTTP/1.1\r\n" "User-Agent: Mozilla/1.0\r\n" "\r\n"; uint32_t httpbuf_request_len = sizeof(httpbuf_request) - 1; /* minus the \0 */ uint8_t httpbuf_response[] = "HTTP/1.1 200 OK\r\n" "Set-Cookie: response_user_agent\r\n" "\r\n"; uint32_t httpbuf_response_len = sizeof(httpbuf_response) - 1; /* minus the \0 */ TcpSession ssn; Packet *p1 = NULL, *p2 = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.flags |= FLOW_IPV4; f.alproto = ALPROTO_HTTP; p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); p1->flow = &f; p1->flowflags |= FLOW_PKT_TOSERVER; p1->flowflags |= FLOW_PKT_ESTABLISHED; p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); p2->flow = &f; p2->flowflags |= FLOW_PKT_TOCLIENT; p2->flowflags |= FLOW_PKT_ESTABLISHED; p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " "(flow:to_client; content:\"response_user_agent\"; " "http_cookie; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* request */ SCMutexLock(&f.m); int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf_request, httpbuf_request_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); http_state = f.alstate; if (http_state == NULL) { printf("no http state: "); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); if (PacketAlertCheck(p1, 1)) { goto end; } /* response */ SCMutexLock(&f.m); r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf_response, httpbuf_response_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); if (!PacketAlertCheck(p2, 1)) { goto end; } result = 1; end: if (det_ctx != NULL) { DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); } if (de_ctx != NULL) { SigGroupCleanup(de_ctx); DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); UTHFreePackets(&p1, 1); UTHFreePackets(&p2, 1); return result; }
TmEcode AlertFastLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertFastLogThread *aft = (AlertFastLogThread *)data; int i; char timebuf[64]; char *action = ""; extern uint8_t engine_mode; if (p->alerts.cnt == 0) return TM_ECODE_OK; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[16], dstip[16]; PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } if ((pa->action & ACTION_DROP) && IS_ENGINE_MODE_IPS(engine_mode)) { action = "[Drop] "; } else if (pa->action & ACTION_DROP) { action = "[wDrop] "; } char proto[16] = ""; if (SCProtoNameValid(IPV4_GET_IPPROTO(p)) == TRUE) { strlcpy(proto, known_proto[IPV4_GET_IPPROTO(p)], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "PROTO:%03" PRIu32, IPV4_GET_IPPROTO(p)); } SCMutexLock(&aft->file_ctx->fp_mutex); #ifdef __tile__ if (aft->file_ctx->filetype == tile_pcie) { TileTrioPrintf(aft->file_ctx->pcie_ctx, "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %"PRIu32"]" " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, proto, srcip, p->sp, dstip, p->dp); } else { #endif fprintf(aft->file_ctx->fp, "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: %"PRIu32"]" " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, proto, srcip, p->sp, dstip, p->dp); fflush(aft->file_ctx->fp); #ifdef __tile__ } #endif aft->file_ctx->alerts++; SCMutexUnlock(&aft->file_ctx->fp_mutex); } return TM_ECODE_OK; }
static int DetectTlsVersionTestDetect03(void) { DetectEngineCtx *de_ctx = NULL; int result = 0; Flow f; uint8_t tlsbuf1[] = { 0x16 }; uint32_t tlslen1 = sizeof(tlsbuf1); uint8_t tlsbuf2[] = { 0x03 }; uint32_t tlslen2 = sizeof(tlsbuf2); uint8_t tlsbuf3[] = { 0x01 }; uint32_t tlslen3 = sizeof(tlsbuf3); uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; uint32_t tlslen4 = sizeof(tlsbuf4); TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); p->tcph->th_seq = htonl(1000); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_TLS; f.proto = p->proto; StreamTcpInitConfig(TRUE); StreamMsg *stream_msg = StreamMsgGetFromPool(); if (stream_msg == NULL) { printf("no stream_msg: "); goto end; } memcpy(stream_msg->data, tlsbuf4, tlslen4); stream_msg->data_len = tlslen4; ssn.toserver_smsg_head = stream_msg; ssn.toserver_smsg_tail = stream_msg; de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; tls.version:1.0; content:\"|01 00 00 AD|\"; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); if (r != 0) { printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); if (r != 0) { printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); SSLState *ssl_state = f.alstate; if (ssl_state == NULL) { printf("no tls state: "); goto end; } if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_connp.content_type); goto end; } if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_connp.version); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("signature 1 didn't match while it should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** *\test Test that the negated http_header content matches against a * http request which doesn't hold the content. */ static int DetectHttpRawHeaderTest11(void) { TcpSession ssn; Packet *p = NULL; ThreadVars th_v; DetectEngineCtx *de_ctx = NULL; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; Flow f; uint8_t http_buf[] = "GET /index.html HTTP/1.0\r\n" "Host: www.openinfosecfoundation.org\r\n" "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" "Content-Type: text/html\r\n" "Content-Length: 26\r\n" "\r\n" "This is dummy message body\r\n"; uint32_t http_len = sizeof(http_buf) - 1; int result = 0; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " "(msg:\"http header test\"; flow:to_server; " "content:!\"lalalalala\"; http_raw_header; " "sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); http_state = f.alstate; if (http_state == NULL) { printf("no http state: "); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("sid 1 didn't match but should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) SigCleanSignatures(de_ctx); if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
void TmqhOutputPacketpool(ThreadVars *t, Packet *p) { int proot = 0; SCEnter(); SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false"); /** \todo make this a callback * Release tcp segments. Done here after alerting can use them. */ if (p->flow != NULL && p->proto == IPPROTO_TCP) { SCMutexLock(&p->flow->m); StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? STREAM_TOSERVER : STREAM_TOCLIENT); SCMutexUnlock(&p->flow->m); } if (IS_TUNNEL_PKT(p)) { SCLogDebug("Packet %p is a tunnel packet: %s", p,p->root ? "upper layer" : "tunnel root"); /* get a lock to access root packet fields */ SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; SCMutexLock(m); if (IS_TUNNEL_ROOT_PKT(p)) { SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE"); if (TUNNEL_PKT_TPR(p) == 0) { SCLogDebug("TUNNEL_PKT_TPR(p) == 0, no more tunnel packet " "depending on this root"); /* if this packet is the root and there are no * more tunnel packets, return it to the pool */ /* fall through */ } else { SCLogDebug("tunnel root Packet %p: TUNNEL_PKT_TPR(p) > 0, so " "packets are still depending on this root, setting " "p->tunnel_verdicted == 1", p); /* if this is the root and there are more tunnel * packets, return this to the pool. It's still referenced * by the tunnel packets, and we will return it * when we handle them */ SET_TUNNEL_PKT_VERDICTED(p); SCMutexUnlock(m); PACKET_PROFILING_END(p); SCReturn; } } else { SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt"); /* the p->root != NULL here seems unnecessary: IS_TUNNEL_PKT checks * that p->tunnel_pkt == 1, IS_TUNNEL_ROOT_PKT checks that + * p->root == NULL. So when we are here p->root can only be * non-NULL, right? CLANG thinks differently. May be a FP, but * better safe than sorry. VJ */ if (p->root != NULL && IS_TUNNEL_PKT_VERDICTED(p->root) && TUNNEL_PKT_TPR(p) == 1) { SCLogDebug("p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1"); /* the root is ready and we are the last tunnel packet, * lets enqueue them both. */ TUNNEL_DECR_PKT_TPR_NOLOCK(p); /* handle the root */ SCLogDebug("setting proot = 1 for root pkt, p->root %p " "(tunnel packet %p)", p->root, p); proot = 1; /* fall through */ } else { /* root not ready yet, so get rid of the tunnel pkt only */ SCLogDebug("NOT p->root->tunnel_verdicted == 1 && " "TUNNEL_PKT_TPR(p) == 1 (%" PRIu32 ")", TUNNEL_PKT_TPR(p)); TUNNEL_DECR_PKT_TPR_NOLOCK(p); /* fall through */ } } SCMutexUnlock(m); SCLogDebug("tunnel stuff done, move on (proot %d)", proot); } FlowDeReference(&p->flow); /* we're done with the tunnel root now as well */ if (proot == 1) { SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false"); FlowDeReference(&p->root->flow); /* if p->root uses extended data, free them */ if (p->root->ext_pkt) { if (!(p->root->flags & PKT_ZERO_COPY)) { SCFree(p->root->ext_pkt); } p->root->ext_pkt = NULL; } p->root->ReleasePacket(p->root); p->root = NULL; } /* if p uses extended data, free them */ if (p->ext_pkt) { if (!(p->flags & PKT_ZERO_COPY)) { SCFree(p->ext_pkt); } p->ext_pkt = NULL; } PACKET_PROFILING_END(p); p->ReleasePacket(p); SCReturn; }
/** * \internal * \brief Write meta data on a single line json record */ static void LogFileWriteJsonRecord(LogFileLogThread *aft, const Packet *p, const File *ff, int ipver) { SCMutexLock(&aft->file_ctx->fp_mutex); /* As writes are done via the LogFileCtx, check for rotation here. */ if (aft->file_ctx->rotation_flag) { aft->file_ctx->rotation_flag = 0; if (SCConfLogReopen(aft->file_ctx) != 0) { SCLogWarning(SC_ERR_FOPEN, "Failed to re-open log file. " "Logging for this module will be disabled."); } } /* Bail early if no file pointer to write to (in the unlikely * event file rotation failed. */ if (aft->file_ctx->fp == NULL) { SCMutexUnlock(&aft->file_ctx->fp_mutex); return; } FILE *fp = aft->file_ctx->fp; char timebuf[64]; AppProto alproto = FlowGetAppProtocol(p->flow); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); fprintf(fp, "{ "); if (ff->file_id > 0) fprintf(fp, "\"id\": %u, ", ff->file_id); fprintf(fp, "\"timestamp\": \""); PrintRawJsonFp(fp, (uint8_t *)timebuf, strlen(timebuf)); fprintf(fp, "\", "); if (p->pcap_cnt > 0) { fprintf(fp, "\"pcap_pkt_num\": %"PRIu64", ", p->pcap_cnt); } fprintf(fp, "\"ipver\": %d, ", ipver == AF_INET ? 4 : 6); char srcip[46], dstip[46]; Port sp, dp; switch (ipver) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); break; default: strlcpy(srcip, "<unknown>", sizeof(srcip)); strlcpy(dstip, "<unknown>", sizeof(dstip)); break; } sp = p->sp; dp = p->dp; fprintf(fp, "\"srcip\": \"%s\", ", srcip); fprintf(fp, "\"dstip\": \"%s\", ", dstip); fprintf(fp, "\"protocol\": %" PRIu32 ", ", p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { fprintf(fp, "\"sp\": %" PRIu16 ", ", sp); fprintf(fp, "\"dp\": %" PRIu16 ", ", dp); } if (alproto == ALPROTO_HTTP) { fprintf(fp, "\"http_uri\": \""); LogFileMetaGetUri(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_host\": \""); LogFileMetaGetHost(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_referer\": \""); LogFileMetaGetReferer(fp, p, ff); fprintf(fp, "\", "); fprintf(fp, "\"http_user_agent\": \""); LogFileMetaGetUserAgent(fp, p, ff); fprintf(fp, "\", "); } else if (p->flow->alproto == ALPROTO_SMTP) { /* Only applicable to SMTP */ LogFileMetaGetSmtp(fp, p, ff); } fprintf(fp, "\"filename\": \""); PrintRawJsonFp(fp, ff->name, ff->name_len); fprintf(fp, "\", "); #ifdef HAVE_MAGIC fprintf(fp, "\"magic\": \""); if (ff->magic) { PrintRawJsonFp(fp, (uint8_t *)ff->magic, strlen(ff->magic)); } else { fprintf(fp, "unknown"); } fprintf(fp, "\", "); #endif switch (ff->state) { case FILE_STATE_CLOSED: fprintf(fp, "\"state\": \"CLOSED\", "); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { fprintf(fp, "\"md5\": \""); size_t x; for (x = 0; x < sizeof(ff->md5); x++) { fprintf(fp, "%02x", ff->md5[x]); } fprintf(fp, "\", "); } if (ff->flags & FILE_SHA1) { fprintf(fp, "\"sha1\": \""); size_t x; for (x = 0; x < sizeof(ff->sha1); x++) { fprintf(fp, "%02x", ff->sha1[x]); } fprintf(fp, "\", "); } if (ff->flags & FILE_SHA256) { fprintf(fp, "\"sha256\": \""); size_t x; for (x = 0; x < sizeof(ff->sha256); x++) { fprintf(fp, "%02x", ff->sha256[x]); } fprintf(fp, "\", "); } #endif break; case FILE_STATE_TRUNCATED: fprintf(fp, "\"state\": \"TRUNCATED\", "); break; case FILE_STATE_ERROR: fprintf(fp, "\"state\": \"ERROR\", "); break; default: fprintf(fp, "\"state\": \"UNKNOWN\", "); break; } fprintf(fp, "\"stored\": %s, ", ff->flags & FILE_STORED ? "true" : "false"); fprintf(fp, "\"size\": %"PRIu64" ", FileSize(ff)); fprintf(fp, "}\n"); fflush(fp); SCMutexUnlock(&aft->file_ctx->fp_mutex); }
/** \test Check a signature with an request method and negation of the same */ static int DetectHttpMethodSigTest04(void) { int result = 0; Flow f; uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n" "Host: foo.bar.tld\r\n" "\r\n"; uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Testing http_method\"; " "content:\"GET\"; http_method; sid:1;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Testing http_method\"; " "content:!\"GET\"; http_method; sid:2;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); if (r != 0) { SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); http_state = f.alstate; if (http_state == NULL) { SCLogDebug("no http state: "); goto end; } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("sid 1 didn't match but should have: "); goto end; } if (PacketAlertCheck(p, 2)) { printf("sid 2 matched but shouldn't have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); } if (det_ctx != NULL) { DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx); } if (de_ctx != NULL) { DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** \brief Return packet to Packet pool * */ void PacketPoolReturnPacket(Packet *p) { PktPool *my_pool = GetThreadPacketPool(); PACKET_RELEASE_REFS(p); PktPool *pool = p->pool; if (pool == NULL) { PacketFree(p); return; } #ifdef DEBUG_VALIDATION BUG_ON(pool->initialized == 0); BUG_ON(pool->destroyed == 1); BUG_ON(my_pool->initialized == 0); BUG_ON(my_pool->destroyed == 1); #endif /* DEBUG_VALIDATION */ if (pool == my_pool) { /* Push back onto this thread's own stack, so no locking. */ p->next = my_pool->head; my_pool->head = p; } else { PktPool *pending_pool = my_pool->pending_pool; if (pending_pool == NULL) { /* No pending packet, so store the current packet. */ p->next = NULL; my_pool->pending_pool = pool; my_pool->pending_head = p; my_pool->pending_tail = p; my_pool->pending_count = 1; } else if (pending_pool == pool) { /* Another packet for the pending pool list. */ p->next = my_pool->pending_head; my_pool->pending_head = p; my_pool->pending_count++; if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > max_pending_return_packets) { /* Return the entire list of pending packets. */ SCMutexLock(&pool->return_stack.mutex); my_pool->pending_tail->next = pool->return_stack.head; pool->return_stack.head = my_pool->pending_head; SC_ATOMIC_RESET(pool->return_stack.sync_now); SCMutexUnlock(&pool->return_stack.mutex); SCCondSignal(&pool->return_stack.cond); /* Clear the list of pending packets to return. */ my_pool->pending_pool = NULL; my_pool->pending_head = NULL; my_pool->pending_tail = NULL; my_pool->pending_count = 0; } } else { /* Push onto return stack for this pool */ SCMutexLock(&pool->return_stack.mutex); p->next = pool->return_stack.head; pool->return_stack.head = p; SC_ATOMIC_RESET(pool->return_stack.sync_now); SCMutexUnlock(&pool->return_stack.mutex); SCCondSignal(&pool->return_stack.cond); } } }
/** \test Send a get request in three chunks + more data. */ static int DetectSshSoftwareVersionTestDetect03(void) { int result = 0; Flow f; uint8_t sshbuf1[] = "SSH-1."; uint32_t sshlen1 = sizeof(sshbuf1) - 1; uint8_t sshbuf2[] = "7-PuTTY_2.123" ; uint32_t sshlen2 = sizeof(sshbuf2) - 1; uint8_t sshbuf3[] = "\n"; uint32_t sshlen3 = sizeof(sshbuf3) - 1; uint8_t sshbuf4[] = "whatever..."; uint32_t sshlen4 = sizeof(sshbuf4) - 1; TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_SSH; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.softwareversion:lalala-3.1.4; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); if (r != 0) { printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); if (r != 0) { printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); SshState *ssh_state = f.alstate; if (ssh_state == NULL) { printf("no ssh state: "); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { printf("Error, 1.7 version is not 2 compat, so the sig should not match: "); goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); return result; }
/** \brief look up a host in the hash * * \param a address to look up * * \retval h *LOCKED* host or NULL */ Host *HostLookupHostFromHash (Address *a) { Host *h = NULL; /* get the key to our bucket */ uint32_t key = HostGetKey(a); /* get our hash bucket and lock it */ HostHashRow *hb = &host_hash[key]; HRLOCK_LOCK(hb); /* see if the bucket already has a host */ if (hb->head == NULL) { HRLOCK_UNLOCK(hb); return h; } /* ok, we have a host in the bucket. Let's find out if it is our host */ h = hb->head; /* see if this is the host we are looking for */ if (HostCompare(h, a) == 0) { while (h) { h = h->hnext; if (h == NULL) { HRLOCK_UNLOCK(hb); return h; } if (HostCompare(h, a) != 0) { /* we found our host, lets put it on top of the * hash list -- this rewards active hosts */ if (h->hnext) { h->hnext->hprev = h->hprev; } if (h->hprev) { h->hprev->hnext = h->hnext; } if (h == hb->tail) { hb->tail = h->hprev; } h->hnext = hb->head; h->hprev = NULL; hb->head->hprev = h; hb->head = h; /* found our host, lock & return */ SCMutexLock(&h->m); (void) HostIncrUsecnt(h); HRLOCK_UNLOCK(hb); return h; } } } /* lock & return */ SCMutexLock(&h->m); (void) HostIncrUsecnt(h); HRLOCK_UNLOCK(hb); return h; }
/** \brief look up a tracker in the hash * * \param a address to look up * * \retval h *LOCKED* tracker or NULL */ DefragTracker *DefragLookupTrackerFromHash (Packet *p) { DefragTracker *dt = NULL; /* get the key to our bucket */ uint32_t key = DefragHashGetKey(p); /* get our hash bucket and lock it */ DefragTrackerHashRow *hb = &defragtracker_hash[key]; DRLOCK_LOCK(hb); /* see if the bucket already has a tracker */ if (hb->head == NULL) { DRLOCK_UNLOCK(hb); return dt; } /* ok, we have a tracker in the bucket. Let's find out if it is our tracker */ dt = hb->head; /* see if this is the tracker we are looking for */ if (DefragTrackerCompare(dt, p) == 0) { while (dt) { dt = dt->hnext; if (dt == NULL) { DRLOCK_UNLOCK(hb); return dt; } if (DefragTrackerCompare(dt, p) != 0) { /* we found our tracker, lets put it on top of the * hash list -- this rewards active tracker */ if (dt->hnext) { dt->hnext->hprev = dt->hprev; } if (dt->hprev) { dt->hprev->hnext = dt->hnext; } if (dt == hb->tail) { hb->tail = dt->hprev; } dt->hnext = hb->head; dt->hprev = NULL; hb->head->hprev = dt; hb->head = dt; /* found our tracker, lock & return */ SCMutexLock(&dt->lock); (void) DefragTrackerIncrUsecnt(dt); DRLOCK_UNLOCK(hb); return dt; } } } /* lock & return */ SCMutexLock(&dt->lock); (void) DefragTrackerIncrUsecnt(dt); DRLOCK_UNLOCK(hb); return dt; }