Subversion Repositories HelenOS

Rev

Rev 4709 | Rev 4731 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4709 Rev 4720
Line 39... Line 39...
39
#include <stdio.h>
39
#include <stdio.h>
40
#include <string.h>
40
#include <string.h>
41
#include <task.h>
41
#include <task.h>
42
 
42
 
43
#include "../../include/in.h"
43
#include "../../include/in.h"
-
 
44
#include "../../include/in6.h"
44
#include "../../include/inet.h"
45
#include "../../include/inet.h"
45
#include "../../include/socket.h"
46
#include "../../include/socket.h"
46
 
47
 
47
#include "../../err.h"
48
#include "../../err.h"
48
 
49
 
49
#include "../parse.h"
50
#include "../parse.h"
-
 
51
#include "../print_error.h"
50
 
52
 
51
/** Echo module name.
53
/** Echo module name.
52
 */
54
 */
53
#define NAME    "Echo"
55
#define NAME    "Echo"
54
 
56
 
Line 65... Line 67...
65
void    print_help( void );
67
void    print_help( void );
66
 
68
 
67
/** Translates the character string to the protocol family number.
69
/** Translates the character string to the protocol family number.
68
 *  @param name The protocol family name. Input parameter.
70
 *  @param name The protocol family name. Input parameter.
69
 *  @returns The corresponding protocol family number.
71
 *  @returns The corresponding protocol family number.
-
 
72
 *  @returns EPFNOSUPPORTED if the protocol family is not supported.
70
 */
73
 */
71
int parse_protocol_family( const char * name );
74
int     parse_protocol_family( const char * name );
72
 
75
 
73
/** Translates the character string to the socket type number.
76
/** Translates the character string to the socket type number.
74
 *  @param name The socket type name. Input parameter.
77
 *  @param name The socket type name. Input parameter.
75
 *  @returns The corresponding socket type number.
78
 *  @returns The corresponding socket type number.
-
 
79
 *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
76
 */
80
 */
77
int parse_socket_type( const char * name );
81
int     parse_socket_type( const char * name );
78
 
82
 
79
void print_help( void ){
83
void print_help( void ){
80
    printf(
84
    printf(
81
        "Network Echo aplication\n" \
85
        "Network Echo aplication\n" \
82
        "Usage: echo [options]\n" \
86
        "Usage: echo [options]\n" \
83
        "Where options are:\n" \
87
        "Where options are:\n" \
84
        "-c count | --count=count\n" \
88
        "-c count | --count=count\n" \
85
        "\tThe number of received messages to handle. A negative number means infinity. The default is infinity.\n" \
89
        "\tThe number of received messages to handle. A negative number means infinity. The default is infinity.\n" \
86
        "\n" \
90
        "\n" \
87
        "-f protocol_family | --family=protocol_family\n" \
91
        "-f protocol_family | --family=protocol_family\n" \
88
        "\tThe listenning socket protocol family. Only the PF_INET is supported.\n"
92
        "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
89
        "\n" \
93
        "\n" \
90
        "-h | --help\n" \
94
        "-h | --help\n" \
91
        "\tShow this application help.\n"
95
        "\tShow this application help.\n"
92
        "\n" \
96
        "\n" \
93
        "-p port_number | --port=port_number\n" \
97
        "-p port_number | --port=port_number\n" \
Line 108... Line 112...
108
}
112
}
109
 
113
 
110
int parse_protocol_family( const char * name ){
114
int parse_protocol_family( const char * name ){
111
    if( str_lcmp( name, "PF_INET", 7 ) == 0 ){
115
    if( str_lcmp( name, "PF_INET", 7 ) == 0 ){
112
        return PF_INET;
116
        return PF_INET;
-
 
117
    }else if( str_lcmp( name, "PF_INET6", 8 ) == 0 ){
-
 
118
        return PF_INET6;
113
    }
119
    }
114
    return ENOENT;
120
    return EPFNOSUPPORT;
115
}
121
}
116
 
122
 
117
int parse_socket_type( const char * name ){
123
int parse_socket_type( const char * name ){
118
    if( str_lcmp( name, "SOCK_DGRAM", 11 ) == 0 ){
124
    if( str_lcmp( name, "SOCK_DGRAM", 11 ) == 0 ){
119
        return SOCK_DGRAM;
125
        return SOCK_DGRAM;
120
    }
126
    }
121
    return ENOENT;
127
    return ESOCKTNOSUPPORT;
122
}
128
}
123
 
129
 
124
int main( int argc, char * argv[] ){
130
int main( int argc, char * argv[] ){
125
    ERROR_DECLARE;
131
    ERROR_DECLARE;
126
 
132
 
127
    size_t              size            = 1024;
133
    size_t              size            = 1024;
128
    int                 verbose         = 0;
134
    int                 verbose         = 0;
129
    char *              reply           = NULL;
135
    char *              reply           = NULL;
130
    sock_type_t         type            = SOCK_DGRAM;
136
    sock_type_t         type            = SOCK_DGRAM;
131
    int                 count           = -1;
137
    int                 count           = -1;
132
    struct sockaddr_in  address         = { .sin_family = AF_INET, .sin_port = 7 };
-
 
133
    int                 family          = PF_INET;
138
    int                 family          = PF_INET;
-
 
139
    uint16_t            port            = 7;
134
 
140
 
-
 
141
    socklen_t           max_length      = sizeof( struct sockaddr_in6 );
-
 
142
    uint8_t             address_data[ max_length ];
-
 
143
    struct sockaddr *       address     = ( struct sockaddr * ) address_data;
-
 
144
    struct sockaddr_in *    address_in      = ( struct sockaddr_in * ) address;
-
 
145
    struct sockaddr_in6 *   address_in6 = ( struct sockaddr_in6 * ) address;
-
 
146
    socklen_t           addrlen;
-
 
147
    char                address_string[ INET6_ADDRSTRLEN ];
-
 
148
    uint8_t *           address_start;
135
    int                 socket_id;
149
    int                 socket_id;
136
    int                 address_length;
-
 
137
    char                address_string[ INET_ADDRSTRLEN ];
-
 
138
    char *              data;
150
    char *              data;
139
    size_t              length;
151
    size_t              length;
140
    int                 index;
152
    int                 index;
141
    size_t              reply_length;
153
    size_t              reply_length;
142
    int                 value;
154
    int                 value;
Line 147... Line 159...
147
    for( index = 1; index < argc; ++ index ){
159
    for( index = 1; index < argc; ++ index ){
148
        if( argv[ index ][ 0 ] == '-' ){
160
        if( argv[ index ][ 0 ] == '-' ){
149
            switch( argv[ index ][ 1 ] ){
161
            switch( argv[ index ][ 1 ] ){
150
                case 'c':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 ));
162
                case 'c':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 ));
151
                            break;
163
                            break;
152
                case 'f':   ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "protocol family", 0, parse_protocol_family ));
164
                case 'f':   ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 0, parse_protocol_family ));
153
                            family = value;
-
 
154
                            switch( family ){
-
 
155
                                case PF_INET:
-
 
156
                                    address.sin_family = AF_INET;
-
 
157
                                    break;
-
 
158
                                default:
-
 
159
                                    return ENOENT;
-
 
160
                            }
-
 
161
                            break;
165
                            break;
162
                case 'h':   print_help();
166
                case 'h':   print_help();
163
                            return EOK;
167
                            return EOK;
164
                            break;
168
                            break;
165
                case 'p':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 ));
169
                case 'p':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 ));
166
                            address.sin_port = ( uint16_t ) value;
170
                            port = ( uint16_t ) value;
167
                            break;
171
                            break;
168
                case 'r':   ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 0 ));
172
                case 'r':   ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 0 ));
169
                            break;
173
                            break;
170
                case 's':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 0 ));
174
                case 's':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 0 ));
171
                            size = (value >= 0 ) ? ( size_t ) value : 0;
175
                            size = (value >= 0 ) ? ( size_t ) value : 0;
Line 176... Line 180...
176
                case 'v':   verbose = 1;
180
                case 'v':   verbose = 1;
177
                            break;
181
                            break;
178
                case '-':   if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){
182
                case '-':   if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){
179
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "received count", 8 ))
183
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "received count", 8 ))
180
                            }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){
184
                            }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){
181
                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "protocol family", 9, parse_protocol_family ));
185
                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 9, parse_protocol_family ));
182
                                family = value;
-
 
183
                                switch( family ){
-
 
184
                                    case PF_INET:
-
 
185
                                        address.sin_family = AF_INET;
-
 
186
                                        break;
-
 
187
                                    default:
-
 
188
                                        return ENOENT;
-
 
189
                                }
-
 
190
                                break;
-
 
191
                            }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){
186
                            }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){
192
                                print_help();
187
                                print_help();
193
                                return EOK;
188
                                return EOK;
194
                            }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){
189
                            }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){
195
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 ));
190
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 ));
196
                                address.sin_port = ( uint16_t ) value;
191
                                port = ( uint16_t ) value;
197
                            }else if( str_lcmp( argv[ index ] + 2, "reply=", 6 ) == 0 ){
192
                            }else if( str_lcmp( argv[ index ] + 2, "reply=", 6 ) == 0 ){
198
                                ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 8 ));
193
                                ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 8 ));
199
                            }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){
194
                            }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){
200
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 7 ));
195
                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 7 ));
201
                                size = (value >= 0 ) ? ( size_t ) value : 0;
196
                                size = (value >= 0 ) ? ( size_t ) value : 0;
Line 237... Line 232...
237
    socket_id = socket( family, type, 0 );
232
    socket_id = socket( family, type, 0 );
238
    if( socket_id < 0 ){
233
    if( socket_id < 0 ){
239
        fprintf( stderr, "Socket create error %d\n", socket_id );
234
        fprintf( stderr, "Socket create error %d\n", socket_id );
240
        return socket_id;
235
        return socket_id;
241
    }
236
    }
-
 
237
 
-
 
238
    bzero( address_data, max_length );
-
 
239
    switch( family ){
-
 
240
        case PF_INET:
-
 
241
            address_in->sin_family = AF_INET;
-
 
242
            address_in->sin_port = port;
-
 
243
            addrlen = sizeof( struct sockaddr_in );
-
 
244
            break;
-
 
245
        case PF_INET6:
-
 
246
            address_in6->sin6_family = AF_INET6;
-
 
247
            address_in6->sin6_port = port;
-
 
248
            addrlen = sizeof( struct sockaddr_in6 );
-
 
249
            break;
-
 
250
        default:
-
 
251
            fprintf( stderr, "Protocol family is not supported\n" );
-
 
252
            return EAFNOSUPPORT;
-
 
253
    }
242
    if( ERROR_OCCURRED( bind( socket_id, ( struct sockaddr * ) & address, sizeof( address )))){
254
    if( ERROR_OCCURRED( bind( socket_id, address, addrlen ))){
243
        fprintf( stderr, "Socket bind error %d\n", ERROR_CODE );
255
        socket_print_error( stderr, ERROR_CODE, "Socket bind: ", "\n" );
244
        return ERROR_CODE;
256
        return ERROR_CODE;
245
    }
257
    }
246
 
258
 
247
    if( verbose ) printf( "Listenning at %d\n", address.sin_port );
259
    if( verbose ) printf( "Listenning at %d\n", port );
248
 
260
 
249
    while( count ){
261
    while( count ){
250
        address_length = sizeof( address );
262
        addrlen = max_length;
251
        value = recvfrom( socket_id, data, size, 0, ( struct sockaddr * ) & address, & address_length );
263
        value = recvfrom( socket_id, data, size, 0, address, & addrlen );
252
        if( value < 0 ){
264
        if( value < 0 ){
253
            fprintf( stderr, "Socket receive error %d\n", value );
265
            socket_print_error( stderr, value, "Socket receive: ", "\n" );
254
        }else{
266
        }else{
255
            length = ( size_t ) value;
267
            length = ( size_t ) value;
256
            if( verbose ){
268
            if( verbose ){
-
 
269
                address_start = NULL;
-
 
270
                switch( address->sa_family ){
-
 
271
                    case AF_INET:
-
 
272
                        port = address_in->sin_port;
-
 
273
                        address_start = ( uint8_t * ) & address_in->sin_addr.s_addr;
-
 
274
                        break;
-
 
275
                    case AF_INET6:
-
 
276
                        port = address_in6->sin6_port;
-
 
277
                        address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr;
-
 
278
                        break;
-
 
279
                    default:
-
 
280
                        fprintf( stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family );
-
 
281
                }
-
 
282
                if( address_start ){
257
                if( ERROR_OCCURRED( inet_ntop( address.sin_family, ( uint8_t * ) & address.sin_addr.s_addr, address_string, sizeof( address_string )))){
283
                    if( ERROR_OCCURRED( inet_ntop( address->sa_family, address_start, address_string, sizeof( address_string )))){
258
                    fprintf( stderr, "Received address error %d\n", ERROR_CODE );
284
                        fprintf( stderr, "Received address error %d\n", ERROR_CODE );
259
                    continue;
-
 
260
                }else{
285
                    }else{
261
                    data[ length ] = '\0';
286
                        data[ length ] = '\0';
262
                    printf( "Received from %s:%d\n%s\n", address_string, address.sin_port, data );
287
                        printf( "Received from %s:%d\n%s\n", address_string, port, data );
-
 
288
                    }
263
                }
289
                }
264
            }
290
            }
265
            if( ERROR_OCCURRED( sendto( socket_id, reply ? reply : data, reply ? reply_length : length, 0, ( struct sockaddr * ) & address, sizeof( address )))){
291
            if( ERROR_OCCURRED( sendto( socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen ))){
266
                fprintf( stderr, "Socket send error %d\n", ERROR_CODE );
292
                socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
267
            }
293
            }
268
        }
294
        }
269
        if( count > 0 ){
295
        if( count > 0 ){
270
            -- count;
296
            -- count;
271
            if( verbose ) printf( "Waiting for next %d packet(s)\n", count );
297
            if( verbose ) printf( "Waiting for next %d packet(s)\n", count );
Line 273... Line 299...
273
    }
299
    }
274
 
300
 
275
    if( verbose ) printf( "Closing the socket\n" );
301
    if( verbose ) printf( "Closing the socket\n" );
276
 
302
 
277
    if( ERROR_OCCURRED( closesocket( socket_id ))){
303
    if( ERROR_OCCURRED( closesocket( socket_id ))){
278
        fprintf( stderr, "Close socket error %d\n", ERROR_CODE );
304
        socket_print_error( stderr, ERROR_CODE, "Close socket: ", "\n" );
279
        return ERROR_CODE;
305
        return ERROR_CODE;
280
    }
306
    }
281
 
307
 
282
    if( verbose ) printf( "Exiting\n" );
308
    if( verbose ) printf( "Exiting\n" );
283
 
309