diff --git a/SCTP_SocketAPI_Status.md b/SCTP_SocketAPI_Status.md
new file mode 100644
index 0000000000000000000000000000000000000000..fddc354ebf6df319c804544a3188a8ffdcef68ac
--- /dev/null
+++ b/SCTP_SocketAPI_Status.md
@@ -0,0 +1,94 @@
+# Status of the socket API support
+
+For Linux the following tables are based on [sctp.h](https://github.com/sctp/lksctp-tools/blob/master/src/include/netinet/sctp.h).
+
+## SCTP cmsgs
+|CMSG Name        | API Spec                                                    | Protocol Spec                                    | packetdrill | Linux       | FreeBSD   |
+|:----------------|:-----------------------------------------------------------:|:------------------------------------------------:|:-----------:|:-----------:|:---------:|
+|`SCTP_INIT`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.1)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`SCTP_SNDRCV`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.2)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`SCTP_EXTRCV`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.3)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`SCTP_SNDINFO`   | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.4)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`SCTP_RCVINFO`   | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.5)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`SCTP_NXTINFO`   | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.6)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`SCTP_PRINFO`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.7)  | [RFC3758](https://tools.ietf.org/html/rfc3758) | unsupported | unsupported | supported |
+|`SCTP_AUTHINFO`  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.8)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | unsupported | supported |
+|`SCTP_DSTADDRV4` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.9)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`SCTP_DSTADDRV6` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+
+## SCTP Notifications
+| Type                              | API Spec                                                      | Protocol Spec                                  | packetdrill | Linux       | FreeBSD     |
+|:----------------------------------|:-------------------------------------------------------------:|:----------------------------------------------:|:-----------:|:-----------:|:-----------:|
+|`SCTP_ASSOC_CHANGE`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.1)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_PEER_ADDR_CHANGE`            | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.2)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_REMOTE_ERROR`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.3)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_SEND_FAILED`                 | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.4)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_SHUTDOWN_EVENT`              | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.5)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_ADAPTATION_INDICATION`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.6)  | [RFC5061](https://tools.ietf.org/html/rfc5061) | unsupported | supported   | supported   |
+|`SCTP_PARTIAL_DELIVERY_EVENT`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.7)  | [RFC3758](https://tools.ietf.org/html/rfc3758) | unsupported | supported   | supported   |
+|`SCTP_AUTHENTICATION_EVENT`        | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.8)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported   | supported   |
+|`SCTP_SENDER_DRY_EVENT`            | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.9)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported   |
+|`SCTP_NOTIFICATIONS_STOPPED_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | unsupported |
+|`SCTP_SEND_FAILED_EVENT`           | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported   |
+
+## SCTP Socket Options
+|Name                          | API Spec                                                      | Protocol Spec                                  | packetdrill | Linux               | FreeBSD   |
+|:-----------------------------|:-------------------------------------------------------------:|:----------------------------------------------:|:-----------:|:-------------------:|:---------:|
+|`SCTP_RTOINFO`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.1)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_ASSOCINFO`              | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.2)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_INITMSG`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.3)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_NODELAY`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.5)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_AUTOCLOSE`              | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.8)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported           | supported |
+|`SCTP_PRIMARY_ADDR`           | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.9)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_ADAPTATION_LAYER`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.10) | [RFC5061](https://tools.ietf.org/html/rfc5061) | supported   | supported           | supported |
+|`SCTP_DISABLE_FRAGMENTS`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.11) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_PEER_ADDR_PARAMS`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.12) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | old structure       | supported |
+|`SCTP_DEFAULT_SEND_PARAM`     | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.13) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_EVENTS`                 | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.14) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_I_WANT_MAPPED_V4_ADDR`  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.15) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_MAXSEG`                 | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.16) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | Check structure     | supported |
+|`SCTP_HMAC_IDENT`             | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.17) | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_AUTH_ACTIVE_KEY`        | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.18) | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_DELAYED_SACK`           | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.19) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_FRAGMENT_INTERLEAVE`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.20) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_PARTIAL_DELIVERY_POINT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.21) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_USE_EXT_RCVINFO`        | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.22) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | unsupported         | supported |
+|`SCTP_AUTO_ASCONF`            | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.23) | [RFC5061](https://tools.ietf.org/html/rfc5061) | unsupported | unsupported         | supported |
+|`SCTP_MAX_BURST`              | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.24) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | Check structure     | supported |
+|`SCTP_CONTEXT`                | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.25) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | supported           | supported |
+|`SCTP_EXPLICIT_EOR`           | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.26) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | unsupported         | supported |
+|`SCTP_REUSE_PORT`             | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.27) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | unsupported         | supported |
+|`SCTP_EVENT`                  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.28) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | unsupported         | supported |
+|`SCTP_RECVRCVINFO`            | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.29) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | unsupported         | supported |
+|`SCTP_RECVNXTINFO`            | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.30) | [RFC4960](https://tools.ietf.org/html/rfc4960) | TBD         | unsupported         | supported |
+|`SCTP_DEFAULT_SNDINFO`        | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.31) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | unsupported         | supported |
+|`SCTP_DEFAULT_PRINFO`         | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.1.32) | [RFC3758](https://tools.ietf.org/html/rfc3758) | unsupported | unsupported         | supported |
+|`SCTP_STATUS`                 | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.1)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_GET_PEER_ADDR_INFO`     | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.2)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported   | supported           | supported |
+|`SCTP_PEER_AUTH_CHUNKS`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.3)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_LOCAL_AUTH_CHUNKS`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.4)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_GET_ASSOC_NUMBER`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.5)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported           | supported |
+|`SCTP_GET_ASSOC_ID_LIST`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.2.6)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported         | supported |
+|`SCTP_SET_PEER_PRIMARY_ADDR`  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.3.1)  | [RFC5061](https://tools.ietf.org/html/rfc5061) | unsupported | supported           | supported |
+|`SCTP_AUTH_CHUNK`             | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.3.2)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_AUTH_KEY`               | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.3.3)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+|`SCTP_AUTH_DEACTIVATE_KEY`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.3.4)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | unsupported         | supported |
+|`SCTP_AUTH_DELETE_KEY`        | [RFC6458](https://tools.ietf.org/html/rfc6458#section-8.3.5)  | [RFC4895](https://tools.ietf.org/html/rfc4895) | unsupported | supported           | supported |
+
+
+## SCTP Functions
+|Name                | API Spec                                                    | Protocol Spec                                  | packetdrill | Linux       | FreeBSD   |
+|:-------------------|:-----------------------------------------------------------:|:----------------------------------------------:|:-----------:|:-----------:|:---------:|
+|`sctp_bindx()`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.1)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_peeloff()`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.2)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_getpaddrs()`  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.3)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_freepaddrs()` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.4)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_getladdrs()`  | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.5)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_freeladdrs()` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.6)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_sendmsg()`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.7)  | [RFC5061](https://tools.ietf.org/html/rfc5061) | unsupported | supported   | supported |
+|`sctp_recvmsg()`    | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.8)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_connectx()`   | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.9)  | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_send()`       | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_sendx()`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.11) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported   | supported |
+|`sctp_sendv()`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.12) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
+|`sctp_recvv()`      | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.13) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported |
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 90aad78557f3e218dda388eed48ac3d608173d2f..bb2fb56b5a72dc63bcf7b54f14b2fa6e5b0f2e2b 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -2577,15 +2577,11 @@ srto_min
 
 sctp_rtoinfo
 : '{' srto_initial ',' srto_max ',' srto_min '}' {
-#ifdef SCTP_RTOINFO
 	$$ = new_expression(EXPR_SCTP_RTOINFO);
 	$$->value.sctp_rtoinfo = 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
 }
 ;
 
@@ -2686,14 +2682,10 @@ sack_freq
 
 sctp_sackinfo
 : '{' sack_delay ',' sack_freq '}' {
-#ifdef SCTP_DELAYED_SACK
 	$$ = new_expression(EXPR_SCTP_SACKINFO);
 	$$->value.sctp_sack_info = calloc(1, sizeof(struct sctp_sack_info_expr));
 	$$->value.sctp_sack_info->sack_delay = $2;
 	$$->value.sctp_sack_info->sack_freq = $4;
-#else
-	$$ = NULL;
-#endif
 }
 ;
 
@@ -2979,7 +2971,6 @@ sasoc_cookie_life
 
 sctp_assocparams
 : '{' sasoc_asocmaxrxt ',' sasoc_number_peer_destinations ',' sasoc_peer_rwnd ',' sasoc_local_rwnd ',' sasoc_cookie_life '}' {
-#ifdef SCTP_ASSOCINFO
 	$$ = new_expression(EXPR_SCTP_ASSOCPARAMS);
         $$->value.sctp_assocparams = calloc(1, sizeof(struct sctp_assocparams_expr));
         $$->value.sctp_assocparams->sasoc_asocmaxrxt = $2;
@@ -2987,9 +2978,6 @@ sctp_assocparams
         $$->value.sctp_assocparams->sasoc_peer_rwnd = $6;
         $$->value.sctp_assocparams->sasoc_local_rwnd = $8;
         $$->value.sctp_assocparams->sasoc_cookie_life = $10;
-#else
-	$$ = NULL;
-#endif
 }
 ;
 
@@ -3018,14 +3006,10 @@ se_on
 
 sctp_event
 : '{' se_type ',' se_on '}' {
-#ifdef SCTP_EVENT
 	$$ = new_expression(EXPR_SCTP_EVENT);
 	$$->value.sctp_event = calloc(1, sizeof(struct sctp_event_expr));
 	$$->value.sctp_event->se_type = $2;
 	$$->value.sctp_event->se_on = $4;
-#else
-	$$ = NULL;
-#endif
 }
 ;
 
@@ -3089,16 +3073,12 @@ sctp_sndinfo
 
 sctp_setadaptation
 : '{' SSB_ADAPTATION_IND '=' INTEGER '}' {
-#ifdef SCTP_ADAPTATION_LAYER
 	$$ = new_expression(EXPR_SCTP_SETADAPTATION);
-	$$->value.sctp_setadaptation = calloc(1, sizeof(struct sctp_setadaptation));
+	$$->value.sctp_setadaptation = calloc(1, sizeof(struct sctp_setadaptation_expr));
 	if (!is_valid_u32($4)) {
 		semantic_error("ssb_adaptation_ind out of range");
 	}
 	$$->value.sctp_setadaptation->ssb_adaptation_ind = new_integer_expression($4, "%u");
-#else
-	$$ = NULL;
-#endif
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 1849fede9eb6aaefc6afcf48d6c01cf59bdd4105..626d692684adc5d3ed925cc2d5c440793ca1a82c 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -275,17 +275,17 @@ static int get_s16(struct expression *expression,
 static int get_u8(struct expression *expression,
 		  u8 *value, char **error)
 {
-        if (check_type(expression, EXPR_INTEGER, error))
-                return STATUS_ERR;
-        if ((expression->value.num > UINT8_MAX) ||
-                (expression->value.num < 0)) {
-                asprintf(error,
-                        "Value out of range for 8-bit unsigned integer: %lld",
-                        expression->value.num);
-                return STATUS_ERR;
-        }
-        *value = expression->value.num;
-        return STATUS_OK;
+	if (check_type(expression, EXPR_INTEGER, error))
+		return STATUS_ERR;
+	if ((expression->value.num > UINT8_MAX) ||
+		(expression->value.num < 0)) {
+		asprintf(error,
+			 "Value out of range for 8-bit unsigned integer: %lld",
+			 expression->value.num);
+		return STATUS_ERR;
+	}
+	*value = expression->value.num;
+	return STATUS_OK;
 }
 #endif
 
@@ -297,17 +297,17 @@ static int get_u8(struct expression *expression,
 static int get_s8(struct expression *expression,
 		  s8 *value, char **error)
 {
-        if (check_type(expression, EXPR_INTEGER, error))
-                return STATUS_ERR;
-        if ((expression->value.num > INT8_MAX) ||
-                (expression->value.num < INT8_MIN)) {
-                asprintf(error,
-                        "Value out of range for 8-bit integer: %lld",
-                        expression->value.num);
-                return STATUS_ERR;
-        }
-        *value = expression->value.num;
-        return STATUS_OK;
+	if (check_type(expression, EXPR_INTEGER, error))
+		return STATUS_ERR;
+	if ((expression->value.num > INT8_MAX) ||
+		(expression->value.num < INT8_MIN)) {
+		asprintf(error,
+			 "Value out of range for 8-bit integer: %lld",
+			 expression->value.num);
+		return STATUS_ERR;
+	}
+	*value = expression->value.num;
+	return STATUS_OK;
 }
 #endif
 
@@ -359,6 +359,30 @@ static int ellipsis_arg(struct expression_list *args, int index, char **error)
 	return STATUS_OK;
 }
 
+#if defined(SCTP_GET_PEER_ADDR_INFO) || defined(SCTP_PEER_ADDR_PARAMS)
+/* Return STATUS_OK if the argument in from type sockaddr_in or
+ * sockaddr_in6
+ */
+static int get_sockstorage_arg(struct expression *arg, struct sockaddr_storage *addr, int live_fd)
+{
+	if (arg->type == EXPR_ELLIPSIS) {
+		socklen_t len;
+
+		len = (socklen_t)sizeof(struct sockaddr_storage);
+		if (getpeername(live_fd, (struct sockaddr *)addr, &len)) {
+			return STATUS_ERR;
+		}
+	} else if (arg->type == EXPR_SOCKET_ADDRESS_IPV4) {
+		memcpy(addr, arg->value.socket_address_ipv4, sizeof(struct sockaddr_in));
+	} else if (arg->type == EXPR_SOCKET_ADDRESS_IPV6) {
+		memcpy(addr, arg->value.socket_address_ipv6, sizeof(struct sockaddr_in6));
+	} else {
+		return STATUS_ERR;
+	}
+	return STATUS_OK;
+}
+#endif
+
 /* Free all the space used by the given iovec. */
 static void iovec_free(struct iovec *iov, size_t iov_len)
 {
@@ -649,8 +673,7 @@ static int end_syscall(struct state *state, struct syscall_spec *syscall,
 	if (mode == CHECK_NON_NEGATIVE) {
 		if (actual < 0) {
 			asprintf(error,
-				 "Expected non-negative result but got %d"
-				 "with errno %d (%s)",
+				 "Expected non-negative result but got %d with errno %d (%s)",
 				 actual, actual_errno, strerror(actual_errno));
 			return STATUS_ERR;
 		}
@@ -658,8 +681,7 @@ static int end_syscall(struct state *state, struct syscall_spec *syscall,
 		if (actual != expected) {
 			if (actual < 0)
 				asprintf(error,
-					 "Expected result %d but got %d "
-					 "with errno %d (%s)",
+					 "Expected result %d but got %d with errno %d (%s)",
 					 expected,
 					 actual,
 					 actual_errno, strerror(actual_errno));
@@ -672,8 +694,7 @@ static int end_syscall(struct state *state, struct syscall_spec *syscall,
 	} else if (mode == CHECK_ALLOW_MAPPING) {
 		if ((expected >= 0)  && (actual < 0)) {
 			asprintf(error,
-				 "Expected non-negative result but got %d "
-				 "with errno %d (%s)",
+				 "Expected non-negative result but got %d with errno %d (%s)",
 				 actual, actual_errno, strerror(actual_errno));
 			return STATUS_ERR;
 		} else if ((expected < 0) && (actual != expected)) {
@@ -1691,7 +1712,7 @@ static int check_linger(struct linger_expr *expr,
 			return STATUS_ERR;
 		}
 		if (linger->l_onoff != l_onoff) {
-			asprintf(error, "Bad getsockopt linger.l_onoff: expected: %d actual: %d",
+			asprintf(error, "linger.l_onoff: expected: %d actual: %d",
 				 l_onoff, linger->l_onoff);
 			return STATUS_ERR;
 		}
@@ -1703,7 +1724,7 @@ static int check_linger(struct linger_expr *expr,
 			return STATUS_ERR;
 		}
 		if (linger->l_linger != l_linger) {
-			asprintf(error, "Bad getsockopt linger.l_linger: expected: %d actual: %d",
+			asprintf(error, "linger.l_linger: expected: %d actual: %d",
 				 l_linger, linger->l_linger);
 			return STATUS_ERR;
 		}
@@ -1722,7 +1743,7 @@ static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_rtoinfo->srto_initial != srto_initial) {
-			asprintf(error, "Bad getsockopt sctp_rtoinfo.srto_initial: expected: %u actual: %u",
+			asprintf(error, "sctp_rtoinfo.srto_initial: expected: %u actual: %u",
 				 srto_initial, sctp_rtoinfo->srto_initial);
 			return STATUS_ERR;
 		}
@@ -1734,7 +1755,7 @@ static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_rtoinfo->srto_max != srto_max) {
-			asprintf(error, "Bad getsockopt sctp_rtoinfo.srto_max: expected: %u actual: %u",
+			asprintf(error, "sctp_rtoinfo.srto_max: expected: %u actual: %u",
 				 srto_max, sctp_rtoinfo->srto_max);
 			return STATUS_ERR;
 		}
@@ -1746,7 +1767,7 @@ static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_rtoinfo->srto_min != srto_min) {
-			asprintf(error, "Bad getsockopt sctp_rtoinfo.srto_min: expected: %u actual: %u",
+			asprintf(error, "sctp_rtoinfo.srto_min: expected: %u actual: %u",
 				srto_min, sctp_rtoinfo->srto_min);
 			return STATUS_ERR;
 		}
@@ -1757,7 +1778,7 @@ static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr,
 
 #ifdef SCTP_INITMSG
 static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
-                              struct sctp_initmsg *sctp_initmsg, char **error)
+			      struct sctp_initmsg *sctp_initmsg, char **error)
 {
 	if (expr->sinit_num_ostreams->type != EXPR_ELLIPSIS) {
 		u16 sinit_num_ostreams;
@@ -1766,7 +1787,7 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_initmsg->sinit_num_ostreams != sinit_num_ostreams) {
-			asprintf(error, "Bad getsockopt sctp_initmsg.sinit_num_ostreams: expected: %hu actual: %hu",
+			asprintf(error, "sctp_initmsg.sinit_num_ostreams: expected: %hu actual: %hu",
 				 sinit_num_ostreams, sctp_initmsg->sinit_num_ostreams);
 			return STATUS_ERR;
 		}
@@ -1778,7 +1799,7 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_initmsg->sinit_max_instreams != sinit_max_instreams) {
-			asprintf(error, "Bad getsockopt sctp_initmsg.sinit_max_instreams: expected: %hu actual: %hu",
+			asprintf(error, "sctp_initmsg.sinit_max_instreams: expected: %hu actual: %hu",
 				 sinit_max_instreams, sctp_initmsg->sinit_max_instreams);
 			return STATUS_ERR;
 		}
@@ -1790,7 +1811,7 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_initmsg->sinit_max_attempts != sinit_max_attempts) {
-			asprintf(error, "Bad getsockopt sctp_initmsg.sinit_max_attempts: expected: %hu actual: %hu",
+			asprintf(error, "sctp_initmsg.sinit_max_attempts: expected: %hu actual: %hu",
 				 sinit_max_attempts, sctp_initmsg->sinit_max_attempts);
 			return STATUS_ERR;
 		}
@@ -1802,7 +1823,7 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_initmsg->sinit_max_init_timeo != sinit_max_init_timeo) {
-			asprintf(error, "Bad getsockopt sctp_initmsg.sinit_max_init_timeo: expected: %hu actual: %hu",
+			asprintf(error, "sctp_initmsg.sinit_max_init_timeo: expected: %hu actual: %hu",
 				 sinit_max_init_timeo, sctp_initmsg->sinit_max_init_timeo);
 			return STATUS_ERR;
 		}
@@ -1823,7 +1844,7 @@ static int check_sctp_sack_info(struct sctp_sack_info_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sack_info->sack_delay != sack_delay) {
-			asprintf(error, "Bad getsockopt sctp_sack_info.sack_delay: expected: %u actual: %u",
+			asprintf(error, "sctp_sack_info.sack_delay: expected: %u actual: %u",
 				 sack_delay, sctp_sack_info->sack_delay);
 			return STATUS_ERR;
 		}
@@ -1835,7 +1856,7 @@ static int check_sctp_sack_info(struct sctp_sack_info_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sack_info->sack_freq != sack_freq) {
-			asprintf(error, "Bad getsockopt sctp_sack_info.sack_freq: expected: %u actual: %u",
+			asprintf(error, "sctp_sack_info.sack_freq: expected: %u actual: %u",
 				 sack_freq, sctp_sack_info->sack_freq);
 			return STATUS_ERR;
 		}
@@ -1844,10 +1865,10 @@ static int check_sctp_sack_info(struct sctp_sack_info_expr *expr,
 }
 #endif
 
-#ifdef SCTP_STATUS
+#if defined(SCTP_GET_PEER_ADDR_INFO) || defined(SCTP_STATUS)
 static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
-			        struct sctp_paddrinfo *sctp_paddrinfo,
-			        char **error)
+				struct sctp_paddrinfo *sctp_paddrinfo,
+				char **error)
 {
 	if (expr->spinfo_state->type != EXPR_ELLIPSIS) {
 		s32 spinfo_state;
@@ -1856,7 +1877,7 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrinfo->spinfo_state != spinfo_state) {
-			asprintf(error, "Bad getsockopt sctp_paddrinfo.spinfo_state: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrinfo.spinfo_state: expected: %u actual: %u",
 				spinfo_state, sctp_paddrinfo->spinfo_state);
 			return STATUS_ERR;
 		}
@@ -1868,7 +1889,7 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrinfo->spinfo_cwnd != spinfo_cwnd) {
-			asprintf(error, "Bad getsockopt sctp_paddrinfo.spinfo_cwnd: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrinfo.spinfo_cwnd: expected: %u actual: %u",
 				 spinfo_cwnd, sctp_paddrinfo->spinfo_cwnd);
 			return STATUS_ERR;
 		}
@@ -1880,7 +1901,7 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrinfo->spinfo_srtt != spinfo_srtt) {
-			asprintf(error, "Bad getsockopt sctp_paddrinfo.spinfo_srtt: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrinfo.spinfo_srtt: expected: %u actual: %u",
 				 spinfo_srtt, sctp_paddrinfo->spinfo_srtt);
 			return STATUS_ERR;
 		}
@@ -1892,7 +1913,7 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrinfo->spinfo_rto != spinfo_rto) {
-			asprintf(error, "Bad getsockopt sctp_paddrinfo.spinfo_rto: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrinfo.spinfo_rto: expected: %u actual: %u",
 				 spinfo_rto, sctp_paddrinfo->spinfo_rto);
 			return STATUS_ERR;
 		}
@@ -1904,14 +1925,16 @@ static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrinfo->spinfo_mtu != spinfo_mtu) {
-			asprintf(error, "Bad getsockopt sctp_paddrinfo.spinfo_mtu: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrinfo.spinfo_mtu: expected: %u actual: %u",
 				 spinfo_mtu, sctp_paddrinfo->spinfo_mtu);
 			return STATUS_ERR;
 		}
 	}
 	return STATUS_OK;
 }
+#endif
 
+#ifdef SCTP_STATUS
 static int check_sctp_status(struct sctp_status_expr *expr,
 			     struct sctp_status *sctp_status,
 			     char **error)
@@ -1923,7 +1946,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_state != sstat_state) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_state: expected: %d actual: %d",
+			asprintf(error, "sctp_status.sstat_state: expected: %d actual: %d",
 				 sstat_state, sctp_status->sstat_state);
 			return STATUS_ERR;
 		}
@@ -1935,7 +1958,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_rwnd != sstat_rwnd) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_rwnd: expected: %u actual: %u",
+			asprintf(error, "sctp_status.sstat_rwnd: expected: %u actual: %u",
 				 sstat_rwnd, sctp_status->sstat_rwnd);
 			return STATUS_ERR;
 		}
@@ -1947,7 +1970,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_unackdata != sstat_unackdata) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_unackdata: expected: %hu actual: %hu",
+			asprintf(error, "sctp_status.sstat_unackdata: expected: %hu actual: %hu",
 				 sstat_unackdata, sctp_status->sstat_unackdata);
 			return STATUS_ERR;
 		}
@@ -1959,7 +1982,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_penddata != sstat_penddata) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_penddata: expected: %hu actual: %hu",
+			asprintf(error, "sctp_status.sstat_penddata: expected: %hu actual: %hu",
 				 sstat_penddata, sctp_status->sstat_penddata);
 			return STATUS_ERR;
 		}
@@ -1971,7 +1994,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_instrms != sstat_instrms) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_instrms: expected: %hu actual: %hu",
+			asprintf(error, "sctp_status.sstat_instrms: expected: %hu actual: %hu",
 				 sstat_instrms, sctp_status->sstat_instrms);
 			return STATUS_ERR;
 		}
@@ -1983,7 +2006,7 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_outstrms != sstat_outstrms) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_outstrms: expected: %hu actual: %hu",
+			asprintf(error, "sctp_status.sstat_outstrms: expected: %hu actual: %hu",
 				 sstat_outstrms, sctp_status->sstat_outstrms);
 			return STATUS_ERR;
 		}
@@ -1995,13 +2018,14 @@ static int check_sctp_status(struct sctp_status_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_status->sstat_fragmentation_point != sstat_fragmentation_point) {
-			asprintf(error, "Bad getsockopt sctp_status.sstat_fragmentation_point: expected: %u actual: %u",
+			asprintf(error, "sctp_status.sstat_fragmentation_point: expected: %u actual: %u",
 				sstat_fragmentation_point, sctp_status->sstat_fragmentation_point);
 			return STATUS_ERR;
 		}
 	}
 	if (expr->sstat_primary->type != EXPR_ELLIPSIS) {
-		if (check_sctp_paddrinfo(expr->sstat_primary->value.sctp_paddrinfo,  &sctp_status->sstat_primary, error)) {
+		if (check_sctp_paddrinfo(expr->sstat_primary->value.sctp_paddrinfo,
+					 &sctp_status->sstat_primary, error)) {
 			return STATUS_ERR;
 		}
 	}
@@ -2021,7 +2045,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_hbinterval != spp_hbinterval) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_hbinterval: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrparams.spp_hbinterval: expected: %u actual: %u",
 				 spp_hbinterval, sctp_paddrparams->spp_hbinterval);
 			return STATUS_ERR;
 		}
@@ -2033,7 +2057,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_pathmaxrxt != spp_pathmaxrxt) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_pathmaxrxt: expected: %hu actual: %hu",
+			asprintf(error, "sctp_paddrparams.spp_pathmaxrxt: expected: %hu actual: %hu",
 				 spp_pathmaxrxt, sctp_paddrparams->spp_pathmaxrxt);
 			return STATUS_ERR;
 		}
@@ -2045,7 +2069,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_pathmtu != spp_pathmtu) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_pathmtu: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrparams.spp_pathmtu: expected: %u actual: %u",
 				 spp_pathmtu, sctp_paddrparams->spp_pathmtu);
 			return STATUS_ERR;
 		}
@@ -2057,14 +2081,14 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_flags != spp_flags) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_flags: expected: 0x%08x actual: 0x%08x",
+			asprintf(error, "sctp_paddrparams.spp_flags: expected: 0x%08x actual: 0x%08x",
 				 spp_flags, sctp_paddrparams->spp_flags);
 			return STATUS_ERR;
 		}
 	}
 	if (expr->spp_ipv6_flowlabel->type != EXPR_ELLIPSIS) {
 #ifdef linux
-		asprintf(error, "Bad getsockopt linux doesn't support sctp_paddrparams.spp_ipv6_flowlabel");
+		asprintf(error, "linux doesn't support sctp_paddrparams.spp_ipv6_flowlabel");
 		return STATUS_ERR;
 #else
 		u32 spp_ipv6_flowlabel;
@@ -2073,7 +2097,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_ipv6_flowlabel != spp_ipv6_flowlabel) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_ipv6_flowlabel: expected: %u actual: %u",
+			asprintf(error, "sctp_paddrparams.spp_ipv6_flowlabel: expected: %u actual: %u",
 				 spp_ipv6_flowlabel, sctp_paddrparams->spp_ipv6_flowlabel);
 			return STATUS_ERR;
 		}
@@ -2081,7 +2105,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 	}
 	if (expr->spp_dscp->type != EXPR_ELLIPSIS) {
 #ifdef linux
-		asprintf(error, "Bad getsockopt linux doesn't support sctp_paddrparams.spp_dscp");
+		asprintf(error, "linux doesn't support sctp_paddrparams.spp_dscp");
 		return STATUS_ERR;
 #else
 		u8 spp_dscp;
@@ -2090,7 +2114,7 @@ static int check_sctp_paddrparams(struct sctp_paddrparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_paddrparams->spp_dscp != spp_dscp) {
-			asprintf(error, "Bad getsockopt sctp_paddrparams.spp_dscp: expected: %hhu actual: %hhu",
+			asprintf(error, "sctp_paddrparams.spp_dscp: expected: %hhu actual: %hhu",
 				 spp_dscp, sctp_paddrparams->spp_dscp);
 			return STATUS_ERR;
 		}
@@ -2112,7 +2136,7 @@ static int check_sctp_assoc_value(struct sctp_assoc_value_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assoc_value->assoc_value != assoc_value) {
-			asprintf(error, "Bad getsockopt sctp_assoc_value.assoc_value: expected: %u actual: %u",
+			asprintf(error, "sctp_assoc_value.assoc_value: expected: %u actual: %u",
 				 assoc_value, sctp_assoc_value->assoc_value);
 			return STATUS_ERR;
 		}
@@ -2133,7 +2157,7 @@ static int check_sctp_stream_value(struct sctp_stream_value_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_stream_value->stream_id != stream_id) {
-			asprintf(error, "Bad getsockopt sctp_stream_value.stream_id: expected: %u actual: %u",
+			asprintf(error, "sctp_stream_value.stream_id: expected: %u actual: %u",
 				 stream_id, sctp_stream_value->stream_id);
 			return STATUS_ERR;
 		}
@@ -2145,7 +2169,7 @@ static int check_sctp_stream_value(struct sctp_stream_value_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_stream_value->stream_value != stream_value) {
-			asprintf(error, "Bad getsockopt sctp_stream_value.stream_value: expected: %u actual: %u",
+			asprintf(error, "sctp_stream_value.stream_value: expected: %u actual: %u",
 				 stream_value, sctp_stream_value->stream_value);
 			return STATUS_ERR;
 		}
@@ -2166,7 +2190,7 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assocparams->sasoc_asocmaxrxt != sasoc_asocmaxrxt) {
-			asprintf(error, "Bad getsockopt sctp_assocparams.sasoc_asocmaxrxt: expected: %hu actual: %hu",
+			asprintf(error, "sctp_assocparams.sasoc_asocmaxrxt: expected: %hu actual: %hu",
 				 sasoc_asocmaxrxt, sctp_assocparams->sasoc_asocmaxrxt);
 			return STATUS_ERR;
 		}
@@ -2178,8 +2202,8 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assocparams->sasoc_number_peer_destinations != sasoc_number_peer_destinations) {
-			asprintf(error, "Bad getsockopt sctp_assocparams.sasoc_number_peer_destinations: expected: %hu actual: %hu",
-				 sasoc_number_peer_destinations, sctp_assocparams->sasoc_number_peer_destinations);
+			asprintf(error, "sctp_assocparams.sasoc_number_peer_destinations: expected: %hu actual: %hu",
+					 sasoc_number_peer_destinations, sctp_assocparams->sasoc_number_peer_destinations);
 			return STATUS_ERR;
 		}
 	}
@@ -2190,7 +2214,7 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assocparams->sasoc_peer_rwnd != sasoc_peer_rwnd) {
-			asprintf(error, "Bad getsockopt sctp_assocparams.sasoc_peer_rwnd: expected: %u actual: %u",
+			asprintf(error, "sctp_assocparams.sasoc_peer_rwnd: expected: %u actual: %u",
 				 sasoc_peer_rwnd, sctp_assocparams->sasoc_peer_rwnd);
 			return STATUS_ERR;
 		}
@@ -2202,7 +2226,7 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assocparams->sasoc_local_rwnd != sasoc_local_rwnd) {
-			asprintf(error, "Bad getsockopt sctp_assocparams.sasoc_local_rwnd: expected: %u actual: %u",
+			asprintf(error, "sctp_assocparams.sasoc_local_rwnd: expected: %u actual: %u",
 				 sasoc_local_rwnd, sctp_assocparams->sasoc_local_rwnd);
 			return STATUS_ERR;
 		}
@@ -2214,7 +2238,7 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_assocparams->sasoc_cookie_life != sasoc_cookie_life) {
-			asprintf(error, "Bad getsockopt sctp_assocparams.sasoc_cookie_life: expected: %u actual: %u",
+			asprintf(error, "sctp_assocparams.sasoc_cookie_life: expected: %u actual: %u",
 				 sasoc_cookie_life, sctp_assocparams->sasoc_cookie_life);
 			return STATUS_ERR;
 		}
@@ -2236,7 +2260,7 @@ static int check_sctp_event(struct sctp_event_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_event->se_type != se_type) {
-			asprintf(error, "Bad getsockopt sctp_event.se_type: expected: %hu actual: %hu",
+			asprintf(error, "sctp_event.se_type: expected: %hu actual: %hu",
 				 se_type, sctp_event->se_type);
 			return STATUS_ERR;
 		}
@@ -2248,7 +2272,7 @@ static int check_sctp_event(struct sctp_event_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_event->se_on != se_on) {
-			asprintf(error, "Bad getsockopt sctp_event.se_on: expected: %hhu actual: %hhu",
+			asprintf(error, "sctp_event.se_on: expected: %hhu actual: %hhu",
 				 se_on, sctp_event->se_on);
 			return STATUS_ERR;
 		}
@@ -2269,7 +2293,7 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sndinfo->snd_sid != snd_sid) {
-			asprintf(error, "Bad getsockopt sctp_sndinfo.snd_sid: expected: %hu actual: %hu",
+			asprintf(error, "sctp_sndinfo.snd_sid: expected: %hu actual: %hu",
 				 snd_sid, sctp_sndinfo->snd_sid);
 			return STATUS_ERR;
 		}
@@ -2281,7 +2305,7 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sndinfo->snd_flags != snd_flags) {
-			asprintf(error, "Bad getsockopt sctp_sndinfo.snd_flags: expected: %hu actual: %hu",
+			asprintf(error, "sctp_sndinfo.snd_flags: expected: %hu actual: %hu",
 				 snd_flags, sctp_sndinfo->snd_flags);
 			return STATUS_ERR;
 		}
@@ -2293,7 +2317,7 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sndinfo->snd_ppid != snd_ppid) {
-			asprintf(error, "Bad getsockopt sctp_sndinfo.snd_ppid: expected: %u actual: %u",
+			asprintf(error, "sctp_sndinfo.snd_ppid: expected: %u actual: %u",
 				 snd_ppid, sctp_sndinfo->snd_ppid);
 			return STATUS_ERR;
 		}
@@ -2305,7 +2329,7 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_sndinfo->snd_context != snd_context) {
-			asprintf(error, "Bad getsockopt sctp_sndinfo.snd_context: expected: %u actual: %u",
+			asprintf(error, "sctp_sndinfo.snd_context: expected: %u actual: %u",
 				 snd_context, sctp_sndinfo->snd_context);
 			return STATUS_ERR;
 		}
@@ -2326,7 +2350,7 @@ static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr,
 			return STATUS_ERR;
 		}
 		if (sctp_setadaptation->ssb_adaptation_ind != ssb_adaptation_ind) {
-			asprintf(error, "Bad getsockopt sctp_setadaptation.ssb_adaptation_ind: expected: %u actual: %u",
+			asprintf(error, "sctp_setadaptation.ssb_adaptation_ind: expected: %u actual: %u",
 				 ssb_adaptation_ind, sctp_setadaptation->ssb_adaptation_ind);
 			return STATUS_ERR;
 		}
@@ -2338,7 +2362,7 @@ static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr,
 static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 			      struct expression_list *args, char **error)
 {
-	int script_fd, live_fd, level, optname, result;
+	int script_fd, live_fd, level, optname, live_result, result = STATUS_OK;
 	s32 script_optval, script_optlen, expected;
 	void *live_optval;
 	socklen_t live_optlen;
@@ -2361,248 +2385,231 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	val_expression = get_arg(args, 3, error);
 	if (val_expression == NULL) {
 		return STATUS_ERR;
-	} else if (val_expression->type == EXPR_LINGER) {
+	}
+	switch (val_expression->type) {
+	case EXPR_LINGER:
 		live_optval = malloc(sizeof(struct linger));
 		live_optlen = (socklen_t)sizeof(struct linger);
+		break;
 #ifdef SCTP_RTOINFO
-	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
+	case EXPR_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;
+		break;
 #endif
 #ifdef SCTP_ASSOCINFO
-	} else if (val_expression->type == EXPR_SCTP_ASSOCPARAMS) {
+	case EXPR_SCTP_ASSOCPARAMS:
 		live_optval = malloc(sizeof(struct sctp_assocparams));
 		live_optlen = (socklen_t)sizeof(struct sctp_assocparams);
 		((struct sctp_assocparams*) live_optval)->sasoc_assoc_id = 0;
+		break;
 #endif
 #ifdef SCTP_INITMSG
-	} else if (val_expression->type == EXPR_SCTP_INITMSG) {
+	case EXPR_SCTP_INITMSG:
 		live_optval = malloc(sizeof(struct sctp_initmsg));
 		live_optlen = (socklen_t)sizeof(struct sctp_initmsg);
+		break;
 #endif
 #ifdef SCTP_DELAYED_SACK
-	} else if (val_expression->type == EXPR_SCTP_SACKINFO) {
+	case EXPR_SCTP_SACKINFO:
 		live_optval = malloc(sizeof(struct sctp_sack_info));
 		live_optlen = (socklen_t)sizeof(struct sctp_sack_info);
 		((struct sctp_sack_info*) live_optval)->sack_assoc_id = 0;
+		break;
 #endif
 #ifdef SCTP_STATUS
-	} else if (val_expression->type == EXPR_SCTP_STATUS) {
+	case EXPR_SCTP_STATUS:
 		live_optval = malloc(sizeof(struct sctp_status));
 		live_optlen = (socklen_t)sizeof(struct sctp_status);
 		((struct sctp_status*) live_optval)->sstat_assoc_id = 0;
+		break;
 #endif
 #ifdef SCTP_GET_PEER_ADDR_INFO
-	} else if (val_expression->type == EXPR_SCTP_PADDRINFO) {
+	case EXPR_SCTP_PADDRINFO: {
 		struct sctp_paddrinfo_expr *expr_paddrinfo = val_expression->value.sctp_paddrinfo;
 		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 (expr_paddrinfo->spinfo_address->type == EXPR_ELLIPSIS) {
-			socklen_t len_addr = sizeof(live_paddrinfo->spinfo_address);
-			if (getpeername(live_fd, (struct sockaddr*) &live_paddrinfo->spinfo_address, &len_addr)) {
-				asprintf(error, "Bad getsockopt, bad get primary peer address");
-				free(live_paddrinfo);
-				return STATUS_ERR;
-			}
-		} else if (expr_paddrinfo->spinfo_address->type == EXPR_SOCKET_ADDRESS_IPV4) {
-			memcpy(&live_paddrinfo->spinfo_address, expr_paddrinfo->spinfo_address->value.socket_address_ipv4, sizeof(struct sockaddr_in));
-		} else if (expr_paddrinfo->spinfo_address->type == EXPR_SOCKET_ADDRESS_IPV6) {
-			memcpy(&live_paddrinfo->spinfo_address, expr_paddrinfo->spinfo_address->value.socket_address_ipv6, sizeof(struct sockaddr_in6));
-		} else {
-			asprintf(error, "Bad getsockopt, bad get input for spinfo_address");
+		if (get_sockstorage_arg(expr_paddrinfo->spinfo_address,
+					&(live_paddrinfo->spinfo_address), live_fd)) {
+			asprintf(error, "can't determine spinfo_address");
 			free(live_paddrinfo);
 			return STATUS_ERR;
 		}
 		live_optval = live_paddrinfo;
+		break;
+	}
 #endif
 #ifdef SCTP_PEER_ADDR_PARAMS
-	} else if (val_expression->type == EXPR_SCTP_PEER_ADDR_PARAMS) {
+	case EXPR_SCTP_PEER_ADDR_PARAMS: {
 		struct sctp_paddrparams_expr *expr_params = val_expression->value.sctp_paddrparams;
 		struct sctp_paddrparams *live_params = malloc(sizeof(struct sctp_paddrparams));
 		memset(live_params, 0, sizeof(struct sctp_paddrparams));
 		live_optlen = sizeof(struct sctp_paddrparams);
-		if (expr_params->spp_address->type == EXPR_ELLIPSIS) {
-			socklen_t len_addr = sizeof(live_params->spp_address);
-			if (getpeername(live_fd, (struct sockaddr*) &live_params->spp_address, &len_addr)) {
-				asprintf(error, "Bad getsockopt, bad get primary peer address");
-				free(live_params);
-				return STATUS_ERR;
-			}
-		} else if (expr_params->spp_address->type == EXPR_SOCKET_ADDRESS_IPV4) {
-			memcpy(&live_params->spp_address, expr_params->spp_address->value.socket_address_ipv4, sizeof(struct sockaddr_in));
-		} else if (expr_params->spp_address->type == EXPR_SOCKET_ADDRESS_IPV6) {
-			memcpy(&live_params->spp_address, expr_params->spp_address->value.socket_address_ipv6, sizeof(struct sockaddr_in6));
-		} else {
-			asprintf(error, "Bad getsockopt, bad get input for spp_address");
+		if (get_sockstorage_arg(expr_params->spp_address, &live_params->spp_address,
+					live_fd)) {
+			asprintf(error, "can't determine spp_address");
 			free(live_params);
 			return STATUS_ERR;
 		}
 		live_params->spp_assoc_id = 0;
 		live_optval = live_params;
+		break;
+	}
 #endif
 #if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
-	} else if (val_expression->type == EXPR_SCTP_ASSOC_VALUE) {
+	case EXPR_SCTP_ASSOC_VALUE:
 		live_optval = malloc(sizeof(struct sctp_assoc_value));
 		live_optlen = (socklen_t)sizeof(struct sctp_assoc_value);
 		((struct sctp_assoc_value *) live_optval)->assoc_id = 0;
+		break;
 #endif
 #ifdef SCTP_SS_VALUE
-	} else if (val_expression->type == EXPR_SCTP_STREAM_VALUE) {
+	case EXPR_SCTP_STREAM_VALUE:
 		live_optval = malloc(sizeof(struct sctp_stream_value));
 		live_optlen = (socklen_t)sizeof(struct sctp_stream_value);
 		((struct sctp_stream_value *) live_optval)->assoc_id = 0;
 		if (get_u16(val_expression->value.sctp_stream_value->stream_id,
-		            &((struct sctp_stream_value *)live_optval)->stream_id,
-		            error)) {
+			    &((struct sctp_stream_value *)live_optval)->stream_id,
+			    error)) {
 			free(live_optval);
 			return STATUS_ERR;
 		}
+		break;
 #endif
 #ifdef SCTP_EVENT
-	} else if (val_expression->type == EXPR_SCTP_EVENT) {
+	case EXPR_SCTP_EVENT:
 		live_optval = malloc(sizeof(struct sctp_event));
 		live_optlen = sizeof(struct sctp_event);
-		((struct sctp_event *)live_optval)->se_assoc_id = 0; 
+		((struct sctp_event *)live_optval)->se_assoc_id = 0;
 		if (get_u16(val_expression->value.sctp_event->se_type,
-		            &((struct sctp_event *)live_optval)->se_type,
+			    &((struct sctp_event *)live_optval)->se_type,
 			    error)) {
-                        free(live_optval);
-                        return STATUS_ERR;
-                }
+			free(live_optval);
+			return STATUS_ERR;
+		}
+		break;
 #endif
 #ifdef SCTP_DEFAULT_SNDINFO
-	} else if (val_expression->type == EXPR_SCTP_SNDINFO) {
+	case EXPR_SCTP_SNDINFO:
 		live_optval = malloc(sizeof(struct sctp_sndinfo));
 		live_optlen = sizeof(struct sctp_sndinfo);
-		((struct sctp_sndinfo *)live_optval)->snd_assoc_id = 0; 
+		((struct sctp_sndinfo *)live_optval)->snd_assoc_id = 0;
+		break;
 #endif
 #ifdef SCTP_ADAPTATION_LAYER
-	} else if (val_expression->type == EXPR_SCTP_SETADAPTATION) {
+	case EXPR_SCTP_SETADAPTATION:
 		live_optval = malloc(sizeof(struct sctp_setadaptation));
 		live_optlen = sizeof(struct sctp_setadaptation);
+		break;
 #endif
-	} else {
+	case EXPR_LIST:
 		s32_bracketed_arg(args, 3, &script_optval, error);
 		live_optval = malloc(sizeof(int));
 		live_optlen = (socklen_t)sizeof(int);
+		break;
+	default:
+		asprintf(error, "unsupported value type: %s",
+			 expression_type_to_string(val_expression->type));
+		return STATUS_ERR;
+		break;
 	}
 
 	begin_syscall(state, syscall);
 
-	result = getsockopt(live_fd, level, optname, live_optval, &live_optlen);
+	live_result = getsockopt(live_fd, level, optname, live_optval, &live_optlen);
 
-	if (end_syscall(state, syscall, CHECK_NON_NEGATIVE, result, error)) {
+	if (end_syscall(state, syscall, CHECK_NON_NEGATIVE, live_result, error)) {
 		return STATUS_ERR;
 	}
 
 	if (live_optlen != script_optlen) {
-		asprintf(error, "Bad getsockopt optlen: expected: %d actual: %d",
+		asprintf(error, "optlen: expected: %d actual: %d",
 		         (int)script_optlen, (int)live_optlen);
 		free(live_optval);
 		return STATUS_ERR;
 	}
-	if (val_expression->type == EXPR_LINGER) {
-		if (check_linger(val_expression->value.linger, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+
+	switch (val_expression->type) {
+	case EXPR_LINGER:
+		result = check_linger(val_expression->value.linger, live_optval, error);
+		break;
 #ifdef SCTP_RTOINFO
-	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
-		if (check_sctp_rtoinfo(val_expression->value.sctp_rtoinfo, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_RTOINFO:
+		result = check_sctp_rtoinfo(val_expression->value.sctp_rtoinfo, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_ASSOCINFO
-	} else if (val_expression->type == EXPR_SCTP_ASSOCPARAMS) {
-		if (check_sctp_assocparams(val_expression->value.sctp_assocparams, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_ASSOCPARAMS:
+		result = check_sctp_assocparams(val_expression->value.sctp_assocparams, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_INITMSG
-	} else if (val_expression->type == EXPR_SCTP_INITMSG) {
-		if (check_sctp_initmsg(val_expression->value.sctp_initmsg, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_INITMSG:
+		result = check_sctp_initmsg(val_expression->value.sctp_initmsg, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_DELAYED_SACK
-	} else if (val_expression->type == EXPR_SCTP_SACKINFO) {
-		if (check_sctp_sack_info(val_expression->value.sctp_sack_info, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_SACKINFO:
+		result = check_sctp_sack_info(val_expression->value.sctp_sack_info, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_STATUS
-	} else if (val_expression->type == EXPR_SCTP_STATUS) {
-		if (check_sctp_status(val_expression->value.sctp_status, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_STATUS:
+		result = check_sctp_status(val_expression->value.sctp_status, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_GET_PEER_ADDR_INFO
-	} else if (val_expression->type == EXPR_SCTP_PADDRINFO) {
-		if (check_sctp_paddrinfo(val_expression->value.sctp_paddrinfo, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_PADDRINFO:
+		result = check_sctp_paddrinfo(val_expression->value.sctp_paddrinfo, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_PEER_ADDR_PARAMS
-	} else if (val_expression->type == EXPR_SCTP_PEER_ADDR_PARAMS) {
-		if (check_sctp_paddrparams(val_expression->value.sctp_paddrparams, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_PEER_ADDR_PARAMS:
+		result = check_sctp_paddrparams(val_expression->value.sctp_paddrparams, live_optval, error);
+		break;
 #endif
 #if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
-	} else if (val_expression->type == EXPR_SCTP_ASSOC_VALUE) {
-		if (check_sctp_assoc_value(val_expression->value.sctp_assoc_value, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_ASSOC_VALUE:
+		result = check_sctp_assoc_value(val_expression->value.sctp_assoc_value, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_SS_VALUE
-	} else if (val_expression->type == EXPR_SCTP_STREAM_VALUE) {
-		if (check_sctp_stream_value(val_expression->value.sctp_stream_value, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_STREAM_VALUE:
+		result = check_sctp_stream_value(val_expression->value.sctp_stream_value, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_EVENT
-	} else if (val_expression->type == EXPR_SCTP_EVENT) {
-		if (check_sctp_event(val_expression->value.sctp_event, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_EVENT:
+		result = check_sctp_event(val_expression->value.sctp_event, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_DEFAULT_SNDINFO
-	} else if (val_expression->type == EXPR_SCTP_SNDINFO) {
-		if (check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_SNDINFO:
+		result = check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error);
+		break;
 #endif
 #ifdef SCTP_ADAPTATION_LAYER
-	} else if (val_expression->type == EXPR_SCTP_SETADAPTATION) {
-		if (check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error)) {
-			free(live_optval);
-			return STATUS_ERR;
-		}
+	case EXPR_SCTP_SETADAPTATION:
+		result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error);
+		break;
 #endif
-	} else {
+	case EXPR_LIST:
 		if (*(int*)live_optval != script_optval) {
-			asprintf(error, "Bad getsockopt optval: expected: %d actual: %d",
+			asprintf(error, "optval: expected: %d actual: %d",
 				(int)script_optval, *(int*)live_optval);
-			free(live_optval);
-			return STATUS_ERR;
+			result = STATUS_ERR;
 		}
+		break;
+	default:
+		asprintf(error, "Cannot check value type: %s",
+			 expression_type_to_string(val_expression->type));
+		break;
 	}
 	free(live_optval);
-	return STATUS_OK;
+	return result;
 }
 
 static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
@@ -2784,7 +2791,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		if (get_u32(val_expression->value.sctp_sack_info->sack_freq,
 		            &sack_info.sack_freq, error)) {
 			return STATUS_ERR;
-		}		
+		}
 		optval = &sack_info;
 		break;
 #endif
@@ -2797,24 +2804,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #ifdef SCTP_GET_PEER_ADDR_INFO
 	case EXPR_SCTP_PADDRINFO:
 		paddrinfo.spinfo_assoc_id = 0;
-		if (val_expression->value.sctp_paddrinfo->spinfo_address->type == EXPR_SOCKET_ADDRESS_IPV4) {
-			memcpy(&paddrinfo.spinfo_address,
-			       val_expression->value.sctp_paddrinfo->spinfo_address->value.socket_address_ipv4,
-			       sizeof(struct sockaddr_in));
-		} else if (val_expression->value.sctp_paddrinfo->spinfo_address->type == EXPR_SOCKET_ADDRESS_IPV6) {
-			memcpy(&paddrinfo.spinfo_address,
-			       val_expression->value.sctp_paddrinfo->spinfo_address->value.socket_address_ipv6,
-			       sizeof(struct sockaddr_in6));
-		} else if (val_expression->value.sctp_paddrinfo->spinfo_address->type == EXPR_ELLIPSIS) {
-			socklen_t len_addr = sizeof(struct sockaddr_storage);
-			if (getpeername(live_fd,
-			                (struct sockaddr*)&paddrinfo.spinfo_address,
-			                &len_addr)) {
-				asprintf(error, "Bad setsockopt, bad get primary peer address");
-				return STATUS_ERR;
-			}
-		} else {
-			asprintf(error, "Bad setsockopt, bad input for spinfo_address for socketoption SCTP_GET_PEER_ADDR_INFO");
+		if (get_sockstorage_arg(val_expression->value.sctp_paddrinfo->spinfo_address,
+					&paddrinfo.spinfo_address, live_fd)) {
+			asprintf(error, "can't determine spp_address");
 			return STATUS_ERR;
 		}
 		optval = &paddrinfo;
@@ -2868,24 +2860,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #ifdef SCTP_PEER_ADDR_PARAMS
 	case EXPR_SCTP_PEER_ADDR_PARAMS:
 		paddrparams.spp_assoc_id = 0;
-		if (val_expression->value.sctp_paddrparams->spp_address->type == EXPR_SOCKET_ADDRESS_IPV4) {
-			memcpy(&paddrparams.spp_address,
-			       val_expression->value.sctp_paddrparams->spp_address->value.socket_address_ipv4,
-			       sizeof(struct sockaddr_in));
-		} else if (val_expression->value.sctp_paddrparams->spp_address->type == EXPR_SOCKET_ADDRESS_IPV6) {
-			memcpy(&paddrparams.spp_address,
-			       val_expression->value.sctp_paddrparams->spp_address->value.socket_address_ipv6,
-			       sizeof(struct sockaddr_in6));
-		} else if (val_expression->value.sctp_paddrparams->spp_address->type == EXPR_ELLIPSIS) {
-			socklen_t len_addr = sizeof(struct sockaddr_storage);
-			if (getpeername(live_fd,
-			                (struct sockaddr*)&paddrparams.spp_address,
-			                &len_addr)) {
-				asprintf(error, "Bad setsockopt, bad get primary peer address");
-				return STATUS_ERR;
-			}
-		} else {
-			asprintf(error, "Bad setsockopt, bad input for spp_address for socketoption SCTP_PADDRPARAMS");
+		if (get_sockstorage_arg(val_expression->value.sctp_paddrparams->spp_address,
+				        &paddrparams.spp_address, live_fd)) {
+			asprintf(error, "can't determine spp_address");
 			return STATUS_ERR;
 		}
 		if (get_u32(val_expression->value.sctp_paddrparams->spp_hbinterval,
@@ -2919,14 +2896,14 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		            &spp_ipv6_flowlabel, error)) {
 			return STATUS_ERR;
 		} else if (spp_ipv6_flowlabel != 0) {
-			asprintf(error, "Bad setsockopt, Linux doesn't support paddrparams.spp_ipv6_flowlabel");
+			asprintf(error, "Linux doesn't support paddrparams.spp_ipv6_flowlabel");
 			return STATUS_ERR;
 		}
 		if (get_u8(val_expression->value.sctp_paddrparams->spp_dscp,
 		           &spp_dscp, error)) {
 			return STATUS_ERR;
 		} else if (spp_dscp != 0) {
-			asprintf(error, "Bad setsockopt, Linux doesn't support paddrparams.spp_dscp");
+			asprintf(error, "Linux doesn't support paddrparams.spp_dscp");
 			return STATUS_ERR;
 		}
 		paddrparams.spp_sackdelay = 0;
@@ -2935,7 +2912,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		break;
 #endif
 	default:
-		asprintf(error, "unsupported setsockopt value type: %s",
+		asprintf(error, "unsupported value type: %s",
 			 expression_type_to_string(val_expression->type));
 		return STATUS_ERR;
 		break;
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 4f3b93549a30ddd6c21580542ad2630b5631abce..5c07f3ee5053bf66edcf3a688dba82a8c9bb82dd 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -65,40 +65,18 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_IOVEC,                "iovec" },
 	{ EXPR_MSGHDR,               "msghdr" },
 	{ EXPR_POLLFD,               "pollfd" },
-#ifdef SCTP_RTOINFO
 	{ EXPR_SCTP_RTOINFO,         "sctp_rtoinfo"},
-#endif
-#ifdef SCTP_INITMSG
 	{ EXPR_SCTP_INITMSG,         "sctp_initmsg"},
-#endif
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 	{ EXPR_SCTP_ASSOC_VALUE,     "sctp_assoc_value"},
-#endif
-#ifdef SCTP_DELAYED_SACK
 	{ EXPR_SCTP_SACKINFO,        "sctp_sackinfo"},
-#endif
-#ifdef SCTP_STATUS
 	{ EXPR_SCTP_STATUS,          "sctp_status"},
 	{ EXPR_SCTP_PADDRINFO,	     "sctp_paddrinfo"},
-#endif
-#ifdef SCTP_PEER_ADDR_PARAMS
-	{ EXPR_SCTP_PEER_ADDR_PARAMS,	"sctp_peer_addr_params"},
-#endif
-#ifdef SCTP_SS_VALUE
+	{ EXPR_SCTP_PEER_ADDR_PARAMS,"sctp_peer_addr_params"},
 	{ EXPR_SCTP_STREAM_VALUE,    "sctp_stream_value"},
-#endif
-#ifdef SCTP_ASSOCINFO
 	{ EXPR_SCTP_ASSOCPARAMS,     "sctp_assocparams"},
-#endif
-#ifdef SCTP_EVENT
 	{ EXPR_SCTP_EVENT,	     "sctp_event"      },
-#endif
-#ifdef SCTP_DEFAULT_SNDINFO
 	{ EXPR_SCTP_SNDINFO,         "sctp_sndinfo"    },
-#endif
-#ifdef SCTP_ADAPTATION_LAYER
 	{ EXPR_SCTP_SETADAPTATION,   "sctp_setadaptation"},
-#endif
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -310,21 +288,16 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.linger->l_onoff);
 		free_expression(expression->value.linger->l_linger);
 		break;
-#ifdef SCTP_RTOINFO
 	case EXPR_SCTP_RTOINFO:
 		assert(expression->value.sctp_rtoinfo);
 		free_expression(expression->value.sctp_rtoinfo->srto_initial);
 		free_expression(expression->value.sctp_rtoinfo->srto_max);
 		free_expression(expression->value.sctp_rtoinfo->srto_min);
 		break;
-#endif
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 	case EXPR_SCTP_ASSOC_VALUE:
 		assert(expression->value.sctp_assoc_value);
 		free_expression(expression->value.sctp_assoc_value->assoc_value);
 		break;
-#endif
-#ifdef SCTP_INITMSG
 	case EXPR_SCTP_INITMSG:
 		assert(expression->value.sctp_initmsg);
 		free_expression(expression->value.sctp_initmsg->sinit_num_ostreams);
@@ -332,15 +305,11 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_initmsg->sinit_max_attempts);
 		free_expression(expression->value.sctp_initmsg->sinit_max_init_timeo);
 		break;
-#endif
-#ifdef SCTP_DELAYED_SACK
 	case EXPR_SCTP_SACKINFO:
 		assert(expression->value.sctp_sack_info);
 		free_expression(expression->value.sctp_sack_info->sack_delay);
 		free_expression(expression->value.sctp_sack_info->sack_freq);		
 		break;
-#endif
-#ifdef SCTP_STATUS
 	case EXPR_SCTP_PADDRINFO:
 		assert(expression->value.sctp_paddrinfo);
 		free_expression(expression->value.sctp_paddrinfo->spinfo_address);
@@ -361,8 +330,6 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_status->sstat_fragmentation_point);
 		free_expression(expression->value.sctp_status->sstat_primary);
 		break;
-#endif
-#ifdef SCTP_PEER_ADDR_PARAMS
 	case EXPR_SCTP_PEER_ADDR_PARAMS:
 		assert(expression->value.sctp_paddrparams);
 		free_expression(expression->value.sctp_paddrparams->spp_address);
@@ -373,15 +340,11 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_paddrparams->spp_ipv6_flowlabel);
 		free_expression(expression->value.sctp_paddrparams->spp_dscp);
 		break;
-#endif
-#ifdef SCTP_SS_VALUE
 	case EXPR_SCTP_STREAM_VALUE:
 		assert(expression->value.sctp_stream_value);
 		free_expression(expression->value.sctp_stream_value->stream_id);
 		free_expression(expression->value.sctp_stream_value->stream_value);
 		break;
-#endif
-#ifdef SCTP_ASSOCINFO
 	case EXPR_SCTP_ASSOCPARAMS:
 		free_expression(expression->value.sctp_assocparams->sasoc_asocmaxrxt);
 		free_expression(expression->value.sctp_assocparams->sasoc_number_peer_destinations);
@@ -389,26 +352,19 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_assocparams->sasoc_local_rwnd);
 		free_expression(expression->value.sctp_assocparams->sasoc_cookie_life);
 		break;
-#endif
-#ifdef SCTP_EVENT
 	case EXPR_SCTP_EVENT:
 		free_expression(expression->value.sctp_event->se_type);
 		free_expression(expression->value.sctp_event->se_on);
 		break;
-#endif
-#ifdef SCTP_DEFAULT_SNDINFO
 	case EXPR_SCTP_SNDINFO:
 		free_expression(expression->value.sctp_sndinfo->snd_sid);
 		free_expression(expression->value.sctp_sndinfo->snd_flags);
 		free_expression(expression->value.sctp_sndinfo->snd_ppid);
 		free_expression(expression->value.sctp_sndinfo->snd_context);
 		break;		
-#endif
-#ifdef SCTP_ADAPTATION_LAYER
 	case EXPR_SCTP_SETADAPTATION:
 		free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind);
 		break;
-#endif
 	case EXPR_WORD:
 		assert(expression->value.string);
 		free(expression->value.string);
@@ -594,7 +550,6 @@ static int evaluate_pollfd_expression(struct expression *in,
 	return STATUS_OK;
 }
 
-#ifdef SCTP_RTOINFO
 static int evaluate_sctp_rtoinfo_expression(struct expression *in,
 					    struct expression *out,
 					    char **error)
@@ -626,9 +581,7 @@ static int evaluate_sctp_rtoinfo_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_INITMSG
 static int evaluate_sctp_initmsg_expression(struct expression *in,
 					    struct expression *out,
 					    char **error)
@@ -663,9 +616,7 @@ static int evaluate_sctp_initmsg_expression(struct expression *in,
 		return STATUS_ERR;
 	return STATUS_OK;
 }
-#endif
 
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 static int evaluate_sctp_assoc_value_expression(struct expression *in,
 						struct expression *out,
 						char **error)
@@ -689,9 +640,7 @@ static int evaluate_sctp_assoc_value_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_DELAYED_SACK
 static int evaluate_sctp_sack_info_expression(struct expression *in,
 					    struct expression *out,
 					    char **error)
@@ -719,9 +668,7 @@ static int evaluate_sctp_sack_info_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_STATUS
 static int evaluate_sctp_paddrinfo_expression(struct expression *in,
 					      struct expression *out,
 					      char **error)
@@ -816,9 +763,7 @@ static int evaluate_sctp_status_expression(struct expression *in,
 		return STATUS_ERR;
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_PEER_ADDR_PARAMS
 static int evaluate_sctp_peer_addr_param_expression(struct expression *in,
 						    struct expression *out,
 						    char **error)
@@ -865,9 +810,7 @@ static int evaluate_sctp_peer_addr_param_expression(struct expression *in,
 		return STATUS_ERR;
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_SS_VALUE
 static int evaluate_sctp_stream_value_expression(struct expression *in,
 						 struct expression *out,
 						 char **error)
@@ -895,9 +838,7 @@ static int evaluate_sctp_stream_value_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_EVENT
 static int evaluate_sctp_event_expression(struct expression *in,
 						 struct expression *out,
 						 char **error)
@@ -925,9 +866,7 @@ static int evaluate_sctp_event_expression(struct expression *in,
 
 	return STATUS_OK; 
 }
-#endif
 
-#ifdef SCTP_ASSOCINFO
 static int evaluate_sctp_accocparams_expression(struct expression *in,
 						struct expression *out,
 						char **error)
@@ -967,9 +906,7 @@ static int evaluate_sctp_accocparams_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_DEFAULT_SNDINFO
 static int evaluate_sctp_sndinfo_expression(struct expression *in,
 					    struct expression *out,
 					    char **error)
@@ -1004,9 +941,7 @@ static int evaluate_sctp_sndinfo_expression(struct expression *in,
 		return STATUS_ERR;
 	return STATUS_OK;
 }
-#endif
 
-#ifdef SCTP_ADAPTATION_LAYER
 static int evaluate_sctp_setadaptation_expression(struct expression *in,
 						  struct expression *out,
 						  char **error)
@@ -1030,7 +965,6 @@ static int evaluate_sctp_setadaptation_expression(struct expression *in,
 
 	return STATUS_OK;
 }
-#endif
 
 static int evaluate(struct expression *in,
 		    struct expression **out_ptr, char **error)
@@ -1055,64 +989,42 @@ static int evaluate(struct expression *in,
 		memcpy(&out->value.linger, &in->value.linger,
 		       sizeof(in->value.linger));
 		break;
-#ifdef SCTP_RTOINFO
 	case EXPR_SCTP_RTOINFO:
-		evaluate_sctp_rtoinfo_expression(in, out, error);
+		result = evaluate_sctp_rtoinfo_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_ASSOCINFO
 	case EXPR_SCTP_ASSOCPARAMS:
-		evaluate_sctp_accocparams_expression(in, out, error);
+		result = evaluate_sctp_accocparams_expression(in, out, error);
 		break;
-#endif	
-#ifdef SCTP_INITMSG
 	case EXPR_SCTP_INITMSG:
-		evaluate_sctp_initmsg_expression(in, out, error);
+		result = evaluate_sctp_initmsg_expression(in, out, error);
 		break;
-#endif
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 	case EXPR_SCTP_ASSOC_VALUE:
-		evaluate_sctp_assoc_value_expression(in, out, error);
+		result = evaluate_sctp_assoc_value_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_DELAYED_SACK
 	case EXPR_SCTP_SACKINFO:
-		evaluate_sctp_sack_info_expression(in, out, error);	
+		result = evaluate_sctp_sack_info_expression(in, out, error);	
 		break;
-#endif
-#ifdef SCTP_STATUS
 	case EXPR_SCTP_PADDRINFO:
-		evaluate_sctp_paddrinfo_expression(in, out, error);
+		result = evaluate_sctp_paddrinfo_expression(in, out, error);
 		break;
 	case EXPR_SCTP_STATUS:
 		result = evaluate_sctp_status_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_PEER_ADDR_PARAMS
 	case EXPR_SCTP_PEER_ADDR_PARAMS:
 		result = evaluate_sctp_peer_addr_param_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_SS_VALUE
 	case EXPR_SCTP_STREAM_VALUE:
-		evaluate_sctp_stream_value_expression(in, out, error);
+		result = evaluate_sctp_stream_value_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_EVENT
 	case EXPR_SCTP_EVENT:
 		result = evaluate_sctp_event_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_DEFAULT_SNDINFO
 	case EXPR_SCTP_SNDINFO:
 		result = evaluate_sctp_sndinfo_expression(in, out, error);
 		break;
-#endif
-#ifdef SCTP_ADAPTATION_LAYER
 	case EXPR_SCTP_SETADAPTATION:
 		result = evaluate_sctp_setadaptation_expression(in, out, error);
 		break;
-#endif
 	case EXPR_WORD:
 		out->type = EXPR_INTEGER;
 		if (symbol_to_int(in->value.string,
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index ecd3a56d0a12762ac50a73371e9dca9cc368a6cb..c614f9d7053d8e3363e8b3bbe254f2f84cc362fd 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -45,41 +45,18 @@ enum expression_t {
 	EXPR_IOVEC,		  /* expression tree for an iovec struct */
 	EXPR_MSGHDR,		  /* expression tree for a msghdr struct */
 	EXPR_POLLFD,		  /* expression tree for a pollfd struct */
-#ifdef SCTP_RTOINFO
 	EXPR_SCTP_RTOINFO,	  /* struct sctp_rtoinfo for SCTP_RTOINFO */
-#endif
-#ifdef SCTP_INITMSG
 	EXPR_SCTP_INITMSG,	  /* struct sctp_initmsg for SCTP_INITMSG */
-#endif
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 	EXPR_SCTP_ASSOC_VALUE,	  /* struct sctp_assoc_value */
-#endif
-#ifdef SCTP_DELAYED_SACK
-	EXPR_SCTP_SACKINFO,	  /* struct sctp_sack_info_expr for
-				   * SCTP_DELAYED_SACK */
-#endif
-#ifdef SCTP_STATUS
+	EXPR_SCTP_SACKINFO,	  /* struct sctp_sack_info_expr for */
 	EXPR_SCTP_STATUS,	  /* struct sctp_status for SCTP_STATUS */
 	EXPR_SCTP_PADDRINFO,
-#endif
-#ifdef SCTP_SS_VALUE
 	EXPR_SCTP_STREAM_VALUE,	  /* struct sctp_stream_value for SCTP_SS_VALUE */
-#endif
-#ifdef SCTP_PEER_ADDR_PARAMS
 	EXPR_SCTP_PEER_ADDR_PARAMS,	 /* struct for sctp_paddrparams for SCTP_PEER_ADDR_PARAMS */
-#endif
-#ifdef SCTP_ASSOCINFO
 	EXPR_SCTP_ASSOCPARAMS,    /* struct sctp_assocparams for SCTP_ASSOCINFO */
-#endif
-#ifdef SCTP_EVENT
 	EXPR_SCTP_EVENT,	  /* struct sctp_event for SCTP_EVENT */
-#endif
-#ifdef SCTP_DEFAULT_SNDINFO
 	EXPR_SCTP_SNDINFO,	  /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */
-#endif
-#ifdef SCTP_ADAPTATION_LAYER
 	EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
-#endif
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -99,40 +76,18 @@ struct expression {
 		struct iovec_expr *iovec;
 		struct msghdr_expr *msghdr;
 		struct pollfd_expr *pollfd;
-#ifdef SCTP_RTOINFO
 		struct sctp_rtoinfo_expr *sctp_rtoinfo;
-#endif
-#ifdef SCTP_INITMSG
 		struct sctp_initmsg_expr *sctp_initmsg;
-#endif
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 		struct sctp_assoc_value_expr *sctp_assoc_value;
-#endif
-#ifdef SCTP_DELAYED_SACK
 		struct sctp_sack_info_expr *sctp_sack_info;
-#endif
-#ifdef SCTP_STATUS
 		struct sctp_status_expr *sctp_status;
 		struct sctp_paddrinfo_expr *sctp_paddrinfo;
-#endif
-#ifdef SCTP_PEER_ADDR_PARAMS
 		struct sctp_paddrparams_expr *sctp_paddrparams;
-#endif
-#ifdef SCTP_SS_VALUE
 		struct sctp_stream_value_expr *sctp_stream_value;
-#endif
-#ifdef SCTP_ASSOCINFO
 		struct sctp_assocparams_expr *sctp_assocparams;
-#endif
-#ifdef SCTP_EVENT
 		struct sctp_event_expr *sctp_event;
-#endif
-#ifdef SCTP_DEFAULT_SNDINFO
 		struct sctp_sndinfo_expr *sctp_sndinfo;
-#endif
-#ifdef SCTP_ADAPTATION_LAYER
 		struct sctp_setadaptation_expr *sctp_setadaptation;
-#endif
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
@@ -180,15 +135,12 @@ struct linger_expr {
 	struct expression *l_linger;
 };
 /* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */
-#ifdef SCTP_RTOINFO
 struct sctp_rtoinfo_expr {
 	struct expression *srto_initial;
 	struct expression *srto_max;
 	struct expression *srto_min;
 };
-#endif
 
-#ifdef SCTP_INITMSG
 /* Parse tree for a sctp_initmsg struct in a [gs]etsockopt syscall. */
 struct sctp_initmsg_expr {
 	struct expression *sinit_num_ostreams;
@@ -196,32 +148,25 @@ struct sctp_initmsg_expr {
 	struct expression *sinit_max_attempts;
 	struct expression *sinit_max_init_timeo;
 };
-#endif
 
-#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 /* Parse tree for a sctp_assoc_value struct in a [gs]etsockopt syscall. */
 struct sctp_assoc_value_expr {
 	struct expression *assoc_value;
 };
-#endif
 
-#ifdef SCTP_SS_VALUE
 /* Parse tree for a sctp_stream_value struct in a [gs]etsockopt syscall. */
 struct sctp_stream_value_expr {
 	struct expression *stream_id;
 	struct expression *stream_value;
 };
-#endif
 
-#ifdef SCTP_DELAYED_SACK
 /* Parse tree for a sctp_sack_info struct in a [gs]etsockopt syscall. */
 struct sctp_sack_info_expr {
 	struct expression *sack_delay;
 	struct expression *sack_freq;
 };
-#endif
+
 /* Parse tree for a sctp_status struct in a [gs]etsockopt syscall. */
-#ifdef SCTP_STATUS
 struct sctp_status_expr {
 	struct expression *sstat_state;
 	struct expression *sstat_rwnd;
@@ -242,7 +187,6 @@ struct sctp_paddrinfo_expr {
 	struct expression *spinfo_rto;
 	struct expression *spinfo_mtu;
 };
-#endif
 
 /* Parse tree for a sctp_paddrparams struct in a [gs]etsockopt syscall. */
 struct sctp_paddrparams_expr {
@@ -255,7 +199,6 @@ struct sctp_paddrparams_expr {
 	struct expression *spp_dscp;
 };
 
-#ifdef SCTP_ASSOCINFO
 /* Parse tree for sctp_assocparams struct in [gs]etsockopt syscall. */
 struct sctp_assocparams_expr {
 	struct expression *sasoc_asocmaxrxt;
@@ -264,17 +207,13 @@ struct sctp_assocparams_expr {
 	struct expression *sasoc_local_rwnd;
 	struct expression *sasoc_cookie_life;
 };
-#endif
 
-#ifdef SCTP_EVENT
 /* Parse tree for sctp_event struct in [gs]etsockopt syscall. */
 struct sctp_event_expr {
 	struct expression *se_type;
 	struct expression *se_on;
 };
-#endif
 
-#ifdef SCTP_DEFAULT_SNDINFO
 /* Parse tree for sctp_sndinfo struct in [gs]etsockopt syscall. */
 struct sctp_sndinfo_expr {
 	struct expression *snd_sid;
@@ -282,14 +221,11 @@ struct sctp_sndinfo_expr {
 	struct expression *snd_ppid;
 	struct expression *snd_context;
 };
-#endif
 
-#ifdef SCTP_ADAPTATION_LAYER
 /* Parse tree for sctp_setadaptation struct in [gs]etsockopt syscall. */
 struct sctp_setadaptation_expr {
 	struct expression *ssb_adaptation_ind;
 };
-#endif
 
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
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 0cd0e2782d3dac117cdea1e727f12af2c1a3b2c4..1c5977792ac854e857f3733b7803f8826aaa9c57 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,7 +8,7 @@
 +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.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
 
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=..., sstat_rwnd=..., sstat_unackdata=..., sstat_penddata=...,
 sstat_instrms=..., sstat_outstrms=..., sstat_fragmentation_point=..., sstat_primary=...}, 176) = -1
diff --git a/gtests/net/packetdrill/tests/linux/sctp/sctp_socket_options.pkt b/gtests/net/packetdrill/tests/linux/sctp/sctp_socket_options.pkt
new file mode 100644
index 0000000000000000000000000000000000000000..bd49d1c95f15dac147462a5f412ac60c18eadbe5
--- /dev/null
+++ b/gtests/net/packetdrill/tests/linux/sctp/sctp_socket_options.pkt
@@ -0,0 +1,51 @@
+0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
+
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=200, srto_min=50}, 16) = 0
++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) = -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)
+
++0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=1024, sinit_max_instreams=1024, sinit_max_attempts=5, sinit_max_init_timeo=100}, 8) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=1024, sinit_max_instreams=1024, sinit_max_attempts=5, sinit_max_init_timeo=100}, 9) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=1024, sinit_max_instreams=1024, sinit_max_attempts=5, sinit_max_init_timeo=100}, 7) = -1  EINVAL (Invalid argument)
+
++0 setsockopt(3, IPPROTO_SCTP, SCTP_NODELAY, [1], 4) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_NODELAY, [5], 4) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_NODELAY, [1], 5) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_NODELAY, [1], 3) = -1 EINVAL (Invalid argument)
+
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, [1000], 4) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, [1000], [4]) = 0
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=1}, 8) = 0
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=0}, 8) = 0
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=1024}, 8) = 0
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=1}, 9) = 0
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=1}, 7) = -1 EINVAL (Invalid argument)
+
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=1000, sack_freq=0}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=500, sack_freq=0}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=200, sack_freq=0}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=100, sack_freq=0}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=10, sack_freq=0}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=0, sack_freq=1}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=0, sack_freq=2}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=0, sack_freq=4}, 12) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=200, sack_freq=2}, 13) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=200, sack_freq=2}, 11) = -1 EINVAL (Invalid argument)
+
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=1}, 8) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=0}, 8) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=1024}, 8) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=1}, 9) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=1}, 7) = -1 EINVAL (Invalid argument)
+
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address=..., spp_hbinterval=30000, spp_pathmaxrxt=100, spp_pathmtu=1468, spp_flags=0, spp_ipv6_flowlabel=0, spp_dscp=0}, [152]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")},
+spp_hbinterval=30000, spp_pathmaxrxt=6, spp_pathmtu=..., spp_flags=..., spp_ipv6_flowlabel=..., spp_dscp=...}, [152]) = 0
+
++0 close(3) = 0