Skip to content
Snippets Groups Projects
Commit 943cc8f9 authored by Julian Cordes's avatar Julian Cordes
Browse files

fixes for support of generic init messages.

parent 08c32a46
No related branches found
No related tags found
No related merge requests found
...@@ -177,6 +177,11 @@ static struct packet *packet_copy_with_headroom(struct packet *old_packet, ...@@ -177,6 +177,11 @@ static struct packet *packet_copy_with_headroom(struct packet *old_packet,
packet->udplite = offset_ptr(old_base, new_base, old_packet->udplite); packet->udplite = offset_ptr(old_base, new_base, old_packet->udplite);
packet->icmpv4 = offset_ptr(old_base, new_base, old_packet->icmpv4); packet->icmpv4 = offset_ptr(old_base, new_base, old_packet->icmpv4);
packet->icmpv6 = offset_ptr(old_base, new_base, old_packet->icmpv6); packet->icmpv6 = offset_ptr(old_base, new_base, old_packet->icmpv6);
if (old_packet->chunk_list == NULL) {
packet->chunk_list = NULL;
return packet;
}
/* Go through the SCTP specific lists */ /* Go through the SCTP specific lists */
for (old_chunk_item = old_packet->chunk_list->first; for (old_chunk_item = old_packet->chunk_list->first;
......
...@@ -191,7 +191,7 @@ static struct socket *handle_listen_for_script_packet( ...@@ -191,7 +191,7 @@ static struct socket *handle_listen_for_script_packet(
*/ */
struct config *config = state->config; struct config *config = state->config;
struct socket *socket = state->socket_under_test; /* shortcut */ struct socket *socket = state->socket_under_test; /* shortcut */
struct sctp_init_chunk *init; u32 initiate_tag, initial_tsn;
struct sctp_chunk_list_item *item; struct sctp_chunk_list_item *item;
bool match = (direction == DIRECTION_INBOUND); bool match = (direction == DIRECTION_INBOUND);
...@@ -210,17 +210,42 @@ static struct socket *handle_listen_for_script_packet( ...@@ -210,17 +210,42 @@ static struct socket *handle_listen_for_script_packet(
} }
if (!match) if (!match)
return NULL; return NULL;
if (packet->sctp != NULL) { if (packet->sctp != NULL) {
assert(packet->chunk_list != NULL); if (packet->chunk_list != NULL) {
item = packet->chunk_list->first; item = packet->chunk_list->first;
if ((item != NULL) && if ((item != NULL) &&
(item->chunk->type == SCTP_INIT_CHUNK_TYPE)) { (item->chunk->type == SCTP_INIT_CHUNK_TYPE)) {
init = (struct sctp_init_chunk *)item->chunk; struct sctp_init_chunk *init = (struct sctp_init_chunk *)item->chunk;
} else { initiate_tag = ntohl(init->initiate_tag);
return NULL; initial_tsn = ntohl(init->initial_tsn);
} else {
return NULL;
}
}
else {
if (packet->flags & FLAGS_SCTP_GENERIC_PACKET) {
u8 *sctp_chunk_start = (u8 *) (packet->sctp + 1);
if (sctp_chunk_start[0] == SCTP_INIT_CHUNK_TYPE) {
u8 *initiate_tag_start = (u8 *) (sctp_chunk_start + 4);
u8 *initial_tsn_start = (u8 *) (sctp_chunk_start + 16);
initiate_tag = initiate_tag_start[3] << 24 | initiate_tag_start[2] << 16 | initiate_tag_start[1] << 8 | initiate_tag_start[0];
initial_tsn = initial_tsn_start[3] << 24 | initial_tsn_start[2] << 16 | initial_tsn_start[1] << 8 | initial_tsn_start[0];
initiate_tag = ntohl(initiate_tag);
initial_tsn = ntohl(initial_tsn);
}
else {
return NULL;
}
}
else {
return NULL;
}
} }
} }
else {
DEBUGP("packet->sctp == NULL");
}
/* Create a child passive socket for this incoming SYN packet. /* Create a child passive socket for this incoming SYN packet.
* Any further packets in the test script will be directed to * Any further packets in the test script will be directed to
...@@ -241,8 +266,8 @@ static struct socket *handle_listen_for_script_packet( ...@@ -241,8 +266,8 @@ static struct socket *handle_listen_for_script_packet(
if (packet->tcp != NULL) { if (packet->tcp != NULL) {
socket->script.remote_isn = ntohl(packet->tcp->seq); socket->script.remote_isn = ntohl(packet->tcp->seq);
} else { } else {
socket->script.remote_initiate_tag = ntohl(init->initiate_tag); socket->script.remote_initiate_tag = initiate_tag;
socket->script.remote_initial_tsn = ntohl(init->initial_tsn); socket->script.remote_initial_tsn = initial_tsn;
} }
socket->script.fd = -1; socket->script.fd = -1;
...@@ -256,8 +281,8 @@ static struct socket *handle_listen_for_script_packet( ...@@ -256,8 +281,8 @@ static struct socket *handle_listen_for_script_packet(
if (packet->tcp != NULL) { if (packet->tcp != NULL) {
socket->live.remote_isn = ntohl(packet->tcp->seq); socket->live.remote_isn = ntohl(packet->tcp->seq);
} else { } else {
socket->live.remote_initiate_tag = ntohl(init->initiate_tag); socket->live.remote_initiate_tag = initiate_tag;
socket->live.remote_initial_tsn = ntohl(init->initial_tsn); socket->live.remote_initial_tsn = initial_tsn;
} }
socket->live.fd = -1; socket->live.fd = -1;
...@@ -2508,93 +2533,95 @@ static int do_inbound_script_packet( ...@@ -2508,93 +2533,95 @@ static int do_inbound_script_packet(
} }
} }
if (packet->sctp) { if (packet->sctp) {
for (item = packet->chunk_list->first; if (packet->chunk_list != NULL) {
item != NULL; for (item = packet->chunk_list->first;
item = item->next) { item != NULL;
switch (item->chunk->type) { item = item->next) {
case SCTP_INIT_ACK_CHUNK_TYPE: switch (item->chunk->type) {
if (socket->state == SOCKET_ACTIVE_INIT_SENT) { case SCTP_INIT_ACK_CHUNK_TYPE:
init_ack = (struct sctp_init_ack_chunk *)item->chunk; if (socket->state == SOCKET_ACTIVE_INIT_SENT) {
DEBUGP("Moving socket in SOCKET_ACTIVE_INIT_ACK_RECEIVED\n"); init_ack = (struct sctp_init_ack_chunk *)item->chunk;
socket->state = SOCKET_ACTIVE_INIT_ACK_RECEIVED; DEBUGP("Moving socket in SOCKET_ACTIVE_INIT_ACK_RECEIVED\n");
socket->script.remote_initiate_tag = ntohl(init_ack->initiate_tag); socket->state = SOCKET_ACTIVE_INIT_ACK_RECEIVED;
socket->script.remote_initial_tsn = ntohl(init_ack->initial_tsn); socket->script.remote_initiate_tag = ntohl(init_ack->initiate_tag);
socket->live.remote_initiate_tag = ntohl(init_ack->initiate_tag); socket->script.remote_initial_tsn = ntohl(init_ack->initial_tsn);
socket->live.remote_initial_tsn = ntohl(init_ack->initial_tsn); socket->live.remote_initiate_tag = ntohl(init_ack->initiate_tag);
DEBUGP("remote_initiate_tag 0x%08x, remote_initial_tsn 0x%08x\n", ntohl(init_ack->initiate_tag), ntohl(init_ack->initial_tsn)); socket->live.remote_initial_tsn = ntohl(init_ack->initial_tsn);
} DEBUGP("remote_initiate_tag 0x%08x, remote_initial_tsn 0x%08x\n", ntohl(init_ack->initiate_tag), ntohl(init_ack->initial_tsn));
break;
case SCTP_COOKIE_ECHO_CHUNK_TYPE:
if (item->flags & FLAG_CHUNK_VALUE_NOCHECK) {
temp_offset = socket->prepared_cookie_echo_length - item->length;
assert(packet->ip_bytes + temp_offset <= packet->buffer_bytes);
memmove((u8 *)item->chunk + item->length + temp_offset,
(u8 *)item->chunk + item->length,
packet_end(packet) - ((u8 *)item->chunk + item->length));
memcpy(item->chunk,
socket->prepared_cookie_echo,
socket->prepared_cookie_echo_length);
item->length = socket->prepared_cookie_echo_length;
packet->buffer_bytes += temp_offset;
packet->ip_bytes += temp_offset;
if (packet->ipv4) {
packet->ipv4->tot_len = htons(ntohs(packet->ipv4->tot_len) + temp_offset);
}
if (packet->ipv6) {
packet->ipv6->payload_len = htons(ntohs(packet->ipv6->payload_len) + temp_offset);
} }
for (i = 0; i < PACKET_MAX_HEADERS; i++) { break;
if ((packet->ipv4 != NULL && packet->headers[i].h.ipv4 == packet->ipv4) || case SCTP_COOKIE_ECHO_CHUNK_TYPE:
(packet->ipv6 != NULL && packet->headers[i].h.ipv6 == packet->ipv6)) { if (item->flags & FLAG_CHUNK_VALUE_NOCHECK) {
break; temp_offset = socket->prepared_cookie_echo_length - item->length;
assert(packet->ip_bytes + temp_offset <= packet->buffer_bytes);
memmove((u8 *)item->chunk + item->length + temp_offset,
(u8 *)item->chunk + item->length,
packet_end(packet) - ((u8 *)item->chunk + item->length));
memcpy(item->chunk,
socket->prepared_cookie_echo,
socket->prepared_cookie_echo_length);
item->length = socket->prepared_cookie_echo_length;
packet->buffer_bytes += temp_offset;
packet->ip_bytes += temp_offset;
if (packet->ipv4) {
packet->ipv4->tot_len = htons(ntohs(packet->ipv4->tot_len) + temp_offset);
} }
if (packet->ipv6) {
packet->ipv6->payload_len = htons(ntohs(packet->ipv6->payload_len) + temp_offset);
}
for (i = 0; i < PACKET_MAX_HEADERS; i++) {
if ((packet->ipv4 != NULL && packet->headers[i].h.ipv4 == packet->ipv4) ||
(packet->ipv6 != NULL && packet->headers[i].h.ipv6 == packet->ipv6)) {
break;
}
}
assert(packet->headers[i + 1].type == HEADER_SCTP);
packet->headers[i].total_bytes += temp_offset;
packet->headers[i + 1].total_bytes += temp_offset;
offset += temp_offset;
} }
assert(packet->headers[i + 1].type == HEADER_SCTP); if (((packet->flags & FLAGS_SCTP_BAD_CRC32C) == 0) &&
packet->headers[i].total_bytes += temp_offset; (((packet->flags & FLAGS_SCTP_EXPLICIT_TAG) == 0) ||
packet->headers[i + 1].total_bytes += temp_offset; ((ntohl(packet->sctp->v_tag) == socket->script.local_initiate_tag) &&
offset += temp_offset; (socket->script.local_initiate_tag != 0)))) {
} socket->state = SOCKET_PASSIVE_COOKIE_ECHO_RECEIVED;
if (((packet->flags & FLAGS_SCTP_BAD_CRC32C) == 0) &&
(((packet->flags & FLAGS_SCTP_EXPLICIT_TAG) == 0) ||
((ntohl(packet->sctp->v_tag) == socket->script.local_initiate_tag) &&
(socket->script.local_initiate_tag != 0)))) {
socket->state = SOCKET_PASSIVE_COOKIE_ECHO_RECEIVED;
}
break;
case SCTP_HEARTBEAT_ACK_CHUNK_TYPE:
if (item->flags & FLAG_CHUNK_VALUE_NOCHECK) {
temp_offset = socket->prepared_heartbeat_ack_length - item->length;
assert(packet->ip_bytes + temp_offset <= packet->buffer_bytes);
memmove((u8 *)item->chunk + item->length + temp_offset,
(u8 *)item->chunk + item->length,
packet_end(packet) - ((u8 *)item->chunk + item->length));
memcpy(item->chunk,
socket->prepared_heartbeat_ack,
socket->prepared_heartbeat_ack_length);
item->length = socket->prepared_heartbeat_ack_length;
packet->buffer_bytes += temp_offset;
packet->ip_bytes += temp_offset;
if (packet->ipv4) {
packet->ipv4->tot_len = htons(ntohs(packet->ipv4->tot_len) + temp_offset);
}
if (packet->ipv6) {
packet->ipv6->payload_len = htons(ntohs(packet->ipv6->payload_len) + temp_offset);
} }
for (i = 0; i < PACKET_MAX_HEADERS; i++) { break;
if ((packet->ipv4 != NULL && packet->headers[i].h.ipv4 == packet->ipv4) || case SCTP_HEARTBEAT_ACK_CHUNK_TYPE:
(packet->ipv6 != NULL && packet->headers[i].h.ipv6 == packet->ipv6)) { if (item->flags & FLAG_CHUNK_VALUE_NOCHECK) {
break; temp_offset = socket->prepared_heartbeat_ack_length - item->length;
assert(packet->ip_bytes + temp_offset <= packet->buffer_bytes);
memmove((u8 *)item->chunk + item->length + temp_offset,
(u8 *)item->chunk + item->length,
packet_end(packet) - ((u8 *)item->chunk + item->length));
memcpy(item->chunk,
socket->prepared_heartbeat_ack,
socket->prepared_heartbeat_ack_length);
item->length = socket->prepared_heartbeat_ack_length;
packet->buffer_bytes += temp_offset;
packet->ip_bytes += temp_offset;
if (packet->ipv4) {
packet->ipv4->tot_len = htons(ntohs(packet->ipv4->tot_len) + temp_offset);
}
if (packet->ipv6) {
packet->ipv6->payload_len = htons(ntohs(packet->ipv6->payload_len) + temp_offset);
}
for (i = 0; i < PACKET_MAX_HEADERS; i++) {
if ((packet->ipv4 != NULL && packet->headers[i].h.ipv4 == packet->ipv4) ||
(packet->ipv6 != NULL && packet->headers[i].h.ipv6 == packet->ipv6)) {
break;
}
} }
assert(packet->headers[i + 1].type == HEADER_SCTP);
packet->headers[i].total_bytes += temp_offset;
packet->headers[i + 1].total_bytes += temp_offset;
offset += temp_offset;
} }
assert(packet->headers[i + 1].type == HEADER_SCTP); break;
packet->headers[i].total_bytes += temp_offset; default:
packet->headers[i + 1].total_bytes += temp_offset; item->chunk = (struct sctp_chunk *)((char *)item->chunk + offset);
offset += temp_offset; break;
} }
break;
default:
item->chunk = (struct sctp_chunk *)((char *)item->chunk + offset);
break;
} }
} }
} }
......
...@@ -1254,8 +1254,11 @@ void ...@@ -1254,8 +1254,11 @@ void
sctp_chunk_list_free(struct sctp_chunk_list *list) sctp_chunk_list_free(struct sctp_chunk_list *list)
{ {
struct sctp_chunk_list_item *current_item, *next_item; struct sctp_chunk_list_item *current_item, *next_item;
assert(list != NULL); if (list == NULL) {
return;
}
current_item = list->first; current_item = list->first;
while (current_item != NULL) { while (current_item != NULL) {
next_item = current_item->next; next_item = current_item->next;
...@@ -2683,7 +2686,7 @@ new_sctp_generic_packet(int address_family, ...@@ -2683,7 +2686,7 @@ new_sctp_generic_packet(int address_family,
sctp_chunk_start[i] = item->byte; sctp_chunk_start[i] = item->byte;
} }
packet->chunk_list = sctp_chunk_list_new(); packet->chunk_list = NULL;
packet->ip_bytes = ip_bytes; packet->ip_bytes = ip_bytes;
return packet; return packet;
} }
\ No newline at end of file
+0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
// Check the handshake with en empty(!) cookie
+0.0 bind(3, ..., ...) = 0
+0.0 listen(3, 1) = 0
+0.0 < sctp: [0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xDC, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01]
//+0.0 < sctp: INIT[flgs=0, tag=1, a_rwnd=1500, os=1, is=1, tsn=1]
+0.0 > sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=..., os=..., is=..., tsn=1, ...]
+0.1 < sctp: COOKIE_ECHO[flgs=0, len=..., val=...]
+0.0 > sctp: COOKIE_ACK[flgs=0]
+0.0 accept(3, ..., ...) = 4
// Tear down the association
+1.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
+0.0 > sctp: SHUTDOWN_ACK[flgs=0]
+0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
+0.0 close(4) = 0
+0.0 close(3) = 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment