int SMTP_CopyToAltBuffer(SFSnortPacket *p, const uint8_t *start, int length) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret; /* if we make a call to this it means we want to use the alt buffer * regardless of whether we copy any data into it or not - barring a failure */ smtp_normalizing = 1; /* if start and end the same, nothing to copy */ if (length == 0) return 0; alt_buf = _dpd.altBuffer->data; alt_size = sizeof(_dpd.altBuffer->data); alt_len = &_dpd.altBuffer->len; ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { _dpd.DetectFlag_Disable(SF_FLAG_ALT_DECODE); smtp_normalizing = 0; return -1; } *alt_len += length; _dpd.SetAltDecode(*alt_len); return 0; }
void HttpBase::Append(const void * context, const s32 size) { while (_content.GetFreeSpace() < size) _content.Expand(); SafeMemcpy(_content.GetFree(), _content.GetFreeSpace(), context, size); _content.In(size); }
int SMTP_CopyToAltBuffer(SFSnortPacket *p, const uint8_t *start, int length) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret; /* if we make a call to this it means we want to use the alt buffer * regardless of whether we copy any data into it or not - barring a failure */ p->flags |= FLAG_ALT_DECODE; smtp_normalizing = 1; /* if start and end the same, nothing to copy */ if (length == 0) return 0; alt_buf = &_dpd.altBuffer[0]; alt_size = _dpd.altBufferLen; alt_len = &p->normalized_payload_size; ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { p->flags &= ~FLAG_ALT_DECODE; smtp_normalizing = 0; *alt_len = 0; return -1; } *alt_len += length; return 0; }
/* accumulate MIME attachment filenames. The filenames are appended by commas */ int log_file_name(const uint8_t *start, int length, FILE_LogState *log_state, bool *disp_cont) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret=0; int cont =0; int log_avail = 0; if(!start || (length <= 0)) { *disp_cont = false; return -1; } if(*disp_cont) cont = 1; ret = extract_file_name((const char **)(&start), length, disp_cont); if (ret == -1) return ret; length = ret; alt_buf = log_state->filenames; alt_size = MAX_FILE; alt_len = &(log_state->file_logged); log_avail = alt_size - *alt_len; if(!alt_buf || (log_avail <= 0)) return -1; if ( *alt_len > 0 && ((*alt_len + 1) < alt_size)) { if(!cont) { alt_buf[*alt_len] = ','; *alt_len = *alt_len + 1; } } ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { if(*alt_len != 0) *alt_len = *alt_len - 1; return -1; } log_state->file_current = *alt_len; *alt_len += length; return 0; }
void Redis::Append(CommandBuff& buf, const void * val, const s32 size) { SafeSprintf(buf.data + buf.size, sizeof(buf.data) - buf.size, "$%d\r\n", size); buf.size += (s32)strlen(buf.data + buf.size); SafeMemcpy(buf.data + buf.size, sizeof(buf.data) - buf.size, val, size); buf.size += size; SafeSprintf(buf.data + buf.size, sizeof(buf.data) - buf.size, "\r\n"); buf.size += (s32)strlen(buf.data + buf.size); }
void Gate::BuildToken(char * token, s32 size, const TokenData& data) { char checkBuf[1024]; SafeMemcpy(checkBuf, sizeof(checkBuf), &data, sizeof(TokenData)); SafeSprintf(checkBuf + sizeof(TokenData), sizeof(checkBuf) - sizeof(TokenData), "%s", _tokenKey.GetString()); MD5 md5; md5.update(checkBuf, sizeof(TokenData) + _tokenKey.Length()); std::string sign = md5.toString(); char buf[1024]; SafeMemcpy(buf, sizeof(buf), &data, sizeof(TokenData)); SafeSprintf(buf + sizeof(TokenData), sizeof(buf) - sizeof(TokenData), "%s", sign.c_str()); u32 outSize = size; s32 ret = Base64Encode((u8*)buf, (u32)(sizeof(TokenData) + sign.size()), token, &outSize); OASSERT(ret == BASE64_OK, "wtf"); token[outSize] = 0; }
template<> inline JUINT32 JList<JPER_RECORD>::CopyObject(JList<JPER_RECORD>& rDst, JList<JPER_RECORD>& rSrc) { JPER_RECORD* pDstData = JNULL; JListItem<JPER_RECORD>* pDstItem = JNULL; JUINT32 uiLen = 0; JPER_RECORD* pSrcData = JNULL; JListItem<JPER_RECORD>* pSrcItem = JNULL; JListItem<JPER_RECORD>* prevDstItem = JNULL; rDst.m_pHead = JNULL; rDst.m_pTail = JNULL; JLogAutoPtr clsLogAutoPtr(JSingleton<JLog>::instance(), JLOG_MOD_LIST, "JList::CopyObject"); JListIterator<JPER_RECORD> clsListIter(rSrc); for (clsListIter.First(); clsListIter.Done(); clsListIter.Next()) { pSrcItem = clsListIter.Item(); pDstData = JNULL; pSrcData = pSrcItem->GetData(); uiLen = pSrcItem->GetDataLength(); if (uiLen) { //alloc memory for the dst data pDstData = reinterpret_cast<JPER_RECORD*>(JSingleton<JStaticMemory>::instance()->Alloc(uiLen+1)); if (pDstData) { SafeMemset(reinterpret_cast<JCHAR*>(pDstData), 0, uiLen+1); SafeMemcpy(reinterpret_cast<JCHAR*>(pDstData), reinterpret_cast<JCHAR*>(pSrcData), uiLen, uiLen+1); } else { JSingleton<JLog>::instance2() << set(JLOG_MOD_LIST, JLOG_ERROR_LEVEL) << "JList::CopyObject memory alloc failure\n"; return JFAILURE; } } //construct the dst item pDstItem = new JListItem<JPER_RECORD>(pDstData); pDstItem->SetDataLength(uiLen); rDst.InsertItem(pDstItem, prevDstItem); prevDstItem = pDstItem; } return JSUCCESS; }
/* * Normalize current line in buffer. Walk buffer, consolidating whitespace into * alternate buffer, then return number of bytes walked in packet data buffer. * * @param p standard Packet structure * @param offset offset into p->data to data of interest * @param cmd_len length of command on this line * * @return length * @retval integer length of line */ int SMTP_Normalize(SFSnortPacket *p, int offset, int cmd_len) { int i = 0; int datalen; char *data; int past_spaces = 0; int first_space = 1; char *startBuffer = &_dpd.altBuffer[0]; char *endBuffer = startBuffer + _dpd.altBufferLen; int ret; data = p->payload + offset; datalen = p->payload_size - offset; //memcpy(_dpd.altBuffer + p->normalized_payload_size, data, cmd_len); ret = SafeMemcpy(startBuffer + p->normalized_payload_size, data, cmd_len, startBuffer, endBuffer); //if (ret == SAFEMEM_ERROR) //{ // DEBUG_WRAP(_dpd.debugMsg(DEBUG_SMTP, "SMTP_Normalize() => SafeMemcpy failed\n");); // return -1; //} data += cmd_len; i += cmd_len; p->normalized_payload_size += cmd_len; for ( ; i < datalen && *data != '\n' && p->normalized_payload_size < _dpd.altBufferLen; i++, data++ ) { if ( !past_spaces && i > cmd_len && !isspace((int)*data) ) { past_spaces = 1; } if ( first_space || past_spaces ) { if (isspace((int)*data)) *(_dpd.altBuffer + p->normalized_payload_size) = ' '; else *(_dpd.altBuffer + p->normalized_payload_size) = *data; p->normalized_payload_size++; first_space = 0; } } return i; }
/* accumulate MIME attachment filenames. The filenames are appended by commas */ int SMTP_CopyFileName(const uint8_t *start, int length) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret=0; int cont =0; if(length == 0) return -1; if(smtp_ssn->state_flags & SMTP_FLAG_IN_CONT_DISP_CONT) cont = 1; ret = SMTP_ExtractFileName((const char **)(&start), length ); if (ret == -1) return ret; length = ret; alt_buf = smtp_ssn->filenames.data; alt_size = sizeof(smtp_ssn->filenames.data); alt_len = &(smtp_ssn->filenames.len); if ( *alt_len > 0 && ((*alt_len + 1) < alt_size)) { if(!cont) { alt_buf[*alt_len] = ','; *alt_len = *alt_len + 1; } } ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { if(*alt_len != 0) *alt_len = *alt_len - 1; return -1; } *alt_len += length; smtp_ssn->log_flags |= SMTP_FLAG_FILENAME_PRESENT; return 0; }
static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n) { KTRIEPATTERN *p; int ret; if (n < 1) return NULL; p = (KTRIEPATTERN*) KTRIE_MALLOC( sizeof(KTRIEPATTERN) ); if (p == NULL) return NULL; /* Save as a nocase string */ p->P = (unsigned char*) KTRIE_MALLOC( n ); if( !p->P ) { KTRIE_FREE(p); return NULL; } ConvertCaseEx( p->P, P, n ); /* Save Case specific version */ p->Pcase = (unsigned char*) KTRIE_MALLOC( n ); if( !p->Pcase ) { KTRIE_FREE(p->P); KTRIE_FREE(p); return NULL; } ret = SafeMemcpy(p->Pcase, P, n, p->Pcase, p->Pcase + n); if (ret != SAFEMEM_SUCCESS) { KTRIE_FREE(p->Pcase); KTRIE_FREE(p->P); KTRIE_FREE(p); return NULL; } p->n = n; p->next = NULL; return p; }
bool Gate::CheckToken(const char * token, TokenData& data, bool login) { u8 buf[1024]; u32 size = 1023; if (BASE64_OK != Base64Decode(token, (u32)strlen(token), buf, &size)) return false; buf[size] = 0; data = *(TokenData*)buf; const char * sign = (const char *)(buf + sizeof(TokenData)); char checkBuf[1024]; SafeMemcpy(checkBuf, sizeof(checkBuf), buf, sizeof(TokenData)); SafeSprintf(checkBuf + sizeof(TokenData), sizeof(checkBuf) - sizeof(TokenData), "%s", login ? _loginKey.GetString() : _tokenKey.GetString()); MD5 md5; md5.update(checkBuf, sizeof(TokenData) + login ? _loginKey.Length() : _tokenKey.Length()); if (strcmp(md5.toString().c_str(), sign) != 0) return false; return true; }
/* Accumulate EOL seperated headers, one or more at a time */ int SMTP_CopyEmailHdrs(const uint8_t *start, int length) { int log_avail = 0; uint8_t *log_buf; uint32_t *hdrs_logged; int ret = 0; if ((smtp_ssn->log_state == NULL) || (length <= 0)) return -1; log_avail = (smtp_ssn->log_state->log_depth - smtp_ssn->log_state->hdrs_logged); hdrs_logged = &(smtp_ssn->log_state->hdrs_logged); log_buf = (uint8_t *)smtp_ssn->log_state->emailHdrs; if(log_avail <= 0) { return -1; } if(length > log_avail ) { length = log_avail; } /* appended by the EOL \r\n */ ret = SafeMemcpy(log_buf + *hdrs_logged, start, length, log_buf, log_buf+(smtp_ssn->log_state->log_depth)); if (ret != SAFEMEM_SUCCESS) { return -1; } *hdrs_logged += length; smtp_ssn->log_flags |= SMTP_FLAG_EMAIL_HDRS_PRESENT; return 0; }
/* Accumulate EOL seperated headers, one or more at a time */ int SMTP_CopyEmailHdrs(const uint8_t *start, int length, MAIL_LogState *log_state) { int log_avail = 0; uint8_t *log_buf; uint32_t *hdrs_logged; int ret = 0; if ((log_state == NULL) || (length <= 0)) return -1; log_avail = (log_state->log_depth - log_state->hdrs_logged); hdrs_logged = &(log_state->hdrs_logged); log_buf = (uint8_t *)log_state->emailHdrs; if(log_avail <= 0) { return -1; } if(length > log_avail ) { length = log_avail; } /* appended by the EOL \r\n */ ret = SafeMemcpy(log_buf + *hdrs_logged, start, length, log_buf, log_buf+(log_state->log_depth)); if (ret != SAFEMEM_SUCCESS) { return -1; } *hdrs_logged += length; return 0; }
static int AddCmd(char *name) { static int num_cmds = CMD_LAST + 1; static int id = CMD_LAST; SMTPToken *cmds, *tmp_cmds; SMTPSearch *cmd_search; SMTPCmdConfig *cmd_config; int ret; /* allocate enough memory for new commmand - alloc one extra for NULL entry */ cmds = (SMTPToken *)calloc(num_cmds + 1, sizeof(SMTPToken)); if (cmds == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_search = (SMTPSearch *)calloc(num_cmds, sizeof(SMTPSearch)); if (cmd_search == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_config = (SMTPCmdConfig *)calloc(num_cmds, sizeof(SMTPCmdConfig)); if (cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* copy existing commands into newly allocated memory * don't need to copy anything from cmd_search since this hasn't been initialized yet */ ret = SafeMemcpy(cmds, _smtp_cmds, id * sizeof(SMTPToken), cmds, cmds + num_cmds); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } ret = SafeMemcpy(cmd_config, _smtp_cmd_config, id * sizeof(SMTPCmdConfig), cmd_config, cmd_config + num_cmds); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* add new command to cmds * cmd_config doesn't need anything added - this will probably be done by a calling function * cmd_search will be initialized when the searches are initialized */ tmp_cmds = &cmds[id]; tmp_cmds->name = strdup(name); tmp_cmds->name_len = strlen(name); tmp_cmds->search_id = id; if (tmp_cmds->name == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* free global memory structures */ if (_smtp_cmds != NULL) free(_smtp_cmds); if (_smtp_cmd_search != NULL) free(_smtp_cmd_search); if (_smtp_cmd_config != NULL) free(_smtp_cmd_config); /* set globals to new memory */ _smtp_cmds = cmds; _smtp_cmd_search = cmd_search; _smtp_cmd_config = cmd_config; ret = id; id++; num_cmds++; return ret; }
static int AddCmd(SMTPConfig *config, char *name) { SMTPToken *cmds, *tmp_cmds; SMTPSearch *cmd_search; SMTPCmdConfig *cmd_config; int ret; if (config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) SMTP config is NULL.\n", __FILE__, __LINE__); } config->num_cmds++; /* allocate enough memory for new commmand - alloc one extra for NULL entry */ cmds = (SMTPToken *)calloc(config->num_cmds + 1, sizeof(SMTPToken)); if (cmds == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* This gets filled in later */ cmd_search = (SMTPSearch *)calloc(config->num_cmds, sizeof(SMTPSearch)); if (cmd_search == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_config = (SMTPCmdConfig *)calloc(config->num_cmds, sizeof(SMTPCmdConfig)); if (cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* copy existing commands into newly allocated memory * don't need to copy anything from cmd_search since this hasn't been initialized yet */ ret = SafeMemcpy(cmds, config->cmds, (config->num_cmds - 1) * sizeof(SMTPToken), cmds, cmds + (config->num_cmds - 1)); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } ret = SafeMemcpy(cmd_config, config->cmd_config, (config->num_cmds - 1) * sizeof(SMTPCmdConfig), cmd_config, cmd_config + (config->num_cmds - 1)); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* add new command to cmds * cmd_config doesn't need anything added - this will probably be done by a calling function * cmd_search will be initialized when the searches are initialized */ tmp_cmds = &cmds[config->num_cmds - 1]; tmp_cmds->name = strdup(name); tmp_cmds->name_len = strlen(name); tmp_cmds->search_id = config->num_cmds - 1; if (tmp_cmds->name == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* free global memory structures */ if (config->cmds != NULL) free(config->cmds); if (config->cmd_search != NULL) free(config->cmd_search); if (config->cmd_config != NULL) free(config->cmd_config); /* set globals to new memory */ config->cmds = cmds; config->cmd_search = cmd_search; config->cmd_config = cmd_config; return (config->num_cmds - 1); }
int HttpResponseInspection(HI_SESSION *Session, Packet *p, const unsigned char *data, int dsize, HttpSessionData *sd) { HTTPINSPECT_CONF *ServerConf; URI_PTR stat_code_ptr; URI_PTR stat_msg_ptr; HEADER_PTR header_ptr; URI_PTR body_ptr; HI_SERVER *Server; const u_char *start; const u_char *end; const u_char *ptr; int len; int iRet = 0; int resp_header_size = 0; /* Refers to the stream reassembled packets when reassembly is turned on. * Refers to all packets when reassembly is turned off. */ int not_stream_insert = 1; #ifdef ZLIB int parse_cont_encoding = 1; int status; #endif int expected_pkt = 0; int alt_dsize; uint32_t seq_num = 0; if (!Session || !p || !data || (dsize == 0)) return HI_INVALID_ARG; ServerConf = Session->server_conf; if(!ServerConf) return HI_INVALID_ARG; Server = &(Session->server); clearHttpRespBuffer(Server); seq_num = GET_PKT_SEQ(p); if ( (sd != NULL) ) { /* If the previously inspected packet in this session identified as a body * and if the packets are stream inserted wait for reassembled */ if (sd->resp_state.inspect_reassembled) { if(p->packet_flags & PKT_STREAM_INSERT) { #ifdef ZLIB parse_cont_encoding = 0; #endif not_stream_insert = 0; } } /* If this packet is the next expected packet to be inspected and is out of sequence * clear out the resp state*/ #ifdef ZLIB if(( sd->decomp_state && sd->decomp_state->decompress_data) && parse_cont_encoding) { if( sd->resp_state.next_seq && (seq_num == sd->resp_state.next_seq) ) { sd->resp_state.next_seq = seq_num + p->dsize; expected_pkt = 1; } else { ResetGzipState(sd->decomp_state); ResetRespState(&(sd->resp_state)); } } else #endif if(sd->resp_state.inspect_body && not_stream_insert) { /* If the server flow depth is 0 then we need to check if the packet * is in sequence */ if(!ServerConf->server_flow_depth) { if( sd->resp_state.next_seq && (seq_num == sd->resp_state.next_seq) ) { sd->resp_state.next_seq = seq_num + p->dsize; expected_pkt = 1; } else { #ifdef ZLIB ResetGzipState(sd->decomp_state); #endif ResetRespState(&(sd->resp_state)); } } else { /*Check if the sequence number of the packet is within the allowed * flow_depth */ if( (sd->resp_state.is_max_seq) && SEQ_LT(seq_num, (sd->resp_state.max_seq))) { expected_pkt = 1; } else { #ifdef ZLIB ResetGzipState(sd->decomp_state); #endif ResetRespState(&(sd->resp_state)); } } } } memset(&stat_code_ptr, 0x00, sizeof(URI_PTR)); memset(&stat_msg_ptr, 0x00, sizeof(URI_PTR)); memset(&header_ptr, 0x00, sizeof(HEADER_PTR)); memset(&body_ptr, 0x00, sizeof(URI_PTR)); start = data; end = data + dsize; ptr = start; /* moving past the CRLF */ while(hi_util_in_bounds(start, end, ptr)) { if(*ptr < 0x21) { if(*ptr < 0x0E && *ptr > 0x08) { ptr++; continue; } else { if(*ptr == 0x20) { ptr++; continue; } } } break; } /*after doing this we need to basically check for version, status code and status message*/ len = end - ptr; if ( len > 4 ) { if(!IsHttpVersion(&ptr, end)) { if(expected_pkt) { ptr = start; p->packet_flags |= PKT_HTTP_DECODE; } else { p->packet_flags |= PKT_HTTP_DECODE; ApplyFlowDepth(ServerConf, p, sd, resp_header_size, 0, seq_num); if ( not_stream_insert && (sd != NULL)) { #ifdef ZLIB ResetGzipState(sd->decomp_state); #endif ResetRespState(&(sd->resp_state)); } CLR_SERVER_HEADER(Server); return HI_SUCCESS; } } else { p->packet_flags |= PKT_HTTP_DECODE; /* This is a next expected packet to be decompressed but the packet is a * valid HTTP response. So the gzip decompression ends here */ if(expected_pkt) { expected_pkt = 0; #ifdef ZLIB ResetGzipState(sd->decomp_state); #endif ResetRespState(&(sd->resp_state)); } while(hi_util_in_bounds(start, end, ptr)) { if (isspace((int)*ptr)) break; ptr++; } } } else if (!expected_pkt) { return HI_SUCCESS; } /*If this is the next expected packet to be decompressed, send this packet * decompression */ if (expected_pkt) { if (hi_util_in_bounds(start, end, ptr)) { iRet = hi_server_inspect_body(Session, sd, ptr, end, &body_ptr); } } else { iRet = hi_server_extract_status_code(Session, start,ptr,end , &stat_code_ptr); if ( iRet == STAT_END ) { Server->response.status_code = stat_code_ptr.uri; Server->response.status_code_size = stat_code_ptr.uri_end - stat_code_ptr.uri; if ( (int)Server->response.status_code_size <= 0) { CLR_SERVER_STAT(Server); } else { iRet = hi_server_extract_status_msg(start, stat_code_ptr.uri_end , end, &stat_msg_ptr); if ( stat_msg_ptr.uri ) { Server->response.status_msg = stat_msg_ptr.uri; Server->response.status_msg_size = stat_msg_ptr.uri_end - stat_msg_ptr.uri; if ((int)Server->response.status_msg_size <= 0) { CLR_SERVER_STAT(Server); } else { #ifdef ZLIB ptr = hi_server_extract_header(Session, ServerConf, &header_ptr, stat_msg_ptr.uri_end , end, parse_cont_encoding, sd ); #else /* We dont need the content-encoding header when zlib is not enabled */ ptr = hi_server_extract_header(Session, ServerConf, &header_ptr, stat_msg_ptr.uri_end , end, 0, sd ); #endif } } else { CLR_SERVER_STAT(Server); } } if (header_ptr.header.uri) { Server->response.header_raw = header_ptr.header.uri; Server->response.header_raw_size = header_ptr.header.uri_end - header_ptr.header.uri; if(!Server->response.header_raw_size) { CLR_SERVER_HEADER(Server); } else { resp_header_size = (header_ptr.header.uri_end - p->data); hi_stats.resp_headers++; Server->response.header_norm = header_ptr.header.uri; if (header_ptr.cookie.cookie) { hi_stats.resp_cookies++; Server->response.cookie.cookie = header_ptr.cookie.cookie; Server->response.cookie.cookie_end = header_ptr.cookie.cookie_end; Server->response.cookie.next = header_ptr.cookie.next; } else { Server->response.cookie.cookie = NULL; Server->response.cookie.cookie_end = NULL; Server->response.cookie.next = NULL; } if (sd != NULL) { #ifdef ZLIB if( header_ptr.content_encoding.compress_fmt ) { hi_stats.gzip_pkts++; /* We've got gzip data - grab buffer from mempool and attach * to session data if server is configured to do so */ if (sd->decomp_state == NULL) SetGzipBuffers(sd, Session); if (sd->decomp_state != NULL) { sd->decomp_state->decompress_data = 1; sd->decomp_state->compress_fmt = header_ptr.content_encoding.compress_fmt; } } else #endif { sd->resp_state.inspect_body = 1; } sd->resp_state.last_pkt_contlen = header_ptr.content_len.len; if(ServerConf->server_flow_depth == -1) sd->resp_state.is_max_seq = 0; else { sd->resp_state.is_max_seq = 1; sd->resp_state.max_seq = seq_num + (header_ptr.header.uri_end - start)+ ServerConf->server_flow_depth; } if (p->packet_flags & PKT_STREAM_INSERT) { if(header_ptr.content_len.cont_len_start && ((end - (header_ptr.header.uri_end)) >= header_ptr.content_len.len)) { /* change this when the api is fixed to flush correctly */ //stream_api->response_flush_stream(p); expected_pkt = 1; } else sd->resp_state.inspect_reassembled = 1; } else { if(p->packet_flags & PKT_REBUILT_STREAM) sd->resp_state.inspect_reassembled = 1; expected_pkt = 1; } if(expected_pkt) { sd->resp_state.next_seq = seq_num + p->dsize; if(hi_util_in_bounds(start, end, header_ptr.header.uri_end)) { iRet = hi_server_inspect_body(Session, sd, header_ptr.header.uri_end, end, &body_ptr); } } } } } else { CLR_SERVER_HEADER(Server); } } else { CLR_SERVER_STAT(Server); } } if( body_ptr.uri ) { Server->response.body = body_ptr.uri; Server->response.body_size = body_ptr.uri_end - body_ptr.uri; if( Server->response.body_size > 0) { if ( Server->response.body_size < sizeof(DecodeBuffer.data) ) { alt_dsize = Server->response.body_size; } else { alt_dsize = sizeof(DecodeBuffer.data); } #ifdef ZLIB if(sd->decomp_state && sd->decomp_state->decompress_data) { status = SafeMemcpy(DecodeBuffer.data, Server->response.body, alt_dsize, DecodeBuffer.data, DecodeBuffer.data + sizeof(DecodeBuffer.data)); if( status != SAFEMEM_SUCCESS ) return HI_MEM_ALLOC_FAIL; p->data_flags |= DATA_FLAGS_GZIP; SetAltDecode(p, alt_dsize); SetDetectLimit(p, alt_dsize); } else #endif { if(sd->resp_state.last_pkt_chunked) { p->data_flags |= DATA_FLAGS_RESP_BODY; SetAltDecode(p, alt_dsize); SetDetectLimit(p, alt_dsize); } else { p->data_flags |= DATA_FLAGS_RESP_BODY; p->packet_flags |= PKT_HTTP_RESP_BODY; SetDetectLimit(p, (alt_dsize + resp_header_size)); } } if (get_decode_utf_state_charset(&(sd->utf_state)) != CHARSET_DEFAULT) { if ( Server->response.body_size < sizeof(DecodeBuffer.data) ) { alt_dsize = Server->response.body_size; } else { alt_dsize = sizeof(DecodeBuffer.data); } SetDetectLimit(p, alt_dsize); SetAltDecode(p, alt_dsize); } } } else { /* There is no body to the HTTP response. * In this case we need to inspect the entire HTTP response header. */ ApplyFlowDepth(ServerConf, p, sd, resp_header_size, 1, seq_num); } return HI_SUCCESS; }
/* DNP3 Transport-Layer reassembly state machine. Arguments: rdata: DNP3 reassembly state object. buf: DNP3 Transport Layer segment buflen: Length of Transport Layer segment. Returns: DNP3_FAIL: Segment was discarded. DNP3_OK: Segment was queued. */ static int DNP3ReassembleTransport(dnp3_reassembly_data_t *rdata, char *buf, uint16_t buflen) { dnp3_transport_header_t *trans_header; if (rdata == NULL || buf == NULL || buflen < sizeof(dnp3_transport_header_t) || (buflen > DNP3_MAX_TRANSPORT_LEN)) { return DNP3_FAIL; } /* Take the first byte as a transport header, cut it off of the buffer. */ trans_header = (dnp3_transport_header_t *)buf; buf += sizeof(dnp3_transport_header_t); buflen -= sizeof(dnp3_transport_header_t); /* If the previously-existing state was DONE, we need to reset it back to IDLE. */ if (rdata->state == DNP3_REASSEMBLY_STATE__DONE) DNP3ReassemblyReset(rdata); switch (rdata->state) { case DNP3_REASSEMBLY_STATE__IDLE: /* Discard any non-first segment. */ if ( DNP3_TRANSPORT_FIR(trans_header->control) == 0 ) return DNP3_FAIL; /* Reset the buffer & queue the first segment */ DNP3ReassemblyReset(rdata); DNP3QueueSegment(rdata, buf, buflen); rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control); if ( DNP3_TRANSPORT_FIN(trans_header->control) ) rdata->state = DNP3_REASSEMBLY_STATE__DONE; else rdata->state = DNP3_REASSEMBLY_STATE__ASSEMBLY; break; case DNP3_REASSEMBLY_STATE__ASSEMBLY: /* Reset if the FIR flag is set. */ if ( DNP3_TRANSPORT_FIR(trans_header->control) ) { DNP3ReassemblyReset(rdata); DNP3QueueSegment(rdata, buf, buflen); rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control); if (DNP3_TRANSPORT_FIN(trans_header->control)) rdata->state = DNP3_REASSEMBLY_STATE__DONE; /* Raise an alert so it's clear the buffer was reset. Could signify device trouble. */ _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_REASSEMBLY_BUFFER_CLEARED, 1, 0, 3, DNP3_REASSEMBLY_BUFFER_CLEARED_STR, 0); } else { /* Same seq but FIN is set. Discard segment, BUT finish reassembly. */ if ((DNP3_TRANSPORT_SEQ(trans_header->control) == rdata->last_seq) && (DNP3_TRANSPORT_FIN(trans_header->control))) { _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_DROPPED_SEGMENT, 1, 0, 3, DNP3_DROPPED_SEGMENT_STR, 0); rdata->state = DNP3_REASSEMBLY_STATE__DONE; return DNP3_FAIL; } /* Discard any other segments without the correct sequence. */ if (DNP3_TRANSPORT_SEQ(trans_header->control) != ((rdata->last_seq + 1) % 0x40 )) { _dpd.alertAdd(GENERATOR_SPP_DNP3, DNP3_DROPPED_SEGMENT, 1, 0, 3, DNP3_DROPPED_SEGMENT_STR, 0); return DNP3_FAIL; } /* Otherwise, queue it up! */ DNP3QueueSegment(rdata, buf, buflen); rdata->last_seq = DNP3_TRANSPORT_SEQ(trans_header->control); if (DNP3_TRANSPORT_FIN(trans_header->control)) rdata->state = DNP3_REASSEMBLY_STATE__DONE; else rdata->state = DNP3_REASSEMBLY_STATE__ASSEMBLY; } break; case DNP3_REASSEMBLY_STATE__DONE: break; } /* Set the Alt Decode buffer. This must be done during preprocessing in order to stop the Fast Pattern matcher from using raw packet data to evaluate the longest content in a rule. */ if (rdata->state == DNP3_REASSEMBLY_STATE__DONE) { uint8_t *alt_buf = _dpd.altBuffer->data; uint16_t alt_len = sizeof(_dpd.altBuffer->data); int ret; ret = SafeMemcpy((void *)alt_buf, (const void *)rdata->buffer, (size_t)rdata->buflen, (const void *)alt_buf, (const void *)(alt_buf + alt_len)); if (ret == SAFEMEM_SUCCESS) _dpd.SetAltDecode(alt_len); } return DNP3_OK; }
/* Accumulate email addresses from RCPT TO and/or MAIL FROM commands. Email addresses are separated by comma */ int SMTP_CopyEmailID(const uint8_t *start, int length, int command_type) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret; const uint8_t *tmp_eol; if (length <= 0) return -1; tmp_eol = (uint8_t *)memchr(start, ':', length); if(tmp_eol == NULL) return -1; if((tmp_eol+1) < (start+length)) { length = length - ( (tmp_eol+1) - start ); start = tmp_eol+1; } else return -1; switch (command_type) { case CMD_MAIL: alt_buf = smtp_ssn->senders.data; alt_size = sizeof(smtp_ssn->senders.data); alt_len = &(smtp_ssn->senders.len); break; case CMD_RCPT: alt_buf = smtp_ssn->recipients.data; alt_size = sizeof(smtp_ssn->recipients.data); alt_len = &(smtp_ssn->recipients.len); break; default: return -1; } if ( *alt_len > 0 && ((*alt_len + 1) < alt_size)) { alt_buf[*alt_len] = ','; *alt_len = *alt_len + 1; } ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { if(*alt_len != 0) *alt_len = *alt_len - 1; return -1; } *alt_len += length; return 0; }
void *DCERPC_FragAlloc(void *p, u_int16_t old_size, u_int16_t *new_size) { u_int16_t add_size; void *new_buf = NULL; if (old_size >= *new_size) { *new_size = old_size; return p; } add_size = *new_size - old_size; if ( (((u_int32_t) add_size) + _total_memory) > _memcap ) { /* Raise alert */ if ( _alert_memcap ) { DCERPC_GenerateAlert(DCERPC_EVENT_MEMORY_OVERFLOW, DCERPC_EVENT_MEMORY_OVERFLOW_STR); } add_size = (u_int16_t) (_memcap - _total_memory); } *new_size = old_size + add_size; if (*new_size == old_size) return p; new_buf = calloc(*new_size, 1); if (new_buf == NULL) { if (p != NULL) { DCERPC_FragFree(p, old_size); } return NULL; } if (p != NULL) { int ret; ret = SafeMemcpy(new_buf, p, old_size, new_buf, (u_int8_t *)new_buf + *new_size); if (ret == 0) { *new_size = old_size; free(new_buf); return p; } DCERPC_FragFree(p, old_size); } /* DCERPC_FragFree will decrement old_size from _total_memory so * we add the *new_size */ _total_memory += *new_size; return new_buf; }
/******************************************************************************* * Function: GetObfuscationPayloadCallback() * * ObfuscationCallback for returning an allocated obfuscated payload. * * Arguments * DAQ_PktHdr_t *pkth * The pcap header information associated with the payload being * obfuscated. * uint8_t *packet_data * Pointer to the packet data to be obfuscated * ob_char_t ob_char * The obfuscation character * ob_size_t length * The length of the portion of packet payload to use * void *user_data * The ObfuscatedPayload data * * Returns * OB_RET_ERROR if copying obfuscation data is not successful * OB_RET_SUCCESS if successful copying data to payload * ******************************************************************************/ static ObRet GetObfuscatedPayloadCallback(const DAQ_PktHdr_t *pkth, const uint8_t *packet_data, ob_size_t length, ob_char_t ob_char, void *user_data) { ObfuscatedPayload *ob_payload = (ObfuscatedPayload *)user_data; uint8_t *payload; ob_size_t payload_len, payload_size; if (ob_payload == NULL) return OB_RET_ERROR; if ((ob_payload->payload == NULL) || (ob_payload->payload_len == NULL)) return OB_RET_ERROR; payload = *ob_payload->payload; payload_len = *ob_payload->payload_len; payload_size = ob_payload->payload_size; if ((payload_len + length) > payload_size) { /* Allocate extra so we don't have to reallocate every time in */ ob_size_t new_size = payload_len + length + 100; uint8_t *tmp = (uint8_t *)SnortAlloc(new_size); if (payload != NULL) { if (SafeMemcpy(tmp, payload, payload_len, tmp, tmp + new_size) != SAFEMEM_SUCCESS) { free(tmp); free(payload); return OB_RET_ERROR; } free(payload); } payload_size = new_size; ob_payload->payload_size = new_size; *ob_payload->payload = tmp; payload = tmp; } if (packet_data != NULL) { if (SafeMemcpy(payload + payload_len, packet_data, length, payload, payload + payload_size) != SAFEMEM_SUCCESS) { free(payload); return OB_RET_ERROR; } } else { if (SafeMemset(payload + payload_len, (uint8_t)ob_char, length, payload, payload + payload_size) != SAFEMEM_SUCCESS) { free(payload); return OB_RET_ERROR; } } *ob_payload->payload_len += length; return OB_RET_SUCCESS; }
/* Accumulate email addresses from RCPT TO and/or MAIL FROM commands. Email addresses are separated by comma */ int SMTP_CopyEmailID(const uint8_t *start, int length, int command_type) { uint8_t *alt_buf; int alt_size; uint16_t *alt_len; int ret; int log_avail=0; const uint8_t *tmp_eol; if ((smtp_ssn->log_state == NULL) || (length <= 0)) return -1; tmp_eol = (uint8_t *)memchr(start, ':', length); if(tmp_eol == NULL) return -1; if((tmp_eol+1) < (start+length)) { length = length - ( (tmp_eol+1) - start ); start = tmp_eol+1; } else return -1; switch (command_type) { case CMD_MAIL: alt_buf = smtp_ssn->log_state->senders; alt_size = MAX_EMAIL; alt_len = &(smtp_ssn->log_state->snds_logged); break; case CMD_RCPT: alt_buf = smtp_ssn->log_state->recipients; alt_size = MAX_EMAIL; alt_len = &(smtp_ssn->log_state->rcpts_logged); break; default: return -1; } log_avail = alt_size - *alt_len; if(log_avail <= 0 || !alt_buf) return -1; else if(log_avail < length) length = log_avail; if ( *alt_len > 0 && ((*alt_len + 1) < alt_size)) { alt_buf[*alt_len] = ','; *alt_len = *alt_len + 1; } ret = SafeMemcpy(alt_buf + *alt_len, start, length, alt_buf, alt_buf + alt_size); if (ret != SAFEMEM_SUCCESS) { if(*alt_len != 0) *alt_len = *alt_len - 1; return -1; } *alt_len += length; return 0; }
int hi_split_header_cookie(HI_SESSION *Session, u_char *header, int *i_header_len, u_char *cookie_header, int *i_cookie_len, const u_char *raw_header, int i_raw_header_len, COOKIE_PTR *cookie) { int iRet = HI_SUCCESS; COOKIE_PTR *last_cookie = NULL; COOKIE_PTR *first_cookie = cookie; const u_char *raw_header_end = raw_header + i_raw_header_len; int this_cookie_len = 0; const u_char *this_header_start = raw_header; const u_char *this_header_end; int this_header_len = 0; const u_char *header_end; const u_char *cookie_end; if (!cookie || !i_header_len || !i_cookie_len) return HI_INVALID_ARG; /* Can't use hi_util_in_bounds header because == is okay */ if (cookie->cookie_end > raw_header + i_raw_header_len) return HI_OUT_OF_BOUNDS; header_end = (const u_char *)(header + *i_header_len); *i_header_len = 0; cookie_end = (const u_char *)(cookie_header + *i_cookie_len); *i_cookie_len = 0; do { this_cookie_len = cookie->cookie_end - cookie->cookie; this_header_end = cookie->cookie; this_header_len = this_header_end - this_header_start; /* Trim the header and only copy what we can store in the buf */ if (*i_header_len + this_header_len > MAX_URI) { this_header_len = MAX_URI - *i_header_len; } /* Copy out the headers from start to beginning of the cookie */ if (this_header_len > 0) { if (SafeMemcpy(header + *i_header_len, this_header_start, this_header_len, header, header_end) == SAFEMEM_SUCCESS) { *i_header_len += this_header_len; } } else { DEBUG_WRAP(DebugMessage(DEBUG_HTTPINSPECT, "HttpInspect: no leading header: %d to %d\n", this_header_end - this_header_start, this_header_len);); } /* Trim the cookie and only copy what we can store in the buf */ if (*i_cookie_len + this_cookie_len > MAX_URI) { this_cookie_len = MAX_URI - *i_cookie_len; } /* And copy the cookie */ if (this_cookie_len > 0) { if (SafeMemcpy(cookie_header + *i_cookie_len, cookie->cookie, this_cookie_len, cookie_header, cookie_end) == SAFEMEM_SUCCESS) { *i_cookie_len += this_cookie_len; } } else { DEBUG_WRAP(DebugMessage(DEBUG_HTTPINSPECT, "HttpInspect: trimming cookie: %d to %d\n", cookie->cookie_end - cookie->cookie, this_cookie_len);); }
/******************************************************************************* * Function: TraverseObfuscationList() * * This is the main function for obfuscating a payload or stream segments. * It walks through a packet and obfuscation entries, calling the user * callback with obfuscated and non-obfuscated instructions. * * Arguments * ObfuscationCallbackData *data * The state tracking data structure. Has the packet being obfuscated, * current obfuscation entry and total number of bytes obfuscated thus * far. * DAQ_PktHdr_t *pkth * The pcap header information associated with the payload being * obfuscated. * uint8_t *pkt * The start of the packet including Ethernet headers, etc. * uint8_t *payload * Pointer to the payload data to be obfuscated * ob_size_t * The size of the payload data * * Returns * OB_RET_SUCCESS if successfully completed * OB_RET_ERROR if the user callback doesn't return OB_RET_SUCCESS * ******************************************************************************/ static ObRet TraverseObfuscationList(ObfuscationCallbackData *data, const DAQ_PktHdr_t *pkth, const uint8_t *payload_data, ob_size_t payload_size) { int i; ob_size_t total_offset = data->total_offset; ob_size_t payload_offset = 0; const DAQ_PktHdr_t *pkth_tmp = pkth; #ifdef OBFUSCATION_TEST uint8_t print_array[OB_LENGTH_MAX]; ob_size_t start_total_offset = 0; ob_size_t start_payload_offset = 0; #endif if ((payload_data == NULL) || (payload_size == 0)) return OB_RET_ERROR; #ifdef OBFUSCATION_TEST LogMessage("Payload data: %u bytes\n", payload_size); LogMessage("===============================================================" "=================\n"); #endif /* Start from current saved obfuscation entry index */ for (i = data->entry_index; i < ob_struct.num_entries; i++) { /* Get the entry from the sorted array */ const ObfuscationEntry *entry = ob_struct.sort_entries[i]; ob_size_t ob_offset = entry->offset; ob_size_t ob_length = entry->length; /* Make sure it's for the right packet */ if (entry->p != data->packet) { #ifdef OBFUSCATION_TEST LogMessage("flags1: %08x, flags2: %08x\n", entry->p->packet_flags, data->packet->packet_flags); #endif continue; } /* We've already obfuscated this part of the packet payload * Account for overflow */ if (((ob_offset + ob_length) <= total_offset) && ((ob_offset + ob_length) > ob_offset)) { continue; } #ifdef OBFUSCATION_TEST LogMessage(" Total offset: %u\n\n", total_offset); start_total_offset = total_offset; start_payload_offset = payload_offset; #endif /* Note the obfuscation offset is only used at this point to determine * the amount of data that does not need to be obfuscated up to the * offset or the length of what needs to be obfuscated if the offset * is less than what's already been logged */ if (ob_offset > total_offset) { /* Get the amount of non-obfuscated data - need to log straight * packet data up to obfuscation offset */ ob_size_t length = ob_offset - total_offset; /* If there is more length than what's left in the packet, * truncate it, do we don't overflow */ if (length > (payload_size - payload_offset)) length = payload_size - payload_offset; /* Call the user callback and tell it not to obfuscate the data * by passing in a non-NULL packet pointer */ if (data->user_callback(pkth_tmp, payload_data + payload_offset, length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST SafeMemcpy(print_array + payload_offset, payload_data + payload_offset, length, print_array, print_array + sizeof(print_array)); #endif /* Only the first payload call sends the pcap_pkthdr */ pkth_tmp = NULL; /* Adjust offsets */ payload_offset += length; total_offset += length; /* If there is no more packet data, break out of the loop */ if (payload_offset == payload_size) { #ifdef OBFUSCATION_TEST PrintPacketData(print_array + start_payload_offset, length); LogMessage("\n"); #endif break; } } else if (ob_offset < total_offset) { /* If the entries offset is less than the current total offset, * decrease the length. */ ob_length -= (total_offset - ob_offset); } /* Adjust the amount of data to obfuscate if it exceeds the amount of * data left in the packet. Account for overflow */ if (((payload_offset + ob_length) > payload_size) || ((payload_offset + ob_length) <= payload_offset)) { ob_length = payload_size - payload_offset; } /* Call the user callback and tell it to obfuscate the data by passing * in a NULL packet pointer */ if (data->user_callback(pkth_tmp, NULL, ob_length, entry->ob_char, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST LogMessage(" Entry: %d\n", i); LogMessage(" --------------------------\n"); PrintObfuscationEntry(entry, 4); LogMessage("\n"); SafeMemset(print_array + payload_offset, entry->ob_char, ob_length, print_array, print_array + sizeof(print_array)); if (ob_length < entry->length) { if (ob_offset < start_total_offset) { if (payload_offset + ob_length == payload_size) { LogMessage(" Obfuscating beyond already obfuscated " "(%u bytes) and to end of payload: %u bytes\n\n", (start_total_offset - ob_offset), ob_length); } else { LogMessage(" Obfuscating beyond already obfuscated " "(%u bytes): %u bytes\n\n", (start_total_offset - ob_offset), ob_length); } } else { LogMessage(" Obfuscating to end of payload: " "%u bytes\n\n", ob_length); } } else { LogMessage(" Obfuscating: %u bytes\n\n", ob_length); } PrintPacketData(print_array + start_payload_offset, (payload_offset - start_payload_offset) + ob_length); if (((entry->offset + entry->length) - (total_offset + ob_length)) > 0) { LogMessage("\n Remaining amount to obfuscate: %u bytes\n", (entry->offset + entry->length) - (total_offset + ob_length)); } LogMessage("\n"); #endif /* Only the first payload call sends the pcap_pkthdr */ pkth_tmp = NULL; /* Adjust offsets */ payload_offset += ob_length; total_offset += ob_length; /* If there is no more packet data, break out of the loop */ if (payload_offset == payload_size) break; } /* There's more data in the packet left, meaning we ran out of * obfuscation entries */ if (payload_size > payload_offset) { ob_size_t length = payload_size - payload_offset; /* Call the user callback and tell it not to obfuscate the data * by passing in a non-NULL packet pointer */ if (data->user_callback(pkth_tmp, payload_data + payload_offset, length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST SafeMemcpy(print_array + payload_offset, payload_data + payload_offset, length, print_array, print_array + sizeof(print_array)); #endif /* Adjust offsets - don't need to adjust packet offset since * we're done with the packet */ total_offset += length; } #ifdef OBFUSCATION_TEST LogMessage("Obfuscated payload\n"); LogMessage("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" "~~~~~~~~~~\n"); PrintPacketData(print_array, payload_size); LogMessage("\n\n"); #endif /* Save these for next time we come in if necessary. Mainly for * traversing stream segments */ data->entry_index = i; data->total_offset = total_offset; return OB_RET_SUCCESS; }