📄 sf_snort_plugin_api.c
字号:
/* * sf_snort_plugin_api.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) 2005-2008 Sourcefire, Inc. * * Author: Steve Sturges * Andy Mullican * * Date: 5/2005 * * Dyanmic Rule Engine */#include "sf_snort_packet.h"#include "sf_snort_plugin_api.h"#include "sf_dynamic_engine.h"/* Need access to the snort-isms that were passed to the engine */extern DynamicEngineData _ded;/* * Get the start and end of the buffer, as divined by the packet flags. * This function is useful so that we don't have to figure out which buffer * we are looking at twice, if we want to check two offsets one after the other. * * return 1 if successful * return < 0 if unsuccessful */ENGINE_LINKAGE int getBuffer(void *packet, int flags, const u_int8_t **start, const u_int8_t **end){ SFSnortPacket *p = (SFSnortPacket *)packet; if ((flags & CONTENT_BUF_NORMALIZED) && (p->flags & FLAG_ALT_DECODE)) { *start = _ded.altBuffer; *end = *start + p->normalized_payload_size; } else if ((flags & CONTENT_BUF_RAW) || (flags & CONTENT_BUF_NORMALIZED)) { *start = p->payload; *end = *start + p->payload_size; } else if (flags & CONTENT_BUF_URI) { if (p->flags & FLAG_HTTP_DECODE) { *start = _ded.uriBuffers[HTTP_BUFFER_URI]->uriBuffer; *end = *start + _ded.uriBuffers[HTTP_BUFFER_URI]->uriLength; } else { return CONTENT_TYPE_MISMATCH; } } else if (flags & CONTENT_BUF_HEADER) { if (p->flags & FLAG_HTTP_DECODE) { *start = _ded.uriBuffers[HTTP_BUFFER_HEADER]->uriBuffer; *end = *start + _ded.uriBuffers[HTTP_BUFFER_HEADER]->uriLength; } else { return CONTENT_TYPE_MISMATCH; } } else if (flags & CONTENT_BUF_POST) { if (p->flags & FLAG_HTTP_DECODE) { *start = _ded.uriBuffers[HTTP_BUFFER_CLIENT_BODY]->uriBuffer; *end = *start + _ded.uriBuffers[HTTP_BUFFER_CLIENT_BODY]->uriLength; } else { return CONTENT_TYPE_MISMATCH; } } else if (flags & CONTENT_BUF_METHOD) { if (p->flags & FLAG_HTTP_DECODE) { *start = _ded.uriBuffers[HTTP_BUFFER_METHOD]->uriBuffer; *end = *start + _ded.uriBuffers[HTTP_BUFFER_METHOD]->uriLength; } else { return CONTENT_TYPE_MISMATCH; } } else if (flags & CONTENT_BUF_COOKIE) { if (p->flags & FLAG_HTTP_DECODE) { *start = _ded.uriBuffers[HTTP_BUFFER_COOKIE]->uriBuffer; *end = *start + _ded.uriBuffers[HTTP_BUFFER_COOKIE]->uriLength; } else { return CONTENT_TYPE_MISMATCH; } } else { return CONTENT_TYPE_MISSING; } return CURSOR_IN_BOUNDS;}int checkCursorSimple(const u_int8_t *cursor, int flags, const u_int8_t *start, const u_int8_t *end, int32_t offset){ if ( cursor == NULL || !(flags & CONTENT_RELATIVE) ) cursor = start; if ((cursor + offset < end) && (cursor + offset >= start)) return CURSOR_IN_BOUNDS; return CURSOR_OUT_OF_BOUNDS;}/* Returns one if cursor is within the buffer */int checkCursorInternal(void *p, int flags, int32_t offset, const u_int8_t *cursor){ const u_int8_t *start; const u_int8_t *end; int ret; SFSnortPacket *sp = (SFSnortPacket *) p; ret = getBuffer(sp, flags, &start, &end); if ( ret < 0 ) { return ret; } return checkCursorSimple(cursor, flags, start, end, offset);}int setCursorInternal(void *p, int flags, int32_t offset, const u_int8_t **cursor){ const u_int8_t *start; const u_int8_t *end; int ret; SFSnortPacket *sp = (SFSnortPacket *) p; if(!cursor) { return RULE_NOMATCH; } ret = getBuffer(sp, flags, &start, &end); if ( ret < 0 ) { return ret; } if ( flags & JUMP_FROM_BEGINNING ) { ret = checkCursorSimple(start, flags, start, end, offset); } else { ret = checkCursorSimple(*cursor, flags, start, end, offset); } if ( ret <= 0 ) { return ret; } if ( flags & JUMP_FROM_BEGINNING ) { *cursor = start + offset; } else { if ( !(flags & CONTENT_RELATIVE) ) *cursor = start + offset; else if (cursor) *cursor += offset; else /* if not set, don't try to use it */ *cursor = start + offset; } return CURSOR_IN_BOUNDS;} /* API FUNCTIONS *//* * Check cursor function * * p: packet data structure, same as the one found in snort. * cursorInfo: data defined in the detection plugin for this rule cursor option * cursor: current position within buffer * * Returns: * > 0 : match found * = 0 : no match found * < 0 : error * * Predefined constants: * (see sf_snort_plugin_api.h for more values) * CURSOR_IN_BOUNDS - if content specifier is found within buffer * CURSOR_OUT_OF_BOUNDS - if content specifier is not found within buffer * * Notes: * Since we are checking the cursor position within a buffer, relativity is assumed. * To check absolute position within a buffer, a NULL pointer can be passed in. * In this case, offset will be checked from the start of the given buffer. * * Currently support: * options: * offset * buffers: * normalized(alt-decode) * raw * uri * */ENGINE_LINKAGE int checkCursor(void *p, CursorInfo* cursorInfo, const u_int8_t *cursor){ return checkCursorInternal(p, cursorInfo->flags, cursorInfo->offset, cursor);}/* * Set cursor function * * p: packet data structure, same as the one found in snort. * cursorInfo: data defined in the detection plugin for this rule cursor option * cursor: updated to point to offset bytes after the buffer start * * Returns: * > 0 : match found * = 0 : no match found * < 0 : error * * Predefined constants: * (see sf_snort_plugin_api.h for more values) * CURSOR_IN_BOUNDS - if content specifier is found within buffer * CURSOR_OUT_OF_BOUNDS - if content specifier is not found within buffer * * Notes: * * Currently support: * options: * offset * buffers: * normalized(alt-decode) * raw * uri * */ENGINE_LINKAGE int setCursor(void *p, CursorInfo* cursorInfo, const u_int8_t **cursor){ return setCursorInternal(p, cursorInfo->flags, cursorInfo->offset, cursor);}ENGINE_LINKAGE void setTempCursor(const u_int8_t **temp_cursor, const u_int8_t **cursor){ *temp_cursor = *cursor;}ENGINE_LINKAGE void revertTempCursor(const u_int8_t **temp_cursor, const u_int8_t **cursor){ *cursor = *temp_cursor;}/* * Check flow function * * p: packet data structure, same as the one found in snort. * flowFlags: data defined in the detection plugin for this rule option * * Returns: * > 0 : match found * = 0 : no match found * * Predefined constants: * (see sf_snort_plugin_api.h for more values) * RULE_MATCH - if packet flow matches rule * RULE_NOMATCH - if packet flow does not match rule * */ENGINE_LINKAGE int checkFlow(void *p, FlowFlags *flowFlags){ SFSnortPacket *sp = (SFSnortPacket *) p; if ((sp->flags & (flowFlags->flags & 0xFF)) != flowFlags->flags) return RULE_NOMATCH; if ((flowFlags->flags & FLOW_ONLY_REASSMBLED) && !(sp->flags & FLAG_REBUILT_STREAM)) return RULE_NOMATCH; if ((flowFlags->flags & FLOW_IGNORE_REASSEMBLED) && (sp->flags & FLAG_REBUILT_STREAM)) return RULE_NOMATCH; return RULE_MATCH;}/* * Process flowbits function * * p: packet data structure, same as the one found in snort. * flowBits: data defined in the detection plugin for this rule option * * Returns: * > 0 : match found * = 0 : no match found * * Predefined constants: * (see sf_snort_plugin_api.h for more values) * RULE_MATCH - if flowbit operation succeeded * RULE_NOMATCH - if flowbit operation failed * */ENGINE_LINKAGE int processFlowbits(void *p, FlowBitsInfo *flowBits){ /* flowbitCheck returns non-zero if the flow bit operation succeeded. */ if (_ded.flowbitCheck(p, flowBits->operation, flowBits->id)) return RULE_MATCH; return RULE_NOMATCH;}/* * Detect ASN1 function * * p: packet data structure, same as the one found in snort. * asn1: data defined in the detection plugin for this rule option * cursor: current position within buffer * * Returns: * > 0 : match found * = 0 : no match found * * Predefined constants: * (see sf_snort_plugin_api.h for more values) * RULE_MATCH - if asn1 specifier is found within buffer * RULE_NOMATCH - if asn1 specifier is not found within buffer * */ENGINE_LINKAGE int detectAsn1(void *p, Asn1Context* asn1, const u_int8_t *cursor){ /* asn1Detect returns non-zero if the options matched. */ if (_ded.asn1Detect(p, (void *) asn1, cursor)) return RULE_MATCH; return RULE_NOMATCH;}/* * Store Rule Specific session data * * p: packet data structure, same as the one found in snort. * rule_data: data to store in the session * * Returns: * nothing * */ENGINE_LINKAGE void storeRuleData(void *p, void *rule_data){ _ded.setRuleData(p, rule_data); }/* * Retrieve Rule Specific session data * * p: packet data structure, same as the one found in snort. * * Returns: * pointer to rule specific session data, NULL if none available * */ENGINE_LINKAGE void *getRuleData(void *p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -