From 9edf1acc84baff9aef7a9f1921b09cf564efa70a Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Mon, 12 Oct 2015 13:55:39 +0200
Subject: [PATCH] Add structur sctp_sndrcvinfo in parser

---
 gtests/net/packetdrill/lexer.l           |   8 ++
 gtests/net/packetdrill/parser.y          | 101 +++++++++++++++++++++++
 gtests/net/packetdrill/run_system_call.c |   2 +-
 gtests/net/packetdrill/script.c          |  66 +++++++++++++++
 gtests/net/packetdrill/script.h          |  16 +++-
 5 files changed, 191 insertions(+), 2 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index acfd944b..5cebb2f7 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -247,6 +247,14 @@ snd_flags			return SND_FLAGS;
 snd_ppid			return SND_PPID;
 snd_context			return SND_CONTEXT;
 ssb_adaptation_ind		return SSB_ADAPTATION_IND;
+sinfo_stream			return SINFO_STREAM;
+sinfo_ssn			return SINFO_SSN;
+sinfo_flags			return SINFO_FLAGS;
+sinfo_ppid			return SINFO_PPID;
+sinfo_context			return SINFO_CONTEXT;
+sinfo_timetolive		return SINFO_TIMETOLIVE;
+sinfo_tsn			return SINFO_TSN;
+sinfo_cumtsn			return SINFO_CUMTSN;
 CHUNK				return CHUNK;
 DATA				return DATA;
 INIT				return INIT;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 3bf683e7..6239ff26 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -539,6 +539,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON
 %token <reserved> SND_SID SND_FLAGS SND_PPID SND_CONTEXT SSB_ADAPTATION_IND
 %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 <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -589,6 +591,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sasoc_local_rwnd sasoc_cookie_life sctp_assocparams
 %type <expression> sctp_sndinfo snd_sid snd_flags snd_ppid snd_context
 %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 <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2401,6 +2405,9 @@ expression
 | null              {
 	$$ = $1;
 }
+| sctp_sndrcvinfo   {
+	$$ = $1;
+}
 ;
 
 decimal_integer
@@ -3069,6 +3076,7 @@ sctp_sndinfo
 	$$->value.sctp_sndinfo->snd_ppid = $6;
 	$$->value.sctp_sndinfo->snd_context = $8;
 }
+;
 
 sctp_setadaptation
 : '{' SSB_ADAPTATION_IND '=' INTEGER '}' {
@@ -3081,6 +3089,99 @@ sctp_setadaptation
 }
 ;
 
+sinfo_stream
+: SINFO_STREAM '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("sinfo_stream out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_STREAM '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_ssn
+: SINFO_SSN '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("sinfo_ssn out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_SSN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_flags
+: SINFO_FLAGS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("sinfo_flags out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_ppid
+: SINFO_PPID '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("sinfo_ppid out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_context
+: SINFO_CONTEXT '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("sinfo_context out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_CONTEXT '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_timetolive
+: SINFO_TIMETOLIVE '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("snd_timetolive out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_TIMETOLIVE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_tsn
+: SINFO_TSN '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("sinfo_tsn out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_TSN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sinfo_cumtsn
+: SINFO_CUMTSN '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("sinfo_cumtsn out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SINFO_CUMTSN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sctp_sndrcvinfo
+: '{' sinfo_stream ',' sinfo_ssn ',' sinfo_flags ',' sinfo_ppid ',' sinfo_context ',' sinfo_timetolive ',' sinfo_tsn ',' sinfo_cumtsn '}' {
+	$$ = new_expression(EXPR_SCTP_SNDRCVINFO);
+	$$->value.sctp_sndrcvinfo = calloc(1, sizeof(struct sctp_sndrcvinfo));
+	$$->value.sctp_sndrcvinfo->sinfo_stream = $2;
+	$$->value.sctp_sndrcvinfo->sinfo_ssn = $4;
+	$$->value.sctp_sndrcvinfo->sinfo_flags = $6;
+	$$->value.sctp_sndrcvinfo->sinfo_ppid = $8;
+	$$->value.sctp_sndrcvinfo->sinfo_context = $10;
+	$$->value.sctp_sndrcvinfo->sinfo_timetolive = $12;
+	$$->value.sctp_sndrcvinfo->sinfo_tsn = $14;
+	$$->value.sctp_sndrcvinfo->sinfo_cumtsn = $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 5432a337..535d2b93 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -3055,7 +3055,7 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
 #endif
 }
 
-static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscall,
+static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscall,
 			struct expression_list *args, char **error)
 {
 	return STATUS_OK;
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 3ff2b522..1b766b82 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -78,6 +78,7 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_EVENT,	     "sctp_event"      },
 	{ EXPR_SCTP_SNDINFO,         "sctp_sndinfo"    },
 	{ EXPR_SCTP_SETADAPTATION,   "sctp_setadaptation"},
+	{ EXPR_SCTP_SNDRCVINFO,      "sctp_sndrcvinfo" },
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -367,6 +368,16 @@ void free_expression(struct expression *expression)
 	case EXPR_SCTP_SETADAPTATION:
 		free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind);
 		break;
+	case EXPR_SCTP_SNDRCVINFO:
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_stream);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_ssn);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_flags);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_ppid);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_context);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_timetolive);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_tsn);
+		free_expression(expression->value.sctp_sndrcvinfo->sinfo_cumtsn);
+		break;
 	case EXPR_WORD:
 		assert(expression->value.string);
 		free(expression->value.string);
@@ -968,6 +979,58 @@ static int evaluate_sctp_setadaptation_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_sndrcvinfo_expression(struct expression *in,
+						  struct expression *out,
+						  char **error)
+{
+        struct sctp_sndrcvinfo_expr *in_info;
+        struct sctp_sndrcvinfo_expr *out_info;
+
+        assert(in->type == EXPR_SCTP_SNDRCVINFO);
+        assert(in->value.sctp_sndrcvinfo);
+        assert(out->type == EXPR_SCTP_SNDRCVINFO);
+
+        out->value.sctp_sndrcvinfo = calloc(1, sizeof(struct sctp_sndrcvinfo_expr));
+                     
+        in_info = in->value.sctp_sndrcvinfo;
+        out_info = out->value.sctp_sndrcvinfo;
+                     
+        if (evaluate(in_info->sinfo_stream,
+		     &out_info->sinfo_stream,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_ssn,
+		     &out_info->sinfo_ssn,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_flags,
+		     &out_info->sinfo_flags,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_ppid,
+		     &out_info->sinfo_ppid,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_context,
+		     &out_info->sinfo_context,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_timetolive,
+		     &out_info->sinfo_timetolive,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_tsn,
+		     &out_info->sinfo_tsn,
+		     error))
+		return STATUS_ERR;
+        if (evaluate(in_info->sinfo_cumtsn,
+		     &out_info->sinfo_cumtsn,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate(struct expression *in,
 		    struct expression **out_ptr, char **error)
 {
@@ -1029,6 +1092,9 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_SETADAPTATION:
 		result = evaluate_sctp_setadaptation_expression(in, out, error);
 		break;
+	case EXPR_SCTP_SNDRCVINFO:
+		result = evaluate_sctp_sndrcvinfo_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 f98d43e2..fbcf7fe7 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -57,7 +57,8 @@ enum expression_t {
 	EXPR_SCTP_ASSOCPARAMS,    /* struct sctp_assocparams for SCTP_ASSOCINFO */
 	EXPR_SCTP_EVENT,	  /* struct sctp_event for SCTP_EVENT */
 	EXPR_SCTP_SNDINFO,	  /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */
-	EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
+	EXPR_SCTP_SETADAPTATION,  /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
+	EXPR_SCTP_SNDRCVINFO,     /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -89,6 +90,7 @@ struct expression {
 		struct sctp_event_expr *sctp_event;
 		struct sctp_sndinfo_expr *sctp_sndinfo;
 		struct sctp_setadaptation_expr *sctp_setadaptation;
+		struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo;
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
@@ -228,6 +230,18 @@ struct sctp_setadaptation_expr {
 	struct expression *ssb_adaptation_ind;
 };
 
+/* Parse tree for sctp_sndrcvinfo in sctp_recvmsg syscall. */
+struct sctp_sndrcvinfo_expr {
+	struct expression *sinfo_stream;
+	struct expression *sinfo_ssn;
+	struct expression *sinfo_flags;
+	struct expression *sinfo_ppid;
+	struct expression *sinfo_context;
+	struct expression *sinfo_timetolive;
+	struct expression *sinfo_tsn;
+	struct expression *sinfo_cumtsn;
+};
+
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
 	const char *errno_macro;	/* errno symbol (C macro name) */
-- 
GitLab