diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index bca3df3b2360ed450acebdffd7ed10c5a8436cfd..694876727fc3a75743a4d2a8fd038a06c3226a15 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -202,6 +202,8 @@ ect0				return ECT0;
 ect1				return ECT1;
 noecn				return NO_ECN;
 ce				return CE;
+iov_base			return IOV_BASE;
+iov_len				return IOV_LEN;
 [.][.][.]			return ELLIPSIS;
 assoc_value			return ASSOC_VALUE;
 stream_id			return STREAM_ID;
@@ -256,6 +258,13 @@ sinfo_context			return SINFO_CONTEXT;
 sinfo_timetolive		return SINFO_TIMETOLIVE;
 sinfo_tsn			return SINFO_TSN;
 sinfo_cumtsn			return SINFO_CUMTSN;
+pr_policy			return PR_POLICY;
+pr_value			return PR_VALUE;
+auth_keynumber			return AUTH_KEYNUMBER;
+sendv_flags			return SENDV_FLAGS;
+sendv_sndinfo			return SENDV_SNDINFO;
+sendv_prinfo			return SENDV_PRINFO;
+sendv_authinfo			return SENDV_AUTHINFO;
 CHUNK				return CHUNK;
 DATA				return DATA;
 INIT				return INIT;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index d6ce691cc26dd4925893a8914185cbff69baa88e..180003aea1e11ae1451f4940821e02a01a82db87 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -498,6 +498,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> FD EVENTS REVENTS ONOFF LINGER
 %token <reserved> ACK ECR EOL MSS NOP SACK SACKOK TIMESTAMP VAL WIN WSCALE PRO
 %token <reserved> FAST_OPEN
+%token <reserved> IOV_BASE IOV_LEN
 %token <reserved> ECT0 ECT1 CE ECT01 NO_ECN
 %token <reserved> IPV4 IPV6 ICMP SCTP UDP UDPLITE GRE MTU
 %token <reserved> MPLS LABEL TC TTL
@@ -541,6 +542,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> BAD_CRC32C NULL_
 %token <reserved> SINFO_STREAM SINFO_SSN SINFO_FLAGS SINFO_PPID SINFO_CONTEXT
 %token <reserved> SINFO_TIMETOLIVE SINFO_TSN SINFO_CUMTSN
+%token <reserved> PR_POLICY PR_VALUE AUTH_KEYNUMBER SENDV_FLAGS SENDV_SNDINFO
+%token <reserved> SENDV_PRINFO SENDV_AUTHINFO
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -593,6 +596,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_event se_type se_on sctp_setadaptation null
 %type <expression> sctp_sndrcvinfo sinfo_stream sinfo_ssn sinfo_flags sinfo_ppid sinfo_context
 %type <expression> sinfo_timetolive sinfo_tsn sinfo_cumtsn
+%type <expression> sctp_prinfo sctp_authinfo pr_policy sctp_sendv_spa
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2456,10 +2460,19 @@ expression
 | sctp_setadaptation{
 	$$ = $1;
 }
-| null              {
+| sctp_sndrcvinfo   {
 	$$ = $1;
 }
-| sctp_sndrcvinfo   {
+| sctp_prinfo       {
+	$$ = $1;
+}
+| sctp_authinfo     {
+	$$ = $1;
+}
+| sctp_sendv_spa    {
+	$$ = $1;
+}
+| null              {
 	$$ = $1;
 }
 ;
@@ -2562,6 +2575,13 @@ iovec
 	iov_expr->iov_base = new_expression(EXPR_ELLIPSIS);
 	iov_expr->iov_len = $4;
 }
+| '{' IOV_BASE '=' ELLIPSIS ',' IOV_LEN '=' decimal_integer '}' {
+	struct iovec_expr *iov_expr = calloc(1, sizeof(struct iovec_expr));
+	$$ = new_expression(EXPR_IOVEC);
+	$$->value.iovec = iov_expr;
+	iov_expr->iov_base = new_expression(EXPR_ELLIPSIS);
+	iov_expr->iov_len = $8;
+}
 ;
 
 pollfd
@@ -3228,6 +3248,53 @@ sctp_sndrcvinfo
 	$$->value.sctp_sndrcvinfo->sinfo_tsn = $14;
 	$$->value.sctp_sndrcvinfo->sinfo_cumtsn = $16;
 };
+
+pr_policy
+: PR_POLICY '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| PR_POLICY '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("pr_policy out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+};
+
+sctp_prinfo
+: '{' pr_policy ',' PR_VALUE '=' INTEGER'}' {
+	$$ = new_expression(EXPR_SCTP_PRINFO);
+	$$->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr));
+	$$->value.sctp_prinfo->pr_policy = $2;
+	if (!is_valid_u32($6)) {
+		semantic_error("pr_value out of range");
+	}
+	$$->value.sctp_prinfo->pr_value = new_integer_expression($6, "%u");
+}
+;
+
+sctp_authinfo
+: '{' AUTH_KEYNUMBER '=' INTEGER '}' {
+	$$ = new_expression(EXPR_SCTP_AUTHINFO);
+	$$->value.sctp_authinfo = calloc(1, sizeof(struct sctp_authinfo_expr));
+	if (!is_valid_u16($4)) {
+		semantic_error("auth_keynumber out of range");
+	}
+	$$->value.sctp_authinfo->auth_keynumber = new_integer_expression($4, "%hu");
+}
+;
+
+sctp_sendv_spa
+: '{' SENDV_FLAGS '=' expression ',' SENDV_SNDINFO '=' expression ',' SENDV_PRINFO '=' expression ',' SENDV_AUTHINFO '=' expression '}' {
+	$$ = new_expression(EXPR_SCTP_SENDV_SPA);
+	$$->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_sendv_spa_expr));
+	$$->value.sctp_sendv_spa->sendv_flags = $4;
+	$$->value.sctp_sendv_spa->sendv_sndinfo = $8;
+	$$->value.sctp_sendv_spa->sendv_prinfo = $12;
+	$$->value.sctp_sendv_spa->sendv_authinfo = $16;
+}
+;
+
 opt_errno
 :                   { $$ = NULL; }
 | WORD note         {
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 10db6470af2447668cfbcbe73ba209b211ebb128..5775c62ccdd2678407b8b70aa9b4200673f243d9 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -122,7 +122,44 @@ static int get_arg_count(struct expression_list *args)
 {
 	return expression_list_length(args);
 }
-
+/* This table maps expression types to human-readable strings */
+struct expression_type_entry {
+        enum expression_t type;
+        const char *name;
+};
+struct expression_type_entry expression_type_table2[] = {
+        { EXPR_NONE,                 "none" },
+        { EXPR_NULL,                 "null" },
+        { EXPR_ELLIPSIS,             "ellipsis" },
+        { EXPR_INTEGER,              "integer" },
+        { EXPR_WORD,                 "word" },
+        { EXPR_STRING,               "string" },
+        { EXPR_SOCKET_ADDRESS_IPV4,  "sockaddr_in" },
+        { EXPR_SOCKET_ADDRESS_IPV6,  "sockaddr_in6" },
+        { EXPR_LINGER,               "linger" },
+        { EXPR_BINARY,               "binary_expression" },
+        { EXPR_LIST,                 "list" },
+        { EXPR_IOVEC,                "iovec" },
+        { EXPR_MSGHDR,               "msghdr" },
+        { EXPR_POLLFD,               "pollfd" },
+        { EXPR_SCTP_RTOINFO,         "sctp_rtoinfo"},
+        { EXPR_SCTP_INITMSG,         "sctp_initmsg"},
+        { EXPR_SCTP_ASSOC_VALUE,     "sctp_assoc_value"},
+        { EXPR_SCTP_SACKINFO,        "sctp_sackinfo"},
+        { EXPR_SCTP_STATUS,          "sctp_status"},
+        { EXPR_SCTP_PADDRINFO,       "sctp_paddrinfo"},
+        { EXPR_SCTP_PEER_ADDR_PARAMS,"sctp_peer_addr_params"},
+        { EXPR_SCTP_STREAM_VALUE,    "sctp_stream_value"},
+        { EXPR_SCTP_ASSOCPARAMS,     "sctp_assocparams"},
+        { EXPR_SCTP_EVENT,           "sctp_event"      },
+        { EXPR_SCTP_SNDINFO,         "sctp_sndinfo"    },
+        { EXPR_SCTP_SETADAPTATION,   "sctp_setadaptation"},
+        { EXPR_SCTP_SNDRCVINFO,      "sctp_sndrcvinfo" },
+        { EXPR_SCTP_PRINFO,          "sctp_prinfo"     },
+        { EXPR_SCTP_AUTHINFO,        "sctp_authinfo"   },
+        { EXPR_SCTP_SENDV_SPA,       "sctp_sendv_spa"  },
+        { NUM_EXPR_TYPES,            NULL}
+};
 /* Verify that the expression list has the expected number of
  * expressions. Returns STATUS_OK on success; on failure returns
  * STATUS_ERR and sets error message.
@@ -3043,11 +3080,10 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 	result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr *) to_ptr,
 			      tolen, ppid, flags, stream_no, timetolive, context);
 
+	free(msg);
 	if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
-		free(msg);
 		return STATUS_ERR;
 	}
-	free(msg);
 	return STATUS_OK;
 #else
 	asprintf(error, "sctp_sendmsg is not supported");
@@ -3294,6 +3330,207 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
 #endif
 }
 
+int parse_expression_to_sctp_sndinfo(struct expression *expr, struct sctp_sndinfo *info, char **error) {
+	if (expr->type == EXPR_SCTP_SNDINFO) {
+		struct sctp_sndinfo_expr *sndinfo_expr = expr->value.sctp_sndinfo;
+		info->snd_assoc_id = 0;
+		if (get_u16(sndinfo_expr->snd_sid, &info->snd_sid, error)) {
+			return STATUS_ERR;
+		}
+		if (get_u16(sndinfo_expr->snd_flags, &info->snd_flags, error)) {
+			return STATUS_ERR;
+		}
+		if (get_u32(sndinfo_expr->snd_ppid, &info->snd_ppid, error)) {
+			return STATUS_ERR;
+		}
+		if (get_u32(sndinfo_expr->snd_context, &info->snd_context, error)) {
+			return STATUS_ERR;
+		}
+	} else {
+		return STATUS_ERR;
+	}
+	return STATUS_OK;
+}
+
+int parse_expression_to_sctp_authinfo(struct expression *expr, struct sctp_authinfo *info, char **error) {
+	if (expr->type == EXPR_SCTP_AUTHINFO) {
+		struct sctp_authinfo_expr *auth_expr = expr->value.sctp_authinfo;
+		if (get_u16(auth_expr->auth_keynumber, &info->auth_keynumber, error)) {
+			return STATUS_ERR;
+		}
+	} else {
+		return STATUS_ERR;
+	}
+	return STATUS_OK;
+}
+
+int parse_expression_to_sctp_prinfo(struct expression *expr, struct sctp_prinfo *info, char **error) {
+	if (expr->type == EXPR_SCTP_PRINFO) {
+		struct sctp_prinfo_expr *prinfo_expr = expr->value.sctp_prinfo;
+		if (get_u16(prinfo_expr->pr_policy, &info->pr_policy, error)) {
+			return STATUS_ERR;
+		}
+		if (get_u32(prinfo_expr->pr_value, &info->pr_value, error)) {
+			return STATUS_ERR;
+		}
+	} else {
+		return STATUS_ERR;
+	}
+	return STATUS_OK;
+}
+
+int parse_expression_to_sctp_sendv_spa(struct expression *expr, struct sctp_sendv_spa *info, char **error) {
+	if (expr->type == EXPR_SCTP_SENDV_SPA) {
+		struct sctp_sendv_spa_expr *spa_expr = expr->value.sctp_sendv_spa;
+		if (get_u32(spa_expr->sendv_flags, &info->sendv_flags, error)) {
+			return STATUS_ERR;
+		}
+		if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
+			if (parse_expression_to_sctp_sndinfo(spa_expr->sendv_sndinfo, &info->sendv_sndinfo, error))
+				return STATUS_ERR;
+		}
+		if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
+			if (parse_expression_to_sctp_prinfo(spa_expr->sendv_prinfo, &info->sendv_prinfo, error))
+				return STATUS_ERR;
+		}
+		if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
+			if (parse_expression_to_sctp_authinfo(spa_expr->sendv_authinfo, &info->sendv_authinfo, error))
+				return STATUS_ERR;
+		}
+	} else {
+		return STATUS_ERR;
+	}
+	return STATUS_OK;
+}
+
+static int syscall_sctp_sendv(struct state *state, struct syscall_spec *syscall,
+			      struct expression_list *args,
+			      char **error)
+{
+#if defined(__FreeBSD__)
+	int script_fd, live_fd, iovcnt, addrcnt, result, flags;
+	u32 infotype, script_iovec_list_len = 0;
+	socklen_t infolen;
+	struct sockaddr *addrs;
+	void *info;
+	struct iovec *iov;
+	struct expression *iovec_expr_list, *iovcnt_expr, *addrs_expr, *addrcnt_expr;
+	struct expression *info_expr, *infolen_expr, *infotype_expr, *flags_expr;
+	struct sctp_sndinfo sndinfo;
+	struct sctp_prinfo prinfo;
+	struct sctp_authinfo authinfo;
+	struct sctp_sendv_spa spa;
+
+	if (check_arg_count(args, 9, error))
+		return STATUS_ERR;
+	if (s32_arg(args, 0, &script_fd, error))
+		return STATUS_ERR;
+	if (to_live_fd(state, script_fd, &live_fd, error))
+		return STATUS_ERR;
+	iovec_expr_list = get_arg(args, 1, error);
+	iovec_new(iovec_expr_list, &iov,  &script_iovec_list_len, error);	
+	iovcnt_expr = get_arg(args, 2, error);
+	if (get_s32(iovcnt_expr, &iovcnt, error))
+		return STATUS_ERR;
+	addrs_expr = get_arg(args, 3, error);
+	if (addrs_expr->type == EXPR_NULL) {
+		addrs = NULL;
+	} else if (addrs_expr->type == EXPR_SOCKET_ADDRESS_IPV4 ||
+		   addrs_expr->type == EXPR_SOCKET_ADDRESS_IPV6 ||
+		   addrs_expr->type == EXPR_ELLIPSIS) {
+		addrs = malloc(sizeof(struct sockaddr_storage));
+		get_sockstorage_arg(addrs_expr, (struct sockaddr_storage *)addrs, live_fd);
+	} else if (addrs_expr->type == EXPR_LIST) {
+		struct expression_list *addrs_expr_list = (struct expression_list *)addrs_expr->value.list;
+		struct expression *expr;
+		int addrlen = expression_list_length(addrs_expr_list);
+		int i = 0;
+		size_t size = 0;
+		struct sockaddr *addr_ptr;
+		for (i = 0; i < addrlen; i++) {
+			expr = get_arg(addrs_expr_list, i, error); 
+			if (expr->type == EXPR_SOCKET_ADDRESS_IPV4) {
+				size += sizeof(struct sockaddr_in);
+			} else if (expr->type == EXPR_SOCKET_ADDRESS_IPV6) {
+				size += sizeof(struct sockaddr_in);
+			} else {
+				return STATUS_ERR;
+			}
+		}
+		addrs = malloc(size);
+		addr_ptr = (struct sockaddr *)addrs;
+		for(i = 0; i < addrlen; i++) {
+			expr = get_arg(addrs_expr_list, i, error);
+                        if (expr->type == EXPR_SOCKET_ADDRESS_IPV4) {
+				size = sizeof(struct sockaddr_in);
+                                memcpy(expr->value.socket_address_ipv4, addr_ptr, size);
+				addr_ptr = addr_ptr + sizeof(struct sockaddr_in);
+                        } else if (expr->type == EXPR_SOCKET_ADDRESS_IPV6) {
+                                size = sizeof(struct sockaddr_in);
+                                memcpy(expr->value.socket_address_ipv6, addr_ptr, size);
+				addr_ptr = addr_ptr + sizeof(struct sockaddr_in6);
+			}
+		}
+	} else {
+		return STATUS_ERR;
+	}
+
+	addrcnt_expr = get_arg(args, 4, error);
+	if (get_s32(addrcnt_expr, &addrcnt, error))
+		return STATUS_ERR;
+	info_expr = get_arg(args, 5, error);
+	if (info_expr->type == EXPR_SCTP_SNDINFO) {
+		if (parse_expression_to_sctp_sndinfo(info_expr, &sndinfo, error))
+			return STATUS_ERR;
+		info = &sndinfo;
+	} else if (info_expr->type == EXPR_SCTP_PRINFO) {
+		info = malloc(sizeof(struct sctp_prinfo));
+		if (parse_expression_to_sctp_prinfo(info_expr, &prinfo, error))
+			return STATUS_ERR;
+		info = &prinfo;
+	} else if (info_expr->type == EXPR_SCTP_AUTHINFO) {
+		if (parse_expression_to_sctp_authinfo(info_expr, &authinfo, error))
+			return STATUS_ERR;
+		info = &authinfo;
+	} else if (info_expr->type == EXPR_SCTP_SENDV_SPA) {
+		if (parse_expression_to_sctp_sendv_spa(info_expr, &spa, error))
+			return STATUS_ERR;
+		info = &spa;
+	} else if (info_expr->type == EXPR_NULL) {
+		info = NULL;
+	} else {
+		asprintf(error, "Bad input for info");
+		return STATUS_ERR;
+	}
+	infolen_expr = get_arg(args, 6, error);
+	if (get_u32(infolen_expr, &infolen, error))
+		return STATUS_ERR;
+	infotype_expr = get_arg(args, 7, error);
+	if (get_u32(infotype_expr, &infotype, error))
+		return STATUS_ERR;
+	flags_expr = get_arg(args, 8, error);
+	if (get_s32(flags_expr, &flags, error))
+		return STATUS_ERR;
+
+	begin_syscall(state, syscall);
+
+	result = sctp_sendv(live_fd, iov, iovcnt, addrs, addrcnt, info, infolen, infotype, flags);
+
+	if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
+		free(addrs);
+		iovec_free(iov, script_iovec_list_len);
+		return STATUS_ERR;
+	}
+	free(addrs);
+	iovec_free(iov, script_iovec_list_len);
+
+	return STATUS_OK;
+#else
+	asprintf(error, "sctp_sendv is not supported");
+	return STATUS_ERR;
+#endif
+}
+
 /* A dispatch table with all the system calls that we support... */
 struct system_call_entry {
 	const char *name;
@@ -3327,6 +3564,7 @@ struct system_call_entry system_call_table[] = {
 	{"poll",       syscall_poll},
 	{"sctp_sendmsg", syscall_sctp_sendmsg},
 	{"sctp_recvmsg", syscall_sctp_recvmsg},
+	{"sctp_sendv", syscall_sctp_sendv},
 };
 
 /* Evaluate the system call arguments and invoke the system call. */
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 1b766b8271d94046728e6806b95f304f37dcf008..c5b493ea7814ee168f8cbd7b47c32d1295c44864 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -79,6 +79,9 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_SNDINFO,         "sctp_sndinfo"    },
 	{ EXPR_SCTP_SETADAPTATION,   "sctp_setadaptation"},
 	{ EXPR_SCTP_SNDRCVINFO,      "sctp_sndrcvinfo" },
+	{ EXPR_SCTP_PRINFO,          "sctp_prinfo"     },
+	{ EXPR_SCTP_AUTHINFO,        "sctp_authinfo"   },
+	{ EXPR_SCTP_SENDV_SPA,       "sctp_sendv_spa"  },
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -378,6 +381,19 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_sndrcvinfo->sinfo_tsn);
 		free_expression(expression->value.sctp_sndrcvinfo->sinfo_cumtsn);
 		break;
+	case EXPR_SCTP_PRINFO:
+		free_expression(expression->value.sctp_prinfo->pr_policy);
+		free_expression(expression->value.sctp_prinfo->pr_value);
+		break;		
+	case EXPR_SCTP_AUTHINFO:
+		free_expression(expression->value.sctp_authinfo->auth_keynumber);
+		break;
+	case EXPR_SCTP_SENDV_SPA:
+		free_expression(expression->value.sctp_sendv_spa->sendv_flags);
+		free_expression(expression->value.sctp_sendv_spa->sendv_sndinfo);
+		free_expression(expression->value.sctp_sendv_spa->sendv_prinfo);
+		free_expression(expression->value.sctp_sendv_spa->sendv_authinfo);
+		break;
 	case EXPR_WORD:
 		assert(expression->value.string);
 		free(expression->value.string);
@@ -1031,6 +1047,94 @@ static int evaluate_sctp_sndrcvinfo_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_prinfo_expression(struct expression *in,
+					   struct expression *out,
+					   char **error)
+{
+        struct sctp_prinfo_expr *in_info;
+        struct sctp_prinfo_expr *out_info;
+
+        assert(in->type == EXPR_SCTP_PRINFO);
+        assert(in->value.sctp_prinfo);
+        assert(out->type == EXPR_SCTP_PRINFO);
+
+        out->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr));
+                     
+        in_info = in->value.sctp_prinfo;
+        out_info = out->value.sctp_prinfo;
+                     
+        if (evaluate(in_info->pr_policy,
+		     &out_info->pr_policy,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->pr_value,
+		     &out_info->pr_value,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;	
+}
+
+static int evaluate_sctp_authinfo_expression(struct expression *in,
+					     struct expression *out,
+					     char **error)
+{
+        struct sctp_authinfo_expr *in_info;
+        struct sctp_authinfo_expr *out_info;
+
+        assert(in->type == EXPR_SCTP_AUTHINFO);
+        assert(in->value.sctp_authinfo);
+        assert(out->type == EXPR_SCTP_AUTHINFO);
+
+        out->value.sctp_authinfo = calloc(1, sizeof(struct sctp_authinfo_expr));
+                     
+        in_info = in->value.sctp_authinfo;
+        out_info = out->value.sctp_authinfo;
+                     
+        if (evaluate(in_info->auth_keynumber,
+		     &out_info->auth_keynumber,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
+static int evaluate_sctp_sendv_spa_expression(struct expression *in,
+					      struct expression *out,
+					      char **error)
+{
+        struct sctp_sendv_spa_expr *in_spa;
+        struct sctp_sendv_spa_expr *out_spa;
+
+        assert(in->type == EXPR_SCTP_SENDV_SPA);
+        assert(in->value.sctp_sendv_spa);
+        assert(out->type == EXPR_SCTP_SENDV_SPA);
+
+        out->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_sendv_spa_expr));
+                     
+        in_spa = in->value.sctp_sendv_spa;
+        out_spa = out->value.sctp_sendv_spa;
+                     
+        if (evaluate(in_spa->sendv_flags,
+		     &out_spa->sendv_flags,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_spa->sendv_sndinfo,
+		     &out_spa->sendv_sndinfo,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_spa->sendv_prinfo,
+		     &out_spa->sendv_prinfo,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_spa->sendv_authinfo,
+		     &out_spa->sendv_authinfo,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate(struct expression *in,
 		    struct expression **out_ptr, char **error)
 {
@@ -1095,6 +1199,15 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_SNDRCVINFO:
 		result = evaluate_sctp_sndrcvinfo_expression(in, out, error);
 		break;
+	case EXPR_SCTP_PRINFO:
+		result = evaluate_sctp_prinfo_expression(in, out, error);
+		break;
+	case EXPR_SCTP_AUTHINFO:
+		result = evaluate_sctp_authinfo_expression(in, out, error);
+		break;
+	case EXPR_SCTP_SENDV_SPA:
+		result = evaluate_sctp_sendv_spa_expression(in, out, error);
+		break;
 	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 fbcf7fe705e49abb54e73dde4a944c3ec54e8e52..35de4e878fc067eb555bca949431b4b962ba5804 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -59,6 +59,9 @@ enum expression_t {
 	EXPR_SCTP_SNDINFO,	  /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */
 	EXPR_SCTP_SETADAPTATION,  /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
 	EXPR_SCTP_SNDRCVINFO,     /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */
+	EXPR_SCTP_PRINFO,	  /* struct sctp_prinfo for syscall sctp_sendv */
+	EXPR_SCTP_AUTHINFO,	  /* struct sctp_authinfo for syscall sctp_sendv */
+	EXPR_SCTP_SENDV_SPA,	  /* struct sctp_sendv_spa for syscall sctp_sendv */
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -91,6 +94,9 @@ struct expression {
 		struct sctp_sndinfo_expr *sctp_sndinfo;
 		struct sctp_setadaptation_expr *sctp_setadaptation;
 		struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo;
+		struct sctp_prinfo_expr *sctp_prinfo;
+		struct sctp_authinfo_expr *sctp_authinfo;
+		struct sctp_sendv_spa_expr *sctp_sendv_spa;
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
@@ -137,6 +143,7 @@ struct linger_expr {
 	struct expression *l_onoff;
 	struct expression *l_linger;
 };
+
 /* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */
 struct sctp_rtoinfo_expr {
 	struct expression *srto_initial;
@@ -242,6 +249,25 @@ struct sctp_sndrcvinfo_expr {
 	struct expression *sinfo_cumtsn;
 };
 
+/* Parse tree for sctp_prinfo in sctp_sendv syscall. */
+struct sctp_prinfo_expr {
+	struct expression *pr_policy;
+	struct expression *pr_value;
+};
+
+/* Parse tree for sctp_authinfo in sctp_sendv syscall. */
+struct sctp_authinfo_expr {
+	struct expression *auth_keynumber;
+};
+
+/* Parse tree for sctp_sendv_spa in sctp_sendv syscall. */
+struct sctp_sendv_spa_expr {
+	struct expression *sendv_flags;
+	struct expression *sendv_sndinfo;
+	struct expression *sendv_prinfo;
+	struct expression *sendv_authinfo;
+};
+
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
 	const char *errno_macro;	/* errno symbol (C macro name) */
diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c
index b5454bae547d452a990c933365dc2d7d5bcbc83b..e6e4d75ccfd85fe193e9c7ee836e7a17469f0250 100644
--- a/gtests/net/packetdrill/symbols_freebsd.c
+++ b/gtests/net/packetdrill/symbols_freebsd.c
@@ -185,6 +185,16 @@ struct int_symbol platform_symbols_table[] = {
         { SCTP_SENDALL,                     "SCTP_SENDALL"                    },
 	{ SCTP_EOR,                         "SCTP_EOR"                        },
 	{ SCTP_SACK_IMMEDIATELY,            "SCTP_SACK_IMMEDIATELY"           },
+	{ SCTP_PR_SCTP_NONE,                "SCTP_PR_SCTP_NONE"		      },
+	{ SCTP_PR_SCTP_TTL,                 "SCTP_PR_SCTP_TTL"		      },
+	{ SCTP_SENDV_NOINFO,                "SCTP_SENDV_NOINFO"               },
+	{ SCTP_SENDV_SNDINFO,               "SCTP_SENDV_SNDINFO"              },
+	{ SCTP_SENDV_PRINFO,                "SCTP_SENDV_PRINFO"               },
+	{ SCTP_SENDV_AUTHINFO,              "SCTP_SENDV_AUTHINFO"             },
+	{ SCTP_SENDV_SPA,                   "SCTP_SENDV_SPA"                  },
+	{ SCTP_SEND_SNDINFO_VALID,          "SCTP_SEND_SNDINFO_VALID"         },
+	{ SCTP_SEND_PRINFO_VALID,           "SCTP_SEND_PRINFO_VALID"          },
+	{ SCTP_SEND_AUTHINFO_VALID,         "SCTP_SEND_AUTHINFO_VALID"        },
 
 	/* /usr/include/netinet/tcp.h */
 	{ TCP_NODELAY,                      "TCP_NODELAY"                     },
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt
new file mode 100644
index 0000000000000000000000000000000000000000..f3fa658a53b094295367e4e72d6ccdcb697d8f3c
--- /dev/null
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt
@@ -0,0 +1,72 @@
+
++0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
++0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
++0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
++0.0 bind(3, ..., ...) = 0
+// Check the handshake with an empty(!) cookie
++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...]
++0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=16, is=16, tsn=1, STATE_COOKIE[len=4, val=...]]
++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
+
+//sctp_sendv(int sd, const struct iovec *iov, int iovcnt, struct sockaddr *addrs, int addrcnt, void *info, socklen_t infolen, unsigned int infotype, int flags);
+
+//test with sctp_sendv_sndinfo
+//+0.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, {snd_sid=1, snd_flags=0, snd_ppid=htonl(1234), snd_context=0}, 16, SCTP_SENDV_SNDINFO, 0) = 1000
+//+0.0 > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=1, ssn=0, ppid=1234]
+//+0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
+
+//test with sctp_sendv_authinfo
++1.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, ..., 1, {auth_keynumber=123}, 2, SCTP_SENDV_AUTHINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
+
+//base test
++1.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=1500, gaps=[], dups=[]]
+
+//base test
++1.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=2, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=1500, gaps=[], dups=[]]
+
+//base test
++5.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=4, sid=0, ssn=3, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=4, a_rwnd=1500, gaps=[], dups=[]]
+
+//TEST NULL as sockaddr
++5.0 sctp_sendv(3, [{iov_base=..., iov_len=500}], 1, NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0) = 500
+*    > sctp: DATA[flgs=BE, len=516, tsn=5, sid=0, ssn=4, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=5, a_rwnd=1500, gaps=[], dups=[]]
+
+//TEST with two structs iov
++5.0 sctp_sendv(3, [{iov_base=..., iov_len=500},{iov_base=..., iov_len=500}], 2, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=6, sid=0, ssn=5, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=6, a_rwnd=1500, gaps=[], dups=[]]
+
+//test with sctp_sendv_prinfo
++5.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, ..., 1, {pr_policy=0, pr_value=0}, 8, SCTP_SENDV_PRINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=7, sid=0, ssn=6, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=7, a_rwnd=1500, gaps=[], dups=[]]
+
+//test with all sctp_sendv_spainfo
++5.0 sctp_sendv(3, [{..., 500}, {..., 500}], 2, ..., 1, {sendv_flags=SCTP_SEND_SNDINFO_VALID, 
+sendv_sndinfo={snd_sid=2, snd_flags=0, snd_ppid=htonl(0), snd_context=0},
+sendv_prinfo={pr_policy=SCTP_PR_SCTP_TTL, pr_value=10},
+sendv_authinfo={auth_keynumber=123}}, 32, SCTP_SENDV_SPA, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=8, sid=2, ssn=0, ppid=0]
++0.0 < sctp: SACK[flgs=0, cum_tsn=8, a_rwnd=1500, gaps=[], dups=[]]
+
+//test with struct sockaddr
++4.0 sctp_sendv(3, [{..., 1000}], 1, [{sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}], 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
+*    > sctp: DATA[flgs=BE, len=1016, tsn=9, sid=5, ssn=0, ppid=1234]
++0.0 < sctp: SACK[flgs=0, cum_tsn=9, a_rwnd=1500, gaps=[], dups=[]]
+
++0.0 close(3) = 0
++0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=0]
++0.1 < sctp: SHUTDOWN_ACK[flgs=0]
++0.0 > sctp: SHUTDOWN_COMPLETE[flgs=0]