diff --git a/gtests/net/packetdrill/README b/gtests/net/packetdrill/README
index bfa0a478374e836f1db85277d1c2f21c25f4c34c..026f6b956f72bc9689a8dfcb04e090057cdf6ba9 100644
--- a/gtests/net/packetdrill/README
+++ b/gtests/net/packetdrill/README
@@ -14,6 +14,7 @@ building
 ========
 
 To build packetdrill, first install flex and bison.
+On Linux you will also need to install the libsctp-dev package.
 
 Then set up the Makefile for your platform:
 
diff --git a/gtests/net/packetdrill/contrib/packetdrill.el b/gtests/net/packetdrill/contrib/packetdrill.el
index 6af4be4038538e93865db5b3a7f17c37e3682d2a..d8c329d02d5c99426b674865b8cba914e0618be1 100644
--- a/gtests/net/packetdrill/contrib/packetdrill.el
+++ b/gtests/net/packetdrill/contrib/packetdrill.el
@@ -1,6 +1,6 @@
-(setq packetdrill-keywords '("sa_family" "sin_port" "sin_addr" "msg_name" "msg_iov" "msg_flags" "fd" "events" "revents" "htons" "icmp" "udp" "inet_addr" "ack" "eol" "ecr" "mss" "mtu" "nop" "sack" "sackOK" "TS" "FO" "LS" "gcn" "minRTO" "val" "win" "wscale" "ect01" "ect0" "ect1" "noecn" "ce" "pro"))
+(setq packetdrill-keywords '("sa_family" "sin_port" "sin_addr" "msg_name" "msg_iov" "msg_flags" "fd" "events" "revents" "htons" "icmp" "udp" "inet_addr" "ack" "eol" "ecr" "mss" "mtu" "nop" "sack" "sackOK" "TS" "FO" "LS" "gcn" "minRTO" "val" "win" "wscale" "ect01" "ect0" "ect1" "noecn" "ce" "pro" "onoff" "linger" "srto_initial" "srto_max" "srto_min" "sinit_num_ostreams" "sinit_max_instreams" "sinit_max_attempts" "sinit_max_init_timeo" "assoc_value" "sack_delay" "sack_freq"))
 
-(setq packetdrill-constants '("AF_INET" "AF_INET6" "PF_INET" "PF_INET6" "SOCK_STREAM" "SOCK_DGRAM" "IPPROTO_IP" "IPPROTO_IPV6" "IPPROTO_ICMP" "IPPROTO_TCP" "IPPROTO_UDP" "SOL_SOCKET" "SOL_IP" "SOL_IPV6" "SOL_TCP" "SOL_UDP" "SO_ACCEPTCONN" "SO_ATTACH_FILTER" "SO_BINDTODEVICE" "SO_BROADCAST" "SO_BSDCOMPAT" "SO_DEBUG" "SO_DETACH_FILTER" "SO_DONTROUTE" "SO_ERROR" "SO_KEEPALIVE" "SO_LINGER" "SO_NO_CHECK" "SO_OOBINLINE" "SO_PASSCRED" "SO_PEERCRED" "SO_PEERNAME" "SO_PEERSEC" "SO_PRIORITY" "SO_RCVBUF" "SO_RCVLOWAT" "SO_RCVTIMEO" "SO_REUSEADDR" "SO_REUSEPORT" "SO_SECURITY_AUTHENTICATION" "SO_SECURITY_ENCRYPTION_NETWORK" "SO_SECURITY_ENCRYPTION_TRANSPORT" "SO_SNDBUF" "SO_SNDLOWAT" "SO_SNDTIMEO" "SO_TIMESTAMP" "SO_TYPE" "IP_TOS" "IP_MTU_DISCOVER" "IP_PMTUDISC_WANT" "IP_PMTUDISC_DONT" "IP_PMTUDISC_DO" "IP_PMTUDISC_PROBE" "IP_MTU" "IPV6_MTU" "TCP_NODELAY" "TCP_MAXSEG" "TCP_CORK" "TCP_KEEPIDLE" "TCP_KEEPINTVL" "TCP_KEEPCNT" "TCP_SYNCNT" "TCP_LINGER2" "TCP_DEFER_ACCEPT" "TCP_WINDOW_CLAMP" "TCP_INFO" "TCP_QUICKACK" "TCP_CONGESTION" "TCP_MD5SIG" "TCP_COOKIE_TRANSACTIONS" "TCP_THIN_LINEAR_TIMEOUTS" "TCP_THIN_DUPACK" "TCP_USER_TIMEOUT" "TCP_MIN_RTO" "TCP_INFO_EXT" "TCP_CWND" "TCP_XMIT_COMPL_SEQ" "TCP_CWND_CLAMP" "TCP_SAVE_SYN" "TCP_SAVED_SYN" "TCP_FASTOPEN" "TCP_MULTIPLE_CONNECTIONS" "O_RDONLY" "O_WRONLY" "O_RDWR" "O_ACCMODE" "O_CREAT" "O_EXCL" "O_NOCTTY" "O_TRUNC" "O_APPEND" "O_NONBLOCK" "F_DUPFD" "F_GETFD" "F_SETFD" "F_GETFL" "F_SETFL" "F_GETLK" "F_SETLK" "F_SETLKW" "F_GETOWN" "F_SETOWN" "F_SETSIG" "F_GETSIG" "F_GETOWN" "F_SETOWN" "F_SETLK" "F_SETLKW" "F_GETLK" "F_SETLK64" "F_SETLKW64" "F_GETLK64" "F_SETLEASE" "F_GETLEASE" "F_NOTIFY" "F_DUPFD_CLOEXEC" "FD_CLOEXEC" "LOCK_SH" "LOCK_EX" "LOCK_NB" "LOCK_UN" "F_RDLCK" "F_WRLCK" "F_UNLCK" "F_EXLCK" "F_SHLCK" "SEEK_SET" "SEEK_CUR" "SEEK_END" "MSG_OOB" "MSG_DONTROUTE" "MSG_PEEK" "MSG_CTRUNC" "MSG_PROXY" "MSG_EOR" "MSG_WAITALL" "MSG_TRUNC" "MSG_CTRUNC" "MSG_ERRQUEUE" "MSG_DONTWAIT" "MSG_CONFIRM" "MSG_FIN" "MSG_SYN" "MSG_RST" "MSG_NOSIGNAL" "MSG_MORE" "MSG_CMSG_CLOEXEC" "MSG_FASTOPEN" "SIOCINQ" "FIONREAD" "POLLIN" "POLLPRI" "POLLOUT" "POLLRDNORM" "POLLRDBAND" "POLLWRNORM" "POLLWRBAND" "POLLMSG" "POLLREMOVE" "POLLRDHUP" "POLLERR" "POLLHUP" "POLLNVAL" "EPERM" "ENOENT" "ESRCH" "EINTR" "EIO" "ENXIO" "E2BIG" "ENOEXEC" "EBADF" "ECHILD" "EAGAIN" "ENOMEM" "EACCES" "EFAULT" "ENOTBLK" "EBUSY" "EEXIST" "EXDEV" "ENODEV" "ENOTDIR" "EISDIR" "EINVAL" "ENFILE" "EMFILE" "ENOTTY" "ETXTBSY" "EFBIG" "ENOSPC" "ESPIPE" "EROFS" "EMLINK" "EPIPE" "EDOM" "ERANGE" "EDEADLK" "ENAMETOOLONG" "ENOLCK" "ENOSYS" "ENOTEMPTY" "ELOOP" "EWOULDBLOCK" "ENOMSG" "EIDRM" "ECHRNG" "EL2NSYNC" "EL3HLT" "EL3RST" "ELNRNG" "EUNATCH" "ENOCSI" "EL2HLT" "EBADE" "EBADR" "EXFULL" "ENOANO" "EBADRQC" "EBADSLT" "EDEADLOCK" "EBFONT" "ENOSTR" "ENODATA" "ETIME" "ENOSR" "ENONET" "ENOPKG" "EREMOTE" "ENOLINK" "EADV" "ESRMNT" "ECOMM" "EPROTO" "EMULTIHOP" "EDOTDOT" "EBADMSG" "EOVERFLOW" "ENOTUNIQ" "EBADFD" "EREMCHG" "ELIBACC" "ELIBBAD" "ELIBSCN" "ELIBMAX" "ELIBEXEC" "EILSEQ" "ERESTART" "ESTRPIPE" "EUSERS" "ENOTSOCK" "EDESTADDRREQ" "EMSGSIZE" "EPROTOTYPE" "ENOPROTOOPT" "EPROTONOSUPPORT" "ESOCKTNOSUPPORT" "EOPNOTSUPP" "EPFNOSUPPORT" "EAFNOSUPPORT" "EADDRINUSE" "EADDRNOTAVAIL" "ENETDOWN" "ENETUNREACH" "ENETRESET" "ECONNABORTED" "ECONNRESET" "ENOBUFS" "EISCONN" "ENOTCONN" "ESHUTDOWN" "ETOOMANYREFS" "ETIMEDOUT" "ECONNREFUSED" "EHOSTDOWN" "EHOSTUNREACH" "EALREADY" "EINPROGRESS" "ESTALE" "EUCLEAN" "ENOTNAM" "ENAVAIL" "EISNAM" "EREMOTEIO" "EDQUOT" "ENOMEDIUM" "EMEDIUMTYPE" "ECANCELED" "ENOKEY" "EKEYEXPIRED" "EKEYREVOKED" "EKEYREJECTED" "EOWNERDEAD" "ENOTRECOVERABLE" "ERFKILL" "POLLIN" "POLLPRI" "POLLOUT" "POLLRDNORM" "POLLRDBAND" "POLLWRNORM" "POLLWRBAND" "POLLMSG" "POLLREMOVE" "POLLRDHUP" "POLLERR" "POLLHUP" "POLLNVAL"))
+(setq packetdrill-constants '("AF_INET" "AF_INET6" "PF_INET" "PF_INET6" "SOCK_STREAM" "SOCK_DGRAM" "IPPROTO_IP" "IPPROTO_IPV6" "IPPROTO_ICMP" "IPPROTO_SCTP" "IPPROTO_TCP" "IPPROTO_UDP" "SOL_SOCKET" "SOL_IP" "SOL_IPV6" "SOL_SCTP" "SOL_TCP" "SOL_UDP" "SO_ACCEPTCONN" "SO_ATTACH_FILTER" "SO_BINDTODEVICE" "SO_BROADCAST" "SO_BSDCOMPAT" "SO_DEBUG" "SO_DETACH_FILTER" "SO_DONTROUTE" "SO_ERROR" "SO_KEEPALIVE" "SO_LINGER" "SO_NO_CHECK" "SO_OOBINLINE" "SO_PASSCRED" "SO_PEERCRED" "SO_PEERNAME" "SO_PEERSEC" "SO_PRIORITY" "SO_RCVBUF" "SO_RCVLOWAT" "SO_RCVTIMEO" "SO_REUSEADDR" "SO_REUSEPORT" "SO_SECURITY_AUTHENTICATION" "SO_SECURITY_ENCRYPTION_NETWORK" "SO_SECURITY_ENCRYPTION_TRANSPORT" "SO_SNDBUF" "SO_SNDLOWAT" "SO_SNDTIMEO" "SO_TIMESTAMP" "SO_TYPE" "IP_TOS" "IP_MTU_DISCOVER" "IP_PMTUDISC_WANT" "IP_PMTUDISC_DONT" "IP_PMTUDISC_DO" "IP_PMTUDISC_PROBE" "IP_MTU" "IPV6_MTU" "SCTP_RTOINFO" "SCTP_INITMSG" "SCTP_NODELAY" "SCTP_MAXSEG" "SCTP_DELAYED_SACK" "SCTP_MAX_BURST" "TCP_NODELAY" "TCP_MAXSEG" "TCP_CORK" "TCP_KEEPIDLE" "TCP_KEEPINTVL" "TCP_KEEPCNT" "TCP_SYNCNT" "TCP_LINGER2" "TCP_DEFER_ACCEPT" "TCP_WINDOW_CLAMP" "TCP_INFO" "TCP_QUICKACK" "TCP_CONGESTION" "TCP_MD5SIG" "TCP_COOKIE_TRANSACTIONS" "TCP_THIN_LINEAR_TIMEOUTS" "TCP_THIN_DUPACK" "TCP_USER_TIMEOUT" "TCP_MIN_RTO" "TCP_INFO_EXT" "TCP_CWND" "TCP_XMIT_COMPL_SEQ" "TCP_CWND_CLAMP" "TCP_SAVE_SYN" "TCP_SAVED_SYN" "TCP_FASTOPEN" "TCP_MULTIPLE_CONNECTIONS" "O_RDONLY" "O_WRONLY" "O_RDWR" "O_ACCMODE" "O_CREAT" "O_EXCL" "O_NOCTTY" "O_TRUNC" "O_APPEND" "O_NONBLOCK" "F_DUPFD" "F_GETFD" "F_SETFD" "F_GETFL" "F_SETFL" "F_GETLK" "F_SETLK" "F_SETLKW" "F_GETOWN" "F_SETOWN" "F_SETSIG" "F_GETSIG" "F_GETOWN" "F_SETOWN" "F_SETLK" "F_SETLKW" "F_GETLK" "F_SETLK64" "F_SETLKW64" "F_GETLK64" "F_SETLEASE" "F_GETLEASE" "F_NOTIFY" "F_DUPFD_CLOEXEC" "FD_CLOEXEC" "LOCK_SH" "LOCK_EX" "LOCK_NB" "LOCK_UN" "F_RDLCK" "F_WRLCK" "F_UNLCK" "F_EXLCK" "F_SHLCK" "SEEK_SET" "SEEK_CUR" "SEEK_END" "MSG_OOB" "MSG_DONTROUTE" "MSG_PEEK" "MSG_CTRUNC" "MSG_PROXY" "MSG_EOR" "MSG_WAITALL" "MSG_TRUNC" "MSG_CTRUNC" "MSG_ERRQUEUE" "MSG_DONTWAIT" "MSG_CONFIRM" "MSG_FIN" "MSG_SYN" "MSG_RST" "MSG_NOSIGNAL" "MSG_MORE" "MSG_CMSG_CLOEXEC" "MSG_FASTOPEN" "SIOCINQ" "FIONREAD" "POLLIN" "POLLPRI" "POLLOUT" "POLLRDNORM" "POLLRDBAND" "POLLWRNORM" "POLLWRBAND" "POLLMSG" "POLLREMOVE" "POLLRDHUP" "POLLERR" "POLLHUP" "POLLNVAL" "EPERM" "ENOENT" "ESRCH" "EINTR" "EIO" "ENXIO" "E2BIG" "ENOEXEC" "EBADF" "ECHILD" "EAGAIN" "ENOMEM" "EACCES" "EFAULT" "ENOTBLK" "EBUSY" "EEXIST" "EXDEV" "ENODEV" "ENOTDIR" "EISDIR" "EINVAL" "ENFILE" "EMFILE" "ENOTTY" "ETXTBSY" "EFBIG" "ENOSPC" "ESPIPE" "EROFS" "EMLINK" "EPIPE" "EDOM" "ERANGE" "EDEADLK" "ENAMETOOLONG" "ENOLCK" "ENOSYS" "ENOTEMPTY" "ELOOP" "EWOULDBLOCK" "ENOMSG" "EIDRM" "ECHRNG" "EL2NSYNC" "EL3HLT" "EL3RST" "ELNRNG" "EUNATCH" "ENOCSI" "EL2HLT" "EBADE" "EBADR" "EXFULL" "ENOANO" "EBADRQC" "EBADSLT" "EDEADLOCK" "EBFONT" "ENOSTR" "ENODATA" "ETIME" "ENOSR" "ENONET" "ENOPKG" "EREMOTE" "ENOLINK" "EADV" "ESRMNT" "ECOMM" "EPROTO" "EMULTIHOP" "EDOTDOT" "EBADMSG" "EOVERFLOW" "ENOTUNIQ" "EBADFD" "EREMCHG" "ELIBACC" "ELIBBAD" "ELIBSCN" "ELIBMAX" "ELIBEXEC" "EILSEQ" "ERESTART" "ESTRPIPE" "EUSERS" "ENOTSOCK" "EDESTADDRREQ" "EMSGSIZE" "EPROTOTYPE" "ENOPROTOOPT" "EPROTONOSUPPORT" "ESOCKTNOSUPPORT" "EOPNOTSUPP" "EPFNOSUPPORT" "EAFNOSUPPORT" "EADDRINUSE" "EADDRNOTAVAIL" "ENETDOWN" "ENETUNREACH" "ENETRESET" "ECONNABORTED" "ECONNRESET" "ENOBUFS" "EISCONN" "ENOTCONN" "ESHUTDOWN" "ETOOMANYREFS" "ETIMEDOUT" "ECONNREFUSED" "EHOSTDOWN" "EHOSTUNREACH" "EALREADY" "EINPROGRESS" "ESTALE" "EUCLEAN" "ENOTNAM" "ENAVAIL" "EISNAM" "EREMOTEIO" "EDQUOT" "ENOMEDIUM" "EMEDIUMTYPE" "ECANCELED" "ENOKEY" "EKEYEXPIRED" "EKEYREVOKED" "EKEYREJECTED" "EOWNERDEAD" "ENOTRECOVERABLE" "ERFKILL" "POLLIN" "POLLPRI" "POLLOUT" "POLLRDNORM" "POLLRDBAND" "POLLWRNORM" "POLLWRBAND" "POLLMSG" "POLLREMOVE" "POLLRDHUP" "POLLERR" "POLLHUP" "POLLNVAL"))
 
 (setq packetdrill-functions '("accept" "bind" "close" "connect" "fcntl" "getsockopt" "ioctl" "listen" "poll" "read" "readv" "recv" "recvfrom" "recvmsg" "send" "sendmsg" "sendto" "setsockopt" "shutdown" "socket" "write" "writev"))
 
diff --git a/gtests/net/packetdrill/contrib/packetdrill.vim b/gtests/net/packetdrill/contrib/packetdrill.vim
index 8bc803e04def3864d4fcd87ad16a1e4e04574dd8..4e1e8b9bfd2c6ef0ca2ae489456f408de99da7a9 100644
--- a/gtests/net/packetdrill/contrib/packetdrill.vim
+++ b/gtests/net/packetdrill/contrib/packetdrill.vim
@@ -11,8 +11,8 @@ endif
 let s:cpo_save = &cpo
 set cpo&vim
 
-syn keyword     pKeyword        sa_family sin_port sin_addr msg_name msg_iov msg_flags fd events revents htons icmp udp inet_addr ack eol ecr mss mtu nop sack sackOK TS FO LS gcn minRTO val win wscale ect01 ect0 ect1 noecn ce pro
-syn keyword     pConstant       AF_INET AF_INET6 PF_INET PF_INET6 SOCK_STREAM SOCK_DGRAM IPPROTO_IP IPPROTO_IPV6 IPPROTO_ICMP IPPROTO_TCP IPPROTO_UDP SOL_SOCKET SOL_IP SOL_IPV6 SOL_TCP SOL_UDP SO_ACCEPTCONN SO_ATTACH_FILTER SO_BINDTODEVICE SO_BROADCAST SO_BSDCOMPAT SO_DEBUG SO_DETACH_FILTER SO_DONTROUTE SO_ERROR SO_KEEPALIVE SO_LINGER SO_NO_CHECK SO_OOBINLINE SO_PASSCRED SO_PEERCRED SO_PEERNAME SO_PEERSEC SO_PRIORITY SO_RCVBUF SO_RCVLOWAT SO_RCVTIMEO SO_REUSEADDR SO_REUSEPORT SO_SECURITY_AUTHENTICATION SO_SECURITY_ENCRYPTION_NETWORK SO_SECURITY_ENCRYPTION_TRANSPORT SO_SNDBUF SO_SNDLOWAT SO_SNDTIMEO SO_TIMESTAMP SO_TYPE IP_TOS IP_MTU_DISCOVER IP_PMTUDISC_WANT IP_PMTUDISC_DONT IP_PMTUDISC_DO IP_PMTUDISC_PROBE IP_MTU IPV6_MTU TCP_NODELAY TCP_MAXSEG TCP_CORK TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT TCP_SYNCNT TCP_LINGER2 TCP_DEFER_ACCEPT TCP_WINDOW_CLAMP TCP_INFO TCP_QUICKACK TCP_CONGESTION TCP_MD5SIG TCP_COOKIE_TRANSACTIONS TCP_THIN_LINEAR_TIMEOUTS TCP_THIN_DUPACK TCP_USER_TIMEOUT TCP_MIN_RTO TCP_INFO_EXT TCP_CWND TCP_XMIT_COMPL_SEQ TCP_CWND_CLAMP TCP_SAVE_SYN TCP_SAVED_SYN TCP_FASTOPEN TCP_MULTIPLE_CONNECTIONS
+syn keyword     pKeyword        sa_family sin_port sin_addr msg_name msg_iov msg_flags fd events revents htons icmp udp inet_addr ack eol ecr mss mtu nop sack sackOK TS FO LS gcn minRTO val win wscale ect01 ect0 ect1 noecn ce pro onoff linger srto_initial srto_max srto_min sinit_num_ostreams sinit_max_instreams sinit_max_attempts sinit_max_init_timeo assoc_value sack_delay sack_freq
+syn keyword     pConstant       AF_INET AF_INET6 PF_INET PF_INET6 SOCK_STREAM SOCK_DGRAM IPPROTO_IP IPPROTO_IPV6 IPPROTO_ICMP IPPROTO_SCTP IPPROTO_TCP IPPROTO_UDP SOL_SOCKET SOL_IP SOL_IPV6 SOL_SCTP SOL_TCP SOL_UDP SO_ACCEPTCONN SO_ATTACH_FILTER SO_BINDTODEVICE SO_BROADCAST SO_BSDCOMPAT SO_DEBUG SO_DETACH_FILTER SO_DONTROUTE SO_ERROR SO_KEEPALIVE SO_LINGER SO_NO_CHECK SO_OOBINLINE SO_PASSCRED SO_PEERCRED SO_PEERNAME SO_PEERSEC SO_PRIORITY SO_RCVBUF SO_RCVLOWAT SO_RCVTIMEO SO_REUSEADDR SO_REUSEPORT SO_SECURITY_AUTHENTICATION SO_SECURITY_ENCRYPTION_NETWORK SO_SECURITY_ENCRYPTION_TRANSPORT SO_SNDBUF SO_SNDLOWAT SO_SNDTIMEO SO_TIMESTAMP SO_TYPE IP_TOS IP_MTU_DISCOVER IP_PMTUDISC_WANT IP_PMTUDISC_DONT IP_PMTUDISC_DO IP_PMTUDISC_PROBE IP_MTU IPV6_MTU SCTP_RTOINFO SCTP_INITMSG SCTP_NODELAY SCTP_MAXSEG SCTP_DELAYED_SACK SCTP_MAX_BURST TCP_NODELAY TCP_MAXSEG TCP_CORK TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT TCP_SYNCNT TCP_LINGER2 TCP_DEFER_ACCEPT TCP_WINDOW_CLAMP TCP_INFO TCP_QUICKACK TCP_CONGESTION TCP_MD5SIG TCP_COOKIE_TRANSACTIONS TCP_THIN_LINEAR_TIMEOUTS TCP_THIN_DUPACK TCP_USER_TIMEOUT TCP_MIN_RTO TCP_INFO_EXT TCP_CWND TCP_XMIT_COMPL_SEQ TCP_CWND_CLAMP TCP_SAVE_SYN TCP_SAVED_SYN TCP_FASTOPEN TCP_MULTIPLE_CONNECTIONS
 syn keyword     pConstant       O_RDONLY O_WRONLY O_RDWR O_ACCMODE O_CREAT O_EXCL O_NOCTTY O_TRUNC O_APPEND O_NONBLOCK F_DUPFD F_GETFD F_SETFD F_GETFL F_SETFL F_GETLK F_SETLK F_SETLKW F_GETOWN F_SETOWN F_SETSIG F_GETSIG F_GETOWN F_SETOWN F_SETLK F_SETLKW F_GETLK F_SETLK64 F_SETLKW64 F_GETLK64 F_SETLEASE F_GETLEASE F_NOTIFY F_DUPFD_CLOEXEC FD_CLOEXEC LOCK_SH LOCK_EX LOCK_NB LOCK_UN F_RDLCK F_WRLCK F_UNLCK F_EXLCK F_SHLCK SEEK_SET SEEK_CUR SEEK_END MSG_OOB MSG_DONTROUTE MSG_PEEK MSG_CTRUNC MSG_PROXY MSG_EOR MSG_WAITALL MSG_TRUNC MSG_CTRUNC MSG_ERRQUEUE MSG_DONTWAIT MSG_CONFIRM MSG_FIN MSG_SYN MSG_RST MSG_NOSIGNAL MSG_MORE MSG_CMSG_CLOEXEC MSG_FASTOPEN SIOCINQ FIONREAD POLLIN POLLPRI POLLOUT POLLRDNORM POLLRDBAND POLLWRNORM POLLWRBAND POLLMSG POLLREMOVE POLLRDHUP POLLERR POLLHUP POLLNVAL EPERM ENOENT ESRCH EINTR EIO ENXIO E2BIG ENOEXEC EBADF ECHILD EAGAIN ENOMEM EACCES EFAULT ENOTBLK EBUSY EEXIST EXDEV ENODEV ENOTDIR EISDIR EINVAL ENFILE EMFILE ENOTTY ETXTBSY EFBIG ENOSPC ESPIPE EROFS EMLINK EPIPE EDOM ERANGE EDEADLK ENAMETOOLONG ENOLCK ENOSYS ENOTEMPTY ELOOP EWOULDBLOCK ENOMSG EIDRM ECHRNG EL2NSYNC EL3HLT EL3RST ELNRNG EUNATCH ENOCSI EL2HLT EBADE EBADR EXFULL ENOANO EBADRQC EBADSLT EDEADLOCK EBFONT ENOSTR ENODATA ETIME ENOSR ENONET ENOPKG EREMOTE ENOLINK EADV ESRMNT ECOMM EPROTO EMULTIHOP EDOTDOT EBADMSG EOVERFLOW ENOTUNIQ EBADFD EREMCHG ELIBACC ELIBBAD ELIBSCN ELIBMAX ELIBEXEC EILSEQ ERESTART ESTRPIPE EUSERS ENOTSOCK EDESTADDRREQ EMSGSIZE EPROTOTYPE ENOPROTOOPT EPROTONOSUPPORT ESOCKTNOSUPPORT EOPNOTSUPP EPFNOSUPPORT EAFNOSUPPORT EADDRINUSE EADDRNOTAVAIL ENETDOWN ENETUNREACH ENETRESET ECONNABORTED ECONNRESET ENOBUFS EISCONN ENOTCONN ESHUTDOWN ETOOMANYREFS ETIMEDOUT ECONNREFUSED EHOSTDOWN EHOSTUNREACH EALREADY EINPROGRESS ESTALE EUCLEAN ENOTNAM ENAVAIL EISNAM EREMOTEIO EDQUOT ENOMEDIUM EMEDIUMTYPE ECANCELED ENOKEY EKEYEXPIRED EKEYREVOKED EKEYREJECTED EOWNERDEAD ENOTRECOVERABLE ERFKILL POLLIN POLLPRI POLLOUT POLLRDNORM POLLRDBAND POLLWRNORM POLLWRBAND POLLMSG POLLREMOVE POLLRDHUP POLLERR POLLHUP POLLNVAL
 syn keyword	pSyscall        accept bind close connect fcntl getsockopt ioctl listen poll read readv recv recvfrom recvmsg send sendmsg sendto setsockopt shutdown socket write writev
 syn keyword	pPythonCmds     contained assert print
diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index c52669d7d648df5783c286277788c230d0e175e7..09cefdcdf414e51d616393f9830b9154896e3a15 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -200,6 +200,16 @@ ect1			return ECT1;
 noecn			return NO_ECN;
 ce			return CE;
 [.][.][.]		return ELLIPSIS;
+assoc_value		return ASSOC_VALUE;
+sack_delay		return SACK_DELAY;
+sack_freq		return SACK_FREQ;
+srto_initial		return SRTO_INITIAL;
+srto_max		return SRTO_MAX;
+srto_min		return SRTO_MIN;
+sinit_num_ostreams	return SINIT_NUM_OSTREAMS;
+sinit_max_instreams	return SINIT_MAX_INSTREAMS;
+sinit_max_attempts	return SINIT_MAX_ATTEMPTS;
+sinit_max_init_timeo	return SINIT_MAX_INIT_TIMEO;
 --[a-zA-Z0-9_]+		yylval.string	= option(yytext); return OPTION;
 [-]?[0-9]*[.][0-9]+	yylval.floating	= atof(yytext);   return FLOAT;
 [-]?[0-9]+		yylval.integer	= atoll(yytext);  return INTEGER;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index a6d405f6462761804c3fcb9b0966f973bdd7c106..6bee8a9d07f52c86a9f76eb035901b97b8e700e9 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -480,6 +480,11 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> IPV4 IPV6 ICMP UDP GRE MTU
 %token <reserved> MPLS LABEL TC TTL
 %token <reserved> OPTION
+%token <reserved> SRTO_INITIAL SRTO_MAX SRTO_MIN
+%token <reserved> SINIT_NUM_OSTREAMS SINIT_MAX_INSTREAMS SINIT_MAX_ATTEMPTS
+%token <reserved> SINIT_MAX_INIT_TIMEO
+%token <reserved> ASSOC_VALUE
+%token <reserved> SACK_DELAY SACK_FREQ
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -512,6 +517,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> expression binary_expression array
 %type <expression> decimal_integer hex_integer
 %type <expression> inaddr sockaddr msghdr iovec pollfd opt_revents linger
+%type <expression> sctp_rtoinfo sctp_initmsg sctp_assocval sctp_sackinfo
 %type <errno_info> opt_errno
 
 %%  /* The grammar follows. */
@@ -1113,6 +1119,18 @@ expression
 | linger            {
 	$$ = $1;
 }
+| sctp_rtoinfo      {
+	$$ = $1;
+}
+| sctp_initmsg      {
+	$$ = $1;
+}
+| sctp_assocval     {
+	$$ = $1;
+}
+| sctp_sackinfo     {
+	$$ = $1;
+}
 ;
 
 decimal_integer
@@ -1239,6 +1257,86 @@ linger
 }
 ;
 
+sctp_rtoinfo
+: '{' SRTO_INITIAL '=' INTEGER ',' SRTO_MAX '=' INTEGER ',' SRTO_MIN '=' INTEGER '}' {
+#ifdef SCTP_RTOINFO
+	$$ = new_expression(EXPR_SCTP_RTOINFO);
+	if (!is_valid_u32($4)) {
+		semantic_error("srto_initial out of range");
+	}
+	$$->value.sctp_rtoinfo.srto_initial = $4;
+	if (!is_valid_u32($8)) {
+		semantic_error("srto_max out of range");
+	}
+	$$->value.sctp_rtoinfo.srto_max = $8;
+	if (!is_valid_u32($12)) {
+		semantic_error("srto_min out of range");
+	}
+	$$->value.sctp_rtoinfo.srto_min = $12;
+#else
+	$$ = NULL;
+#endif
+}
+;
+
+sctp_initmsg
+: '{' SINIT_NUM_OSTREAMS '=' INTEGER ',' SINIT_MAX_INSTREAMS '=' INTEGER ',' SINIT_MAX_ATTEMPTS '=' INTEGER ',' SINIT_MAX_INIT_TIMEO '=' INTEGER '}' {
+#ifdef SCTP_INITMSG
+	$$ = new_expression(EXPR_SCTP_INITMSG);
+	if (!is_valid_u16($4)) {
+		semantic_error("sinit_num_ostreams out of range");
+	}
+	$$->value.sctp_initmsg.sinit_num_ostreams = $4;
+	if (!is_valid_u16($8)) {
+		semantic_error("sinit_max_instreams out of range");
+	}
+	$$->value.sctp_initmsg.sinit_max_instreams = $8;
+	if (!is_valid_u16($12)) {
+		semantic_error("sinit_max_attempts out of range");
+	}
+	$$->value.sctp_initmsg.sinit_max_attempts = $12;
+	if (!is_valid_u16($16)) {
+		semantic_error("sinit_max_init_timeo out of range");
+	}
+	$$->value.sctp_initmsg.sinit_max_init_timeo = $16;
+#else
+	$$ = NULL;
+#endif
+}
+;
+
+sctp_assocval
+: '{' ASSOC_VALUE '=' INTEGER '}' {
+#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST)
+	$$ = new_expression(EXPR_SCTP_ASSOCVAL);
+	if (!is_valid_u32($4)) {
+		semantic_error("assoc_value out of range");
+	}
+	$$->value.sctp_assoc_value.assoc_value = $4;
+#else
+	$$ = NULL;
+#endif
+}
+;
+
+sctp_sackinfo
+: '{' SACK_DELAY '=' INTEGER ',' SACK_FREQ '=' INTEGER '}' {
+#ifdef SCTP_DELAYED_SACK
+	$$ = new_expression(EXPR_SCTP_SACKINFO);
+	if (!is_valid_u32($4)) {
+		semantic_error("sack_delay out of range");
+	}
+	$$->value.sctp_sack_info.sack_delay = $4;
+	if (!is_valid_u32($8)) {
+		semantic_error("sack_freq out of range");
+	}
+	$$->value.sctp_sack_info.sack_freq  = $8;
+#else
+	$$ = NULL;
+#endif
+}
+;
+
 opt_errno
 :                   { $$ = NULL; }
 | WORD note         {
diff --git a/gtests/net/packetdrill/platforms.h b/gtests/net/packetdrill/platforms.h
index 5fdda2cc21307b5f96199f37a9a87be25088d163..160869020876d97723f9110e66c742faa44c6e1c 100644
--- a/gtests/net/packetdrill/platforms.h
+++ b/gtests/net/packetdrill/platforms.h
@@ -30,6 +30,7 @@
 
 #ifdef linux
 
+#include <netinet/sctp.h>
 #include <features.h>
 #define HAVE_OPEN_MEMSTREAM     1
 #define HAVE_FMEMOPEN           1
@@ -43,6 +44,7 @@
 
 #if defined(__FreeBSD__)
 
+#include <netinet/sctp.h>
 #include <sys/param.h>
 #define USE_LIBPCAP             1
 #define TUN_PATH                "/dev/tun0"
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 46baeb6f32070019a6f9371289888289134ba190..aa9c3a90f9a8301e0a017a3763fc9e3cc3e55d0e 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -152,6 +152,9 @@ static struct expression *get_arg(struct expression_list *args,
 		++current;
 	}
 	if ((args != NULL) && (current == index)) {
+		if (!args->expression)
+			asprintf(error, "Unknown expression at index %d",
+				 index);
 		return args->expression;
 	} else {
 		asprintf(error, "Argument list too short");
@@ -1633,6 +1636,22 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		if (s32_bracketed_arg(args, 3, &optval_s32, error))
 			return STATUS_ERR;
 		optval = &optval_s32;
+#ifdef SCTP_RTOINFO
+	} else if (val_expression->type == EXPR_SCTP_RTOINFO) {
+		optval = &val_expression->value.sctp_rtoinfo;
+#endif
+#ifdef SCTP_INITMSG
+	} else if (val_expression->type == EXPR_SCTP_INITMSG) {
+		optval = &val_expression->value.sctp_initmsg;
+#endif
+#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST)
+	} else if (val_expression->type == EXPR_SCTP_ASSOCVAL) {
+		optval = &val_expression->value.sctp_assoc_value;
+#endif
+#ifdef SCTP_DELAYED_SACK
+	} else if (val_expression->type == EXPR_SCTP_SACKINFO) {
+		optval = &val_expression->value.sctp_sack_info;
+#endif
 	} else {
 		asprintf(error, "unsupported setsockopt value type: %s",
 			 expression_type_to_string(
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index f6692030a580501342d3bf77fc1d2aad5e579285..fbf150c9f7b59a11d5c69d68cd52ec6d80f2dd5b 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -65,6 +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)
+	{ EXPR_SCTP_ASSOCVAL,        "sctp_assocvalue"},
+#endif
+#ifdef SCTP_DELAYED_SACK
+	{ EXPR_SCTP_SACKINFO,        "sctp_sackinfo"},
+#endif
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -92,6 +104,9 @@ struct int_symbol cross_platform_symbols[] = {
 	{ IPPROTO_IP,                       "IPPROTO_IP"                      },
 	{ IPPROTO_IPV6,                     "IPPROTO_IPV6"                    },
 	{ IPPROTO_ICMP,                     "IPPROTO_ICMP"                    },
+#ifdef IPPROTO_SCTP
+	{ IPPROTO_SCTP,                     "IPPROTO_SCTP"                    },
+#endif
 	{ IPPROTO_TCP,                      "IPPROTO_TCP"                     },
 	{ IPPROTO_UDP,                      "IPPROTO_UDP"                     },
 
@@ -269,6 +284,18 @@ void free_expression(struct expression *expression)
 	case EXPR_ELLIPSIS:
 	case EXPR_INTEGER:
 	case EXPR_LINGER:
+#ifdef SCTP_RTOINFO
+	case EXPR_SCTP_RTOINFO:
+#endif
+#ifdef SCTP_INITMSG
+	case EXPR_SCTP_INITMSG:
+#endif
+#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST)
+	case EXPR_SCTP_ASSOCVAL:
+#endif
+#ifdef SCTP_DELAYED_SACK
+	case EXPR_SCTP_SACKINFO:
+#endif
 		break;
 	case EXPR_WORD:
 		assert(expression->value.string);
@@ -478,6 +505,31 @@ 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:		/* copy as-is */
+		memcpy(&out->value.sctp_rtoinfo, &in->value.sctp_rtoinfo,
+		       sizeof(in->value.sctp_rtoinfo));
+		break;
+#endif
+#ifdef SCTP_INITMSG
+	case EXPR_SCTP_INITMSG:		/* copy as-is */
+		memcpy(&out->value.sctp_initmsg, &in->value.sctp_initmsg,
+		       sizeof(in->value.sctp_initmsg));
+		break;
+#endif
+#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST)
+	case EXPR_SCTP_ASSOCVAL:	/* copy as-is */
+		memcpy(&out->value.sctp_assoc_value,
+		       &in->value.sctp_assoc_value,
+		       sizeof(in->value.sctp_assoc_value));
+		break;
+#endif
+#ifdef SCTP_DELAYED_SACK
+	case EXPR_SCTP_SACKINFO:	/* copy as-is */
+		memcpy(&out->value.sctp_sack_info, &in->value.sctp_sack_info,
+		       sizeof(in->value.sctp_sack_info));
+		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 ac14e65b2e40f850a67456bdf5ed5d7acbd3166c..cab9a22d618561be05239e1e5fba9f45393553cb 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -45,6 +45,19 @@ 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)
+	EXPR_SCTP_ASSOCVAL,	  /* struct sctp_assoc_value */
+#endif
+#ifdef SCTP_DELAYED_SACK
+	EXPR_SCTP_SACKINFO,	  /* struct sctp_sack_info for
+				   * SCTP_DELAYED_SACK */
+#endif
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -64,6 +77,18 @@ struct expression {
 		struct iovec_expr *iovec;
 		struct msghdr_expr *msghdr;
 		struct pollfd_expr *pollfd;
+#ifdef SCTP_RTOINFO
+		struct sctp_rtoinfo sctp_rtoinfo;
+#endif
+#ifdef SCTP_INITMSG
+		struct sctp_initmsg sctp_initmsg;
+#endif
+#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST)
+		struct sctp_assoc_value sctp_assoc_value;
+#endif
+#ifdef SCTP_DELAYED_SACK
+		struct sctp_sack_info sctp_sack_info;
+#endif
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c
index 9f630f50f42c6dc7eeb732fe1a7b6f661595216d..d78a73ec61bfc035309134f802cbd7413075db71 100644
--- a/gtests/net/packetdrill/symbols_freebsd.c
+++ b/gtests/net/packetdrill/symbols_freebsd.c
@@ -78,6 +78,14 @@ struct int_symbol platform_symbols_table[] = {
 	{ SO_SETFIB,                        "SO_SETFIB"                       },
 	{ SO_USER_COOKIE,                   "SO_USER_COOKIE"                  },
 
+	/* /usr/include/netinet/sctp.h */
+	{ SCTP_RTOINFO,                     "SCTP_RTOINFO"                    },
+	{ SCTP_INITMSG,                     "SCTP_INITMSG"                    },
+	{ SCTP_NODELAY,                     "SCTP_NODELAY"                    },
+	{ SCTP_MAXSEG,                      "SCTP_MAXSEG"                     },
+	{ SCTP_DELAYED_SACK,                "SCTP_DELAYED_SACK"               },
+	{ SCTP_MAX_BURST,                   "SCTP_MAX_BURST"                  },
+
 	/* /usr/include/netinet/tcp.h */
 	{ TCP_NODELAY,                      "TCP_NODELAY"                     },
 	{ TCP_MAXSEG,                       "TCP_MAXSEG"                      },
diff --git a/gtests/net/packetdrill/symbols_linux.c b/gtests/net/packetdrill/symbols_linux.c
index 641e37813461bae4be381b54c0e71503e70c4a33..173474361d05d8623cecc1599e337c76ba8d85b9 100644
--- a/gtests/net/packetdrill/symbols_linux.c
+++ b/gtests/net/packetdrill/symbols_linux.c
@@ -48,6 +48,9 @@
 struct int_symbol platform_symbols_table[] = {
 	{ SOL_IP,                           "SOL_IP"                          },
 	{ SOL_IPV6,                         "SOL_IPV6"                        },
+#ifdef SOL_SCTP
+	{ SOL_SCTP,                         "SOL_SCTP"                        },
+#endif
 	{ SOL_TCP,                          "SOL_TCP"                         },
 	{ SOL_UDP,                          "SOL_UDP"                         },
 
@@ -96,6 +99,25 @@ struct int_symbol platform_symbols_table[] = {
 	{ IPV6_MTU,                         "IPV6_MTU"                        },
 #endif
 
+#ifdef SCTP_RTOINFO
+	{ SCTP_RTOINFO,                     "SCTP_RTOINFO"                    },
+#endif
+#ifdef SCTP_INITMSG
+	{ SCTP_INITMSG,                     "SCTP_INITMSG"                    },
+#endif
+#ifdef SCTP_NODELAY
+	{ SCTP_NODELAY,                     "SCTP_NODELAY"                    },
+#endif
+#ifdef SCTP_MAXSEG
+	{ SCTP_MAXSEG,                      "SCTP_MAXSEG"                     },
+#endif
+#ifdef SCTP_DELAYED_SACK
+	{ SCTP_DELAYED_SACK,                "SCTP_DELAYED_SACK"               },
+#endif
+#ifdef SCTP_MAX_BURST
+	{ SCTP_MAX_BURST,                   "SCTP_MAX_BURST"                  },
+#endif
+
 	{ TCP_NODELAY,                      "TCP_NODELAY"                     },
 	{ TCP_MAXSEG,                       "TCP_MAXSEG"                      },
 	{ TCP_CORK,                         "TCP_CORK"                        },