From ecf389483b64f2f66d880114bf95c850c6dd045f Mon Sep 17 00:00:00 2001 From: Michael Tuexen <tuexen@fh-muenster.de> Date: Fri, 13 Oct 2017 21:07:07 +0200 Subject: [PATCH] Improve support for partial TLVs. --- gtests/net/packetdrill/packet_to_string.c | 6 ++- gtests/net/packetdrill/run_packet.c | 39 ++++++++++++++--- gtests/net/packetdrill/sctp_chunk_to_string.c | 42 +++++++++++++++---- gtests/net/packetdrill/sctp_iterator.c | 20 ++++----- 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/gtests/net/packetdrill/packet_to_string.c b/gtests/net/packetdrill/packet_to_string.c index c40738af..1e3fb6ff 100644 --- a/gtests/net/packetdrill/packet_to_string.c +++ b/gtests/net/packetdrill/packet_to_string.c @@ -155,8 +155,12 @@ static int sctp_packet_to_string(FILE *s, struct packet *packet, int i, fputc(' ', s); else fputs("; ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_chunk_to_string(s, chunk, error); assert(result != STATUS_OK || *error == NULL); if (result != STATUS_OK) diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index e1bd279f..bfdb99e5 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -679,6 +679,7 @@ static int map_inbound_sctp_packet( bool reflect_v_tag; bool contains_init_chunk; + assert(*error == NULL); reflect_v_tag = false; contains_init_chunk = false; /* Map the TSNs and the initiate tags in the INIT and INIT-ACK chunk */ @@ -686,7 +687,10 @@ static int map_inbound_sctp_packet( chunk != NULL; chunk = sctp_chunks_next(&iter, error)) { if (*error != NULL) { - return STATUS_ERR; + DEBUGP("Partial chunk detected\n"); + free(*error); + *error = NULL; + return STATUS_OK; } DEBUGP("live remote tsn 0x%08x, script remote tsn 0x%08x\n", socket->live.remote_initial_tsn, socket->script.remote_initial_tsn); @@ -792,6 +796,12 @@ static int map_inbound_sctp_packet( &iter, error); parameter != NULL; parameter = sctp_parameters_next(&iter, error)) { + if (*error != NULL) { + DEBUGP("Partial parameter detected\n"); + free(*error); + *error = NULL; + break; + } switch (htons(parameter->type)) { case SCTP_OUTGOING_SSN_RESET_REQUEST_PARAMETER_TYPE: { struct sctp_outgoing_ssn_reset_request_parameter *reset; @@ -1005,12 +1015,15 @@ static int map_outbound_live_sctp_packet( u32 local_diff, remote_diff; u16 nr_gap_blocks, nr_dup_tsns, number_of_nr_gap_blocks, i; + assert(*error == NULL); /* FIXME: transform v-tag in the common header*/ DEBUGP("map_outbound_live_sctp_packet\n"); for (chunk = sctp_chunks_begin(actual_packet, &iter, error); chunk != NULL; chunk = sctp_chunks_next(&iter, error)) { if (*error != NULL) { + free(*error); + asprintf(error, "Partial chunk for outbound packet");; return STATUS_ERR; } local_diff = socket->script.local_initial_tsn - socket->live.local_initial_tsn; @@ -1092,6 +1105,11 @@ static int map_outbound_live_sctp_packet( &iter, error); parameter != NULL; parameter = sctp_parameters_next(&iter, error)) { + if (*error != NULL) { + free(*error); + asprintf(error, "Partial parameter for outbound packet");; + return STATUS_ERR; + } switch (htons(parameter->type)) { case SCTP_OUTGOING_SSN_RESET_REQUEST_PARAMETER_TYPE: { struct sctp_outgoing_ssn_reset_request_parameter *reset; @@ -1464,7 +1482,8 @@ static int verify_sctp_parameters(u8 *begin, u16 length, actual_parameter = sctp_parameters_next(&iter, error), script_parameter_item = script_parameter_item->next) { if (*error != NULL) { - DEBUGP("Error during iteration\n"); + free(*error); + asprintf(error, "Partial parameter for outbound packet");; return STATUS_ERR; } script_parameter = script_parameter_item->parameter; @@ -1676,7 +1695,8 @@ static int verify_sctp_causes(struct sctp_chunk *chunk, u16 offset, actual_cause = sctp_causes_next(&iter, error), script_cause_item = script_cause_item->next) { if (*error != NULL) { - DEBUGP("Error during iteration\n"); + free(*error); + asprintf(error, "Partial cause for outbound packet");; return STATUS_ERR; } script_cause = script_cause_item->cause; @@ -2358,7 +2378,8 @@ static int verify_sctp( actual_chunk = sctp_chunks_next(&iter, error), script_chunk_item = script_chunk_item->next) { if (*error != NULL) { - DEBUGP("Error during iteration\n"); + free(*error); + asprintf(error, "Partial chunk for outbound packet");; return STATUS_ERR; } script_chunk = script_chunk_item->chunk; @@ -3079,8 +3100,11 @@ static int do_outbound_script_packet( for (chunk = sctp_chunks_begin(live_packet, &chunk_iter, error); chunk != NULL; chunk = sctp_chunks_next(&chunk_iter, error)) { - if (*error != NULL) + if (*error != NULL) { + free(*error); + asprintf(error, "Partial chunk for outbound packet");; goto out; + } if ((socket->state == SOCKET_PASSIVE_PACKET_RECEIVED) && (chunk->type == SCTP_INIT_ACK_CHUNK_TYPE)) { chunk_length = ntohs(chunk->length); @@ -3096,8 +3120,11 @@ static int do_outbound_script_packet( ¶m_iter, error); parameter != NULL; parameter = sctp_parameters_next(¶m_iter, error)) { - if (*error != NULL) + if (*error != NULL) { + free(*error); + asprintf(error, "Partial parameter for outbound packet");; goto out; + } if (ntohs(parameter->type) == SCTP_STATE_COOKIE_PARAMETER_TYPE) { state_cookie = (struct sctp_state_cookie_parameter *)parameter; parameter_length = ntohs(state_cookie->length); diff --git a/gtests/net/packetdrill/sctp_chunk_to_string.c b/gtests/net/packetdrill/sctp_chunk_to_string.c index 3ae8e2d1..fa809a80 100644 --- a/gtests/net/packetdrill/sctp_chunk_to_string.c +++ b/gtests/net/packetdrill/sctp_chunk_to_string.c @@ -902,8 +902,12 @@ static int sctp_unrecognized_parameters_cause_to_string( parameter = sctp_parameters_next(&iter, error)) { if (index > 0) fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_parameter_to_string(s, parameter, error); if (result != STATUS_OK) break; @@ -977,8 +981,12 @@ static int sctp_restart_with_new_addresses_cause_to_string( parameter = sctp_parameters_next(&iter, error)) { if (index > 0) fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_parameter_to_string(s, parameter, error); if (result != STATUS_OK) break; @@ -1190,8 +1198,12 @@ static int sctp_init_chunk_to_string(FILE *s, parameter != NULL; parameter = sctp_parameters_next(&iter, error)) { fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_parameter_to_string(s, parameter, error); if (result != STATUS_OK) break; @@ -1231,8 +1243,12 @@ static int sctp_init_ack_chunk_to_string(FILE *s, parameter != NULL; parameter = sctp_parameters_next(&iter, error)) { fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_parameter_to_string(s, parameter, error); if (result != STATUS_OK) break; @@ -1428,8 +1444,12 @@ static int sctp_abort_chunk_to_string(FILE *s, cause != NULL; cause = sctp_causes_next(&iter, error)) { fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_cause_to_string(s, cause, error); if (result != STATUS_OK) break; @@ -1499,8 +1519,12 @@ static int sctp_error_chunk_to_string(FILE *s, cause != NULL; cause = sctp_causes_next(&iter, error)) { fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_cause_to_string(s, cause, error); if (result != STATUS_OK) break; @@ -1694,8 +1718,12 @@ static int sctp_reconfig_chunk_to_string( parameter != NULL; parameter = sctp_parameters_next(&iter, error)) { fputs(", ", s); - if (*error != NULL) + if (*error != NULL) { + fputs(*error, s); + free(*error); + *error = NULL; break; + } result = sctp_parameter_to_string(s, parameter, error); if (result != STATUS_OK) break; diff --git a/gtests/net/packetdrill/sctp_iterator.c b/gtests/net/packetdrill/sctp_iterator.c index b4df6d5c..4194a196 100644 --- a/gtests/net/packetdrill/sctp_iterator.c +++ b/gtests/net/packetdrill/sctp_iterator.c @@ -40,16 +40,14 @@ static struct sctp_chunk *get_current_chunk(struct sctp_chunks_iterator *iter, iter->current_chunk = NULL; else if (iter->current_chunk + sizeof(struct sctp_chunk) > iter->packet_end) { - asprintf(error, "Partial SCTP chunk not allowed"); - iter->current_chunk = NULL; + asprintf(error, "CHUNK[too short]"); } else { chunk = (struct sctp_chunk *)iter->current_chunk; chunk_length = ntohs(chunk->length); if (iter->current_chunk + chunk_length > iter->packet_end) { asprintf(error, - "Partial SCTP chunk (type 0x%02x, length %u) not allowed", - chunk->type, chunk_length); - iter->current_chunk = NULL; + "CHUNK[type=0x%02x, flgs=0x%02x, len=%u (partital!)]", + chunk->type, chunk->type, chunk_length); } } return (struct sctp_chunk *)iter->current_chunk; @@ -99,16 +97,14 @@ get_current_parameter(struct sctp_parameters_iterator *iter, iter->current_parameter = NULL; else if (iter->current_parameter + sizeof(struct sctp_parameter) > iter->end) { - asprintf(error, "Partial SCTP parameter not allowed"); - iter->current_parameter = NULL; + asprintf(error, "PARAMETER[too short]"); } else { parameter = (struct sctp_parameter *)iter->current_parameter; parameter_length = ntohs(parameter->length); if (iter->current_parameter + parameter_length > iter->end) { asprintf(error, - "Partial SCTP parameter (type 0x%04x, length %u) not allowed", + "PARAMETER[type=0x%04x, len=%u (partial!)]", ntohs(parameter->type), parameter_length); - iter->current_parameter = NULL; } } return (struct sctp_parameter *)iter->current_parameter; @@ -160,16 +156,14 @@ static struct sctp_cause *get_current_cause(struct sctp_causes_iterator *iter, iter->current_cause = NULL; else if (iter->current_cause + sizeof(struct sctp_cause) > iter->chunk_end) { - asprintf(error, "Partial SCTP cause not allowed"); - iter->current_cause = NULL; + asprintf(error, "CAUSE[too short]"); } else { cause = (struct sctp_cause *)iter->current_cause; cause_length = ntohs(cause->length); if (iter->current_cause + cause_length > iter->chunk_end) { asprintf(error, - "Partial SCTP cause (code 0x%04x, length %u) not allowed", + "CAUSE[code=0x%04x, len=%u (partial!)]", ntohs(cause->code), cause_length); - iter->current_cause = NULL; } } return (struct sctp_cause *)iter->current_cause; -- GitLab