source: mainline/uspace/app/nettest1/nettest.c@ cbfece7

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

nettest fixes (thx Antonin Steinhauser)

  • Property mode set to 100644
File size: 9.5 KB
RevLine 
[3be62bc]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
[3d459fc]30 * @{
[3be62bc]31 */
32
33/** @file
[3d459fc]34 * Networking test support functions implementation.
[3be62bc]35 */
36
37#include <stdio.h>
[d9e2e0e]38#include <net/socket.h>
[3be62bc]39
40#include "nettest.h"
41#include "print_error.h"
42
[3d459fc]43/** Creates new sockets.
44 *
45 * @param[in] verbose A value indicating whether to print out verbose information.
46 * @param[out] socket_ids A field to store the socket identifiers.
47 * @param[in] sockets The number of sockets to create. Should be at most the size of the field.
48 * @param[in] family The socket address family.
49 * @param[in] type The socket type.
[1bfd3d3]50 * @return EOK on success.
51 * @return Other error codes as defined for the socket() function.
[3d459fc]52 */
[c442f63]53int sockets_create(int verbose, int *socket_ids, unsigned int sockets,
54 uint16_t family, sock_type_t type)
[3d459fc]55{
56 if (verbose)
[3be62bc]57 printf("Create\t");
[c442f63]58
[3be62bc]59 fflush(stdout);
[3d459fc]60
[c442f63]61 for (unsigned int index = 0; index < sockets; index++) {
[3be62bc]62 socket_ids[index] = socket(family, type, 0);
[3d459fc]63 if (socket_ids[index] < 0) {
[c442f63]64 printf("Socket %u (%d) error:\n", index, socket_ids[index]);
[3be62bc]65 socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
66 return socket_ids[index];
67 }
[c442f63]68
[3d459fc]69 if (verbose)
[3be62bc]70 print_mark(index);
71 }
[3d459fc]72
[3be62bc]73 return EOK;
74}
75
[3d459fc]76/** Closes sockets.
77 *
78 * @param[in] verbose A value indicating whether to print out verbose information.
79 * @param[in] socket_ids A field of stored socket identifiers.
80 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
[1bfd3d3]81 * @return EOK on success.
82 * @return Other error codes as defined for the closesocket() function.
[3d459fc]83 */
[c442f63]84int sockets_close(int verbose, int *socket_ids, unsigned int sockets)
[3d459fc]85{
86 if (verbose)
[3be62bc]87 printf("\tClose\t");
[c442f63]88
[3be62bc]89 fflush(stdout);
[3d459fc]90
[c442f63]91 for (unsigned int index = 0; index < sockets; index++) {
92 int rc = closesocket(socket_ids[index]);
[0bbef9b]93 if (rc != EOK) {
[c442f63]94 printf("Socket %u (%d) error:\n", index, socket_ids[index]);
[0bbef9b]95 socket_print_error(stderr, rc, "Socket close: ", "\n");
96 return rc;
[3be62bc]97 }
[c442f63]98
[3d459fc]99 if (verbose)
[3be62bc]100 print_mark(index);
101 }
[3d459fc]102
[3be62bc]103 return EOK;
104}
105
[3d459fc]106/** Connects sockets.
107 *
108 * @param[in] verbose A value indicating whether to print out verbose information.
109 * @param[in] socket_ids A field of stored socket identifiers.
110 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
111 * @param[in] address The destination host address to connect to.
112 * @param[in] addrlen The length of the destination address in bytes.
[1bfd3d3]113 * @return EOK on success.
114 * @return Other error codes as defined for the connect() function.
[3d459fc]115 */
[c442f63]116int sockets_connect(int verbose, int *socket_ids, unsigned int sockets,
117 struct sockaddr *address, socklen_t addrlen)
[3d459fc]118{
119 if (verbose)
[3be62bc]120 printf("\tConnect\t");
[3d459fc]121
[3be62bc]122 fflush(stdout);
[3d459fc]123
[c442f63]124 for (unsigned int index = 0; index < sockets; index++) {
125 int rc = connect(socket_ids[index], address, addrlen);
[0bbef9b]126 if (rc != EOK) {
127 socket_print_error(stderr, rc, "Socket connect: ", "\n");
128 return rc;
[3be62bc]129 }
[c442f63]130
[3d459fc]131 if (verbose)
[3be62bc]132 print_mark(index);
133 }
[3d459fc]134
[3be62bc]135 return EOK;
136}
137
[c442f63]138/** Send data via sockets.
139 *
140 * @param[in] verbose Print out verbose information.
141 * @param[in] socket_ids Stored socket identifiers.
142 * @param[in] sockets Number of sockets.
143 * @param[in] address Destination host address to send data to.
144 * @param[in] addrlen Length of the destination address in bytes.
145 * @param[in] data Data to be sent.
146 * @param[in] size Size of the data in bytes.
147 * @param[in] messages Number of datagrams per socket to be sent.
148 * @param[in] type Socket type.
[3d459fc]149 *
[1bfd3d3]150 * @return EOK on success.
151 * @return Other error codes as defined for the sendto() function.
[c442f63]152 *
[3d459fc]153 */
[c442f63]154int sockets_sendto(int verbose, int *socket_ids, unsigned int sockets,
155 struct sockaddr *address, socklen_t addrlen, char *data, size_t size,
156 unsigned int messages, sock_type_t type)
[3d459fc]157{
158 if (verbose)
[3be62bc]159 printf("\tSendto\t");
[c442f63]160
[3be62bc]161 fflush(stdout);
[3d459fc]162
[c442f63]163 for (unsigned int index = 0; index < sockets; index++) {
164 for (unsigned int message = 0; message < messages; message++) {
165 int rc;
166
167 switch (type) {
168 case SOCK_STREAM:
169 rc = send(socket_ids[index], data, size, 0);
170 break;
171 case SOCK_DGRAM:
172 rc = sendto(socket_ids[index], data, size, 0, address, addrlen);
173 break;
174 default:
175 rc = EINVAL;
176 }
177
[0bbef9b]178 if (rc != EOK) {
[c442f63]179 printf("Socket %u (%d), message %u error:\n",
180 index, socket_ids[index], message);
[0bbef9b]181 socket_print_error(stderr, rc, "Socket send: ", "\n");
182 return rc;
[3be62bc]183 }
184 }
[c442f63]185
[3d459fc]186 if (verbose)
[3be62bc]187 print_mark(index);
188 }
[3d459fc]189
[3be62bc]190 return EOK;
191}
192
[c442f63]193/** Receive data via sockets.
194 *
195 * @param[in] verbose Print out verbose information.
196 * @param[in] socket_ids Stored socket identifiers.
197 * @param[in] sockets Number of sockets.
198 * @param[in] address Source host address of received datagrams.
199 * @param[in,out] addrlen Maximum length of the source address in bytes.
200 * The actual size of the source address is set.
201 * @param[out] data Received data.
202 * @param[in] size Maximum data size in bytes.
203 * @param[in] messages Number of datagrams per socket to be received.
[3d459fc]204 *
[1bfd3d3]205 * @return EOK on success.
206 * @return Other error codes as defined for the recvfrom() function.
[c442f63]207 *
[3d459fc]208 */
[c442f63]209int sockets_recvfrom(int verbose, int *socket_ids, unsigned int sockets,
210 struct sockaddr *address, socklen_t *addrlen, char *data, size_t size,
211 unsigned int messages)
[3d459fc]212{
213 if (verbose)
[3be62bc]214 printf("\tRecvfrom\t");
[3d459fc]215
[3be62bc]216 fflush(stdout);
[3d459fc]217
[c442f63]218 for (unsigned int index = 0; index < sockets; index++) {
219 for (unsigned int message = 0; message < messages; message++) {
220 int rc = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
221 if (rc < 0) {
222 printf("Socket %u (%d), message %u error:\n",
223 index, socket_ids[index], message);
224 socket_print_error(stderr, rc, "Socket receive: ", "\n");
225 return rc;
[3be62bc]226 }
227 }
[c442f63]228
[3d459fc]229 if (verbose)
[3be62bc]230 print_mark(index);
231 }
[c442f63]232
[3be62bc]233 return EOK;
234}
235
[c442f63]236/** Send and receive data via sockets.
[3d459fc]237 *
238 * Each datagram is sent and a reply read consequently.
239 * The next datagram is sent after the reply is received.
240 *
[c442f63]241 * @param[in] verbose Print out verbose information.
242 * @param[in] socket_ids Stored socket identifiers.
243 * @param[in] sockets Number of sockets.
244 * @param[in,out] address Destination host address to send data to.
245 * The source host address of received datagrams is set.
246 * @param[in] addrlen Length of the destination address in bytes.
247 * @param[in,out] data Data to be sent. The received data are set.
248 * @param[in] size Size of the data in bytes.
249 * @param[in] messages Number of datagrams per socket to be received.
250 * @param[in] type Socket type.
251 *
[1bfd3d3]252 * @return EOK on success.
253 * @return Other error codes as defined for the recvfrom() function.
[c442f63]254 *
[3d459fc]255 */
[c442f63]256int sockets_sendto_recvfrom(int verbose, int *socket_ids, unsigned int sockets,
257 struct sockaddr *address, socklen_t *addrlen, char *data,
258 size_t size, unsigned int messages, sock_type_t type)
[3d459fc]259{
260 if (verbose)
[3be62bc]261 printf("\tSendto and recvfrom\t");
[c442f63]262
[3be62bc]263 fflush(stdout);
[3d459fc]264
[c442f63]265 for (unsigned int index = 0; index < sockets; index++) {
266 for (unsigned int message = 0; message < messages; message++) {
267 int rc;
268
269 switch (type) {
270 case SOCK_STREAM:
271 rc = send(socket_ids[index], data, size, 0);
272 break;
273 case SOCK_DGRAM:
274 rc = sendto(socket_ids[index], data, size, 0, address, *addrlen);
275 break;
276 default:
277 rc = EINVAL;
278 }
279
[0bbef9b]280 if (rc != EOK) {
[c442f63]281 printf("Socket %u (%d), message %u error:\n",
282 index, socket_ids[index], message);
[0bbef9b]283 socket_print_error(stderr, rc, "Socket send: ", "\n");
284 return rc;
[3be62bc]285 }
[c442f63]286
287 rc = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
288 if (rc < 0) {
289 printf("Socket %u (%d), message %u error:\n",
290 index, socket_ids[index], message);
291 socket_print_error(stderr, rc, "Socket receive: ", "\n");
292 return rc;
[3be62bc]293 }
294 }
[c442f63]295
[3d459fc]296 if (verbose)
[3be62bc]297 print_mark(index);
298 }
[3d459fc]299
[3be62bc]300 return EOK;
301}
302
[3d459fc]303/** Prints a mark.
304 *
305 * If the index is a multiple of ten, a different mark is printed.
306 *
307 * @param[in] index The index of the mark to be printed.
[c442f63]308 *
[3d459fc]309 */
[c442f63]310void print_mark(unsigned int index)
[3d459fc]311{
312 if ((index + 1) % 10)
[3be62bc]313 printf("*");
[3d459fc]314 else
[3be62bc]315 printf("|");
[c442f63]316
[3be62bc]317 fflush(stdout);
318}
319
320/** @}
321 */
Note: See TracBrowser for help on using the repository browser.