char const *tds_info_2_str(struct proto_info const *info_) { struct tds_proto_info const *info = DOWNCAST(info_, info, tds_proto_info); char *str = tempstr_printf("%s, type=%s, status=0x%x, length=%"PRIu16"", proto_info_2_str(info_), tds_packet_type_2_str(info->type), info->status, info->length); return str; }
static enum proto_parse_status tds_parse_header(struct cursor *cursor, struct tds_header *out_header, bool *unknown_token) { # define TDS_PKT_HDR_LEN 8 CHECK_LEN(cursor, TDS_PKT_HDR_LEN, 0); struct tds_header header; header.type = cursor_read_u8(cursor); header.status = cursor_read_u8(cursor); header.len = cursor_read_u16n(cursor); header.channel = cursor_read_u16n(cursor); header.pkt_number = cursor_read_u8(cursor); header.window = cursor_read_u8(cursor); SLOG(LOG_DEBUG, "Reading new TDS packet %s", tds_header_2_str(&header)); // sanity check if (header.len < TDS_PKT_HDR_LEN) return PROTO_PARSE_ERR; switch (header.type) { case TDS_PKT_TYPE_SQL_BATCH: case TDS_PKT_TYPE_LOGIN: case TDS_PKT_TYPE_RPC: case TDS_PKT_TYPE_RESULT: case TDS_PKT_TYPE_ATTENTION: case TDS_PKT_TYPE_BULK_LOAD: case TDS_PKT_TYPE_MANAGER_REQ: case TDS_PKT_TYPE_TDS7_LOGIN: case TDS_PKT_TYPE_SSPI: case TDS_PKT_TYPE_PRELOGIN: break; default: SLOG(LOG_DEBUG, "Unknown tds type %u", header.type); if (unknown_token) *unknown_token = true; return PROTO_PARSE_ERR; } if (header.window != 0) { SLOG(LOG_DEBUG, "Window is %"PRIu8" instead of 0", header.window); return PROTO_PARSE_ERR; } size_t data_left = header.len - TDS_PKT_HDR_LEN; if ((data_left > 0) != tds_packet_has_data(header.type)) { SLOG(LOG_DEBUG, "This TDS packet of type %s has %zu bytes of data, but should%s have data", tds_packet_type_2_str(header.type), data_left, tds_packet_has_data(header.type) ? "":" not"); return PROTO_PARSE_ERR; } if (out_header) *out_header = header; return PROTO_OK; }
static char const *tds_header_2_str(struct tds_header *header) { return tempstr_printf("Type: %s, Status: %d, Length: %zu, Channel %"PRIu16", Pkt number %"PRIu8", Window %"PRIu8"", tds_packet_type_2_str(header->type), header->status, header->len, header->channel, header->pkt_number, header->window); }