📄 sp_pattern_match.c
字号:
ds_idx->replace_size = dummy_size; DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "ds_idx (%p) replace_size(%d) replace_buf(%s)\n", ds_idx, ds_idx->replace_size, ds_idx->replace_buf);); return ds_idx;}int PayloadReplace(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list, int depth){ struct pseudoheader { u_int32_t sip, dip; u_int8_t zero; u_int8_t protocol; u_int16_t len; }; PatternMatchData *idx; struct pseudoheader ph; unsigned int ip_len; unsigned int hlen; int ret; //idx = (PatternMatchData *)otn->ds_list[PLUGIN_PATTERN_MATCH]; idx = (PatternMatchData *)fp_list->context; if (depth >= 0) { //memcpy(p->data+depth, idx->replace_buf, strlen(idx->replace_buf)); ret = SafeMemcpy( (void *)(p->data + depth), idx->replace_buf, strlen(idx->replace_buf), p->data, (p->data + p->dsize) ); if (ret == SAFEMEM_ERROR) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "PayloadReplace() => SafeMemcpy() failed\n");); return 0; }#ifdef GIDS InlineReplace();#endif if(IS_IP4(p)) {#ifdef SUP_IP6 sfip_t *tmp; p->ip4h.ip_csum=0; hlen = GET_IPH_HLEN(p) << 2; ip_len=ntohs(p->ip4h.ip_len); ip_len -= hlen; p->ip4h.ip_csum = in_chksum_ip((u_short *)p->iph, hlen); tmp = GET_SRC_IP(p); ph.sip = tmp->ip32[0]; tmp = GET_DST_IP(p); ph.dip = tmp->ip32[0];#else /* calculate new checksum */ ((IPHdr *)p->iph)->ip_csum=0; hlen = IP_HLEN(p->iph) << 2; ip_len=ntohs(p->iph->ip_len); ip_len -= hlen; ((IPHdr *)p->iph)->ip_csum = in_chksum_ip((u_short *)p->iph, hlen); ph.sip = (u_int32_t)(p->iph->ip_src.s_addr); ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);#endif if (p->tcph) { ((TCPHdr *)p->tcph)->th_sum = 0; ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = htons((u_short)ip_len); ((TCPHdr *)p->tcph)->th_sum = in_chksum_tcp((u_short *)&ph, (u_short *)(p->tcph), ip_len); } else if (p->udph) { ((UDPHdr *)p->udph)->uh_chk = 0; ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = htons((u_short)ip_len); ((UDPHdr *)p->udph)->uh_chk = in_chksum_udp((u_short *)&ph, (u_short *)(p->udph), ip_len); } else if (p->icmph) { ((ICMPHdr *)p->icmph)->csum = 0; ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = htons((u_short)ip_len); ((ICMPHdr *)p->icmph)->csum = in_chksum_icmp((u_int16_t *)(p->icmph), ip_len); } }#ifdef SUP_IP6 else { struct pseudoheader6 { struct in6_addr sip, dip; u_int8_t zero; u_int8_t protocol; u_int16_t len; }; struct pseudoheader6 ph6; sfip_t *tmp; hlen = GET_IPH_HLEN(p) << 2; ip_len=ntohs(p->ip6h.len); ip_len -= hlen; tmp = GET_SRC_IP(p); memcpy(&ph.sip, tmp->ip8, sizeof(struct in6_addr)); tmp = GET_DST_IP(p); memcpy(&ph.dip, tmp->ip8, sizeof(struct in6_addr)); ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = htons((u_short)ip_len); if (p->tcph) { ((TCPHdr *)p->tcph)->th_sum = 0; ((TCPHdr *)p->tcph)->th_sum = in_chksum_tcp6((u_short *)&ph6, (u_short *)(p->tcph), ip_len); } else if (p->udph) { ((UDPHdr *)p->udph)->uh_chk = 0; ((UDPHdr *)p->udph)->uh_chk = in_chksum_udp6((u_short *)&ph6, (u_short *)(p->udph), ip_len); } else if (p->icmph) { ((ICMPHdr *)p->icmph)->csum = 0; ((ICMPHdr *)p->icmph)->csum = in_chksum_icmp6((u_int16_t *)(p->icmph), ip_len); } }#endif } return 1;}static inline int computeDepth(int dlen, PatternMatchData * pmd) { /* do some tests to make sure we stay in bounds */ if((pmd->depth + pmd->offset) > dlen) { /* we want to check only depth bytes anyway */ int sub_depth = dlen - pmd->offset; if((sub_depth > 0) && (sub_depth >= (int)pmd->pattern_size)) { return sub_depth; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match failed -- sub_depth: %d < " "(int)pmd->pattern_size: %d!\n", sub_depth, (int)pmd->pattern_size);); return -1; } } else { if(pmd->depth && (dlen - pmd->offset > pmd->depth)) { return pmd->depth; } else { return dlen - pmd->offset; } }}/* * Figure out how deep the into the packet from the base_ptr we can go * * base_ptr = the offset into the payload relative to the last match plus the offset * contained within the current pmd * * dlen = amount of data in the packet from the base_ptr to the end of the packet * * pmd = the patterm match data struct for this test */static inline int computeWithin(int dlen, PatternMatchData *pmd){ /* do we want to check more bytes than there are in the buffer? */ if(pmd->within > dlen) { /* should we just return -1 here since the data might actually be within * the stream but not the current packet's payload? */ /* if the buffer size is greater than the size of the pattern to match */ if(dlen >= (int)pmd->pattern_size) { /* return the size of the buffer */ return dlen; } else { /* failed, pattern size is greater than number of bytes in the buffer */ return -1; } } /* the within vaule is in range of the number of buffer bytes */ return pmd->within;}#if 0/* not in use - delete? */static int uniSearchREG(char * data, int dlen, PatternMatchData * pmd){ int depth = computeDepth(dlen, pmd); /* int distance_adjustment = 0; * int depth_adjustment = 0; */ int success = 0; if (depth < 0) return 0; /* XXX DESTROY ME */ /*success = mSearchREG(data + pmd->offset + distance_adjustment, depth_adjustment!=0?depth_adjustment:depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride);*/ return success;}#endif/* * case sensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct */static int uniSearch(const char *data, int dlen, PatternMatchData *pmd){ return uniSearchReal(data, dlen, pmd, 0);}/* * case insensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct */static int uniSearchCI(const char *data, int dlen, PatternMatchData *pmd){ return uniSearchReal(data, dlen, pmd, 1);}/* * single search function. * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct * nocase = 0 means case sensitve, 1 means case insensitive * * return 1 for found * return 0 for not found * return -1 for error (search out of bounds) */ static int uniSearchReal(const char *data, int dlen, PatternMatchData *pmd, int nocase){ /* * in theory computeDepth doesn't need to be called because the * depth + offset adjustments have been made by the calling function */ int depth = dlen; int old_depth = dlen; int success = 0; const char *start_ptr = data; const char *end_ptr = data + dlen; const char *base_ptr = start_ptr; DEBUG_WRAP(char *hexbuf;); if(pmd->use_doe != 1) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "NOT Using Doe Ptr\n");); doe_ptr = NULL; /* get rid of all our pattern match state */ } /* check to see if we've got a stateful start point */ if(doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Doe Ptr\n");); base_ptr = (const char *)doe_ptr; depth = dlen - ((char *) doe_ptr - data); } else { base_ptr = start_ptr; depth = dlen; } /* if we're using a distance call */ if(pmd->distance) { /* set the base pointer up for the distance */ base_ptr += pmd->distance; depth -= pmd->distance; } else /* otherwise just use the offset (validated by calling function) */ { base_ptr += pmd->offset; depth -= pmd->offset; } if(pmd->within != 0) { /* * calculate the "real" depth based on the current base and available * number of bytes in the buffer * * this should account for the current base_ptr as it relates to * the back of the buffer being tested */ old_depth = depth; depth = computeWithin(depth, pmd); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Changing Depth from %d to %d\n", old_depth, depth);); } /* make sure we and in range */ if(!inBounds((const u_int8_t *)start_ptr, (const u_int8_t *)end_ptr, (const u_int8_t *)base_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because base_ptr" " is out of bounds start_ptr: %p end: %p base: %p\n", start_ptr, end_ptr, base_ptr);); return -1; } if(depth < 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because depth is negative (%d)\n", depth);); return -1; } if(depth > dlen) { /* if offsets are negative but somehow before the start of the packet, let's make sure that we get everything going straight */ depth = dlen; } if((pmd->depth > 0) && (depth > pmd->depth)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting new depth to %d from %d\n", pmd->depth, depth);); depth = pmd->depth; } /* make sure we end in range */ if(!inBounds((const u_int8_t *)start_ptr, (const u_int8_t *)end_ptr, (const u_int8_t *)(base_ptr + depth - 1))) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because base_ptr + depth - 1" " is out of bounds start_ptr: %p end: %p base: %p\n", start_ptr, end_ptr, base_ptr);); return 0; }#ifdef DEBUG assert(depth <= old_depth); DebugMessage(DEBUG_PATTERN_MATCH, "uniSearchReal:\n "); hexbuf = hex((u_char *)pmd->pattern_buf, pmd->pattern_size); DebugMessage(DEBUG_PATTERN_MATCH, " p->data: %p\n doe_ptr: %p\n " "base_ptr: %p\n depth: %d\n searching for: %s\n", data, doe_ptr, base_ptr, depth, hexbuf); free(hexbuf);#endif /* DEBUG */ if(nocase) { success = mSearchCI(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); } else { success = mSearch(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); }#ifdef DEBUG if(success) { DebugMessage(DEBUG_PATTERN_MATCH, "matched, doe_ptr: %p (%d)\n", doe_ptr, ((char *)doe_ptr - data)); }#endif return success;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -