enum proto_parse_status cursor_read_fixed_int_le(struct cursor *cursor, uint_least64_t *out_res, unsigned len) { uint_least64_t res; if (cursor->cap_len < len) return PROTO_TOO_SHORT; switch (len) { case 0: res = 0; break; case 1: res = cursor_read_u8(cursor); break; case 2: res = cursor_read_u16le(cursor); break; case 3: res = cursor_read_u24le(cursor); break; case 4: res = cursor_read_u32le(cursor); break; case 8: res = cursor_read_u64le(cursor); break; default: SLOG(LOG_DEBUG, "Can't read a %d bytes long number", len); return PROTO_PARSE_ERR; } if (out_res) *out_res = res; return PROTO_OK; }
// | 1 byte | 1 byte | 2 bytes | 4 bytes | 4 bytes | 4 bytes | // | SMID (0x53) | Flag | SID | Length | Seq num | Window | static enum proto_parse_status tds_parse_smp_header(struct cursor *cursor, struct smp_header *out_header) { # define SMP_PKT_HDR_LEN 0x10 # define SMP_SMID 0x53 if (cursor_peek_u8(cursor, 0) == SMP_SMID) { CHECK_LEN(cursor, SMP_PKT_HDR_LEN, 0); cursor_drop(cursor, 1); out_header->flags = cursor_read_u8(cursor); out_header->sid = cursor_read_u16le(cursor); out_header->length = cursor_read_u32le(cursor); out_header->seq_num = cursor_read_u32le(cursor); out_header->window = cursor_read_u32le(cursor); } return PROTO_OK; }
static enum proto_parse_status tns_parse_login_property(struct sql_proto_info *info, struct cursor *cursor) { SLOG(LOG_DEBUG, "Parsing tns login property"); // We are only interested in response if (info->is_query) return PROTO_OK; if (info->msg_type != SQL_UNKNOWN && info->msg_type != SQL_STARTUP) return PROTO_PARSE_ERR; // Drop Server version DROP_FIX(cursor, 3); // Drop Server version text uint8_t marker = 0x00; enum proto_parse_status status = cursor_drop_until(cursor, &marker, sizeof(marker)); if (status != PROTO_OK) return status; // Drop Null byte DROP_FIX(cursor, 1); CHECK(2); uint16_t charset = cursor_read_u16le(cursor); SLOG(LOG_DEBUG, "Found a charset of 0x%02x", charset); switch (charset) { case 0x01: case 0x02: case 0x1f: case 0xb2: sql_set_encoding(info, SQL_ENCODING_LATIN1); break; case 0x366: case 0x367: case 0x369: sql_set_encoding(info, SQL_ENCODING_UTF8); break; default: SLOG(LOG_DEBUG, "Unknown charset"); break; } // We don't care of the rest... cursor_drop(cursor, cursor->cap_len); return PROTO_OK; }
uint_least32_t cursor_read_u32le(struct cursor *cursor) { uint_least32_t a = cursor_read_u16le(cursor); uint_least32_t b = cursor_read_u16le(cursor); return a | (b << 16); }