First try at implementing --extra-data. (#729)

Towards #600.
diff --git a/src/iperf.h b/src/iperf.h
index b33ba37..5c36123 100755
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -1,5 +1,5 @@
 /*
- * iperf, Copyright (c) 2014, 2015, 2016, 2017, The Regents of the University of
+ * iperf, Copyright (c) 2014-2018, The Regents of the University of
  * California, through Lawrence Berkeley National Laboratory (subject
  * to receipt of any required approvals from the U.S. Dept. of
  * Energy).  All rights reserved.
@@ -254,6 +254,7 @@
     cpuset_t cpumask;
 #endif /* HAVE_CPUSET_SETAFFINITY */
     char     *title;				/* -T option */
+    char     *extra_data;			/* --extra-data */
     char     *congestion;			/* -C option */
     char     *congestion_used;			/* what was actually used */
     char     *remote_congestion_used;		/* what the other side used */
diff --git a/src/iperf3.1 b/src/iperf3.1
index 673cf16..538e93c 100644
--- a/src/iperf3.1
+++ b/src/iperf3.1
@@ -335,6 +335,9 @@
 .BR -T ", " --title " \fIstr\fR"
 Prefix every output line with this string.
 .TP
+.BR --extra-data " \fIstr\fR"
+Specify an extra data string field to be included in JSON output.
+.TP
 .BR -C ", " --congestion " \fIalgo\fR"
 Set the congestion control algorithm (Linux and FreeBSD only).  An
 older
diff --git a/src/iperf_api.c b/src/iperf_api.c
index 8d3608b..9af71c3 100755
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -297,6 +297,12 @@
     return ipt->settings->tos;
 }
 
+char *
+iperf_get_test_extra_data(struct iperf_test *ipt)
+{
+    return ipt->extra_data;
+}
+
 /************** Setter routines for some fields inside iperf_test *************/
 
 void
@@ -500,6 +506,12 @@
     ipt->settings->tos = tos;
 }
 
+void
+iperf_set_test_extra_data(struct iperf_test *ipt, char *dat)
+{
+    ipt->extra_data = dat;
+}
+
 /********************** Get/set test protocol structure ***********************/
 
 struct protocol *
@@ -688,6 +700,7 @@
         {"version6", no_argument, NULL, '6'},
         {"tos", required_argument, NULL, 'S'},
         {"dscp", required_argument, NULL, OPT_DSCP},
+	{"extra-data", required_argument, NULL, OPT_EXTRA_DATA},
 #if defined(HAVE_FLOWLABEL)
         {"flowlabel", required_argument, NULL, 'L'},
 #endif /* HAVE_FLOWLABEL */
@@ -937,6 +950,10 @@
 		}
 		client_flag = 1;
                 break;
+	    case OPT_EXTRA_DATA:
+		test->extra_data = strdup(optarg);
+		client_flag = 1;
+	        break;
             case 'L':
 #if defined(HAVE_FLOWLABEL)
                 test->settings->flowlabel = strtol(optarg, &endptr, 0);
@@ -1547,6 +1564,8 @@
 	    cJSON_AddNumberToObject(j, "flowlabel", test->settings->flowlabel);
 	if (test->title)
 	    cJSON_AddStringToObject(j, "title", test->title);
+	if (test->extra_data)
+	    cJSON_AddStringToObject(j, "extra_data", test->extra_data);
 	if (test->congestion)
 	    cJSON_AddStringToObject(j, "congestion", test->congestion);
 	if (test->congestion_used)
@@ -1636,6 +1655,8 @@
 	    test->settings->flowlabel = j_p->valueint;
 	if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL)
 	    test->title = strdup(j_p->valuestring);
+	if ((j_p = cJSON_GetObjectItem(j, "extra_data")) != NULL)
+	    test->extra_data = strdup(j_p->valuestring);
 	if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL)
 	    test->congestion = strdup(j_p->valuestring);
 	if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL)
@@ -2102,6 +2123,7 @@
     CPU_ZERO(&testp->cpumask);
 #endif /* HAVE_CPUSET_SETAFFINITY */
     testp->title = NULL;
+    testp->extra_data = NULL;
     testp->congestion = NULL;
     testp->congestion_used = NULL;
     testp->remote_congestion_used = NULL;
@@ -2234,6 +2256,8 @@
     free(test->settings);
     if (test->title)
 	free(test->title);
+    if (test->extra_data)
+	free(test->extra_data);
     if (test->congestion)
 	free(test->congestion);
     if (test->congestion_used)
@@ -2384,6 +2408,10 @@
 	free(test->title);
 	test->title = NULL;
     }
+    if (test->extra_data) {
+	free(test->extra_data);
+	test->extra_data = NULL;
+    }
 
     /* Free output line buffers, if any (on the server only) */
     struct iperf_textline *t;
@@ -3598,6 +3626,8 @@
 {
     if (test->title)
 	cJSON_AddStringToObject(test->json_top, "title", test->title);
+    if (test->extra_data)
+	cJSON_AddStringToObject(test->json_top, "extra_data", test->extra_data);
     /* Include server output */
     if (test->json_server_output) {
 	cJSON_AddItemToObject(test->json_top, "server_output_json", test->json_server_output);
diff --git a/src/iperf_api.h b/src/iperf_api.h
index 7e8346b..53012c0 100755
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -69,6 +69,7 @@
 #define OPT_PACING_TIMER 16
 #define OPT_CONNECT_TIMEOUT 17
 #define OPT_REPEATING_PAYLOAD 18
+#define OPT_EXTRA_DATA 19
 
 /* states */
 #define TEST_START 1
@@ -117,6 +118,7 @@
 int	iperf_get_test_udp_counters_64bit( struct iperf_test* ipt );
 int	iperf_get_test_one_off( struct iperf_test* ipt );
 int iperf_get_test_tos( struct iperf_test* ipt );
+char*	iperf_get_extra_data( struct iperf_test* ipt );
 
 /* Setter routines for some fields inside iperf_test. */
 void	iperf_set_verbose( struct iperf_test* ipt, int verbose );
@@ -144,6 +146,7 @@
 void	iperf_set_test_udp_counters_64bit( struct iperf_test* ipt, int udp_counters_64bit );
 void	iperf_set_test_one_off( struct iperf_test* ipt, int one_off );
 void    iperf_set_test_tos( struct iperf_test* ipt, int tos );
+void	iperf_set_extra_data( struct iperf_test* ipt, char *dat);
 
 #if defined(HAVE_SSL)
 void    iperf_set_test_client_username(struct iperf_test *ipt, char *client_username);
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
index 2f31f13..a1a240c 100644
--- a/src/iperf_locale.c
+++ b/src/iperf_locale.c
@@ -169,6 +169,7 @@
                            "  -Z, --zerocopy            use a 'zero copy' method of sending data\n"
                            "  -O, --omit N              omit the first n seconds\n"
                            "  -T, --title str           prefix every output line with this string\n"
+                           "  --extra-data str          data string to include in client and server JSON\n"
                            "  --get-server-output       get results from server\n"
                            "  --udp-counters-64bit      use 64-bit counters in UDP test packets\n"
                            "  --repeating-payload       use repeating pattern in payload, instead of\n"