diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index a8aa42363c5ab2ca6a32c6a55ecf3b73a1d177e7..8f353410b201060a80ebbcd1c7cfa2262974a2f4 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -564,9 +564,10 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression_list> expression_list function_arguments
 %type <expression> expression binary_expression array
 %type <expression> decimal_integer hex_integer
-%type <expression> inaddr sockaddr msghdr iovec pollfd opt_revents linger
-%type <expression> sctp_rtoinfo sctp_initmsg sctp_assocval sctp_sackinfo
-%type <expression> sctp_status
+%type <expression> inaddr sockaddr msghdr iovec pollfd opt_revents 
+%type <expression> linger l_onoff l_linger
+%type <expression> sctp_status sctp_initmsg sctp_assocval sctp_sackinfo
+%type <expression> sctp_rtoinfo srto_initial srto_max srto_min
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2280,30 +2281,74 @@ opt_revents
 | ',' REVENTS '=' expression     { $$ = $4; }
 ;
 
+l_onoff
+: ONOFF '=' INTEGER { 
+	if (!is_valid_s32($3)) {
+		semantic_error("linger onoff out of range");
+	} else {
+		$$ = new_integer_expression($3, "%ld"); 
+	}	
+}
+| ONOFF '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+l_linger
+: LINGER '=' INTEGER { 
+	if (!is_valid_s32($3)) {
+		semantic_error("linger out of range");
+	}
+	$$ = new_integer_expression($3, "%ld");
+}
+| LINGER '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
 linger
-: '{' ONOFF '=' INTEGER ',' LINGER '=' INTEGER '}' {
+: '{' l_onoff ',' l_linger '}' {
 	$$ = new_expression(EXPR_LINGER);
-	$$->value.linger.l_onoff  = $4;
-	$$->value.linger.l_linger = $8;
+	$$->value.linger = (struct linger_expr*) calloc(1, sizeof(struct linger_expr));
+	$$->value.linger->l_onoff  = $2;
+	$$->value.linger->l_linger = $4;
 }
 ;
 
-sctp_rtoinfo
-: '{' SRTO_INITIAL '=' INTEGER ',' SRTO_MAX '=' INTEGER ',' SRTO_MIN '=' INTEGER '}' {
-#ifdef SCTP_RTOINFO
-	$$ = new_expression(EXPR_SCTP_RTOINFO);
-	if (!is_valid_u32($4)) {
+srto_initial
+: SRTO_INITIAL '=' INTEGER {
+	if (!is_valid_u32($3)){
 		semantic_error("srto_initial out of range");
 	}
-	$$->value.sctp_rtoinfo.srto_initial = $4;
-	if (!is_valid_u32($8)) {
+        $$ = new_integer_expression($3, "%u");
+}
+| SRTO_INITIAL '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+srto_max
+: SRTO_MAX '=' INTEGER {
+	if (!is_valid_u32($3)) {
 		semantic_error("srto_max out of range");
 	}
-	$$->value.sctp_rtoinfo.srto_max = $8;
-	if (!is_valid_u32($12)) {
+	$$ = new_integer_expression($3, "%u");
+}
+| SRTO_MAX '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+srto_min
+: SRTO_MIN '=' INTEGER {
+	if (!is_valid_u32($3)) {
 		semantic_error("srto_min out of range");
 	}
-	$$->value.sctp_rtoinfo.srto_min = $12;
+	$$ = new_integer_expression($3, "%u");
+}
+| SRTO_MIN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sctp_rtoinfo
+: '{' srto_initial ',' srto_max ',' srto_min '}' {
+#ifdef SCTP_RTOINFO
+	$$ = new_expression(EXPR_SCTP_RTOINFO);
+	$$->value.sctp_rtoinfo = (struct sctp_rtoinfo_expr*) calloc(1, sizeof(struct sctp_rtoinfo_expr));
+	$$->value.sctp_rtoinfo->srto_initial = $2;
+	$$->value.sctp_rtoinfo->srto_max = $4;
+	$$->value.sctp_rtoinfo->srto_min = $6;
 #else
 	$$ = NULL;
 #endif
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 6f5a018b38f53adee2f175b76498b861234524d2..5457c70580d851771f3834e2507778f75881e714 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -1582,12 +1582,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	if (val_expression == NULL) {
 		return STATUS_ERR;
 	} else if (val_expression->type == EXPR_LINGER) {
-		live_optval = malloc(sizeof(val_expression->value.linger));
-		live_optlen = (socklen_t)sizeof(val_expression->value.linger);
+		live_optval = malloc(sizeof(struct linger));
+		live_optlen = (socklen_t)sizeof(struct linger);
 #ifdef SCTP_RTOINFO
 	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
-		live_optval = malloc(sizeof(val_expression->value.sctp_rtoinfo));
-		live_optlen = (socklen_t)sizeof(val_expression->value.sctp_rtoinfo);
+		live_optval = malloc(sizeof(struct sctp_rtoinfo));
+		live_optlen = (socklen_t)sizeof(struct sctp_rtoinfo);
+		((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0;
 #endif
 #ifdef SCTP_STATUS
 	} else if (val_expression->type == EXPR_SCTP_STATUS) {
@@ -1614,39 +1615,77 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		free(live_optval);
 		return STATUS_ERR;
 	}
-
 	if (val_expression->type == EXPR_LINGER) {
+		struct expression *l_onoff = val_expression->value.linger->l_onoff;
+		struct expression *l_linger = val_expression->value.linger->l_linger;
 		struct linger *ling = live_optval;
-		if (ling->l_onoff != val_expression->value.linger.l_onoff) {
-			asprintf(error, "Bad getsockopt Linger onoff: expected: %d actual: %d",
-			         val_expression->value.linger.l_onoff, ling->l_onoff);
-			free(live_optval);
-			return STATUS_ERR;
+		int val_onoff = 0; 
+		if (l_onoff->type == EXPR_INTEGER) {
+			if (get_s32(l_onoff, &val_onoff, error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+			if (val_onoff != ling->l_onoff) {
+				asprintf(error, "Bad getsockopt Linger onoff: expected: %d actual: %d",
+			         	(int) val_onoff, ling->l_onoff);
+				free(live_optval);
+				return STATUS_ERR;
+			}
 		}
-		if (ling->l_linger != val_expression->value.linger.l_linger) {
-			asprintf(error, "Bad getsockopt Linger Value: expected: %d actual: %d",
-			         val_expression->value.linger.l_linger, ling->l_linger);
-			free(live_optval);
-			return STATUS_ERR;
+		int val_linger = 0;
+		if (l_linger->type == EXPR_INTEGER) {
+			if (get_s32(l_linger, &val_linger, error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+			if (ling->l_linger != val_linger) {
+				asprintf(error, "Bad getsockopt Linger Value: expected: %d actual: %d",
+			        	 val_linger, ling->l_linger);
+				free(live_optval);
+				return STATUS_ERR;
+			}
 		}
+
 #ifdef SCTP_RTOINFO
 	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
+		struct expression *srto_initial = val_expression->value.sctp_rtoinfo->srto_initial;
+		struct expression *srto_max = val_expression->value.sctp_rtoinfo->srto_max;
+		struct expression *srto_min = val_expression->value.sctp_rtoinfo->srto_min;
 		struct sctp_rtoinfo *rtoinfo = live_optval;
-		if (rtoinfo->srto_initial != val_expression->value.sctp_rtoinfo.srto_initial){
-			asprintf(error, "Bad getsockopt SCTP_RTOINFO initial: expected: %u actual: %u",
-			         val_expression->value.sctp_rtoinfo.srto_initial, rtoinfo->srto_initial);
-			free(live_optval);
-			return STATUS_ERR;
-		} else if (rtoinfo->srto_max != val_expression->value.sctp_rtoinfo.srto_max){
-		 	asprintf(error, "Bad getsockopt SCTP_RTOINFO SRTO_MAX: expected: %u actual: %u",
-		 	         val_expression->value.sctp_rtoinfo.srto_max, rtoinfo->srto_max);
-			free(live_optval);
-			return STATUS_ERR;
-		} else if (rtoinfo->srto_min != val_expression->value.sctp_rtoinfo.srto_min){
-		 	asprintf(error, "Bad getsockopt SCTP_RTOINFO SRTO_MIN: expected: %u actual: %u",
-		 	         val_expression->value.sctp_rtoinfo.srto_min, rtoinfo->srto_min);
-			free(live_optval);
-			return STATUS_ERR;
+		int initial=0, max=0, min=0;
+		if (srto_initial->type == EXPR_INTEGER) {
+			if (get_s32(srto_initial, &initial, error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+			if (rtoinfo->srto_initial != initial) {
+				asprintf(error, "Bad getsockopt SCTP_RTOINFO initial: expected: %u actual: %u",
+					initial, rtoinfo->srto_initial);
+				free(live_optval);
+				return STATUS_ERR;
+			}
+		} else if (srto_max->type == EXPR_INTEGER) {
+			if (get_s32(srto_max, &max, error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+			if (rtoinfo->srto_max != max) {
+				asprintf(error, "Bad getsockopt SCTP_RTOINFO SRTO_MAX: expected: %u actual: %u",
+					max, rtoinfo->srto_max);
+				free(live_optval);
+				return STATUS_ERR;
+			}
+		} else if (srto_min->type == EXPR_INTEGER) {
+			if (get_s32(srto_min, &min, error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+			if (rtoinfo->srto_min != min) {
+				asprintf(error, "Bad getsockopt SCTP_RTOINFO SRTO_MIN: expected: %u actual: %u",
+					min, rtoinfo->srto_min);
+				free(live_optval);
+				return STATUS_ERR;
+			}
 		}
 #endif
 #ifdef SCTP_STATUS
@@ -1726,7 +1765,11 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 	if (val_expression == NULL)
 		return STATUS_ERR;
 	if (val_expression->type == EXPR_LINGER) {
-		optval = &val_expression->value.linger;
+		optval = malloc(sizeof(struct linger));
+		get_s32(val_expression->value.linger->l_onoff, 
+			&(((struct linger*) optval)->l_onoff), error);
+		get_s32(val_expression->value.linger->l_linger,
+                        &(((struct linger*) optval)->l_linger), error);
 	} else if (val_expression->type == EXPR_STRING) {
 		optval = val_expression->value.string;
 	} else if (val_expression->type == EXPR_LIST) {
@@ -1735,7 +1778,20 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		optval = &optval_s32;
 #ifdef SCTP_RTOINFO
 	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
-		optval = &val_expression->value.sctp_rtoinfo;
+		struct sctp_rtoinfo *rtoinfo;
+		struct sctp_rtoinfo_expr *expr_rtoinfo  = val_expression->value.sctp_rtoinfo;
+		if (expr_rtoinfo->srto_initial->type != EXPR_INTEGER ||
+			expr_rtoinfo->srto_max->type != EXPR_INTEGER ||
+			expr_rtoinfo->srto_min->type != EXPR_INTEGER) { 
+			asprintf(error, "Bad setsockopt, bad inputtype for rtoinfo");
+			return STATUS_ERR;
+		}
+		rtoinfo = malloc(sizeof(struct sctp_rtoinfo));
+		rtoinfo->srto_initial = expr_rtoinfo->srto_initial->value.num;
+		rtoinfo->srto_max = expr_rtoinfo->srto_max->value.num;
+		rtoinfo->srto_min = expr_rtoinfo->srto_min->value.num;
+		rtoinfo->srto_assoc_id = 0;
+		optval = rtoinfo;
 #endif
 #ifdef SCTP_INITMSG
 	} else if (val_expression->type == EXPR_SCTP_INITMSG) {
@@ -1765,6 +1821,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 	result = setsockopt(live_fd, level, optname, optval, optlen);
 
 	return end_syscall(state, syscall, CHECK_EXACT, result, error);
+	free(optval);
 }
 
 static int syscall_poll(struct state *state, struct syscall_spec *syscall,
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index c4fdb4b2aedff29ebc5592f6bb95651b6cdd9b35..7b7d656577e63322f865f600d38a354e1280bd73 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -285,9 +285,17 @@ void free_expression(struct expression *expression)
 	switch (expression->type) {
 	case EXPR_ELLIPSIS:
 	case EXPR_INTEGER:
+		break;
 	case EXPR_LINGER:
+		free(expression->value.linger->l_onoff);
+		free(expression->value.linger->l_linger);
+		break;
 #ifdef SCTP_RTOINFO
 	case EXPR_SCTP_RTOINFO:
+		free(expression->value.sctp_rtoinfo->srto_initial);
+		free(expression->value.sctp_rtoinfo->srto_max);
+		free(expression->value.sctp_rtoinfo->srto_min);
+		break;
 #endif
 #ifdef SCTP_INITMSG
 	case EXPR_SCTP_INITMSG:
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index a2b2e46b118718d717504bb56fc35586d0c9e21b..cba02337b50e441dd038f2b8a4e5f6fcc50a81cc 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -72,7 +72,7 @@ struct expression {
 	union {
 		s64 num;
 		char *string;
-		struct linger linger;
+		struct linger_expr *linger;
 		struct sockaddr_in *socket_address_ipv4;
 		struct sockaddr_in6 *socket_address_ipv6;
 		struct binary_expression *binary;
@@ -81,7 +81,7 @@ struct expression {
 		struct msghdr_expr *msghdr;
 		struct pollfd_expr *pollfd;
 #ifdef SCTP_RTOINFO
-		struct sctp_rtoinfo sctp_rtoinfo;
+		struct sctp_rtoinfo_expr *sctp_rtoinfo;
 #endif
 #ifdef SCTP_INITMSG
 		struct sctp_initmsg sctp_initmsg;
@@ -136,6 +136,20 @@ struct pollfd_expr {
 	struct expression *revents;	/* returned events */
 };
 
+/* Handle values for socketoption SO_Linger with inputtypes and values*/
+struct linger_expr {
+	struct expression *l_onoff;
+	struct expression *l_linger;
+};
+/* Parse tree for syscall get/setsockopt for sctp_rtoinfo*/
+#ifdef SCTP_RTOINFO
+struct sctp_rtoinfo_expr {
+	struct expression *srto_initial;
+	struct expression *srto_max;
+	struct expression *srto_min;
+};
+#endif
+
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
 	const char *errno_macro;	/* errno symbol (C macro name) */
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
index 3310fd898266cb57a1efbbe9445c2d0775544a8e..8374c2c9fb78140ccaaeeeefef61792e53cb6ef0 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
@@ -10,15 +10,20 @@
 
 +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, [16]) = 0
-
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, 
-	sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+ 		sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
 
 +0 setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=30}, 8) = 0
 +0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=128, linger=30}, [8]) = 0
++0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=128, linger=...}, [8]) = 0
++0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=30}, [8]) = 0
++0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=...}, [8]) = 0
 
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, [16]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, [16]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=..., srto_min=50}, [16]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=...}, [16]) = 0
 
 +0 close(3) = 0