static int ParseTNSPktHdr(TNSPktHeader *hdr, uint8_t *in, uint32_t len) { uint8_t *p = in; uint16_t res = 0; if (ByteExtractUint16(&res, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); hdr->length = res; p += 2; if (ByteExtractUint16(&res, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); hdr->chksum = res; p += 2; hdr->type = *p; ++p; hdr->reserved = *p; ++p; if (ByteExtractUint16(&res, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); hdr->hdr_chksum = res; return 0; }
static int ByteTest02 (void) { uint16_t val = 0x0102; uint16_t i16 = 0xbfbf; uint8_t bytes[2] = { 0x01, 0x02 }; int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes); if ((ret == 2) && (i16 == val)) { return 1; } return 0; }
/** * \brief Function to parse the TLS field in packet received from the server * * \param tls_state Pointer the state in which the value to be stored * \param pstate Application layer tarser state for this session * \param input Pointer the received input data * \param input_len Length in bytes of the received data * \param output Pointer to the list of parsed output elements */ static int TLSParseServerRecord(Flow *f, void *tls_state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, AppLayerParserResult *output) { SCEnter(); if (input_len >= 7) { if (SSLParseServerRecord(f, tls_state, pstate, input, input_len, output) == 1) { SCLogDebug("it seems the ssl version 2 is detected"); SCReturnInt(1); } } SCLogDebug("tls_state %p, pstate %p, input %p,input_len %" PRIu32 "", tls_state, pstate, input, input_len); //PrintRawDataFp(stdout, input,input_len); uint16_t max_fields = 3; int16_t u = 0; uint32_t offset = 0; if (pstate == NULL) SCReturnInt(-1); for (u = pstate->parse_field; u < max_fields; u++) { SCLogDebug("u %" PRIu32 "", u); switch(u % 3) { case 0: /* TLS CONTENT TYPE */ { uint8_t *data = input + offset; uint32_t data_len = input_len - offset; int r = AlpParseFieldBySize(output, pstate, TLS_FIELD_SERVER_CONTENT_TYPE, /* single byte field */1, data, data_len, &offset); SCLogDebug("r = %" PRId32 "", r); if (r == 0) { pstate->parse_field = 0; SCReturnInt(0); } else if (r == -1) { SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, " "r %d", r); SCReturnInt(-1); } break; } case 1: /* TLS VERSION */ { uint8_t *data = input + offset; uint32_t data_len = input_len - offset; int r = AlpParseFieldBySize(output, pstate, TLS_FIELD_SERVER_VERSION,/* 2 byte *field */2, data, data_len, &offset); if (r == 0) { pstate->parse_field = 1; SCReturnInt(0); } else if (r == -1) { SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, " "r %d", r); SCReturnInt(-1); } break; } case 2: /* TLS Record Message Length */ { uint8_t *data = input + offset; uint32_t data_len = input_len - offset; int r = AlpParseFieldBySize(output, pstate, TLS_FIELD_LENGTH, /* 2 byte field */2, data, data_len, &offset); if (r == 0) { pstate->parse_field = 2; SCReturnInt(0); } else if (r == -1) { SCLogError(SC_ERR_ALPARSER, "AlpParseFieldBySize failed, " "r %d", r); SCReturnInt(-1); } /* Parsing of the record is done. Since we may have more than * one record, we check here if we still have data left *after* * this record. In that case setup the parser to parse that * record as well. */ uint16_t record_len; int ret = ByteExtractUint16(&record_len, BYTE_BIG_ENDIAN, output->tail->data_len, output->tail->data_ptr); if (ret != 2) { SCReturnInt(-1); } /* calulate the point up to where the current record * is in the data */ uint32_t record_offset = (offset + record_len); SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len" " %"PRIu16")", record_offset, offset, record_len); /* if our input buffer is bigger than the data up to and * including the current record, we instruct the parser to * expect another record of 3 fields */ if (input_len <= record_offset) break; max_fields += 3; offset += record_len; break; } } } pstate->parse_field = 0; SCReturnInt(1); }
static int ParseTNSConnectPkt(TNSState *s, uint8_t *in, uint32_t len, TNSPktHeader *hdr) { /* * @service_option: * ____ * |15| * |14| * |13| -> broken connect notify * |12| -> pkt checksum * |11| -> hdr checksum * |10| -> full duplex * |09| -> half duplex * |08| -> don't care * |07| -> don't care * |06| -> * |05| -> * |04| -> direct IO to transport * |03| -> attention processing * |02| -> can receive attention * |01| -> can send attention * |00| * ---- * * @nt_protocol_characters: * ____ * |15| -> hangon to listener connec * |14| -> confirmed release * |13| -> TDU based IO * |12| -> spawner running * |11| -> data test * |10| -> callback IO support * |09| -> async IO support * |08| -> packet oriented IO * |07| -> can grant connection to another * |06| -> can handoff connection to another * |05| -> generate SIGIO signal * |04| -> generate SIGPIPE signal * |03| -> generate SIGURG signal * |02| -> urgent IO support * |01| -> full duplex IO support * |00| -> test operation * ---- * * @conn_flag: * ___ * |07| -> * |06| -> * |05| -> * |04| -> NA service required * |03| -> NA service linked in * |02| -> NA service enabled * |01| -> interchange is involved * |00| -> NA service wanted * ---- */ struct tns_conn_ { uint16_t version, version_compatible; short service_option; uint16_t session_data_unit_size, max_transmission_data_unit_size; short nt_protocol_characters; uint16_t line_turnaround, val_of_1_in_hardware, length_of_connect_data, offset_to_connect_data; uint32_t max_recv_conn_data; /* they seem the same value in wireshark */ uint8_t conn_flag0, conn_flag1; uint32_t trace_cross_facility_item0, trace_cross_facility_item1; uint64_t trace_unique_conn_id; char *conn_data; } conn; if (ByteExtractUint16(&conn.version, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.version_compatible, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16((uint16_t *)&conn.service_option, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.session_data_unit_size, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.max_transmission_data_unit_size, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16((uint16_t *)&conn.nt_protocol_characters, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.line_turnaround, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.val_of_1_in_hardware, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.length_of_connect_data, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint16(&conn.offset_to_connect_data, BYTE_LITTLE_ENDIAN, 2, p) <= 0) SCReturnInt(-1); p += 2; if (ByteExtractUint32(&conn.max_recv_conn_data, BYTE_LITTLE_ENDIAN, 4, p) <= 0) SCReturnInt(-1); p += 4; conn.conn_flag0 = *p; ++p; conn.conn_flag1 = *p; ++p; if (ByteExtractUint32(&conn.trace_cross_facility_item0, BYTE_LITTLE_ENDIAN, 4, p) <= 0) SCReturnInt(-1); p += 4; if (ByteExtractUint32(&conn.trace_cross_facility_item1, BYTE_LITTLE_ENDIAN, 4, p) <= 0) SCReturnInt(-1); p += 4; if (ByteExtractUint64(&conn.trace_unique_conn_id, BYTE_LITTLE_ENDIAN, 8, p) <= 0) SCReturnInt(-1); p += 8; conn.conn_data = SCCalloc(conn.length_of_connect_data + 1); if (conn.conn_data == NULL) SCReturnInt(-1); memcpy(conn.conn_data, input + conn.offset_to_connect_data, conn.length_of_connect_data); /* if we need the conn, just attach to @s */ /* we may offer some parse on @conn_data to retrieve more info about the connection */ s->conn_data = conn.conn_data; s->cur_tx->req_conn = 1; return 0; }