From 3cb1a73636166dbbf5d1ec3f892b51a66496e10d Mon Sep 17 00:00:00 2001
From: Michael Tuexen <tuexen@fh-muenster.de>
Date: Thu, 17 Sep 2015 21:50:20 +0200
Subject: [PATCH] Add constructor for I-DATA chunks.

---
 gtests/net/packetdrill/sctp_packet.c | 76 ++++++++++++++++++++++++++++
 gtests/net/packetdrill/sctp_packet.h | 11 ++++
 2 files changed, 87 insertions(+)

diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c
index ac26f208..2ac76055 100644
--- a/gtests/net/packetdrill/sctp_packet.c
+++ b/gtests/net/packetdrill/sctp_packet.c
@@ -1097,6 +1097,82 @@ sctp_shutdown_complete_chunk_new(s64 flgs)
 	                                sctp_cause_list_new());
 }
 
+struct sctp_chunk_list_item *
+sctp_i_data_chunk_new(s64 flgs, s64 len, s64 tsn, s64 sid, s64 res, s64 mid,
+                      s64 ppid, s64 fsn)
+{
+	struct sctp_i_data_chunk *chunk;
+	u32 flags;
+	u16 length, padding_length;
+
+	flags = 0;
+	if (len == -1) {
+		length = (u16)sizeof(struct sctp_i_data_chunk);
+	} else {
+		length = (u16)len;
+	}
+	padding_length = length % 4;
+	if (padding_length > 0) {
+		padding_length = 4 - padding_length;
+	}
+	chunk = malloc(length + padding_length);
+	assert(chunk != NULL);
+	chunk->type = SCTP_I_DATA_CHUNK_TYPE;
+	if (flgs == -1) {
+		chunk->flags = 0;
+		flags |= FLAG_CHUNK_FLAGS_NOCHECK;
+	} else {
+		 chunk->flags = (u8)flgs;
+	}
+	chunk->length = htons(length);
+	if (len == -1) {
+		flags |= FLAG_CHUNK_LENGTH_NOCHECK;
+		flags |= FLAG_CHUNK_VALUE_NOCHECK;
+	}
+	if (tsn == -1) {
+		chunk->tsn = htonl(0);
+		flags |= FLAG_I_DATA_CHUNK_TSN_NOCHECK;
+	} else {
+		chunk->tsn = htonl((u32)tsn);
+	}
+	if (sid == -1) {
+		chunk->sid = htons(0);
+		flags |= FLAG_I_DATA_CHUNK_SID_NOCHECK;
+	} else {
+		chunk->sid = htons((u16)sid);
+	}
+	if (res == -1) {
+		chunk->res = htons(0);
+		flags |= FLAG_I_DATA_CHUNK_RES_NOCHECK;
+	} else {
+		chunk->res = htons((u16)res);
+	}
+	if (mid == -1) {
+		chunk->mid = htonl(0);
+		flags |= FLAG_I_DATA_CHUNK_MID_NOCHECK;
+	} else {
+		chunk->mid = htonl((u32)mid);
+	}
+	if (ppid == -1) {
+		chunk->field.ppid = htonl(0);
+		flags |= FLAG_I_DATA_CHUNK_PPID_NOCHECK;
+	} else {
+		chunk->field.ppid = htonl((u32)ppid);
+	}
+	if (fsn == -1) {
+		chunk->field.fsn = htonl(0);
+		flags |= FLAG_I_DATA_CHUNK_FSN_NOCHECK;
+	} else {
+		chunk->field.fsn = htonl((u32)fsn);
+	}
+	memset(chunk->data, 0,
+	       length + padding_length - sizeof(struct sctp_i_data_chunk));
+	return sctp_chunk_list_item_new((struct sctp_chunk *)chunk,
+	                                length + padding_length, flags,
+	                                sctp_parameter_list_new(),
+	                                sctp_cause_list_new());
+}
+
 struct sctp_chunk_list_item *
 sctp_pad_chunk_new(s64 flgs, s64 len, u8* padding)
 {
diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h
index ad974346..246859e0 100644
--- a/gtests/net/packetdrill/sctp_packet.h
+++ b/gtests/net/packetdrill/sctp_packet.h
@@ -275,6 +275,17 @@ sctp_cwr_chunk_new(s64 flgs, s64 lowest_tsn);
 struct sctp_chunk_list_item *
 sctp_shutdown_complete_chunk_new(s64 flgs);
 
+#define FLAG_I_DATA_CHUNK_TSN_NOCHECK           0x00000100
+#define FLAG_I_DATA_CHUNK_SID_NOCHECK           0x00000200
+#define FLAG_I_DATA_CHUNK_RES_NOCHECK           0x00000400
+#define FLAG_I_DATA_CHUNK_MID_NOCHECK           0x00000800
+#define FLAG_I_DATA_CHUNK_PPID_NOCHECK          0x00001000
+#define FLAG_I_DATA_CHUNK_FSN_NOCHECK           0x00002000
+
+struct sctp_chunk_list_item *
+sctp_i_data_chunk_new(s64 flgs, s64 len, s64 tsn, s64 sid, s64 res, s64 mid,
+                      s64 ppid, s64 fsn);
+
 struct sctp_chunk_list_item *
 sctp_pad_chunk_new(s64 flgs, s64 len, u8* padding);
 
-- 
GitLab