From 77d7bb73f7b9443b8f594a79bec8616a649cd2ce Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Wed, 30 Sep 2015 13:42:59 +0200
Subject: [PATCH] add last corrections from diff and fix sctp_rtoinfo for
 setsockopt with ellipsis as type for all values

---
 gtests/net/packetdrill/parser.y               |  8 +--
 gtests/net/packetdrill/run_system_call.c      | 50 ++++++++-------
 gtests/net/packetdrill/script.c               | 53 +++++++++++++++-
 .../bsd/sctp/sctp_get_socket_options.pkt      | 63 +++++++++++--------
 .../tests/bsd/sctp/sctp_socket_options.pkt    |  2 +-
 5 files changed, 120 insertions(+), 56 deletions(-)

diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index abc2d404..87dd50c2 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -2425,13 +2425,9 @@ sctp_sackinfo
 ;
 
 sstat_state
-: SSTAT_STATE '=' INTEGER {
-	if (!is_valid_u32($3)) {
-		semantic_error("sstat_state out of range");
-	}
-	$$ = new_integer_expression($3, "%ld");
+: SSTAT_STATE '=' expression {
+	$$ = $3;
 }
-| SSTAT_STATE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
 ;
 
 sstat_rwnd
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 29373db6..60e149a9 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -204,7 +204,7 @@ static int get_s32(struct expression *expression,
  * valid s16 or u16, and matches the expected type. Returns STATUS_OK on
  * success; on failure returns STATUS_ERR and sets error message.
  */
-static short get_s16(struct expression *expression, 
+static short get_s16(struct expression *expression,
 		s16 *value, char **error)
 {
 	if (check_type(expression, EXPR_INTEGER, error))
@@ -1657,7 +1657,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		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;
-		int val_onoff = 0; 
+		int val_onoff = 0;
 		if (l_onoff->type != EXPR_ELLIPSIS) {
 			if (get_s32(l_onoff, &val_onoff, error)) {
 				free(live_optval);
@@ -1678,7 +1678,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 			}
 			if (ling->l_linger != val_linger) {
 				asprintf(error, "Bad getsockopt Linger Value: expected: %d actual: %d",
-					 val_linger, ling->l_linger);
+					val_linger, ling->l_linger);
 				free(live_optval);
 				return STATUS_ERR;
 			}
@@ -1691,7 +1691,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		struct expression *srto_min = val_expression->value.sctp_rtoinfo->srto_min;
 		struct sctp_rtoinfo *rtoinfo = live_optval;
 		int initial=0, max=0, min=0;
-		if (srto_initial->type == EXPR_INTEGER) {
+		if (srto_initial->type != EXPR_ELLIPSIS) {
 			if (get_s32(srto_initial, &initial, error)) {
 				free(live_optval);
 				return STATUS_ERR;
@@ -1702,7 +1702,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 				free(live_optval);
 				return STATUS_ERR;
 			}
-		} else if (srto_max->type == EXPR_INTEGER) {
+		} else if (srto_max->type != EXPR_ELLIPSIS) {
 			if (get_s32(srto_max, &max, error)) {
 				free(live_optval);
 				return STATUS_ERR;
@@ -1713,7 +1713,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 				free(live_optval);
 				return STATUS_ERR;
 			}
-		} else if (srto_min->type == EXPR_INTEGER) {
+		} else if (srto_min->type != EXPR_ELLIPSIS) {
 			if (get_s32(srto_min, &min, error)) {
 				free(live_optval);
 				return STATUS_ERR;
@@ -1894,7 +1894,6 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		struct expression *spp_hbinterval = val_expression->value.sctp_paddrparams->spp_hbinterval;
 		struct expression *spp_pathmaxrxt = val_expression->value.sctp_paddrparams->spp_pathmaxrxt;
 		struct expression *spp_pathmtu = val_expression->value.sctp_paddrparams->spp_pathmtu;
-		
 		struct sctp_paddrparams *live_params = live_optval;
 		int hbinterval, pathmtu;
 		short pathmaxrxt;
@@ -1938,7 +1937,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	} else {
 		if (*(int*)live_optval != script_optval) {
 			asprintf(error, "Bad getsockopt optval: expected: %d actual: %d",
-			         (int)script_optval, *(int*)live_optval);
+				(int)script_optval, *(int*)live_optval);
 			free(live_optval);
 			return STATUS_ERR;
 		}
@@ -1948,7 +1947,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 }
 
 static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
-			      struct expression_list *args, char **error)
+			struct expression_list *args, char **error)
 {
 	int script_fd, live_fd, level, optname, optval_s32, optlen, result;
 	void *optval = NULL;
@@ -1972,10 +1971,10 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		return STATUS_ERR;
 	if (val_expression->type == EXPR_LINGER) {
 		optval = malloc(sizeof(struct linger));
-		get_s32(val_expression->value.linger->l_onoff, 
+		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);
+			&(((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) {
@@ -1986,17 +1985,24 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 	} else if (val_expression->type == EXPR_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;
-		}
+		socklen_t live_optlen = sizeof(struct sctp_paddrparams);
 		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;
+		memset(rtoinfo, 0, sizeof(struct sctp_rtoinfo));
 		rtoinfo->srto_assoc_id = 0;
+		if (getsockopt(live_fd, level, optname, rtoinfo, &live_optlen) == -1) {
+			asprintf(error, "Bad setsockopt, bad get actuall values");
+			free(rtoinfo);
+			return STATUS_ERR;
+		}
+		if (expr_rtoinfo->srto_initial->type != EXPR_ELLIPSIS) {
+			rtoinfo->srto_initial = expr_rtoinfo->srto_initial->value.num;	
+		}
+		if (expr_rtoinfo->srto_max->type != EXPR_ELLIPSIS) {
+			rtoinfo->srto_max = expr_rtoinfo->srto_max->value.num;		
+		}
+		if (expr_rtoinfo->srto_min->type != EXPR_ELLIPSIS) {
+			rtoinfo->srto_min = expr_rtoinfo->srto_min->value.num;
+		}
 		optval = rtoinfo;
 #endif
 #ifdef SCTP_INITMSG
@@ -2030,7 +2036,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 			free(params);
 			return STATUS_ERR;
 		}
-		params->spp_assoc_id = 0;                
+		params->spp_assoc_id = 0;
 		if (getsockopt(live_fd, level, optname, params, &live_optlen) == -1) {
 			asprintf(error, "Bad setsockopt, bad get actuall values");
 			free(params);
@@ -2039,7 +2045,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		if (expr_params->spp_hbinterval->type != EXPR_ELLIPSIS) {
 			params->spp_hbinterval = expr_params->spp_hbinterval->value.num;
 		}
-		if (expr_params->spp_pathmaxrxt->type != EXPR_ELLIPSIS) {		
+		if (expr_params->spp_pathmaxrxt->type != EXPR_ELLIPSIS) {
 			params->spp_pathmaxrxt = expr_params->spp_pathmaxrxt->value.num;
 		}
 		if (expr_params->spp_pathmtu->type != EXPR_ELLIPSIS) {
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 650ede2f..56a74a77 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -499,6 +499,56 @@ static int evaluate_msghdr_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+#ifdef SCTP_STATUS
+static int evaluate_sctp_status_expression(struct expression *in,
+						struct expression *out, char **error)
+{
+	struct sctp_status_expr *in_status;
+	struct sctp_status_expr *out_status;
+
+	assert(in->type == EXPR_SCTP_STATUS);
+	assert(in->value.sctp_status);
+	assert(out->type == EXPR_SCTP_STATUS);
+
+	out->value.sctp_status = calloc(1, sizeof(struct sctp_status_expr));
+
+	in_status = in->value.sctp_status;
+	out_status = out->value.sctp_status;
+	if (evaluate(in_status->sstat_state,
+			&out_status->sstat_state,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_rwnd,
+			&out_status->sstat_rwnd,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_unackdata,
+			&out_status->sstat_unackdata,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_penddata,
+			&out_status->sstat_penddata,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_instrms,
+			&out_status->sstat_instrms,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_outstrms,
+			&out_status->sstat_outstrms,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_fragmentation_point,
+			&out_status->sstat_fragmentation_point,
+			error))
+		return STATUS_ERR;
+	if (evaluate(in_status->sstat_primary,
+			&out_status->sstat_primary,
+			error))
+		return STATUS_ERR;
+	return STATUS_OK;
+}
+#endif
 static int evaluate_pollfd_expression(struct expression *in,
 				      struct expression *out, char **error)
 {
@@ -574,8 +624,7 @@ static int evaluate(struct expression *in,
 #endif
 #ifdef SCTP_STATUS
 	case EXPR_SCTP_PADDRINFO:
-		memcpy(&out->value.sctp_paddrinfo, &in->value.sctp_paddrinfo,
-			sizeof(in->value.sctp_paddrinfo));
+		result = evaluate_sctp_status_expression(in, out, error);
 		break;
 	case EXPR_SCTP_STATUS:	/* copy as-is */
 		memcpy(&out->value.sctp_status, &in->value.sctp_status,
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 2812fe2a..e165429e 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
@@ -8,39 +8,52 @@
 +0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...]
 +0.1 < sctp: COOKIE_ACK[flgs=0]
 
-+0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 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
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=..., sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=0, sstat_instrms=1, 
-	sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=..., sstat_unackdata=0, sstat_penddata=0, sstat_instrms=1, 
-	sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=..., sstat_penddata=0, sstat_instrms=1, 
-	sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=..., sstat_instrms=1, 
-	sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=0, sstat_instrms=..., 
-	sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 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=..., sstat_fragmentation_point=1452, sstat_primary=... }, [176])= 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=..., sstat_primary=... }, [176])= 0
+//+0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
+
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=SCTP_ESTABLISHED, sstat_rwnd=1500, 
+sstat_unackdata=0, sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=..., sstat_rwnd=1500, sstat_unackdata=0, 
+sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=..., sstat_unackdata=0, 
+sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=..., 
+sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, 
+sstat_penddata=..., sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, 
+sstat_penddata=0, sstat_instrms=..., sstat_outstrms=1, sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 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=..., sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 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=..., sstat_primary=...}, [176])= 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=..., 
-	sstat_primary={ spinfo_state=1, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=1468} }, [176])= 0
+sstat_outstrms=1, sstat_fragmentation_point=..., 
+sstat_primary={ spinfo_state=1, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=1468} }, [176])= 0
+
 
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-	spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=...}, 152) = 0
+spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=...}, 152) = 0
 
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-	spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=5}, [152]) = 0
+spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=5}, [152]) = 0
+
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-	spp_hbinterval=..., spp_pathmtu=1468, spp_pathmaxrxt=5}, [152]) = 0
+spp_hbinterval=..., spp_pathmtu=1468, spp_pathmaxrxt=5}, [152]) = 0
+
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-	spp_hbinterval=60000, spp_pathmtu=..., spp_pathmaxrxt=5}, [152]) = 0
+spp_hbinterval=60000, spp_pathmtu=..., spp_pathmaxrxt=5}, [152]) = 0
+
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-	spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=...}, [152]) = 0
+spp_hbinterval=60000, spp_pathmtu=1468, spp_pathmaxrxt=...}, [152]) = 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
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
index 5a69cf3c..6b0e90a2 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
@@ -5,7 +5,7 @@
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=200, srto_max=200, srto_min=50}, 16) = 0
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=50}, 16) = 0
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 17) = 0 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=25, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=225, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=200}, 16) = -1 EINVAL (Invalid argument)
-- 
GitLab