int setCursorInternal(void *p, int flags, int offset, u_int8_t **cursor) { u_int8_t *start; 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; }
/* Returns one if cursor is within the buffer */ int checkCursorInternal(void *p, int flags, int offset, u_int8_t *cursor) { u_int8_t *start; 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); }
/* * extract byte value from data * * Return 1 if successfully extract value. * Return < 0 if fail to extract value. */ int extractValueInternal(void *p, ByteData *byteData, u_int32_t *value, u_int8_t *cursor) { char byteArray[BYTE_STRING_LEN]; u_int32_t i; char *endPtr; u_int32_t extracted = 0; int base = 10; u_int8_t *start; u_int8_t *end; int ret; SFSnortPacket *sp = (SFSnortPacket *) p; ret = getBuffer(sp, byteData->flags, &start, &end); if ( ret < 0 ) { return ret; } /* Check the start location */ if (checkCursorSimple(cursor, byteData->flags, start, end, byteData->offset) <= 0) return -1; /* and the end location */ if (checkCursorSimple(cursor, byteData->flags, start, end, byteData->offset + byteData->bytes - 1) <= 0) return -1; /* Extract can be from beginning of buffer, or relative to cursor */ if ( cursor == NULL || !(byteData->flags & CONTENT_RELATIVE) ) { cursor = start; } if (byteData->flags & EXTRACT_AS_BYTE) { if ( byteData->bytes != 1 && byteData->bytes != 2 && byteData->bytes != 4 ) { return -5; /* We only support 1, 2, or 4 bytes */ } if (byteData->bytes < 1 || byteData->bytes > 4) return -2; if ( byteData->flags & BYTE_BIG_ENDIAN ) { for (i = byteData->bytes; i > 0; i--) { extracted |= *(cursor + byteData->offset + byteData->bytes - i) << 8*(i-1); } } else { for (i = 0; i < byteData->bytes; i++) { extracted |= *(cursor + byteData->offset + i) << 8*i; } } *value = extracted; return 1; } else if (byteData->flags & EXTRACT_AS_STRING) { if (byteData->bytes < 1 || byteData->bytes > (BYTE_STRING_LEN - 1)) { /* Log Error message */ return -2; } if (byteData->flags & EXTRACT_AS_DEC) base = 10; else if (byteData->flags & EXTRACT_AS_HEX) base = 16; else if (byteData->flags & EXTRACT_AS_OCT) base = 8; else if (byteData->flags & EXTRACT_AS_BIN) base = 2; for (i=0;i<byteData->bytes;i++) { byteArray[i] = *(cursor + byteData->offset + i); } byteArray[i] = '\0'; extracted = strtoul(byteArray, &endPtr, base); if (endPtr == &byteArray[0]) return -3; /* Nothing to convert */ *value = extracted; return 1; } return -4; }
/* * extract byte value from data * * Return 1 if successfully extract value. * Return < 0 if fail to extract value. */ int extractValueInternal(void *p, ByteData *byteData, uint32_t *value, const uint8_t *cursor) { char byteArray[BYTE_STRING_LEN]; uint32_t i; char *endPtr; uint32_t extracted = 0; int base = 10; const uint8_t *start; const uint8_t *end; int ret; SFSnortPacket *sp = (SFSnortPacket *) p; ret = getBuffer(sp, byteData->flags, &start, &end); if ( ret < 0 ) { return ret; } /* Check for byte_extract variables and use them if present. */ if (byteData->offset_location) { byteData->offset = *byteData->offset_location; } if (byteData->value_location) { byteData->value = *byteData->value_location; } /* Check the start location */ if (checkCursorSimple(cursor, byteData->flags, start, end, byteData->offset) <= 0) return -1; /* and the end location */ if (checkCursorSimple(cursor, byteData->flags, start, end, byteData->offset + byteData->bytes - 1) <= 0) return -1; /* Extract can be from beginning of buffer, or relative to cursor */ if ( cursor == NULL || !(byteData->flags & CONTENT_RELATIVE) ) { cursor = start; } if (byteData->flags & EXTRACT_AS_BYTE) { if ( byteData->bytes != 1 && byteData->bytes != 2 && byteData->bytes != 4 ) { return -5; /* We only support 1, 2, or 4 bytes */ } if (byteData->bytes < 1 || byteData->bytes > 4) return -2; if ( byteData->flags & BYTE_BIG_ENDIAN ) { for (i = byteData->bytes; i > 0; i--) { extracted |= *(cursor + byteData->offset + byteData->bytes - i) << 8*(i-1); } } else { for (i = 0; i < byteData->bytes; i++) { extracted |= *(cursor + byteData->offset + i) << 8*i; } } *value = extracted; return 1; } else if (byteData->flags & EXTRACT_AS_STRING) { const uint8_t *space_ptr = cursor + byteData->offset; if (byteData->bytes < 1 || byteData->bytes > (BYTE_STRING_LEN - 1)) { /* Log Error message */ return -2; } // Only positive numbers should be processed and strtoul will // eat up white space and process '-' and '+' so move past // white space and check for a negative sign. while ((space_ptr < (cursor + byteData->offset + byteData->bytes)) && isspace((int)*space_ptr)) space_ptr++; // If all spaces or a negative sign is found, return error. if ((space_ptr == (cursor + byteData->offset + byteData->bytes)) || (*space_ptr == '-')) return -2; if (byteData->flags & EXTRACT_AS_DEC) base = 10; else if (byteData->flags & EXTRACT_AS_HEX) base = 16; else if (byteData->flags & EXTRACT_AS_OCT) base = 8; else if (byteData->flags & EXTRACT_AS_BIN) base = 2; for (i=0;i<byteData->bytes;i++) { byteArray[i] = *(cursor + byteData->offset + i); } byteArray[i] = '\0'; extracted = strtoul(byteArray, &endPtr, base); if (endPtr == &byteArray[0]) return -3; /* Nothing to convert */ *value = extracted; return 1; } return -4; }