00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include "nettest.h"
00038 #include "print_error.h"
00039
00040 #include <malloc.h>
00041 #include <stdio.h>
00042 #include <str.h>
00043 #include <task.h>
00044 #include <time.h>
00045 #include <arg_parse.h>
00046 #include <bool.h>
00047
00048 #include <net/in.h>
00049 #include <net/in6.h>
00050 #include <net/inet.h>
00051 #include <net/socket.h>
00052 #include <net/socket_parse.h>
00053
00055 #define NAME "Nettest2"
00056
00058 #define NETTEST2_TEXT "Networking test 2 - transfer"
00059
00060 static size_t size;
00061 static bool verbose;
00062 static sock_type_t type;
00063 static int sockets;
00064 static int messages;
00065 static int family;
00066 static uint16_t port;
00067
00068 static void nettest2_print_help(void)
00069 {
00070 printf(
00071 "Network Networking test 2 aplication - UDP transfer\n"
00072 "Usage: echo [options] address\n"
00073 "Where options are:\n"
00074 "-f protocol_family | --family=protocol_family\n"
00075 "\tThe listenning socket protocol family. Only the PF_INET and "
00076 "PF_INET6 are supported.\n"
00077 "\n"
00078 "-h | --help\n"
00079 "\tShow this application help.\n"
00080 "\n"
00081 "-m count | --messages=count\n"
00082 "\tThe number of messages to send and receive per socket. The "
00083 "default is 10.\n"
00084 "\n"
00085 "-n sockets | --sockets=count\n"
00086 "\tThe number of sockets to use. The default is 10.\n"
00087 "\n"
00088 "-p port_number | --port=port_number\n"
00089 "\tThe port number the application should send messages to. The "
00090 "default is 7.\n"
00091 "\n"
00092 "-s packet_size | --size=packet_size\n"
00093 "\tThe packet data size the application sends. The default is 29 "
00094 "bytes.\n"
00095 "\n"
00096 "-v | --verbose\n"
00097 "\tShow all output messages.\n");
00098 }
00099
00105 static void nettest2_fill_buffer(char *buffer, size_t size)
00106 {
00107 size_t length;
00108
00109 length = 0;
00110 while (size > length + sizeof(NETTEST2_TEXT) - 1) {
00111 memcpy(buffer + length, NETTEST2_TEXT,
00112 sizeof(NETTEST2_TEXT) - 1);
00113 length += sizeof(NETTEST2_TEXT) - 1;
00114 }
00115
00116 memcpy(buffer + length, NETTEST2_TEXT, size - length);
00117 buffer[size] = '\0';
00118 }
00119
00126 static int nettest2_parse_opt(int argc, char *argv[], int *index)
00127 {
00128 int value;
00129 int rc;
00130
00131 switch (argv[*index][1]) {
00132
00133
00134
00135 case 'f':
00136 rc = arg_parse_name_int(argc, argv, index, &family, 0,
00137 socket_parse_protocol_family);
00138 if (rc != EOK)
00139 return rc;
00140 break;
00141 case 'h':
00142 nettest2_print_help();
00143 return EOK;
00144 break;
00145 case 'm':
00146 rc = arg_parse_int(argc, argv, index, &messages, 0);
00147 if (rc != EOK)
00148 return rc;
00149 break;
00150 case 'n':
00151 rc = arg_parse_int(argc, argv, index, &sockets, 0);
00152 if (rc != EOK)
00153 return rc;
00154 break;
00155 case 'p':
00156 rc = arg_parse_int(argc, argv, index, &value, 0);
00157 if (rc != EOK)
00158 return rc;
00159 port = (uint16_t) value;
00160 break;
00161 case 's':
00162 rc = arg_parse_int(argc, argv, index, &value, 0);
00163 if (rc != EOK)
00164 return rc;
00165 size = (value >= 0) ? (size_t) value : 0;
00166 break;
00167 case 't':
00168 rc = arg_parse_name_int(argc, argv, index, &value, 0,
00169 socket_parse_socket_type);
00170 if (rc != EOK)
00171 return rc;
00172 type = (sock_type_t) value;
00173 break;
00174 case 'v':
00175 verbose = true;
00176 break;
00177
00178
00179
00180 case '-':
00181 if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
00182 rc = arg_parse_name_int(argc, argv, index, &family, 9,
00183 socket_parse_protocol_family);
00184 if (rc != EOK)
00185 return rc;
00186 } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
00187 nettest2_print_help();
00188 return EOK;
00189 } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) {
00190 rc = arg_parse_int(argc, argv, index, &messages, 8);
00191 if (rc != EOK)
00192 return rc;
00193 } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) {
00194 rc = arg_parse_int(argc, argv, index, &sockets, 8);
00195 if (rc != EOK)
00196 return rc;
00197 } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
00198 rc = arg_parse_int(argc, argv, index, &value, 7);
00199 if (rc != EOK)
00200 return rc;
00201 port = (uint16_t) value;
00202 } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
00203 rc = arg_parse_name_int(argc, argv, index, &value, 7,
00204 socket_parse_socket_type);
00205 if (rc != EOK)
00206 return rc;
00207 type = (sock_type_t) value;
00208 } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
00209 verbose = 1;
00210 } else {
00211 nettest2_print_help();
00212 return EINVAL;
00213 }
00214 break;
00215 default:
00216 nettest2_print_help();
00217 return EINVAL;
00218 }
00219
00220 return EOK;
00221 }
00222
00223 int main(int argc, char *argv[])
00224 {
00225 struct sockaddr *address;
00226 struct sockaddr_in address_in;
00227 struct sockaddr_in6 address_in6;
00228 socklen_t addrlen;
00229 uint8_t *address_start;
00230
00231 int *socket_ids;
00232 char *data;
00233 int index;
00234 struct timeval time_before;
00235 struct timeval time_after;
00236
00237 int rc;
00238
00239 size = 28;
00240 verbose = false;
00241 type = SOCK_DGRAM;
00242 sockets = 10;
00243 messages = 10;
00244 family = PF_INET;
00245 port = 7;
00246
00247
00248
00249
00250
00251
00252 for (index = 1; (index < argc - 1) || ((index == argc - 1) &&
00253 (argv[index][0] == '-')); ++index) {
00254
00255
00256 if (argv[index][0] == '-') {
00257 rc = nettest2_parse_opt(argc, argv, &index);
00258 if (rc != EOK)
00259 return rc;
00260 } else {
00261 nettest2_print_help();
00262 return EINVAL;
00263 }
00264 }
00265
00266
00267 if (index >= argc) {
00268 printf("Command line error: missing address\n");
00269 nettest2_print_help();
00270 return EINVAL;
00271 }
00272
00273
00274
00275 switch (family) {
00276 case PF_INET:
00277 address_in.sin_family = AF_INET;
00278 address_in.sin_port = htons(port);
00279 address = (struct sockaddr *) &address_in;
00280 addrlen = sizeof(address_in);
00281 address_start = (uint8_t *) &address_in.sin_addr.s_addr;
00282 break;
00283 case PF_INET6:
00284 address_in6.sin6_family = AF_INET6;
00285 address_in6.sin6_port = htons(port);
00286 address = (struct sockaddr *) &address_in6;
00287 addrlen = sizeof(address_in6);
00288 address_start = (uint8_t *) &address_in6.sin6_addr.s6_addr;
00289 break;
00290 default:
00291 fprintf(stderr, "Address family is not supported\n");
00292 return EAFNOSUPPORT;
00293 }
00294
00295
00296 rc = inet_pton(family, argv[argc - 1], address_start);
00297 if (rc != EOK) {
00298 fprintf(stderr, "Address parse error %d\n", rc);
00299 return rc;
00300 }
00301
00302
00303 if (size <= 0) {
00304 fprintf(stderr, "Data buffer size too small (%zu). Using 1024 "
00305 "bytes instead.\n", size);
00306 size = 1024;
00307 }
00308
00309
00310
00311
00312
00313 data = (char *) malloc(size + 1);
00314 if (!data) {
00315 fprintf(stderr, "Failed to allocate data buffer.\n");
00316 return ENOMEM;
00317 }
00318
00319
00320 nettest2_fill_buffer(data, size);
00321
00322
00323 if (sockets <= 0) {
00324 fprintf(stderr, "Socket count too small (%d). Using "
00325 "2 instead.\n", sockets);
00326 sockets = 2;
00327 }
00328
00329
00330
00331
00332
00333 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
00334 if (!socket_ids) {
00335 fprintf(stderr, "Failed to allocate receive buffer.\n");
00336 return ENOMEM;
00337 }
00338 socket_ids[sockets] = 0;
00339
00340 if (verbose)
00341 printf("Starting tests\n");
00342
00343 rc = sockets_create(verbose, socket_ids, sockets, family, type);
00344 if (rc != EOK)
00345 return rc;
00346
00347 if (type == SOCK_STREAM) {
00348 rc = sockets_connect(verbose, socket_ids, sockets,
00349 address, addrlen);
00350 if (rc != EOK)
00351 return rc;
00352 }
00353
00354 if (verbose)
00355 printf("\n");
00356
00357 rc = gettimeofday(&time_before, NULL);
00358 if (rc != EOK) {
00359 fprintf(stderr, "Get time of day error %d\n", rc);
00360 return rc;
00361 }
00362
00363 rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address,
00364 &addrlen, data, size, messages);
00365 if (rc != EOK)
00366 return rc;
00367
00368 rc = gettimeofday(&time_after, NULL);
00369 if (rc != EOK) {
00370 fprintf(stderr, "Get time of day error %d\n", rc);
00371 return rc;
00372 }
00373
00374 if (verbose)
00375 printf("\tOK\n");
00376
00377 printf("sendto + recvfrom tested in %ld microseconds\n",
00378 tv_sub(&time_after, &time_before));
00379
00380 rc = gettimeofday(&time_before, NULL);
00381 if (rc != EOK) {
00382 fprintf(stderr, "Get time of day error %d\n", rc);
00383 return rc;
00384 }
00385
00386 rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen,
00387 data, size, messages);
00388 if (rc != EOK)
00389 return rc;
00390
00391 rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen,
00392 data, size, messages);
00393 if (rc != EOK)
00394 return rc;
00395
00396 rc = gettimeofday(&time_after, NULL);
00397 if (rc != EOK) {
00398 fprintf(stderr, "Get time of day error %d\n", rc);
00399 return rc;
00400 }
00401
00402 if (verbose)
00403 printf("\tOK\n");
00404
00405 printf("sendto, recvfrom tested in %ld microseconds\n",
00406 tv_sub(&time_after, &time_before));
00407
00408 rc = sockets_close(verbose, socket_ids, sockets);
00409 if (rc != EOK)
00410 return rc;
00411
00412 if (verbose)
00413 printf("\nExiting\n");
00414
00415 return EOK;
00416 }
00417