Subversion Repositories HelenOS

Rev

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

Rev 3685 Rev 3846
Line 31... Line 31...
31
 */
31
 */
32
 
32
 
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
-
 
36
#include <as.h>
36
#include <async.h>
37
#include <async.h>
37
#include <errno.h>
38
#include <errno.h>
38
#include <stdio.h>
39
#include <stdio.h>
-
 
40
 
39
#include <ipc/ipc.h>
41
#include <ipc/ipc.h>
40
#include <ipc/services.h>
42
#include <ipc/services.h>
41
//#include <sys/mman.h>
-
 
42
 
43
 
43
#include "../err.h"
44
#include "../err.h"
44
#include "../measured_strings.h"
45
#include "../measured_strings.h"
45
#include "../messages.h"
46
#include "../messages.h"
46
#include "../modules.h"
47
#include "../modules.h"
-
 
48
#include "../packet.h"
-
 
49
 
-
 
50
#include "../include/sockaddr.h"
-
 
51
#include "../include/socket.h"
47
#include "../netif/netif_device_id_type.h"
52
#include "../netif/device.h"
48
 
53
 
49
#include "ip.h"
54
#include "ip.h"
-
 
55
#include "ip_messages.h"
-
 
56
#include "ip_module.h"
50
 
57
 
51
#define DEFAULT_IPV 4
58
#define DEFAULT_IPV     4
-
 
59
 
-
 
60
#define IPC_GET_DEVICE( call )      ( device_id_t ) IPC_GET_ARG1( * call )
-
 
61
#define IPC_GET_PROTO( call )       ( int ) IPC_GET_ARG1( * call )
-
 
62
#define IPC_GET_SERVICE( call )     ( services_t ) IPC_GET_ARG2( * call )
-
 
63
#define IPC_GET_STATE( call )       ( device_state_t ) IPC_GET_ARG2( * call )
-
 
64
#define IPC_GET_PHONE( call )       ( int ) IPC_GET_ARG5( * call )
52
 
65
 
53
ip_globals_t    ip_globals;
66
ip_globals_t    ip_globals;
54
 
67
 
55
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
68
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
56
 
69
 
-
 
70
INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
-
 
71
 
-
 
72
int ip_register_message( int protocol, int phone );
57
int parse_address( char * value, address_ref address );
73
int ip_state_message( device_id_t device_id, device_state_t state );
-
 
74
void    ip_driver_receiver( ipc_callid_t iid, ipc_call_t * icall );
58
 
75
 
59
/** Initializes the module.
76
/** Initializes the module.
60
 */
77
 */
61
int ip_initialize( void ){
78
int ip_initialize( void ){
62
    ip_netifs_initialize( & ip_globals.netifs );
79
    ip_netifs_initialize( & ip_globals.netifs );
-
 
80
    ip_protos_initialize( & ip_globals.protos );
63
    return EOK;
81
    return EOK;
64
}
82
}
65
 
83
 
-
 
84
int ip_echo_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t * answer1, ipcarg_t * answer2, ipcarg_t * answer3, ipcarg_t * answer4, ipcarg_t * answer5 ){
-
 
85
    if( answer1 ) * answer1 = arg1;
-
 
86
    if( answer2 ) * answer2 = arg2;
-
 
87
    if( answer3 ) * answer3 = arg3;
-
 
88
    if( answer4 ) * answer4 = arg4;
66
int ip_call( ipc_callid_t callid ){
89
    if( answer5 ) * answer5 = arg5;
67
    return EOK;
90
    return EOK;
68
}
91
}
69
 
92
 
70
int parse_address( char * value, address_ref address ){
93
int ip_device_message( device_id_t device_id, services_t service ){
71
    char *  next;
-
 
72
    int index;
-
 
73
 
-
 
74
    if( ! value ){
-
 
75
        ( * address )[ 0 ] = ( * address )[ 1 ] = ( * address )[ 2 ] = ( * address )[ 3 ] = 0;
-
 
76
        return ENOENT;
-
 
77
    }
-
 
78
    next = value;
-
 
79
    for( index = 0; index < 4; ++ index ){
-
 
80
        if(( ! next ) || ( ! * next )) return EINVAL;
-
 
81
        if( index ) ++ next;
-
 
82
        ( * address )[ index ] = strtoul( next, & next, 0 );
-
 
83
    }
-
 
84
    return EOK;
-
 
85
}
-
 
86
 
-
 
87
int ip_message( ipc_callid_t callid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
-
 
88
    ERROR_DECLARE;
94
    ERROR_DECLARE;
89
 
95
 
90
    ip_netif_ref        ip_netif;
96
    ip_netif_ref        ip_netif;
91
    aid_t           message;
97
    aid_t           message;
92
    ipc_call_t      answer;
98
    ipc_call_t      answer;
93
    measured_string_t   configuration[ 9 ] = {{ "IPV", 3 }, { "IP_CONFIG", 9 }, { "IP_ADDR", 7 }, { "NETMASK", 7 }, { "GATEWAY", 7 }, { "BROADCAST", 9 }, { "DNS1", 4 }, { "DNS2", 4 }, { "ARP", 3 }};
99
    measured_string_t   configuration[ 9 ] = {{ "IPV", 3 }, { "IP_CONFIG", 9 }, { "IP_ADDR", 7 }, { "NETMASK", 7 }, { "GATEWAY", 7 }, { "BROADCAST", 9 }, { "DNS1", 4 }, { "DNS2", 4 }, { "ARP", 3 }};
94
    int         count = 9;
100
    int         count = 9;
95
    measured_string_ref settings;
101
    measured_string_ref settings;
96
    char *          data;
102
    char *          data;
97
 
103
 
-
 
104
    ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
-
 
105
    if( ! ip_netif ) return ENOMEM;
-
 
106
    ip_netif->device_id = device_id;
-
 
107
    // get configuration
-
 
108
    // TODO mapping
-
 
109
    message = async_send_2( ip_globals.networking_phone, NET_NET_GET_DEVICE_CONF, ip_netif->device_id, count, & answer );
-
 
110
    // send names and get settings
-
 
111
    if( ERROR_OCCURED( measured_strings_send( ip_globals.networking_phone, configuration, count ))
-
 
112
    || ERROR_OCCURED( measured_strings_return( ip_globals.networking_phone, & settings, & data, count ))){
-
 
113
        async_wait_for( message, NULL );
-
 
114
        return ERROR_CODE;
-
 
115
    }
-
 
116
    if( settings ){
-
 
117
        if( settings[ 0 ].value ){
-
 
118
            ip_netif->ipv = strtol( settings[ 0 ].value, NULL, 0 );
-
 
119
        }else{
-
 
120
            ip_netif->ipv = DEFAULT_IPV;
-
 
121
        }
-
 
122
        ip_netif->dhcp = ! strcmp( settings[ 1 ].value, "DHCP" );
-
 
123
        if( ip_netif->dhcp ){
-
 
124
            // TODO dhcp
-
 
125
            free( ip_netif );
-
 
126
            return ENOTSUP;
-
 
127
        }else if( ip_netif->ipv == 4 ){
-
 
128
            if( ERROR_OCCURED( inet_pton( AF_INET, settings[ 2 ].value, ( uint8_t * ) & ip_netif->address ))
-
 
129
            || ERROR_OCCURED( inet_pton( AF_INET, settings[ 3 ].value, ( uint8_t * ) & ip_netif->netmask ))
-
 
130
            || ( inet_pton( AF_INET, settings[ 4 ].value, ( uint8_t * ) & ip_netif->gateway ) == EINVAL )
-
 
131
            || ( inet_pton( AF_INET, settings[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast ) == EINVAL )
-
 
132
            || ( inet_pton( AF_INET, settings[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
-
 
133
            || ( inet_pton( AF_INET, settings[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
-
 
134
                free( ip_netif );
-
 
135
                return EINVAL;
-
 
136
            }
-
 
137
        }else{
-
 
138
            // TODO ipv6
-
 
139
            free( ip_netif );
-
 
140
            return ENOTSUP;
-
 
141
        }
-
 
142
        // TODO ARP module
-
 
143
    }
-
 
144
    // TODO arp module
-
 
145
    free( settings );
-
 
146
    free( data );
-
 
147
    // end request
-
 
148
    // TODO mapping
-
 
149
    async_wait_for( message, NULL );
-
 
150
    // print the settings
-
 
151
    printf( "\n -IPV =\t%d", ip_netif->ipv );
-
 
152
    printf( "\n -configuration =\t%s", ip_netif->dhcp ? "dhcp" : "static" );
-
 
153
    // TODO ipv6
-
 
154
    data = malloc( INET_ADDRSTRLEN );
-
 
155
    if( data ){
-
 
156
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->address, data, INET_ADDRSTRLEN );
-
 
157
        printf( "\n -address =\t%s", data );
-
 
158
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->netmask, data, INET_ADDRSTRLEN );
-
 
159
        printf( "\n -netmask =\t%s", data );
-
 
160
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->gateway, data, INET_ADDRSTRLEN );
-
 
161
        printf( "\n -gateway =\t%s", data );
-
 
162
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast, data, INET_ADDRSTRLEN );
-
 
163
        printf( "\n -broadcast =\t%s", data );
-
 
164
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns1, data, INET_ADDRSTRLEN );
-
 
165
        printf( "\n -dns1 =\t%s", data );
-
 
166
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
-
 
167
        printf( "\n -dns2 =\t%s", data );
-
 
168
        free( data );
-
 
169
    }
-
 
170
    // TODO mapping
-
 
171
    ip_netif->phone = bind_service( service, ip_netif->device_id, SERVICE_IP, 0, ip_driver_receiver );
-
 
172
    if( ERROR_OCCURED( ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif ))){
-
 
173
        free( ip_netif );
-
 
174
        return ERROR_CODE;
-
 
175
    }
-
 
176
    return EOK;
-
 
177
}
-
 
178
 
-
 
179
void ip_driver_receiver( ipc_callid_t iid, ipc_call_t * icall ){
-
 
180
    ERROR_DECLARE;
-
 
181
 
-
 
182
    ipc_callid_t    callid;
-
 
183
    ipc_call_t  call;
-
 
184
//  ipc_call_t  answer;
-
 
185
//  int     count;
-
 
186
    int     result;
-
 
187
    packet_t    packet;
-
 
188
 
-
 
189
    /*
-
 
190
     * Accept the connection
-
 
191
     *  - Answer the first IPC_M_CONNECT_ME_TO call.
-
 
192
     */
-
 
193
    ipc_answer_0( iid, EOK );
-
 
194
 
98
    switch( method ){
195
    while( true ){
-
 
196
/*      // refresh data
-
 
197
        count = 0;
-
 
198
        IPC_SET_RETVAL( answer, 0 );
-
 
199
        // just to be precize
-
 
200
        IPC_SET_RETVAL( answer, 0 );
-
 
201
        IPC_SET_ARG1( answer, 0 );
-
 
202
        IPC_SET_ARG2( answer, 0 );
-
 
203
        IPC_SET_ARG3( answer, 0 );
-
 
204
        IPC_SET_ARG4( answer, 0 );
-
 
205
        IPC_SET_ARG5( answer, 0 );
-
 
206
*/
-
 
207
        callid = async_get_call( & call );
-
 
208
        switch( IPC_GET_METHOD( call )){
-
 
209
            case NET_IL_DEVICE_STATE:
-
 
210
            case NET_NIL_DEVICE_STATE:
-
 
211
                result = ip_state_message( IPC_GET_DEVICE( & call ), IPC_GET_STATE( & call ));
-
 
212
                ipc_answer_0( callid, result );
-
 
213
            // TODO packer received
-
 
214
            case NET_IL_RECEIVED:
-
 
215
            case NET_NIL_RECEIVED:
-
 
216
                if( ERROR_OCCURED( result = packet_receive( & packet ))){
-
 
217
                    ipc_answer_0( callid, ERROR_CODE );
-
 
218
                    continue;
-
 
219
                }
-
 
220
                //result = ip_receive_message( IPC_GET_DEVICE( call ), packet );
-
 
221
                packet_destroy( packet );
-
 
222
                ipc_answer_0( callid, result );
-
 
223
        }
-
 
224
    }
-
 
225
}
-
 
226
 
-
 
227
int ip_state_message( device_id_t device_id, device_state_t state ){
-
 
228
    // TODO state
-
 
229
    printf( "\nip - device %d changed state to %d\n", device_id, state );
-
 
230
    return EOK;
-
 
231
}
-
 
232
 
-
 
233
int ip_register_message( int protocol, int phone ){
-
 
234
    ERROR_DECLARE;
-
 
235
 
-
 
236
    ip_proto_ref    proto;
-
 
237
 
-
 
238
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
-
 
239
    if( ! proto ) return ENOMEM;
-
 
240
    proto->protocol = protocol;
-
 
241
    proto->phone = phone;
-
 
242
    if( ERROR_OCCURED( ip_protos_add( & ip_globals.protos, proto->protocol, proto ))){
-
 
243
        free( proto );
-
 
244
        return ERROR_CODE;
-
 
245
    }
-
 
246
    return EOK;
-
 
247
}
-
 
248
 
-
 
249
int ip_send_message( device_id_t device_id, packet_t packet ){
-
 
250
    // TODO send packet
-
 
251
    printf( "Packet to send via %d: %s", device_id, packet_get_data( packet ));
-
 
252
    return EOK;
-
 
253
}
-
 
254
 
-
 
255
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
-
 
256
    ERROR_DECLARE;
-
 
257
 
-
 
258
    packet_t    packet;
-
 
259
 
-
 
260
    * answer_count = 0;
-
 
261
    switch( IPC_GET_METHOD( * call )){
99
        case IPC_M_PHONE_HUNGUP:
262
        case IPC_M_PHONE_HUNGUP:
100
            return EOK;
263
            return EOK;
101
        case NET_IP_ECHO:
264
        case NET_IP_ECHO:
102
            if( result1 ) * result1 = arg1;
-
 
103
            if( result2 ) * result2 = arg2;
-
 
104
            if( result3 ) * result3 = arg3;
265
            * answer_count = 5;
105
            return EOK;
266
            return ip_echo_message( IPC_GET_ARG1( * call ), IPC_GET_ARG2( * call ), IPC_GET_ARG3( * call ), IPC_GET_ARG4( * call ), IPC_GET_ARG5( * call ), & IPC_GET_ARG1( * answer ), & IPC_GET_ARG2( * answer ), & IPC_GET_ARG3( * answer ), & IPC_GET_ARG4( * answer ), & IPC_GET_ARG5( * answer ) );
106
        case NET_IL_DEVICE:
267
        case NET_IL_DEVICE:
107
            ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
268
            return ip_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
108
            if( ! ip_netif ) return ENOMEM;
-
 
109
            ip_netif->device_id = arg1;
-
 
110
            // get configuration
-
 
111
            message = async_send_2( ip_globals.networking_phone, NET_NETWORKING_GET_DEVICE_CONFIGURATION, ip_netif->device_id, count, & answer );
-
 
112
            // send names and get settings
-
 
113
            if( ERROR_OCCURED( measured_strings_send( ip_globals.networking_phone, configuration, count ))
-
 
114
            || ERROR_OCCURED( measured_strings_return( ip_globals.networking_phone, & settings, & data, count ))){
-
 
115
                async_wait_for( message, NULL );
-
 
116
                return ERROR_CODE;
269
        case IPC_M_CONNECT_TO_ME:
117
            }
-
 
118
            if( settings ){
-
 
119
                if( settings[ 0 ].value ){
-
 
120
                    ip_netif->ipv = strtol( settings[ 0 ].value, NULL, 0 );
-
 
121
                }else{
-
 
122
                    ip_netif->ipv = DEFAULT_IPV;
-
 
123
                }
-
 
124
                ip_netif->dhcp = ! strcmp( settings[ 1 ].value, "DHCP" );
-
 
125
                if( ip_netif->dhcp ){
-
 
126
                    // TODO dhcp
-
 
127
                    free( ip_netif );
-
 
128
                    return ENOTSUP;
-
 
129
                }else if( ip_netif->ipv == 4 ){
-
 
130
                    if( ERROR_OCCURED( parse_address( settings[ 2 ].value, & ip_netif->address ))
-
 
131
                    || ERROR_OCCURED( parse_address( settings[ 3 ].value, & ip_netif->netmask ))
-
 
132
                    || ( parse_address( settings[ 4 ].value, & ip_netif->gateway ) == EINVAL )
-
 
133
                    || ( parse_address( settings[ 5 ].value, & ip_netif->broadcast ) == EINVAL )
-
 
134
                    || ( parse_address( settings[ 6 ].value, & ip_netif->dns1 ) == EINVAL )
-
 
135
                    || ( parse_address( settings[ 7 ].value, & ip_netif->dns2 ) == EINVAL )){
270
            return ip_register_message( IPC_GET_PROTO( call ), IPC_GET_PHONE( call ));
136
                        free( ip_netif );
-
 
137
                        return EINVAL;
-
 
138
                    }
-
 
139
                }else{
-
 
140
                    // TODO ipv6
-
 
141
                    free( ip_netif );
-
 
142
                    return ENOTSUP;
-
 
143
                }
-
 
144
                // TODO ARP module
-
 
145
            }
-
 
146
            // print the settings
-
 
147
            printf( "\n -IPV=%d", ip_netif->ipv );
-
 
148
            printf( "\n -configuration=%s", ip_netif->dhcp ? "dhcp" : "static" );
-
 
149
            // TODO ipv6
271
        case NET_IP_SEND:
150
            printf( "\n -address=%d.%d.%d.%d", ip_netif->address[ 0 ], ip_netif->address[ 1 ], ip_netif->address[ 2 ], ip_netif->address[ 3 ] );
-
 
151
            printf( "\n -netmask=%d.%d.%d.%d", ip_netif->netmask[ 0 ], ip_netif->netmask[ 1 ], ip_netif->netmask[ 2 ], ip_netif->netmask[ 3 ] );
-
 
152
            printf( "\n -gateway=%d.%d.%d.%d", ip_netif->gateway[ 0 ], ip_netif->gateway[ 1 ], ip_netif->gateway[ 2 ], ip_netif->gateway[ 3 ] );
-
 
153
            printf( "\n -broadcast=%d.%d.%d.%d", ip_netif->broadcast[ 0 ], ip_netif->broadcast[ 1 ], ip_netif->broadcast[ 2 ], ip_netif->broadcast[ 3 ] );
-
 
154
            printf( "\n -dns1=%d.%d.%d.%d", ip_netif->dns1[ 0 ], ip_netif->dns1[ 1 ], ip_netif->dns1[ 2 ], ip_netif->dns1[ 3 ] );
-
 
155
            printf( "\n -dns2=%d.%d.%d.%d", ip_netif->dns2[ 0 ], ip_netif->dns2[ 1 ], ip_netif->dns2[ 2 ], ip_netif->dns2[ 3 ] );
-
 
156
            // TODO arp module
-
 
157
            free( settings );
-
 
158
            free( data );
-
 
159
            // end request
-
 
160
            async_wait_for( message, NULL );
-
 
161
            ip_netif->phone = connect_to_service( arg2 );
272
            ERROR_PROPAGATE( packet_receive( & packet ));
162
            if( ERROR_OCCURED( async_req_2_0( ip_netif->phone, NET_LL_REGISTER, arg1, SERVICE_IP ))
-
 
163
            || ERROR_OCCURED( ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif ))){
-
 
164
                free( ip_netif );
-
 
165
                return ERROR_CODE;
-
 
166
            }
-
 
167
            return EOK;
-
 
168
        case NET_IL_DEVICE_STATE_CHANGED:
-
 
169
        case NET_LL_DEVICE_STATE_CHANGED:
-
 
170
            // arg1 device id
-
 
171
            // arg2 state
-
 
172
            // TODO state
-
 
173
            printf( "\nip - device %d changed state to %d\n", arg1, arg2 );
273
            return ip_send_message( IPC_GET_DEVICE( call ), packet );
174
        case NET_IP_TCP_REGISTER:
-
 
175
            ip_globals.tcp_phone = connect_to_service( arg1 );
-
 
176
            return EOK;
-
 
177
    }
274
    }
178
    return ENOTSUP;
275
    return ENOTSUP;
179
}
276
}
180
 
277
 
181
/** @}
278
/** @}