From d7404992d1029208e3b290b08b2861c2cbac2dc6 Mon Sep 17 00:00:00 2001
From: Michael Tuexen <tuexen@fh-muenster.de>
Date: Tue, 13 Oct 2015 23:09:03 +0200
Subject: [PATCH] Handle byte ordering of the PPID.

---
 gtests/net/packetdrill/parser.y               | 30 +++++++++++++++----
 gtests/net/packetdrill/run_system_call.c      | 24 +++++++--------
 .../tests/bsd/sctp/sctp_recvmsg.pkt           |  8 ++---
 .../tests/bsd/sctp/sctp_sendmsg.pkt           |  6 ++--
 4 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 6ccea5f6..e2c99dce 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -1292,6 +1292,12 @@ opt_ppid
 	}
 	$$ = $3;
 }
+| PPID '=' HEX_INTEGER  {
+	if (!is_valid_u32($3)) {
+		semantic_error("ppid value out of range");
+	}
+	$$ = $3;
+}
 ;
 
 opt_fsn
@@ -2328,6 +2334,18 @@ expression
 }
 | decimal_integer   { $$ = $1; }
 | hex_integer       { $$ = $1; }
+| _HTONL_ '(' INTEGER ')' {
+	if (!is_valid_u32($3)) {
+		semantic_error("number out of range");
+	}
+	$$ = new_integer_expression(htonl((u32)$3), "%lu");
+}
+| _HTONL_ '(' HEX_INTEGER ')' {
+	if (!is_valid_u32($3)) {
+		semantic_error("number out of range");
+	}
+	$$ = new_integer_expression(htonl((u32)$3), "%#lx");
+}
 | WORD              {
 	$$ = new_expression(EXPR_WORD);
 	$$->value.string = $1;
@@ -3040,11 +3058,11 @@ snd_flags
 ;
 
 snd_ppid
-: SND_PPID '=' INTEGER {
-	if (!is_valid_u32($3)) {
+: SND_PPID '=' _HTONL_ '(' INTEGER ')'{
+	if (!is_valid_u32($5)) {
 		semantic_error("snd_ppid out of range");
 	}
-	$$ = new_integer_expression($3, "%u");
+	$$ = new_integer_expression(htonl((u32)$5), "%u");
 }
 | SND_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
 ;
@@ -3112,11 +3130,11 @@ sinfo_flags
 ;
 
 sinfo_ppid
-: SINFO_PPID '=' INTEGER {
-	if (!is_valid_u32($3)) {
+: SINFO_PPID '=' _HTONL_ '(' INTEGER ')' {
+	if (!is_valid_u32($5)) {
 		semantic_error("sinfo_ppid out of range");
 	}
-	$$ = new_integer_expression($3, "%u");
+	$$ = new_integer_expression(htonl((u32)$5), "%u");
 }
 | SINFO_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
 ;
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 95cab272..10db6470 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -2983,7 +2983,7 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 	u32 ppid, flags, timetolive, context;
 	u16 stream_no;
 	struct expression *sockaddr_expr, *tolen_expr, *ppid_expr, *flags_expr, *ttl_expr, *stream_no_expr, *context_expr;
-	
+
 	if (check_arg_count(args, 10, error))
 		return STATUS_ERR;
 	if (s32_arg(args, 0, &script_fd, error))
@@ -3012,11 +3012,11 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 			memcpy(to_ptr, sockaddr_expr->value.socket_address_ipv6, sizeof(struct sockaddr_in6));
 			tolen = sizeof(struct sockaddr_in6);
 		} else {
-			asprintf(error, "Bad input for reciever in sctp_sentmsg");
+			asprintf(error, "Bad input for receiver in sctp_sendmsg");
 			return STATUS_ERR;
 		}
 	}
-	tolen_expr = get_arg(args, 4, error);	
+	tolen_expr = get_arg(args, 4, error);
 	if (tolen_expr->type != EXPR_ELLIPSIS)
 		if (get_u32(tolen_expr, &tolen, error))
 			return STATUS_ERR;
@@ -3037,10 +3037,10 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 		return STATUS_ERR;
 
 	msg = calloc(len, 1);
-	assert(msg != NULL);	
+	assert(msg != NULL);
 
 	begin_syscall(state, syscall);
-	result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr*) to_ptr, 
+	result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr *) to_ptr,
 			      tolen, ppid, flags, stream_no, timetolive, context);
 
 	if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
@@ -3057,7 +3057,7 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 
 #if defined(__FreeBSD__) || defined(__Linux__)
 static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr,
-				 struct sctp_sndrcvinfo *sctp_sndrcvinfo, 
+				 struct sctp_sndrcvinfo *sctp_sndrcvinfo,
 				 char** error) {
 	if (expr->sinfo_stream->type != EXPR_ELLIPSIS) {
 		u16 sinfo_stream;
@@ -3101,9 +3101,9 @@ static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr,
 		if (get_u32(expr->sinfo_ppid, &sinfo_ppid, error)) {
 			return STATUS_ERR;
 		}
-		if (sctp_sndrcvinfo->sinfo_ppid != sinfo_ppid) {
+		if (ntohl(sctp_sndrcvinfo->sinfo_ppid) != ntohl(sinfo_ppid)) {
 			asprintf(error, "sctp_sndrcvinfo.sinfo_ppid: expected: %u actual: %u",
-				 sinfo_ppid, sctp_sndrcvinfo->sinfo_ppid);
+				 ntohl(sinfo_ppid), ntohl(sctp_sndrcvinfo->sinfo_ppid));
 			return STATUS_ERR;
 		}
 	}
@@ -3192,7 +3192,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
 	result = sctp_recvmsg(live_fd, msg, len, (struct sockaddr*) &live_from,
 			      &live_fromlen, &live_sinfo, &live_msg_flags);
 	free(msg);
-	
+
 	if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
 		return STATUS_ERR;
 	}
@@ -3206,7 +3206,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
 			script_addr = (struct sockaddr*)script_from_expr->value.socket_address_ipv6;
 		} else {
 			asprintf(error, "sctp_recvmsg fromlen: can't check sctp_recvmsg from");
-			return STATUS_ERR;			
+			return STATUS_ERR;
 		}
 		if (script_addr->sa_family != live_from.sa_family) {
 			asprintf(error, "sctp_recvmsg from.sa_family: expected: %d actual: %d",
@@ -3214,7 +3214,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
 			return STATUS_ERR;
 		}
 		switch(script_addr->sa_family) {
-		case AF_INET: 
+		case AF_INET:
 			{
 				struct sockaddr_in *script_sockaddr = (struct sockaddr_in*)script_addr;
 				struct sockaddr_in *live_sockaddr = (struct sockaddr_in*)&live_from;
@@ -3234,7 +3234,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
 				}
 			}
 			break;
-		case AF_INET6: 
+		case AF_INET6:
 			{
 				struct sockaddr_in6 *script_sockaddr = (struct sockaddr_in6*)script_addr;
 				struct sockaddr_in6 *live_sockaddr = (struct sockaddr_in6*)&live_from;
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt
index c4df4023..c972405b 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt
@@ -1,6 +1,7 @@
 +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, ...]
@@ -14,15 +15,14 @@
 *    > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]]
 +0.0 sctp_recvmsg(3, ..., 1000, ..., ..., ..., 8) = 1000
 
-+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0]
++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=1234]
 *    > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]]
-+0.0 sctp_recvmsg(3, ..., 1000, ..., ..., {sinfo_stream=0, sinfo_ssn=1, sinfo_flags=0,
-sinfo_ppid=0, sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=2, sinfo_cumtsn=2}, 8) = 1000
++0.0 sctp_recvmsg(3, ..., 1000, ..., ..., {sinfo_stream=0, sinfo_ssn=1, sinfo_flags=0, sinfo_ppid=htonl(1234), sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=2, sinfo_cumtsn=2}, 8) = 1000
 
 +0.0 < sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=2, ppid=0]
 *    > sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=..., gaps=[], dups=[]]
 +0.0 sctp_recvmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16,
-{sinfo_stream=0, sinfo_ssn=2, sinfo_flags=0, sinfo_ppid=0, sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=3, sinfo_cumtsn=3}, 8) = 1000
+{sinfo_stream=0, sinfo_ssn=2, sinfo_flags=0, sinfo_ppid=htonl(0), sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=3, sinfo_cumtsn=3}, 8) = 1000
 
 +0.0 close(3) = 0
 +0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=3]
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt
index 6b9864ef..a4cee701 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt
@@ -11,11 +11,11 @@
 +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
 //sctp_sendmsg(int sd, const void * msg, size_t len, struct sockaddr *to, socklen_t tolen,
 //             uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context);
-+0.0 sctp_sendmsg(3, ..., 1000, ..., ..., 1234, SCTP_UNORDERED, 1, 0, 0) = 1000
++0.0 sctp_sendmsg(3, ..., 1000, ..., ..., htonl(1234), SCTP_UNORDERED, 1, 0, 0) = 1000
 +0.0 > sctp: DATA[flgs=UBE, len=1016, tsn=1, sid=1, ssn=0, ppid=1234]
 +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
-+0.0 sctp_sendmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16, 0, 0, 0, 0, 0) = 1000
-+0.0 > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=0, ppid=0]
++0.0 sctp_sendmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16, htonl(0x1234), 0, 0, 0, 0) = 1000
++0.0 > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=0, ppid=0x1234]
 +0.0 < sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=1500, gaps=[], dups=[]]
 +0.0 sctp_sendmsg(3, ..., 1000, NULL, 0, 0, 0, 0, 0, 0) = 1000
 +0.0 > sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=1, ppid=0]
-- 
GitLab