diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 5f753b208de5a02f77b315fe1c76ada2bfa71660..bae3af88fe6a50547ca96344444fd613754a23df 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -1185,7 +1185,8 @@ dup
 
 sctp_generic_chunk_spec
 : CHUNK '[' opt_chunk_type ',' opt_flags ',' opt_len ',' opt_val ']' {
-	if (($7 != -1) && ($7 < sizeof(struct sctp_chunk))) {
+	if (($7 != -1) &&
+	    (!is_valid_u16($7) || ($7 < sizeof(struct sctp_chunk)))) {
 		semantic_error("length value out of range");
 	}
 	if (($7 != -1) && ($9 != NULL) &&
@@ -1200,7 +1201,8 @@ sctp_generic_chunk_spec
 
 sctp_data_chunk_spec
 : DATA '[' opt_data_flags ',' opt_len ',' opt_tsn ',' opt_sid ',' opt_ssn ',' opt_ppid ']' {
-	if (($5 != -1) && ($5 < sizeof(struct sctp_data_chunk))) {
+	if (($5 != -1) &&
+	    (!is_valid_u16($5) || ($5 < sizeof(struct sctp_data_chunk)))) {
 		semantic_error("length value out of range");
 	}
 	$$ = sctp_data_chunk_new($3, $5, $7, $9, $11, $13);
@@ -1253,6 +1255,10 @@ sctp_error_chunk_spec
 
 sctp_cookie_echo_chunk_spec
 : COOKIE_ECHO '[' opt_flags ',' opt_len ',' VAL '=' ELLIPSIS ']' {
+	if (($5 != -1) &&
+	    (!is_valid_u16($5) || ($5 < sizeof(struct sctp_cookie_echo_chunk)))) {
+		semantic_error("length value out of range");
+	}
 	$$ = sctp_cookie_echo_chunk_new($3, $5, NULL);
 }
 
@@ -1278,6 +1284,10 @@ sctp_shutdown_complete_chunk_spec
 
 sctp_pad_chunk_spec
 : PAD '[' opt_flags ',' opt_len ',' VAL '=' ELLIPSIS ']' {
+	if (($5 != -1) &&
+	    (!is_valid_u16($5) || ($5 < sizeof(struct sctp_pad_chunk)))) {
+		semantic_error("length value out of range");
+	}
 	$$ = sctp_pad_chunk_new($3, $5, NULL);
 }
 
@@ -1326,7 +1336,8 @@ opt_parameter_type
 
 sctp_generic_parameter_spec
 : PARAMETER '[' opt_parameter_type ',' opt_len ',' opt_val ']' {
-	if (($5 != -1) && ($5 < sizeof(struct sctp_parameter))) {
+	if (($5 != -1) &&
+	    (!is_valid_u16($5) || ($5 < sizeof(struct sctp_parameter)))) {
 		semantic_error("length value out of range");
 	}
 	if (($5 != -1) && ($7 != NULL) &&
@@ -1343,15 +1354,19 @@ sctp_heartbeat_information_parameter_spec
 : HEARTBEAT_INFORMATION '[' ELLIPSIS ']' {
 	$$ = sctp_heartbeat_information_parameter_new(-1, NULL);
 }
-| HEARTBEAT_INFORMATION '[' LEN '=' ELLIPSIS ',' VAL '=' ELLIPSIS ']' {
-	$$ = sctp_heartbeat_information_parameter_new(-1, NULL);
-}
-| HEARTBEAT_INFORMATION '[' LEN '=' INTEGER ',' VAL '=' ELLIPSIS ']' {
-	if (($5 < sizeof(struct sctp_heartbeat_information_parameter)) ||
-	    !is_valid_u16($5)) {
-		semantic_error("len value out of range");
+| HEARTBEAT_INFORMATION '[' opt_len ',' opt_val ']' {
+	if (($3 != -1) &&
+	    (!is_valid_u16($3) || ($3 < sizeof(struct sctp_heartbeat_information_parameter)))) {
+		semantic_error("length value out of range");
+	}
+	if (($3 != -1) && ($5 != NULL) &&
+	    ($3 != sizeof(struct sctp_heartbeat_information_parameter) + $5->nr_entries)) {
+		semantic_error("length value incompatible with val");
+	}
+	if (($3 == -1) && ($5 != NULL)) {
+		semantic_error("length needs to be specified");
 	}
-	$$ = sctp_heartbeat_information_parameter_new($5, NULL);
+	$$ = sctp_heartbeat_information_parameter_new($3, $5);
 }
 
 sctp_ipv4_address_parameter_spec
@@ -1517,7 +1532,8 @@ opt_cause_code
 
 sctp_generic_cause_spec
 : CAUSE '[' opt_cause_code ',' opt_len ',' opt_info ']' {
-	if (($5 != -1) && ($5 < sizeof(struct sctp_cause))) {
+	if (($5 != -1) &&
+	    (!is_valid_u16($5) || ($5 < sizeof(struct sctp_cause)))) {
 		semantic_error("length value out of range");
 	}
 	if (($5 != -1) && ($7 != NULL) &&
diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c
index 8a7280749969993e4970f29819034e6ea457e290..08df4f48bfd2b64550a24bd58341dd65c6f9f8f7 100644
--- a/gtests/net/packetdrill/sctp_packet.c
+++ b/gtests/net/packetdrill/sctp_packet.c
@@ -945,7 +945,9 @@ sctp_cookie_echo_chunk_new(s64 flgs, s64 len, u8* cookie)
 	u32 flags;
 	u16 chunk_length, cookie_length, padding_length;
 
-	assert((len == -1) || is_valid_u16(len));
+	assert((len == -1) ||
+	       (is_valid_u16(len) &&
+	        len >= sizeof(struct sctp_cookie_echo_chunk)));
 	assert((len != -1) || (cookie == NULL));
 	flags = 0;
 	if (len == -1) {
@@ -1247,41 +1249,9 @@ sctp_generic_parameter_new(s64 type, s64 len, struct sctp_byte_list *bytes)
 }
 
 struct sctp_parameter_list_item *
-sctp_heartbeat_information_parameter_new(s64 len, u8 *information)
+sctp_heartbeat_information_parameter_new(s64 len, struct sctp_byte_list *bytes)
 {
-	struct sctp_heartbeat_information_parameter *parameter;
-	u32 flags;
-	u16 parameter_length, information_length, padding_length;
-
-	assert((len == -1) || is_valid_u16(len));
-	assert((len != -1) || (information == NULL));
-	flags = 0;
-	if (len == -1) {
-		information_length = 0;
-		flags |= FLAG_PARAMETER_LENGTH_NOCHECK;
-	} else {
-		assert(len <= MAX_SCTP_PARAMETER_BYTES - sizeof(struct sctp_heartbeat_information_parameter));
-		information_length = len - sizeof(struct sctp_heartbeat_information_parameter);
-	}
-	parameter_length = information_length + sizeof(struct sctp_heartbeat_information_parameter);
-	padding_length = parameter_length % 4;
-	if (padding_length > 0) {
-		padding_length = 4 - padding_length;
-	}
-	parameter = malloc(parameter_length + padding_length);
-	assert(parameter != NULL);
-	parameter->type = htons(SCTP_HEARTBEAT_INFORMATION_PARAMETER_TYPE);
-	parameter->length = htons(parameter_length);
-	if (information != NULL) {
-		memcpy(parameter->information, information, information_length);
-	} else {
-		flags |= FLAG_PARAMETER_VALUE_NOCHECK;
-		memset(parameter->information, 'A', information_length);
-	}
-	/* Clear the padding */
-	memset(parameter->information + information_length, 0, padding_length);
-	return sctp_parameter_list_item_new((struct sctp_parameter *)parameter,
-	                                    parameter_length, flags);
+	return sctp_generic_parameter_new(SCTP_HEARTBEAT_INFORMATION_PARAMETER_TYPE, len,bytes);
 }
 
 struct sctp_parameter_list_item *
diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h
index 4207111139aaa9dd03eafc0a98cb913215a651f2..7e2b170a58f4bd4925eac539b5868a8f8e2c0594 100644
--- a/gtests/net/packetdrill/sctp_packet.h
+++ b/gtests/net/packetdrill/sctp_packet.h
@@ -300,7 +300,7 @@ struct sctp_parameter_list_item *
 sctp_generic_parameter_new(s64 type, s64 len, struct sctp_byte_list *bytes);
 
 struct sctp_parameter_list_item *
-sctp_heartbeat_information_parameter_new(s64 len, u8 *information);
+sctp_heartbeat_information_parameter_new(s64 len, struct sctp_byte_list *bytes);
 
 struct sctp_parameter_list_item *
 sctp_ipv4_address_parameter_new(struct in_addr *addr);