source: mainline/uspace/app/nettest1/nettest1.c@ c51fa73

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c51fa73 was c51fa73, checked in by Martin Decky <martin@…>, 16 years ago

down print the banner

  • Property mode set to 100644
File size: 13.3 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nettest
30 * @{
31 */
32
33/** @file
34 * Networking test 1 application - sockets.
35 */
36
37#include <malloc.h>
38#include <stdio.h>
39#include <str.h>
40#include <task.h>
41#include <time.h>
42
43#include <in.h>
44#include <in6.h>
45#include <inet.h>
46#include <socket.h>
47#include <net_err.h>
48
49#include "nettest.h"
50#include "parse.h"
51#include "print_error.h"
52
53/** Echo module name.
54 */
55#define NAME "Nettest1"
56
57/** Packet data pattern.
58 */
59#define NETTEST1_TEXT "Networking test 1 - sockets"
60
61/** Module entry point.
62 * Starts testing.
63 * @param[in] argc The number of command line parameters.
64 * @param[in] argv The command line parameters.
65 * @returns EOK on success.
66 */
67int main(int argc, char * argv[]);
68
69/** Prints the application help.
70 */
71void nettest1_print_help(void);
72
73/** Refreshes the data.
74 * Fills the data block with the NETTEST1_TEXT pattern.
75 * @param[out] data The data block.
76 * @param[in] size The data block size in bytes.
77 */
78void nettest1_refresh_data(char * data, size_t size);
79
80int main(int argc, char * argv[]){
81 ERROR_DECLARE;
82
83 size_t size = 27;
84 int verbose = 0;
85 sock_type_t type = SOCK_DGRAM;
86 int sockets = 10;
87 int messages = 10;
88 int family = PF_INET;
89 uint16_t port = 7;
90
91 socklen_t max_length = sizeof(struct sockaddr_in6);
92 uint8_t address_data[max_length];
93 struct sockaddr * address = (struct sockaddr *) address_data;
94 struct sockaddr_in * address_in = (struct sockaddr_in *) address;
95 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address;
96 socklen_t addrlen;
97// char address_string[INET6_ADDRSTRLEN];
98 uint8_t * address_start;
99
100 int * socket_ids;
101 char * data;
102 int value;
103 int index;
104 struct timeval time_before;
105 struct timeval time_after;
106
107 // parse the command line arguments
108 // stop before the last argument if it does not start with the minus sign ('-')
109 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
110 // options should start with the minus sign ('-')
111 if(argv[index][0] == '-'){
112 switch(argv[index][1]){
113 // short options with only one letter
114 case 'f':
115 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
116 break;
117 case 'h':
118 nettest1_print_help();
119 return EOK;
120 break;
121 case 'm':
122 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
123 break;
124 case 'n':
125 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
126 break;
127 case 'p':
128 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
129 port = (uint16_t) value;
130 break;
131 case 's':
132 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
133 size = (value >= 0) ? (size_t) value : 0;
134 break;
135 case 't':
136 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
137 type = (sock_type_t) value;
138 break;
139 case 'v':
140 verbose = 1;
141 break;
142 // long options with the double minus sign ('-')
143 case '-':
144 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
145 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
146 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
147 nettest1_print_help();
148 return EOK;
149 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
150 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
151 }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
152 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
153 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
154 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
155 port = (uint16_t) value;
156 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
157 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
158 type = (sock_type_t) value;
159 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
160 verbose = 1;
161 }else{
162 print_unrecognized(index, argv[index] + 2);
163 nettest1_print_help();
164 return EINVAL;
165 }
166 break;
167 default:
168 print_unrecognized(index, argv[index] + 1);
169 nettest1_print_help();
170 return EINVAL;
171 }
172 }else{
173 print_unrecognized(index, argv[index]);
174 nettest1_print_help();
175 return EINVAL;
176 }
177 }
178
179 // if not before the last argument containing the address
180 if(index >= argc){
181 printf("Command line error: missing address\n");
182 nettest1_print_help();
183 return EINVAL;
184 }
185
186 // prepare the address buffer
187 bzero(address_data, max_length);
188 switch(family){
189 case PF_INET:
190 address_in->sin_family = AF_INET;
191 address_in->sin_port = htons(port);
192 address_start = (uint8_t *) &address_in->sin_addr.s_addr;
193 addrlen = sizeof(struct sockaddr_in);
194 break;
195 case PF_INET6:
196 address_in6->sin6_family = AF_INET6;
197 address_in6->sin6_port = htons(port);
198 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
199 addrlen = sizeof(struct sockaddr_in6);
200 break;
201 default:
202 fprintf(stderr, "Address family is not supported\n");
203 return EAFNOSUPPORT;
204 }
205
206 // parse the last argument which should contain the address
207 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
208 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
209 return ERROR_CODE;
210 }
211
212 // check the buffer size
213 if(size <= 0){
214 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
215 size = 1024;
216 }
217
218 // prepare the buffer
219 // size plus the terminating null (\0)
220 data = (char *) malloc(size + 1);
221 if(! data){
222 fprintf(stderr, "Failed to allocate data buffer.\n");
223 return ENOMEM;
224 }
225 nettest1_refresh_data(data, size);
226
227 // check the socket count
228 if(sockets <= 0){
229 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
230 sockets = 2;
231 }
232
233 // prepare the socket buffer
234 // count plus the terminating null (\0)
235 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
236 if(! socket_ids){
237 fprintf(stderr, "Failed to allocate receive buffer.\n");
238 return ENOMEM;
239 }
240 socket_ids[sockets] = NULL;
241
242 if(verbose){
243 printf("Starting tests\n");
244 }
245
246 if(verbose){
247 printf("1 socket, 1 message\n");
248 }
249
250 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
251 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
252 return ERROR_CODE;
253 }
254
255 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
256 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
257 if(verbose){
258 printf("\tOK\n");
259 }
260
261 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
262 if(type == SOCK_STREAM){
263 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
264 }
265 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1));
266 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
267 if(verbose){
268 printf("\tOK\n");
269 }
270
271 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
272 if(type == SOCK_STREAM){
273 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
274 }
275 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, 1));
276 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1));
277 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
278 if(verbose){
279 printf("\tOK\n");
280 }
281
282 if(verbose){
283 printf("1 socket, %d messages\n", messages);
284 }
285
286 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
287 if(type == SOCK_STREAM){
288 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
289 }
290 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages));
291 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
292 if(verbose){
293 printf("\tOK\n");
294 }
295
296 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
297 if(type == SOCK_STREAM){
298 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
299 }
300 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, messages));
301 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages));
302 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
303 if(verbose){
304 printf("\tOK\n");
305 }
306
307 if(verbose){
308 printf("%d sockets, 1 message\n", sockets);
309 }
310
311 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
312 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
313 if(verbose){
314 printf("\tOK\n");
315 }
316
317 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
318 if(type == SOCK_STREAM){
319 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
320 }
321 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1));
322 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
323 if(verbose){
324 printf("\tOK\n");
325 }
326
327 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
328 if(type == SOCK_STREAM){
329 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
330 }
331 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, 1));
332 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1));
333 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
334 if(verbose){
335 printf("\tOK\n");
336 }
337
338 if(verbose){
339 printf("%d sockets, %d messages\n", sockets, messages);
340 }
341
342 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
343 if(type == SOCK_STREAM){
344 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
345 }
346 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
347 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
348 if(verbose){
349 printf("\tOK\n");
350 }
351
352 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
353 if(type == SOCK_STREAM){
354 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
355 }
356 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages));
357 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
358 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
359
360 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
361 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
362 return ERROR_CODE;
363 }
364
365 if(verbose){
366 printf("\tOK\n");
367 }
368
369 printf("Tested in %d microseconds\n", tv_sub(&time_after, &time_before));
370
371 if(verbose){
372 printf("Exiting\n");
373 }
374
375 return EOK;
376}
377
378void nettest1_print_help(void){
379 printf(
380 "Network Networking test 1 aplication - sockets\n" \
381 "Usage: echo [options] numeric_address\n" \
382 "Where options are:\n" \
383 "-f protocol_family | --family=protocol_family\n" \
384 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
385 "\n" \
386 "-h | --help\n" \
387 "\tShow this application help.\n"
388 "\n" \
389 "-m count | --messages=count\n" \
390 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
391 "\n" \
392 "-n sockets | --sockets=count\n" \
393 "\tThe number of sockets to use. The default is 10.\n" \
394 "\n" \
395 "-p port_number | --port=port_number\n" \
396 "\tThe port number the application should send messages to. The default is 7.\n" \
397 "\n" \
398 "-s packet_size | --size=packet_size\n" \
399 "\tThe packet data size the application sends. The default is 28 bytes.\n" \
400 "\n" \
401 "-v | --verbose\n" \
402 "\tShow all output messages.\n"
403 );
404}
405
406void nettest1_refresh_data(char * data, size_t size){
407 size_t length;
408
409 // fill the data
410 length = 0;
411 while(size > length + sizeof(NETTEST1_TEXT) - 1){
412 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
413 length += sizeof(NETTEST1_TEXT) - 1;
414 }
415 memcpy(data + length, NETTEST1_TEXT, size - length);
416 data[size] = '\0';
417}
418
419/** @}
420 */
Note: See TracBrowser for help on using the repository browser.