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