From d4c3290c6a35efd4d60aa413dd9bccb38965b981 Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Fri, 27 Nov 2015 01:01:36 +0100
Subject: [PATCH] add spinfo_assoc_id in struct sctp_paddrinfo

---
 gtests/net/packetdrill/lexer.l                |  1 +
 gtests/net/packetdrill/parser.y               | 18 +++++-----
 gtests/net/packetdrill/run_system_call.c      | 34 +++++++++++++------
 gtests/net/packetdrill/script.c               |  5 +++
 gtests/net/packetdrill/script.h               |  1 +
 .../bsd/sctp/sctp_get_socket_options.pkt      | 18 +++++-----
 6 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index 95d44be0..41035ebd 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -240,6 +240,7 @@ sstat_instrms			return SSTAT_INSTRMS;
 sstat_outstrms			return SSTAT_OUTSTRMS;
 sstat_fragmentation_point	return SSTAT_FRAGMENTATION_POINT;
 sstat_primary			return SSTAT_PRIMARY;
+spinfo_assoc_id			return SPINFO_ASSOC_ID;
 spinfo_address			return SPINFO_ADDRESS;
 spinfo_state			return SPINFO_STATE;
 spinfo_cwnd			return SPINFO_CWND;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index eca3d27c..3ee8ff41 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -512,7 +512,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SSTAT_ASSOC_ID SSTAT_STATE SSTAT_RWND SSTAT_UNACKDATA SSTAT_PENDDATA
 %token <reserved> SSTAT_INSTRMS SSTAT_OUTSTRMS SSTAT_FRAGMENTATION_POINT
 %token <reserved> SSTAT_PRIMARY
-%token <reserved> SPINFO_ADDRESS SPINFO_STATE SPINFO_CWND SPINFO_SRTT SPINFO_RTO
+%token <reserved> SPINFO_ASSOC_ID SPINFO_ADDRESS SPINFO_STATE SPINFO_CWND SPINFO_SRTT SPINFO_RTO
 %token <reserved> SPINFO_MTU
 %token <reserved> CHUNK DATA INIT INIT_ACK HEARTBEAT HEARTBEAT_ACK ABORT
 %token <reserved> SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECNE CWR
@@ -3055,15 +3055,17 @@ spinfo_mtu
 ;
 
 sctp_paddrinfo
-: '{' spinfo_address ',' spinfo_state ',' spinfo_cwnd ',' spinfo_srtt ',' spinfo_rto ',' spinfo_mtu '}' {
+: '{' SPINFO_ASSOC_ID '=' sctp_assoc_id ',' spinfo_address ',' spinfo_state ',' spinfo_cwnd ','
+      spinfo_srtt ',' spinfo_rto ',' spinfo_mtu '}' {
 	$$ = new_expression(EXPR_SCTP_PADDRINFO);
 	$$->value.sctp_paddrinfo = calloc(1, sizeof(struct sctp_paddrinfo_expr));
-	$$->value.sctp_paddrinfo->spinfo_address = $2;
-	$$->value.sctp_paddrinfo->spinfo_state = $4;
-	$$->value.sctp_paddrinfo->spinfo_cwnd = $6;
-	$$->value.sctp_paddrinfo->spinfo_srtt = $8;
-	$$->value.sctp_paddrinfo->spinfo_rto = $10;
-	$$->value.sctp_paddrinfo->spinfo_mtu = $12;
+	$$->value.sctp_paddrinfo->spinfo_assoc_id = $4;
+	$$->value.sctp_paddrinfo->spinfo_address = $6;
+	$$->value.sctp_paddrinfo->spinfo_state = $8;
+	$$->value.sctp_paddrinfo->spinfo_cwnd = $10;
+	$$->value.sctp_paddrinfo->spinfo_srtt = $12;
+	$$->value.sctp_paddrinfo->spinfo_rto = $14;
+	$$->value.sctp_paddrinfo->spinfo_mtu = $16;
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 87b6e9ec..313fb695 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -277,15 +277,19 @@ static int get_size_t(struct expression *expression,
 static int get_sctp_assoc_t(struct expression *expression,
 			    sctp_assoc_t *value, char **error)
 {
-	if (check_type(expression, EXPR_INTEGER, error))
-		return STATUS_ERR;
-	if (expression->value.num < 0) {
-		asprintf(error,
-			 "Value out of range for sctp_assoc_t: %lld",
-			 expression->value.num);
-		return STATUS_ERR;
+	if (expression->type == EXPR_ELLIPSIS) {
+		value = 0;
+	} else {
+		if (check_type(expression, EXPR_INTEGER, error))
+			return STATUS_ERR;
+		if (expression->value.num < 0) {
+			asprintf(error,
+				 "Value out of range for sctp_assoc_t: %lld",
+				 expression->value.num);
+			return STATUS_ERR;
+		}
+		*value = expression->value.num;
 	}
-	*value = expression->value.num;
 	return STATUS_OK;
 }
 #endif
@@ -2588,6 +2592,9 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 				struct sctp_paddrinfo *sctp_paddrinfo,
 				char **error)
 {
+	if (check_sctp_assoc_t_expr(expr->spinfo_assoc_id, sctp_paddrinfo->spinfo_assoc_id,
+				    "sctp_paddrinfo.spinfo_assoc_id", error))
+		return STATUS_ERR;
 	if (check_s32_expr(expr->spinfo_state, sctp_paddrinfo->spinfo_state,
 			   "sctp_paddrinfo.spinfo_state", error))
 		return STATUS_ERR;
@@ -2980,7 +2987,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		struct sctp_paddrinfo *live_paddrinfo = malloc(sizeof(struct sctp_paddrinfo));
 		live_optlen = (socklen_t) sizeof(struct sctp_paddrinfo);
 		memset(live_paddrinfo, 0, sizeof(struct sctp_paddrinfo));
-		live_paddrinfo->spinfo_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_paddrinfo->spinfo_assoc_id,
+				    &(live_paddrinfo->spinfo_assoc_id), error)) {
+			free(live_paddrinfo);
+			return STATUS_ERR;
+		}
 		if (get_sockstorage_arg(expr_paddrinfo->spinfo_address,
 					&(live_paddrinfo->spinfo_address), live_fd)) {
 			asprintf(error, "can't determine spinfo_address");
@@ -3427,7 +3438,10 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #endif
 #ifdef SCTP_GET_PEER_ADDR_INFO
 	case EXPR_SCTP_PADDRINFO:
-		paddrinfo.spinfo_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_paddrinfo->spinfo_assoc_id,
+				    &paddrinfo.spinfo_assoc_id, error)) {
+			return STATUS_ERR;
+		}
 		if (get_sockstorage_arg(val_expression->value.sctp_paddrinfo->spinfo_address,
 					&paddrinfo.spinfo_address, live_fd)) {
 			asprintf(error, "can't determine spp_address");
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index c6159bba..e51c89f6 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -340,6 +340,7 @@ void free_expression(struct expression *expression)
 		break;
 	case EXPR_SCTP_PADDRINFO:
 		assert(expression->value.sctp_paddrinfo);
+		free_expression(expression->value.sctp_paddrinfo->spinfo_assoc_id);
 		free_expression(expression->value.sctp_paddrinfo->spinfo_address);
 		free_expression(expression->value.sctp_paddrinfo->spinfo_state);
 		free_expression(expression->value.sctp_paddrinfo->spinfo_cwnd);
@@ -937,6 +938,10 @@ static int evaluate_sctp_paddrinfo_expression(struct expression *in,
 	in_paddrinfo = in->value.sctp_paddrinfo;
 	out_paddrinfo = out->value.sctp_paddrinfo;
 
+	if (evaluate(in_paddrinfo->spinfo_assoc_id,
+	             &out_paddrinfo->spinfo_assoc_id,
+	             error))
+		return STATUS_ERR;
 	if (evaluate(in_paddrinfo->spinfo_address,
 	             &out_paddrinfo->spinfo_address,
 	             error))
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index 99876144..df4e1d76 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -242,6 +242,7 @@ struct sctp_status_expr {
 
 /* Parse tree for a sctp_paddrinfo struct in a [gs]etsockopt syscall. */
 struct sctp_paddrinfo_expr {
+	struct expression *spinfo_assoc_id;
 	struct expression *spinfo_address;
 	struct expression *spinfo_state;
 	struct expression *spinfo_cwnd;
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 1315c9f3..d0e775b5 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
@@ -16,10 +16,10 @@
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_PRINFO, {pr_policy=SCTP_PR_SCTP_TTL, pr_value=5, pr_assoc_id=3}, 12) = 0
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_PRINFO, {pr_policy=SCTP_PR_SCTP_TTL, pr_value=5, pr_assoc_id=3}, [12]) = 0
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_assoc_id=3, sstat_state=..., sstat_rwnd=..., sstat_unackdata=..., sstat_penddata=...,
++0 setsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_assoc_id=..., sstat_state=..., sstat_rwnd=..., sstat_unackdata=..., sstat_penddata=...,
 sstat_instrms=..., sstat_outstrms=..., sstat_fragmentation_point=..., sstat_primary=...}, 176) = -1
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_assoc_id=3, sstat_state=..., sstat_rwnd=1500, sstat_unackdata=0, 
++0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_assoc_id=..., 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_assoc_id=3, sstat_state=SCTP_ESTABLISHED, sstat_rwnd=1500, 
@@ -44,27 +44,27 @@ sstat_penddata=0, sstat_instrms=1, sstat_outstrms=..., sstat_fragmentation_point
 sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=..., sstat_primary=...}, [176]) = 0
 
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_assoc_id=3, sstat_state=SCTP_ESTABLISHED, sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=0,
-sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=..., sstat_primary={spinfo_address={sa_family=AF_INET,sin_port=htons(8080), 
+sstat_instrms=1, sstat_outstrms=1, sstat_fragmentation_point=..., sstat_primary={spinfo_assoc_id=3, spinfo_address={sa_family=AF_INET,sin_port=htons(8080), 
 sin_addr=inet_addr("192.0.2.1")}, spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=1468} }, [176]) = 0
 
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 setsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_assoc_id=..., spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=111, spinfo_rto=1000, spinfo_mtu=1468}, 152) = -1 (ENOPROTOOPT)
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_assoc_id=3, spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spinfo_state=..., spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=1468}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_assoc_id=3, spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spinfo_state=SCTP_ACTIVE, spinfo_cwnd=..., spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=1468}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_assoc_id=3, spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=..., spinfo_mtu=1468}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, {spinfo_assoc_id=3, spinfo_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=...}, [152]) = 0
 
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=3, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=8, spp_pathmtu=1468, spp_flags=SPP_DSCP|SPP_HB_ENABLE, spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0
 
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
-- 
GitLab