Changeset aadf01e in mainline for uspace/srv/net/il
- Timestamp:
- 2010-03-07T15:13:28Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 936835e
- Parents:
- aa85487
- Location:
- uspace/srv/net/il
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
raa85487 raadf01e 81 81 * @returns ENOMEM if there is not enough memory left. 82 82 */ 83 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address);83 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 84 84 85 85 /** Clears the device specific data. 86 86 * @param[in] device The device specific data. 87 87 */ 88 void arp_clear_device( arp_device_ref device);88 void arp_clear_device(arp_device_ref device); 89 89 90 90 /** @name Message processing functions … … 103 103 * @returns Other error codes as defined for the measured_strings_return() function. 104 104 */ 105 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address);105 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 106 106 107 107 /** Returns the hardware address for the given protocol address. … … 116 116 * @returns NULL if the hardware address is not found in the cache. 117 117 */ 118 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target);118 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 119 119 120 120 /** Processes the received ARP packet. … … 131 131 * @returns ENOMEM if there is not enough memory left. 132 132 */ 133 int arp_receive_message( device_id_t device_id, packet_t packet);133 int arp_receive_message(device_id_t device_id, packet_t packet); 134 134 135 135 /** Updates the device content length according to the new MTU value. … … 139 139 * @returns EOK on success. 140 140 */ 141 int arp_mtu_changed_message( device_id_t device_id, size_t mtu);141 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 142 142 143 143 /*@}*/ 144 144 145 DEVICE_MAP_IMPLEMENT( arp_cache, arp_device_t)146 147 INT_MAP_IMPLEMENT( arp_protos, arp_proto_t)148 149 GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t)150 151 task_id_t arp_task_get_id( void){145 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t) 146 147 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t) 148 149 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t) 150 151 task_id_t arp_task_get_id(void){ 152 152 return task_get_id(); 153 153 } 154 154 155 int arp_clear_device_req( int arp_phone, device_id_t device_id){156 arp_device_ref 157 158 fibril_rwlock_write_lock( & arp_globals.lock);159 device = arp_cache_find( & arp_globals.cache, device_id);160 if( ! device){161 fibril_rwlock_write_unlock( & arp_globals.lock);155 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 156 arp_device_ref device; 157 158 fibril_rwlock_write_lock(&arp_globals.lock); 159 device = arp_cache_find(&arp_globals.cache, device_id); 160 if(! device){ 161 fibril_rwlock_write_unlock(&arp_globals.lock); 162 162 return ENOENT; 163 163 } 164 arp_clear_device( device);165 printf( "Device %d cleared\n", device_id);166 fibril_rwlock_write_unlock( & arp_globals.lock);167 return EOK; 168 } 169 170 int arp_clear_address_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){171 arp_device_ref 172 arp_proto_ref 173 174 fibril_rwlock_write_lock( & arp_globals.lock);175 device = arp_cache_find( & arp_globals.cache, device_id);176 if( ! device){177 fibril_rwlock_write_unlock( & arp_globals.lock);164 arp_clear_device(device); 165 printf("Device %d cleared\n", device_id); 166 fibril_rwlock_write_unlock(&arp_globals.lock); 167 return EOK; 168 } 169 170 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 171 arp_device_ref device; 172 arp_proto_ref proto; 173 174 fibril_rwlock_write_lock(&arp_globals.lock); 175 device = arp_cache_find(&arp_globals.cache, device_id); 176 if(! device){ 177 fibril_rwlock_write_unlock(&arp_globals.lock); 178 178 return ENOENT; 179 179 } 180 proto = arp_protos_find( & device->protos, protocol);181 if( ! proto){182 fibril_rwlock_write_unlock( & arp_globals.lock);180 proto = arp_protos_find(&device->protos, protocol); 181 if(! proto){ 182 fibril_rwlock_write_unlock(&arp_globals.lock); 183 183 return ENOENT; 184 184 } 185 arp_addr_exclude( & proto->addresses, address->value, address->length ); 186 fibril_rwlock_write_unlock( & arp_globals.lock ); 187 return EOK; 188 } 189 190 int arp_clean_cache_req( int arp_phone ){ 191 int count; 192 arp_device_ref device; 193 194 fibril_rwlock_write_lock( & arp_globals.lock ); 195 for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){ 196 device = arp_cache_get_index( & arp_globals.cache, count ); 197 if( device ){ 198 arp_clear_device( device ); 199 if( device->addr_data ) free( device->addr_data ); 200 if( device->broadcast_data ) free( device->broadcast_data ); 201 } 202 } 203 arp_cache_clear( & arp_globals.cache ); 204 fibril_rwlock_write_unlock( & arp_globals.lock ); 205 printf( "Cache cleaned\n" ); 206 return EOK; 207 } 208 209 int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){ 185 arp_addr_exclude(&proto->addresses, address->value, address->length); 186 fibril_rwlock_write_unlock(&arp_globals.lock); 187 return EOK; 188 } 189 190 int arp_clean_cache_req(int arp_phone){ 191 int count; 192 arp_device_ref device; 193 194 fibril_rwlock_write_lock(&arp_globals.lock); 195 for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){ 196 device = arp_cache_get_index(&arp_globals.cache, count); 197 if(device){ 198 arp_clear_device(device); 199 if(device->addr_data){ 200 free(device->addr_data); 201 } 202 if(device->broadcast_data){ 203 free(device->broadcast_data); 204 } 205 } 206 } 207 arp_cache_clear(&arp_globals.cache); 208 fibril_rwlock_write_unlock(&arp_globals.lock); 209 printf("Cache cleaned\n"); 210 return EOK; 211 } 212 213 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 210 214 ERROR_DECLARE; 211 215 … … 213 217 214 218 // copy the given address for exclusive use 215 tmp = measured_string_copy( address);216 if( ERROR_OCCURRED( arp_device_message( device_id, netif, protocol, tmp))){217 free( tmp->value);218 free( tmp);219 tmp = measured_string_copy(address); 220 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 221 free(tmp->value); 222 free(tmp); 219 223 } 220 224 return ERROR_CODE; 221 225 } 222 226 223 int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){224 measured_string_ref 225 226 fibril_rwlock_read_lock( & arp_globals.lock);227 tmp = arp_translate_message( device_id, protocol, address);228 if( tmp){229 * translation = measured_string_copy( tmp);230 fibril_rwlock_read_unlock( & arp_globals.lock);231 if( * translation){232 * data = ( ** translation).value;227 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 228 measured_string_ref tmp; 229 230 fibril_rwlock_read_lock(&arp_globals.lock); 231 tmp = arp_translate_message(device_id, protocol, address); 232 if(tmp){ 233 *translation = measured_string_copy(tmp); 234 fibril_rwlock_read_unlock(&arp_globals.lock); 235 if(*translation){ 236 *data = (** translation).value; 233 237 return EOK; 234 238 }else{ … … 236 240 } 237 241 }else{ 238 fibril_rwlock_read_unlock( & arp_globals.lock);242 fibril_rwlock_read_unlock(&arp_globals.lock); 239 243 return ENOENT; 240 244 } 241 245 } 242 246 243 int arp_initialize( async_client_conn_t client_connection){247 int arp_initialize(async_client_conn_t client_connection){ 244 248 ERROR_DECLARE; 245 249 246 fibril_rwlock_initialize( & arp_globals.lock);247 fibril_rwlock_write_lock( & arp_globals.lock);250 fibril_rwlock_initialize(&arp_globals.lock); 251 fibril_rwlock_write_lock(&arp_globals.lock); 248 252 arp_globals.client_connection = client_connection; 249 ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache));250 fibril_rwlock_write_unlock( & arp_globals.lock);251 return EOK; 252 } 253 254 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address){253 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache)); 254 fibril_rwlock_write_unlock(&arp_globals.lock); 255 return EOK; 256 } 257 258 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 255 259 ERROR_DECLARE; 256 260 257 * proto = ( arp_proto_ref ) malloc( sizeof( arp_proto_t )); 258 if( !( * proto )) return ENOMEM; 259 ( ** proto ).service = service; 260 ( ** proto ).addr = address; 261 ( ** proto ).addr_data = address->value; 262 if( ERROR_OCCURRED( arp_addr_initialize( &( ** proto).addresses ))){ 263 free( * proto ); 261 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 262 if(!(*proto)){ 263 return ENOMEM; 264 } 265 (** proto).service = service; 266 (** proto).addr = address; 267 (** proto).addr_data = address->value; 268 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 269 free(*proto); 264 270 return ERROR_CODE; 265 271 } … … 267 273 } 268 274 269 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){275 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 270 276 ERROR_DECLARE; 271 277 272 arp_device_ref 273 arp_proto_ref 274 int 275 hw_type_t 276 277 fibril_rwlock_write_lock( & arp_globals.lock);278 arp_device_ref device; 279 arp_proto_ref proto; 280 int index; 281 hw_type_t hardware; 282 283 fibril_rwlock_write_lock(&arp_globals.lock); 278 284 // an existing device? 279 device = arp_cache_find( & arp_globals.cache, device_id);280 if( device){281 if( device->service != service){282 printf( "Device %d already exists\n", device->device_id);283 fibril_rwlock_write_unlock( & arp_globals.lock);285 device = arp_cache_find(&arp_globals.cache, device_id); 286 if(device){ 287 if(device->service != service){ 288 printf("Device %d already exists\n", device->device_id); 289 fibril_rwlock_write_unlock(&arp_globals.lock); 284 290 return EEXIST; 285 291 } 286 proto = arp_protos_find( & device->protos, protocol);287 if( proto){288 free( proto->addr);289 free( proto->addr_data);292 proto = arp_protos_find(&device->protos, protocol); 293 if(proto){ 294 free(proto->addr); 295 free(proto->addr_data); 290 296 proto->addr = address; 291 297 proto->addr_data = address->value; 292 298 }else{ 293 if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address))){294 fibril_rwlock_write_unlock( & arp_globals.lock);299 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 300 fibril_rwlock_write_unlock(&arp_globals.lock); 295 301 return ERROR_CODE; 296 302 } 297 index = arp_protos_add( & device->protos, proto->service, proto);298 if( index < 0){299 fibril_rwlock_write_unlock( & arp_globals.lock);300 free( proto);303 index = arp_protos_add(&device->protos, proto->service, proto); 304 if(index < 0){ 305 fibril_rwlock_write_unlock(&arp_globals.lock); 306 free(proto); 301 307 return index; 302 308 } 303 printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);309 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol); 304 310 } 305 311 }else{ 306 hardware = hardware_map( service ); 307 if( ! hardware ) return ENOENT; 312 hardware = hardware_map(service); 313 if(! hardware){ 314 return ENOENT; 315 } 308 316 // create a new device 309 device = ( arp_device_ref ) malloc( sizeof( arp_device_t));310 if( ! device){311 fibril_rwlock_write_unlock( & arp_globals.lock);317 device = (arp_device_ref) malloc(sizeof(arp_device_t)); 318 if(! device){ 319 fibril_rwlock_write_unlock(&arp_globals.lock); 312 320 return ENOMEM; 313 321 } 314 322 device->hardware = hardware; 315 323 device->device_id = device_id; 316 if( ERROR_OCCURRED( arp_protos_initialize( & device->protos))317 || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address))){318 fibril_rwlock_write_unlock( & arp_globals.lock);319 free( device);320 return ERROR_CODE; 321 } 322 index = arp_protos_add( & device->protos, proto->service, proto);323 if( index < 0){324 fibril_rwlock_write_unlock( & arp_globals.lock);325 arp_protos_destroy( & device->protos);326 free( device);324 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos)) 325 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 326 fibril_rwlock_write_unlock(&arp_globals.lock); 327 free(device); 328 return ERROR_CODE; 329 } 330 index = arp_protos_add(&device->protos, proto->service, proto); 331 if(index < 0){ 332 fibril_rwlock_write_unlock(&arp_globals.lock); 333 arp_protos_destroy(&device->protos); 334 free(device); 327 335 return index; 328 336 } 329 337 device->service = service; 330 338 // bind the new one 331 device->phone = nil_bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, arp_globals.client_connection);332 if( device->phone < 0){333 fibril_rwlock_write_unlock( & arp_globals.lock);334 arp_protos_destroy( & device->protos);335 free( device);339 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection); 340 if(device->phone < 0){ 341 fibril_rwlock_write_unlock(&arp_globals.lock); 342 arp_protos_destroy(&device->protos); 343 free(device); 336 344 return EREFUSED; 337 345 } 338 346 // get packet dimensions 339 if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->packet_dimension))){340 fibril_rwlock_write_unlock( & arp_globals.lock);341 arp_protos_destroy( & device->protos);342 free( device);347 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){ 348 fibril_rwlock_write_unlock(&arp_globals.lock); 349 arp_protos_destroy(&device->protos); 350 free(device); 343 351 return ERROR_CODE; 344 352 } 345 353 // get hardware address 346 if( ERROR_OCCURRED( nil_get_addr_req( device->phone, device_id, & device->addr, & device->addr_data))){347 fibril_rwlock_write_unlock( & arp_globals.lock);348 arp_protos_destroy( & device->protos);349 free( device);354 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){ 355 fibril_rwlock_write_unlock(&arp_globals.lock); 356 arp_protos_destroy(&device->protos); 357 free(device); 350 358 return ERROR_CODE; 351 359 } 352 360 // get broadcast address 353 if( ERROR_OCCURRED( nil_get_broadcast_addr_req( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){ 354 fibril_rwlock_write_unlock( & arp_globals.lock ); 355 free( device->addr ); 356 free( device->addr_data ); 357 arp_protos_destroy( & device->protos ); 358 free( device ); 359 return ERROR_CODE; 360 } 361 if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ 362 fibril_rwlock_write_unlock( & arp_globals.lock ); 363 free( device->addr ); 364 free( device->addr_data ); 365 free( device->broadcast_addr ); 366 free( device->broadcast_data ); 367 arp_protos_destroy( & device->protos ); 368 free( device ); 369 return ERROR_CODE; 370 } 371 printf( "New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol ); 372 } 373 fibril_rwlock_write_unlock( & arp_globals.lock ); 374 return EOK; 375 } 376 377 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ 378 arp_device_ref device; 379 arp_proto_ref proto; 380 measured_string_ref addr; 381 size_t length; 382 packet_t packet; 383 arp_header_ref header; 384 385 if( ! target ) return NULL; 386 device = arp_cache_find( & arp_globals.cache, device_id ); 387 if( ! device ) return NULL; 388 proto = arp_protos_find( & device->protos, protocol ); 389 if(( ! proto ) || ( proto->addr->length != target->length )) return NULL; 390 addr = arp_addr_find( & proto->addresses, target->value, target->length ); 391 if( addr ) return addr; 392 // ARP packet content size = header + ( address + translation ) * 2 393 length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2; 394 if( length > device->packet_dimension.content ) return NULL; 395 packet = packet_get_4( arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix ); 396 if( ! packet ) return NULL; 397 header = ( arp_header_ref ) packet_suffix( packet, length ); 398 if( ! header ){ 399 pq_release( arp_globals.net_phone, packet_get_id( packet )); 361 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){ 362 fibril_rwlock_write_unlock(&arp_globals.lock); 363 free(device->addr); 364 free(device->addr_data); 365 arp_protos_destroy(&device->protos); 366 free(device); 367 return ERROR_CODE; 368 } 369 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){ 370 fibril_rwlock_write_unlock(&arp_globals.lock); 371 free(device->addr); 372 free(device->addr_data); 373 free(device->broadcast_addr); 374 free(device->broadcast_data); 375 arp_protos_destroy(&device->protos); 376 free(device); 377 return ERROR_CODE; 378 } 379 printf("New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol); 380 } 381 fibril_rwlock_write_unlock(&arp_globals.lock); 382 return EOK; 383 } 384 385 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 386 arp_device_ref device; 387 arp_proto_ref proto; 388 measured_string_ref addr; 389 size_t length; 390 packet_t packet; 391 arp_header_ref header; 392 393 if(! target){ 400 394 return NULL; 401 395 } 402 header->hardware = htons( device->hardware ); 403 header->hardware_length = ( uint8_t ) device->addr->length; 404 header->protocol = htons( protocol_map( device->service, protocol )); 405 header->protocol_length = ( uint8_t ) proto->addr->length; 406 header->operation = htons( ARPOP_REQUEST ); 407 length = sizeof( arp_header_t ); 408 memcpy((( uint8_t * ) header ) + length, device->addr->value, device->addr->length ); 396 device = arp_cache_find(&arp_globals.cache, device_id); 397 if(! device){ 398 return NULL; 399 } 400 proto = arp_protos_find(&device->protos, protocol); 401 if((! proto) || (proto->addr->length != target->length)){ 402 return NULL; 403 } 404 addr = arp_addr_find(&proto->addresses, target->value, target->length); 405 if(addr){ 406 return addr; 407 } 408 // ARP packet content size = header + (address + translation) * 2 409 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 410 if(length > device->packet_dimension.content){ 411 return NULL; 412 } 413 packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 414 if(! packet){ 415 return NULL; 416 } 417 header = (arp_header_ref) packet_suffix(packet, length); 418 if(! header){ 419 pq_release(arp_globals.net_phone, packet_get_id(packet)); 420 return NULL; 421 } 422 header->hardware = htons(device->hardware); 423 header->hardware_length = (uint8_t) device->addr->length; 424 header->protocol = htons(protocol_map(device->service, protocol)); 425 header->protocol_length = (uint8_t) proto->addr->length; 426 header->operation = htons(ARPOP_REQUEST); 427 length = sizeof(arp_header_t); 428 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 409 429 length += device->addr->length; 410 memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length);430 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 411 431 length += proto->addr->length; 412 bzero((( uint8_t * ) header ) + length, device->addr->length);432 bzero(((uint8_t *) header) + length, device->addr->length); 413 433 length += device->addr->length; 414 memcpy((( uint8_t * ) header ) + length, target->value, target->length);415 if( packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length )) != EOK){416 pq_release( arp_globals.net_phone, packet_get_id( packet));434 memcpy(((uint8_t *) header) + length, target->value, target->length); 435 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){ 436 pq_release(arp_globals.net_phone, packet_get_id(packet)); 417 437 return NULL; 418 438 } 419 nil_send_msg( device->phone, device_id, packet, SERVICE_ARP);439 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 420 440 return NULL; 421 441 } 422 442 423 int arp_receive_message( device_id_t device_id, packet_t packet){443 int arp_receive_message(device_id_t device_id, packet_t packet){ 424 444 ERROR_DECLARE; 425 445 426 size_t length; 427 arp_header_ref header; 428 arp_device_ref device; 429 arp_proto_ref proto; 430 measured_string_ref hw_source; 431 uint8_t * src_hw; 432 uint8_t * src_proto; 433 uint8_t * des_hw; 434 uint8_t * des_proto; 435 436 length = packet_get_data_length( packet ); 437 if( length <= sizeof( arp_header_t )) return EINVAL; 438 device = arp_cache_find( & arp_globals.cache, device_id ); 439 if( ! device ) return ENOENT; 440 header = ( arp_header_ref ) packet_get_data( packet ); 441 if(( ntohs( header->hardware ) != device->hardware ) 442 || ( length < sizeof( arp_header_t ) + header->hardware_length * 2u + header->protocol_length * 2u )){ 446 size_t length; 447 arp_header_ref header; 448 arp_device_ref device; 449 arp_proto_ref proto; 450 measured_string_ref hw_source; 451 uint8_t * src_hw; 452 uint8_t * src_proto; 453 uint8_t * des_hw; 454 uint8_t * des_proto; 455 456 length = packet_get_data_length(packet); 457 if(length <= sizeof(arp_header_t)){ 443 458 return EINVAL; 444 459 } 445 proto = arp_protos_find( & device->protos, protocol_unmap( device->service, ntohs( header->protocol ))); 446 if( ! proto ) return ENOENT; 447 src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t ); 460 device = arp_cache_find(&arp_globals.cache, device_id); 461 if(! device){ 462 return ENOENT; 463 } 464 header = (arp_header_ref) packet_get_data(packet); 465 if((ntohs(header->hardware) != device->hardware) 466 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 467 return EINVAL; 468 } 469 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 470 if(! proto){ 471 return ENOENT; 472 } 473 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 448 474 src_proto = src_hw + header->hardware_length; 449 475 des_hw = src_proto + header->protocol_length; 450 476 des_proto = des_hw + header->hardware_length; 451 hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length));477 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 452 478 // exists? 453 if( hw_source){454 if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length)){479 if(hw_source){ 480 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 455 481 return EINVAL; 456 482 } 457 memcpy( hw_source->value, src_hw, hw_source->length);483 memcpy(hw_source->value, src_hw, hw_source->length); 458 484 } 459 485 // is my protocol address? 460 if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->protocol_length)){486 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 461 487 return EINVAL; 462 488 } 463 if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length)){489 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 464 490 // not already upadted? 465 if( ! hw_source ){ 466 hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length )); 467 if( ! hw_source ) return ENOMEM; 468 ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source )); 469 } 470 if( ntohs( header->operation ) == ARPOP_REQUEST ){ 471 header->operation = htons( ARPOP_REPLY ); 472 memcpy( des_proto, src_proto, header->protocol_length ); 473 memcpy( src_proto, proto->addr->value, header->protocol_length ); 474 memcpy( src_hw, device->addr->value, device->packet_dimension.addr_len ); 475 memcpy( des_hw, hw_source->value, header->hardware_length ); 476 ERROR_PROPAGATE( packet_set_addr( packet, src_hw, des_hw, header->hardware_length )); 477 nil_send_msg( device->phone, device_id, packet, SERVICE_ARP ); 491 if(! hw_source){ 492 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 493 if(! hw_source){ 494 return ENOMEM; 495 } 496 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 497 } 498 if(ntohs(header->operation) == ARPOP_REQUEST){ 499 header->operation = htons(ARPOP_REPLY); 500 memcpy(des_proto, src_proto, header->protocol_length); 501 memcpy(src_proto, proto->addr->value, header->protocol_length); 502 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 503 memcpy(des_hw, hw_source->value, header->hardware_length); 504 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 505 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 478 506 return 1; 479 507 } … … 482 510 } 483 511 484 void arp_clear_device( arp_device_ref device ){ 485 int count; 486 arp_proto_ref proto; 487 488 for( count = arp_protos_count( & device->protos ) - 1; count >= 0; -- count ){ 489 proto = arp_protos_get_index( & device->protos, count ); 490 if( proto ){ 491 if( proto->addr ) free( proto->addr ); 492 if( proto->addr_data ) free( proto->addr_data ); 493 arp_addr_destroy( & proto->addresses ); 494 } 495 } 496 arp_protos_clear( & device->protos ); 497 } 498 499 int arp_connect_module( services_t service ){ 500 if( service != SERVICE_ARP ) return EINVAL; 501 return EOK; 502 } 503 504 int arp_mtu_changed_message( device_id_t device_id, size_t mtu ){ 505 arp_device_ref device; 506 507 fibril_rwlock_write_lock( & arp_globals.lock ); 508 device = arp_cache_find( & arp_globals.cache, device_id ); 509 if( ! device ){ 510 fibril_rwlock_write_unlock( & arp_globals.lock ); 512 void arp_clear_device(arp_device_ref device){ 513 int count; 514 arp_proto_ref proto; 515 516 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 517 proto = arp_protos_get_index(&device->protos, count); 518 if(proto){ 519 if(proto->addr){ 520 free(proto->addr); 521 } 522 if(proto->addr_data){ 523 free(proto->addr_data); 524 } 525 arp_addr_destroy(&proto->addresses); 526 } 527 } 528 arp_protos_clear(&device->protos); 529 } 530 531 int arp_connect_module(services_t service){ 532 if(service != SERVICE_ARP){ 533 return EINVAL; 534 } 535 return EOK; 536 } 537 538 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 539 arp_device_ref device; 540 541 fibril_rwlock_write_lock(&arp_globals.lock); 542 device = arp_cache_find(&arp_globals.cache, device_id); 543 if(! device){ 544 fibril_rwlock_write_unlock(&arp_globals.lock); 511 545 return ENOENT; 512 546 } 513 547 device->packet_dimension.content = mtu; 514 printf( "arp - device %d changed mtu to %d\n\n", device_id, mtu);515 fibril_rwlock_write_unlock( & arp_globals.lock);516 return EOK; 517 } 518 519 int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){548 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 549 fibril_rwlock_write_unlock(&arp_globals.lock); 550 return EOK; 551 } 552 553 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 520 554 ERROR_DECLARE; 521 555 522 measured_string_ref 523 measured_string_ref 524 char * 525 packet_t 526 packet_t 527 528 // printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_ARP_FIRST);529 * 530 switch( IPC_GET_METHOD( * call)){556 measured_string_ref address; 557 measured_string_ref translation; 558 char * data; 559 packet_t packet; 560 packet_t next; 561 562 // printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST); 563 *answer_count = 0; 564 switch(IPC_GET_METHOD(*call)){ 531 565 case IPC_M_PHONE_HUNGUP: 532 566 return EOK; 533 567 case NET_ARP_DEVICE: 534 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));535 if( ERROR_OCCURRED( arp_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), ARP_GET_NETIF( call ), address))){536 free( address);537 free( data);568 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 569 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 570 free(address); 571 free(data); 538 572 } 539 573 return ERROR_CODE; 540 574 case NET_ARP_TRANSLATE: 541 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));542 fibril_rwlock_read_lock( & arp_globals.lock);543 translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address);544 free( address);545 free( data);546 if( ! translation){547 fibril_rwlock_read_unlock( & arp_globals.lock);575 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 576 fibril_rwlock_read_lock(&arp_globals.lock); 577 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 578 free(address); 579 free(data); 580 if(! translation){ 581 fibril_rwlock_read_unlock(&arp_globals.lock); 548 582 return ENOENT; 549 583 } 550 ERROR_CODE = measured_strings_reply( translation, 1);551 fibril_rwlock_read_unlock( & arp_globals.lock);584 ERROR_CODE = measured_strings_reply(translation, 1); 585 fibril_rwlock_read_unlock(&arp_globals.lock); 552 586 return ERROR_CODE; 553 587 case NET_ARP_CLEAR_DEVICE: 554 return arp_clear_device_req( 0, IPC_GET_DEVICE( call));588 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 555 589 case NET_ARP_CLEAR_ADDRESS: 556 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));557 arp_clear_address_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address);558 free( address);559 free( data);590 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 591 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 592 free(address); 593 free(data); 560 594 return EOK; 561 595 case NET_ARP_CLEAN_CACHE: 562 return arp_clean_cache_req( 0);596 return arp_clean_cache_req(0); 563 597 case NET_IL_DEVICE_STATE: 564 598 // do nothing - keep the cache 565 599 return EOK; 566 600 case NET_IL_RECEIVED: 567 if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){568 fibril_rwlock_read_lock( & arp_globals.lock);601 if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 602 fibril_rwlock_read_lock(&arp_globals.lock); 569 603 do{ 570 next = pq_detach( packet ); 571 ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet ); 572 if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet )); 604 next = pq_detach(packet); 605 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 606 if(ERROR_CODE != 1){ 607 pq_release(arp_globals.net_phone, packet_get_id(packet)); 608 } 573 609 packet = next; 574 }while( packet);575 fibril_rwlock_read_unlock( & arp_globals.lock);610 }while(packet); 611 fibril_rwlock_read_unlock(&arp_globals.lock); 576 612 } 577 613 return ERROR_CODE; 578 614 case NET_IL_MTU_CHANGED: 579 return arp_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call));615 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 580 616 } 581 617 return ENOTSUP; -
uspace/srv/net/il/arp/arp.h
raa85487 raadf01e 80 80 * @see device.h 81 81 */ 82 DEVICE_MAP_DECLARE( arp_cache, arp_device_t)82 DEVICE_MAP_DECLARE(arp_cache, arp_device_t) 83 83 84 84 /** ARP protocol map. … … 86 86 * @see int_map.h 87 87 */ 88 INT_MAP_DECLARE( arp_protos, arp_proto_t)88 INT_MAP_DECLARE(arp_protos, arp_proto_t) 89 89 90 90 /** ARP address map. … … 92 92 * @see generic_char_map.h 93 93 */ 94 GENERIC_CHAR_MAP_DECLARE( arp_addr, measured_string_t)94 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t) 95 95 96 96 /** ARP device specific data. … … 99 99 /** Device identifier. 100 100 */ 101 device_id_t 101 device_id_t device_id; 102 102 /** Hardware type. 103 103 */ 104 hw_type_t 104 hw_type_t hardware; 105 105 /** Packet dimension. 106 106 */ 107 packet_dimension_t 107 packet_dimension_t packet_dimension; 108 108 /** Actual device hardware address. 109 109 */ 110 measured_string_ref 110 measured_string_ref addr; 111 111 /** Actual device hardware address data. 112 112 */ 113 char * 113 char * addr_data; 114 114 /** Broadcast device hardware address. 115 115 */ 116 measured_string_ref 116 measured_string_ref broadcast_addr; 117 117 /** Broadcast device hardware address data. 118 118 */ 119 char * 119 char * broadcast_data; 120 120 /** Device module service. 121 121 */ 122 services_t 122 services_t service; 123 123 /** Device module phone. 124 124 */ 125 int 125 int phone; 126 126 /** Protocol map. 127 127 * Address map for each protocol. 128 128 */ 129 arp_protos_t 129 arp_protos_t protos; 130 130 }; 131 131 … … 135 135 /** Protocol service. 136 136 */ 137 services_t 137 services_t service; 138 138 /** Actual device protocol address. 139 139 */ 140 measured_string_ref 140 measured_string_ref addr; 141 141 /** Actual device protocol address data. 142 142 */ 143 char * 143 char * addr_data; 144 144 /** Address map. 145 145 */ 146 arp_addr_t 146 arp_addr_t addresses; 147 147 }; 148 148 … … 152 152 /** Networking module phone. 153 153 */ 154 int 154 int net_phone; 155 155 /** Safety lock. 156 156 */ 157 fibril_rwlock_t 157 fibril_rwlock_t lock; 158 158 /** ARP address cache. 159 159 */ 160 arp_cache_t 160 arp_cache_t cache; 161 161 /** The client connection processing function. 162 162 * The module skeleton propagates its own one. -
uspace/srv/net/il/arp/arp_header.h
raa85487 raadf01e 57 57 * @see hardware.h 58 58 */ 59 uint16_t 59 uint16_t hardware; 60 60 /** Protocol identifier. 61 61 */ 62 uint16_t 62 uint16_t protocol; 63 63 /** Hardware address length in bytes. 64 64 */ 65 uint8_t 65 uint8_t hardware_length; 66 66 /** Protocol address length in bytes. 67 67 */ 68 uint8_t 68 uint8_t protocol_length; 69 69 /** ARP packet type. 70 70 * @see arp_oc.h 71 71 */ 72 uint16_t 72 uint16_t operation; 73 73 } __attribute__ ((packed)); 74 74 -
uspace/srv/net/il/arp/arp_messages.h
raa85487 raadf01e 75 75 * @param[in] call The message call structure. 76 76 */ 77 #define ARP_GET_NETIF( call ) ( services_t ) IPC_GET_ARG2( * call)77 #define ARP_GET_NETIF(call) (services_t) IPC_GET_ARG2(*call) 78 78 79 79 /*@}*/ -
uspace/srv/net/il/arp/arp_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the ARP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the ARP message. … … 80 80 * @returns Other error codes as defined for the arp_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** ARP module global data. … … 86 86 extern arp_globals_t arp_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t 95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 arp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 ERROR_PROPAGATE( 100 if( ERROR_OCCURRED( arp_initialize( client_connection))101 || ERROR_OCCURRED( REGISTER_ME( SERVICE_ARP, & phonehash))){97 async_set_client_connection(client_connection); 98 arp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 ERROR_PROPAGATE(pm_init()); 100 if(ERROR_OCCURRED(arp_initialize(client_connection)) 101 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))){ 102 102 pm_destroy(); 103 103 return ERROR_CODE; … … 110 110 } 111 111 112 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){113 return arp_message( callid, call, answer, answer_count);112 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 113 return arp_message(callid, call, answer, answer_count); 114 114 } 115 115 -
uspace/srv/net/il/arp/arp_module.h
raa85487 raadf01e 46 46 * @returns ENOMEM if there is not enough memory left. 47 47 */ 48 int arp_initialize( async_client_conn_t client_connection);48 int arp_initialize(async_client_conn_t client_connection); 49 49 50 50 /** Processes the ARP message. … … 58 58 * @see IS_NET_ARP_MESSAGE() 59 59 */ 60 int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);60 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 61 61 62 62 #endif -
uspace/srv/net/il/arp/arp_remote.c
raa85487 raadf01e 52 52 #include "arp_messages.h" 53 53 54 int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){55 aid_t 56 ipcarg_t 54 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 55 aid_t message_id; 56 ipcarg_t result; 57 57 58 message_id = async_send_3( arp_phone, NET_ARP_DEVICE, ( ipcarg_t ) device_id, protocol, netif, NULL);59 measured_strings_send( arp_phone, address, 1);60 async_wait_for( message_id, & result);61 return ( int) result;58 message_id = async_send_3(arp_phone, NET_ARP_DEVICE, (ipcarg_t) device_id, protocol, netif, NULL); 59 measured_strings_send(arp_phone, address, 1); 60 async_wait_for(message_id, &result); 61 return (int) result; 62 62 } 63 63 64 int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){65 return generic_translate_req( arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data);64 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 65 return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data); 66 66 } 67 67 68 int arp_clear_device_req( int arp_phone, device_id_t device_id){69 return ( int ) async_req_1_0( arp_phone, NET_ARP_CLEAR_DEVICE, ( ipcarg_t ) device_id);68 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 69 return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE, (ipcarg_t) device_id); 70 70 } 71 71 72 int arp_clear_address_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){73 aid_t 74 ipcarg_t 72 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 73 aid_t message_id; 74 ipcarg_t result; 75 75 76 message_id = async_send_2( arp_phone, NET_ARP_CLEAR_ADDRESS, ( ipcarg_t ) device_id, protocol, NULL);77 measured_strings_send( arp_phone, address, 1);78 async_wait_for( message_id, & result);79 return ( int) result;76 message_id = async_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS, (ipcarg_t) device_id, protocol, NULL); 77 measured_strings_send(arp_phone, address, 1); 78 async_wait_for(message_id, &result); 79 return (int) result; 80 80 } 81 81 82 int arp_clean_cache_req( int arp_phone){83 return ( int ) async_req_0_0( arp_phone, NET_ARP_CLEAN_CACHE);82 int arp_clean_cache_req(int arp_phone){ 83 return (int) async_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE); 84 84 } 85 85 86 int arp_connect_module( services_t service ){ 87 if( service != SERVICE_ARP ) return EINVAL; 88 return connect_to_service( SERVICE_ARP ); 86 int arp_connect_module(services_t service){ 87 if(service != SERVICE_ARP){ 88 return EINVAL; 89 } 90 return connect_to_service(SERVICE_ARP); 89 91 } 90 92 91 task_id_t arp_task_get_id( void){93 task_id_t arp_task_get_id(void){ 92 94 return 0; 93 95 } -
uspace/srv/net/il/il_messages.h
raa85487 raadf01e 78 78 * @param[in] call The message call structure. 79 79 */ 80 #define IL_GET_PROTO( call ) ( int ) IPC_GET_ARG1( * call)80 #define IL_GET_PROTO(call) (int) IPC_GET_ARG1(*call) 81 81 82 82 /** Returns the registering service message parameter. 83 83 * @param[in] call The message call structure. 84 84 */ 85 #define IL_GET_SERVICE( call ) ( services_t ) IPC_GET_ARG2( * call)85 #define IL_GET_SERVICE(call) (services_t) IPC_GET_ARG2(*call) 86 86 87 87 /*@}*/ -
uspace/srv/net/il/ip/ip.c
raa85487 raadf01e 108 108 /** IP packet address length. 109 109 */ 110 #define IP_ADDR sizeof( struct sockaddr_in6)110 #define IP_ADDR sizeof(struct sockaddr_in6) 111 111 112 112 /** IP packet prefix length. 113 113 */ 114 #define IP_PREFIX sizeof( ip_header_t)114 #define IP_PREFIX sizeof(ip_header_t) 115 115 116 116 /** IP packet suffix length. … … 124 124 /** The IP localhost address. 125 125 */ 126 #define IPV4_LOCALHOST_ADDRESS htonl(( 127 << 24 ) + 1)126 #define IPV4_LOCALHOST_ADDRESS htonl((127 << 24) + 1) 127 127 128 128 /** IP global data. … … 130 130 ip_globals_t ip_globals; 131 131 132 DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t)133 134 INT_MAP_IMPLEMENT( ip_protos, ip_proto_t)135 136 GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t)132 DEVICE_MAP_IMPLEMENT(ip_netifs, ip_netif_t) 133 134 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t) 135 136 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t) 137 137 138 138 /** Updates the device content length according to the new MTU value. … … 142 142 * @returns ENOENT if device is not found. 143 143 */ 144 int ip_mtu_changed_message( device_id_t device_id, size_t mtu);144 int ip_mtu_changed_message(device_id_t device_id, size_t mtu); 145 145 146 146 /** Updates the device state. … … 150 150 * @returns ENOENT if device is not found. 151 151 */ 152 int ip_device_state_message( device_id_t device_id, device_state_t state);152 int ip_device_state_message(device_id_t device_id, device_state_t state); 153 153 154 154 /** Returns the device packet dimensions for sending. … … 162 162 * @returns EOK on success. 163 163 */ 164 int ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);164 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix); 165 165 166 166 /** Registers the transport layer protocol. … … 175 175 * @returns ENOMEM if there is not enough memory left. 176 176 */ 177 int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg);177 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg); 178 178 179 179 /** Initializes a new network interface specific data. … … 192 192 * @returns Other error codes as defined for the nil_packet_size_req() function. 193 193 */ 194 int ip_netif_initialize( ip_netif_ref ip_netif);194 int ip_netif_initialize(ip_netif_ref ip_netif); 195 195 196 196 /** Sends the packet or the packet queue via the specified route. … … 206 206 * @returns Other error codes as defined for the ip_prepare_packet() function. 207 207 */ 208 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error);208 int ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error); 209 209 210 210 /** Prepares the outgoing packet or the packet queue. … … 222 222 * @returns Other error codes as defined for the packet_set_addr() function. 223 223 */ 224 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination);224 int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination); 225 225 226 226 /** Checks the packet queue lengths and fragments the packets if needed. … … 235 235 * @returns NULL if there are no packets left. 236 236 */ 237 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error);237 packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error); 238 238 239 239 /** Checks the packet length and fragments it if needed. … … 255 255 * @returns Other error codes as defined for the ip_fragment_packet_data() function. 256 256 */ 257 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len);257 int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len); 258 258 259 259 /** Fragments the packet from the end. … … 271 271 * @returns Other error codes as defined for the pq_insert_after() function. 272 272 */ 273 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen);273 int ip_fragment_packet_data(packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen); 274 274 275 275 /** Prefixes a middle fragment header based on the last fragment header to the packet. … … 279 279 * @returns NULL on error. 280 280 */ 281 ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last);281 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last); 282 282 283 283 /** Copies the fragment header. … … 286 286 * @param[in] first The original header to be copied. 287 287 */ 288 void ip_create_last_header( ip_header_ref last, ip_header_ref first);288 void ip_create_last_header(ip_header_ref last, ip_header_ref first); 289 289 290 290 /** Returns the network interface's IP address. … … 293 293 * @returns NULL if no IP address was found. 294 294 */ 295 in_addr_t * ip_netif_address( ip_netif_ref netif);295 in_addr_t * ip_netif_address(ip_netif_ref netif); 296 296 297 297 /** Searches all network interfaces if there is a suitable route. … … 300 300 * @returns NULL if no route was found. 301 301 */ 302 ip_route_ref ip_find_route( in_addr_t destination);302 ip_route_ref ip_find_route(in_addr_t destination); 303 303 304 304 /** Searches the network interfaces if there is a suitable route. … … 308 308 * @returns NULL if no route was found. 309 309 */ 310 ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination);310 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination); 311 311 312 312 /** Processes the received IP packet or the packet queue one by one. … … 321 321 * @returns ENOMEM if there is not enough memory left. 322 322 */ 323 int ip_receive_message( device_id_t device_id, packet_t packet);323 int ip_receive_message(device_id_t device_id, packet_t packet); 324 324 325 325 /** Processes the received packet. … … 338 338 * @returns ENOENT if the packet is for another host and the routing is disabled. 339 339 */ 340 int ip_process_packet( device_id_t device_id, packet_t packet);340 int ip_process_packet(device_id_t device_id, packet_t packet); 341 341 342 342 /** Returns the packet destination address from the IP header. … … 344 344 * @returns The packet destination address. 345 345 */ 346 in_addr_t ip_get_destination( ip_header_ref header);346 in_addr_t ip_get_destination(ip_header_ref header); 347 347 348 348 /** Delivers the packet to the local host. … … 361 361 * @returns Other error codes as defined for the protocol specific tl_received_msg function. 362 362 */ 363 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error);363 int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error); 364 364 365 365 /** Prepares the ICMP notification packet. … … 374 374 * @returns EINVAL if the ip_prepare_icmp() fails. 375 375 */ 376 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header);376 int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header); 377 377 378 378 /** Returns the ICMP phone. … … 381 381 * @returns ENOENT if the ICMP is not registered. 382 382 */ 383 int ip_get_icmp_phone( void);383 int ip_get_icmp_phone(void); 384 384 385 385 /** Prepares the ICMP notification packet. … … 395 395 * @returns Other error codes as defined for the packet_set_addr(). 396 396 */ 397 int ip_prepare_icmp( packet_t packet, ip_header_ref header);397 int ip_prepare_icmp(packet_t packet, ip_header_ref header); 398 398 399 399 /** Releases the packet and returns the result. … … 402 402 * @return The result parameter. 403 403 */ 404 int ip_release_and_return( packet_t packet, int result);405 406 int ip_initialize( async_client_conn_t client_connection){404 int ip_release_and_return(packet_t packet, int result); 405 406 int ip_initialize(async_client_conn_t client_connection){ 407 407 ERROR_DECLARE; 408 408 409 fibril_rwlock_initialize( & ip_globals.lock);410 fibril_rwlock_write_lock( & ip_globals.lock);411 fibril_rwlock_initialize( & ip_globals.protos_lock);412 fibril_rwlock_initialize( & ip_globals.netifs_lock);409 fibril_rwlock_initialize(&ip_globals.lock); 410 fibril_rwlock_write_lock(&ip_globals.lock); 411 fibril_rwlock_initialize(&ip_globals.protos_lock); 412 fibril_rwlock_initialize(&ip_globals.netifs_lock); 413 413 ip_globals.packet_counter = 0; 414 414 ip_globals.gateway.address.s_addr = 0; … … 416 416 ip_globals.gateway.gateway.s_addr = 0; 417 417 ip_globals.gateway.netif = NULL; 418 ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs));419 ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos));418 ERROR_PROPAGATE(ip_netifs_initialize(&ip_globals.netifs)); 419 ERROR_PROPAGATE(ip_protos_initialize(&ip_globals.protos)); 420 420 ip_globals.client_connection = client_connection; 421 ERROR_PROPAGATE( modules_initialize( & ip_globals.modules));422 ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module));423 fibril_rwlock_write_unlock( & ip_globals.lock);421 ERROR_PROPAGATE(modules_initialize(&ip_globals.modules)); 422 ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module)); 423 fibril_rwlock_write_unlock(&ip_globals.lock); 424 424 return EOK; 425 425 } 426 426 427 int ip_device_req( int il_phone, device_id_t device_id, services_t netif){427 int ip_device_req(int il_phone, device_id_t device_id, services_t netif){ 428 428 ERROR_DECLARE; 429 429 430 ip_netif_ref ip_netif; 431 ip_route_ref route; 432 int index; 433 char * data; 434 435 ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t )); 436 if( ! ip_netif ) return ENOMEM; 437 if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){ 438 free( ip_netif ); 430 ip_netif_ref ip_netif; 431 ip_route_ref route; 432 int index; 433 char * data; 434 435 ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t)); 436 if(! ip_netif){ 437 return ENOMEM; 438 } 439 if(ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))){ 440 free(ip_netif); 439 441 return ERROR_CODE; 440 442 } … … 442 444 ip_netif->service = netif; 443 445 ip_netif->state = NETIF_STOPPED; 444 fibril_rwlock_write_lock( & ip_globals.netifs_lock);445 if( ERROR_OCCURRED( ip_netif_initialize( ip_netif))){446 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);447 ip_routes_destroy( & ip_netif->routes);448 free( ip_netif);446 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 447 if(ERROR_OCCURRED(ip_netif_initialize(ip_netif))){ 448 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 449 ip_routes_destroy(&ip_netif->routes); 450 free(ip_netif); 449 451 return ERROR_CODE; 450 452 } 451 if( ip_netif->arp ) ++ ip_netif->arp->usage; 453 if(ip_netif->arp){ 454 ++ ip_netif->arp->usage; 455 } 452 456 // print the settings 453 printf( "New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv);454 printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static");457 printf("New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv); 458 printf("\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static"); 455 459 // TODO ipv6 addresses 456 data = ( char * ) malloc( INET_ADDRSTRLEN);457 if( data){458 for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index){459 route = ip_routes_get_index( & ip_netif->routes, index);460 if( route){461 printf( "\tRouting %d:\n", index);462 inet_ntop( AF_INET, ( uint8_t * ) & route->address.s_addr, data, INET_ADDRSTRLEN);463 printf( "\t\taddress\t= %s\n", data);464 inet_ntop( AF_INET, ( uint8_t * ) & route->netmask.s_addr, data, INET_ADDRSTRLEN);465 printf( "\t\tnetmask\t= %s\n", data);466 inet_ntop( AF_INET, ( uint8_t * ) & route->gateway.s_addr, data, INET_ADDRSTRLEN);467 printf( "\t\tgateway\t= %s\n", data);468 } 469 } 470 inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN);471 printf( "\t\tbroadcast\t= %s\n", data);472 free( data);473 } 474 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);460 data = (char *) malloc(INET_ADDRSTRLEN); 461 if(data){ 462 for(index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){ 463 route = ip_routes_get_index(&ip_netif->routes, index); 464 if(route){ 465 printf("\tRouting %d:\n", index); 466 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, data, INET_ADDRSTRLEN); 467 printf("\t\taddress\t= %s\n", data); 468 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, data, INET_ADDRSTRLEN); 469 printf("\t\tnetmask\t= %s\n", data); 470 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, data, INET_ADDRSTRLEN); 471 printf("\t\tgateway\t= %s\n", data); 472 } 473 } 474 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN); 475 printf("\t\tbroadcast\t= %s\n", data); 476 free(data); 477 } 478 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 475 479 return EOK; 476 480 } 477 481 478 int ip_netif_initialize( ip_netif_ref ip_netif){482 int ip_netif_initialize(ip_netif_ref ip_netif){ 479 483 ERROR_DECLARE; 480 484 481 measured_string_t names[] = {{ str_dup("IPV"), 3 }, { str_dup("IP_CONFIG"), 9 }, { str_dup("IP_ADDR"), 7 }, { str_dup("IP_NETMASK"), 10 }, { str_dup("IP_GATEWAY"), 10 }, { str_dup("IP_BROADCAST"), 12 }, { str_dup("ARP"), 3 }, { str_dup("IP_ROUTING"), 10}};482 measured_string_ref 483 size_t count = sizeof( names ) / sizeof( measured_string_t);484 char * 485 measured_string_t 486 int 487 ip_route_ref 488 in_addr_t 485 measured_string_t names[] = {{str_dup("IPV"), 3}, {str_dup("IP_CONFIG"), 9}, {str_dup("IP_ADDR"), 7}, {str_dup("IP_NETMASK"), 10}, {str_dup("IP_GATEWAY"), 10}, {str_dup("IP_BROADCAST"), 12}, {str_dup("ARP"), 3}, {str_dup("IP_ROUTING"), 10}}; 486 measured_string_ref configuration; 487 size_t count = sizeof(names) / sizeof(measured_string_t); 488 char * data; 489 measured_string_t address; 490 int index; 491 ip_route_ref route; 492 in_addr_t gateway; 489 493 490 494 ip_netif->arp = NULL; … … 493 497 ip_netif->dhcp = false; 494 498 ip_netif->routing = NET_DEFAULT_IP_ROUTING; 495 configuration = & names[ 0];499 configuration = &names[0]; 496 500 // get configuration 497 ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data));498 if( configuration){499 if( configuration[ 0 ].value){500 ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0);501 } 502 ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length);503 if( ip_netif->dhcp){501 ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, &configuration, count, &data)); 502 if(configuration){ 503 if(configuration[0].value){ 504 ip_netif->ipv = strtol(configuration[0].value, NULL, 0); 505 } 506 ip_netif->dhcp = ! str_lcmp(configuration[1].value, "dhcp", configuration[1].length); 507 if(ip_netif->dhcp){ 504 508 // TODO dhcp 505 net_free_settings( configuration, data);509 net_free_settings(configuration, data); 506 510 return ENOTSUP; 507 }else if( ip_netif->ipv == IPV4){508 route = ( ip_route_ref ) malloc( sizeof( ip_route_t));509 if( ! route){510 net_free_settings( configuration, data);511 }else if(ip_netif->ipv == IPV4){ 512 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 513 if(! route){ 514 net_free_settings(configuration, data); 511 515 return ENOMEM; 512 516 } … … 515 519 route->gateway.s_addr = 0; 516 520 route->netif = ip_netif; 517 index = ip_routes_add( & ip_netif->routes, route);518 if( index < 0){519 net_free_settings( configuration, data);520 free( route);521 index = ip_routes_add(&ip_netif->routes, route); 522 if(index < 0){ 523 net_free_settings(configuration, data); 524 free(route); 521 525 return index; 522 526 } 523 if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr))524 || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr))525 || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL)526 || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL)){527 net_free_settings( configuration, data);527 if(ERROR_OCCURRED(inet_pton(AF_INET, configuration[2].value, (uint8_t *) &route->address.s_addr)) 528 || ERROR_OCCURRED(inet_pton(AF_INET, configuration[3].value, (uint8_t *) &route->netmask.s_addr)) 529 || (inet_pton(AF_INET, configuration[4].value, (uint8_t *) &gateway.s_addr) == EINVAL) 530 || (inet_pton(AF_INET, configuration[5].value, (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)){ 531 net_free_settings(configuration, data); 528 532 return EINVAL; 529 533 } 530 534 }else{ 531 535 // TODO ipv6 in separate module 532 net_free_settings( configuration, data);536 net_free_settings(configuration, data); 533 537 return ENOTSUP; 534 538 } 535 if( configuration[ 6 ].value){536 ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 6 ].value);537 if( ! ip_netif->arp){538 printf( "Failed to start the arp %s\n", configuration[ 6 ].value);539 net_free_settings( configuration, data);539 if(configuration[6].value){ 540 ip_netif->arp = get_running_module(&ip_globals.modules, configuration[6].value); 541 if(! ip_netif->arp){ 542 printf("Failed to start the arp %s\n", configuration[6].value); 543 net_free_settings(configuration, data); 540 544 return EINVAL; 541 545 } 542 546 } 543 if( configuration[ 7 ].value){544 ip_netif->routing = ( configuration[ 7 ].value[ 0 ] == 'y');545 } 546 net_free_settings( configuration, data);547 if(configuration[7].value){ 548 ip_netif->routing = (configuration[7].value[0] == 'y'); 549 } 550 net_free_settings(configuration, data); 547 551 } 548 552 // binds the netif service which also initializes the device 549 ip_netif->phone = nil_bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection);550 if( ip_netif->phone < 0){551 printf( "Failed to contact the nil service %d\n", ip_netif->service);553 ip_netif->phone = nil_bind_service(ip_netif->service, (ipcarg_t) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection); 554 if(ip_netif->phone < 0){ 555 printf("Failed to contact the nil service %d\n", ip_netif->service); 552 556 return ip_netif->phone; 553 557 } 554 558 // has to be after the device netif module initialization 555 if( ip_netif->arp){556 if( route){557 address.value = ( char * ) &route->address.s_addr;558 address.length = CONVERT_SIZE( in_addr_t, char, 1);559 ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & address));559 if(ip_netif->arp){ 560 if(route){ 561 address.value = (char *) &route->address.s_addr; 562 address.length = CONVERT_SIZE(in_addr_t, char, 1); 563 ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, &address)); 560 564 }else{ 561 565 ip_netif->arp = 0; … … 563 567 } 564 568 // get packet dimensions 565 ERROR_PROPAGATE( nil_packet_size_req( ip_netif->phone, ip_netif->device_id, & ip_netif->packet_dimension));566 if( ip_netif->packet_dimension.content < IP_MIN_CONTENT){567 printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT);569 ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone, ip_netif->device_id, &ip_netif->packet_dimension)); 570 if(ip_netif->packet_dimension.content < IP_MIN_CONTENT){ 571 printf("Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT); 568 572 ip_netif->packet_dimension.content = IP_MIN_CONTENT; 569 573 } 570 index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif ); 571 if( index < 0 ) return index; 572 if( gateway.s_addr ){ 574 index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif); 575 if(index < 0){ 576 return index; 577 } 578 if(gateway.s_addr){ 573 579 // the default gateway 574 580 ip_globals.gateway.address.s_addr = 0; … … 580 586 } 581 587 582 int ip_mtu_changed_message( device_id_t device_id, size_t mtu){583 ip_netif_ref 584 585 fibril_rwlock_write_lock( & ip_globals.netifs_lock);586 netif = ip_netifs_find( & ip_globals.netifs, device_id);587 if( ! netif){588 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);588 int ip_mtu_changed_message(device_id_t device_id, size_t mtu){ 589 ip_netif_ref netif; 590 591 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 592 netif = ip_netifs_find(&ip_globals.netifs, device_id); 593 if(! netif){ 594 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 589 595 return ENOENT; 590 596 } 591 597 netif->packet_dimension.content = mtu; 592 printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu);593 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);598 printf("ip - device %d changed mtu to %d\n\n", device_id, mtu); 599 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 594 600 return EOK; 595 601 } 596 602 597 int ip_device_state_message( device_id_t device_id, device_state_t state){598 ip_netif_ref 599 600 fibril_rwlock_write_lock( & ip_globals.netifs_lock);603 int ip_device_state_message(device_id_t device_id, device_state_t state){ 604 ip_netif_ref netif; 605 606 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 601 607 // find the device 602 netif = ip_netifs_find( & ip_globals.netifs, device_id);603 if( ! netif){604 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);608 netif = ip_netifs_find(&ip_globals.netifs, device_id); 609 if(! netif){ 610 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 605 611 return ENOENT; 606 612 } 607 613 netif->state = state; 608 printf( "ip - device %d changed state to %d\n\n", device_id, state);609 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);614 printf("ip - device %d changed state to %d\n\n", device_id, state); 615 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 610 616 return EOK; 611 617 } 612 618 613 int ip_connect_module( services_t service){619 int ip_connect_module(services_t service){ 614 620 return EOK; 615 621 } 616 622 617 int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){ 618 return ip_register( protocol, me, 0, received_msg ); 619 } 620 621 int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){ 622 ip_proto_ref proto; 623 int index; 624 625 if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL; 626 proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t )); 627 if( ! proto ) return ENOMEM; 623 int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg){ 624 return ip_register(protocol, me, 0, received_msg); 625 } 626 627 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t received_msg){ 628 ip_proto_ref proto; 629 int index; 630 631 if(!(protocol && service && ((phone > 0) || (received_msg)))){ 632 return EINVAL; 633 } 634 proto = (ip_proto_ref) malloc(sizeof(ip_protos_t)); 635 if(! proto){ 636 return ENOMEM; 637 } 628 638 proto->protocol = protocol; 629 639 proto->service = service; 630 640 proto->phone = phone; 631 641 proto->received_msg = received_msg; 632 fibril_rwlock_write_lock( & ip_globals.protos_lock);633 index = ip_protos_add( & ip_globals.protos, proto->protocol, proto);634 if( index < 0){635 fibril_rwlock_write_unlock( & ip_globals.protos_lock);636 free( proto);642 fibril_rwlock_write_lock(&ip_globals.protos_lock); 643 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 644 if(index < 0){ 645 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 646 free(proto); 637 647 return index; 638 648 } 639 printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone);640 fibril_rwlock_write_unlock( & ip_globals.protos_lock);649 printf("New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone); 650 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 641 651 return EOK; 642 652 } 643 653 644 int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){654 int ip_send_msg(int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){ 645 655 ERROR_DECLARE; 646 656 647 int 648 ip_netif_ref 649 ip_route_ref 650 struct sockaddr * 651 struct sockaddr_in * 657 int addrlen; 658 ip_netif_ref netif; 659 ip_route_ref route; 660 struct sockaddr * addr; 661 struct sockaddr_in * address_in; 652 662 // struct sockaddr_in6 * address_in6; 653 in_addr_t * 654 in_addr_t * 655 int 663 in_addr_t * dest; 664 in_addr_t * src; 665 int phone; 656 666 657 667 // addresses in the host byte order 658 668 // should be the next hop address or the target destination address 659 addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr);660 if( addrlen < 0){661 return ip_release_and_return( packet, addrlen);662 } 663 if(( size_t ) addrlen < sizeof( struct sockaddr)){664 return ip_release_and_return( packet, EINVAL);665 } 666 switch( addr->sa_family){669 addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr); 670 if(addrlen < 0){ 671 return ip_release_and_return(packet, addrlen); 672 } 673 if((size_t) addrlen < sizeof(struct sockaddr)){ 674 return ip_release_and_return(packet, EINVAL); 675 } 676 switch(addr->sa_family){ 667 677 case AF_INET: 668 if( addrlen != sizeof( struct sockaddr_in)){669 return ip_release_and_return( packet, EINVAL);670 } 671 address_in = ( struct sockaddr_in *) addr;672 dest = & 673 if( ! dest->s_addr){678 if(addrlen != sizeof(struct sockaddr_in)){ 679 return ip_release_and_return(packet, EINVAL); 680 } 681 address_in = (struct sockaddr_in *) addr; 682 dest = &address_in->sin_addr; 683 if(! dest->s_addr){ 674 684 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 675 685 } … … 677 687 // TODO IPv6 678 688 /* case AF_INET6: 679 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 680 address_in6 = ( struct sockaddr_in6 * ) dest; 689 if(addrlen != sizeof(struct sockaddr_in6)){ 690 return EINVAL; 691 } 692 address_in6 = (struct sockaddr_in6 *) dest; 681 693 address_in6.sin6_addr.s6_addr; 682 694 IPV6_LOCALHOST_ADDRESS; 683 695 */ default: 684 return ip_release_and_return( packet, EAFNOSUPPORT);685 } 686 fibril_rwlock_read_lock( & ip_globals.netifs_lock);696 return ip_release_and_return(packet, EAFNOSUPPORT); 697 } 698 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 687 699 // device specified? 688 if( device_id > 0){689 netif = ip_netifs_find( & ip_globals.netifs, device_id);690 route = ip_netif_find_route( netif, * dest);691 if( netif && ( ! route ) && ( ip_globals.gateway.netif == netif)){692 route = & 700 if(device_id > 0){ 701 netif = ip_netifs_find(&ip_globals.netifs, device_id); 702 route = ip_netif_find_route(netif, * dest); 703 if(netif && (! route) && (ip_globals.gateway.netif == netif)){ 704 route = &ip_globals.gateway; 693 705 } 694 706 }else{ 695 route = ip_find_route( * dest);707 route = ip_find_route(*dest); 696 708 netif = route ? route->netif : NULL; 697 709 } 698 if( !( netif && route)){699 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);700 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);701 if( phone >= 0){710 if(!(netif && route)){ 711 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 712 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 713 if(phone >= 0){ 702 714 // unreachable ICMP if no routing 703 icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet);715 icmp_destination_unreachable_msg(phone, ICMP_NET_UNREACH, 0, packet); 704 716 } 705 717 return ENOENT; 706 718 } 707 if( error){719 if(error){ 708 720 // do not send for broadcast, anycast packets or network broadcast 709 if(( ! dest->s_addr)710 || ( !( ~ dest->s_addr))711 || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr)))712 || ( !( dest->s_addr & ( ~ route->netmask.s_addr)))){713 return ip_release_and_return( packet, EINVAL);714 } 715 } 716 if( route->address.s_addr == dest->s_addr){721 if((! dest->s_addr) 722 || (!(~ dest->s_addr)) 723 || (!(~((dest->s_addr &(~ route->netmask.s_addr)) | route->netmask.s_addr))) 724 || (!(dest->s_addr &(~ route->netmask.s_addr)))){ 725 return ip_release_and_return(packet, EINVAL); 726 } 727 } 728 if(route->address.s_addr == dest->s_addr){ 717 729 // find the loopback device to deliver 718 730 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 719 route = ip_find_route( * dest);731 route = ip_find_route(*dest); 720 732 netif = route ? route->netif : NULL; 721 if( !( netif && route)){722 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);723 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);724 if( phone >= 0){733 if(!(netif && route)){ 734 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 735 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 736 if(phone >= 0){ 725 737 // unreachable ICMP if no routing 726 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);738 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 727 739 } 728 740 return ENOENT; 729 741 } 730 742 } 731 src = ip_netif_address( netif);732 if( ! src){733 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);734 return ip_release_and_return( packet, ENOENT);735 } 736 ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error);737 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);743 src = ip_netif_address(netif); 744 if(! src){ 745 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 746 return ip_release_and_return(packet, ENOENT); 747 } 748 ERROR_CODE = ip_send_route(packet, netif, route, src, * dest, error); 749 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 738 750 return ERROR_CODE; 739 751 } 740 752 741 in_addr_t * ip_netif_address( ip_netif_ref netif){742 ip_route_ref 743 744 route = ip_routes_get_index( & netif->routes, 0);745 return route ? & 746 } 747 748 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error){753 in_addr_t * ip_netif_address(ip_netif_ref netif){ 754 ip_route_ref route; 755 756 route = ip_routes_get_index(&netif->routes, 0); 757 return route ? &route->address : NULL; 758 } 759 760 int ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error){ 749 761 ERROR_DECLARE; 750 762 751 measured_string_t 752 measured_string_ref 753 char * 754 int 763 measured_string_t destination; 764 measured_string_ref translation; 765 char * data; 766 int phone; 755 767 756 768 // get destination hardware address 757 if( netif->arp && ( route->address.s_addr != dest.s_addr)){758 destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) &dest.s_addr;759 destination.length = CONVERT_SIZE( dest.s_addr, char, 1);760 if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data))){761 // sleep( 1);762 // ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data));763 pq_release( ip_globals.net_phone, packet_get_id( packet));769 if(netif->arp && (route->address.s_addr != dest.s_addr)){ 770 destination.value = route->gateway.s_addr ? (char *) &route->gateway.s_addr : (char *) &dest.s_addr; 771 destination.length = CONVERT_SIZE(dest.s_addr, char, 1); 772 if(ERROR_OCCURRED(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data))){ 773 // sleep(1); 774 // ERROR_PROPAGATE(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data)); 775 pq_release(ip_globals.net_phone, packet_get_id(packet)); 764 776 return ERROR_CODE; 765 777 } 766 if( !( translation && translation->value)){767 if( translation){768 free( translation);769 free( data);770 } 771 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);772 if( phone >= 0){778 if(!(translation && translation->value)){ 779 if(translation){ 780 free(translation); 781 free(data); 782 } 783 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 784 if(phone >= 0){ 773 785 // unreachable ICMP if no routing 774 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);786 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 775 787 } 776 788 return EINVAL; 777 789 } 778 790 }else translation = NULL; 779 if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation))){780 pq_release( ip_globals.net_phone, packet_get_id( packet));791 if(ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))){ 792 pq_release(ip_globals.net_phone, packet_get_id(packet)); 781 793 }else{ 782 packet = ip_split_packet( packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error);783 if( packet){784 nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP);785 } 786 } 787 if( translation){788 free( translation);789 free( data);794 packet = ip_split_packet(packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error); 795 if(packet){ 796 nil_send_msg(netif->phone, netif->device_id, packet, SERVICE_IP); 797 } 798 } 799 if(translation){ 800 free(translation); 801 free(data); 790 802 } 791 803 return ERROR_CODE; 792 804 } 793 805 794 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination){806 int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination){ 795 807 ERROR_DECLARE; 796 808 797 size_t length; 798 ip_header_ref header; 799 ip_header_ref last_header; 800 ip_header_ref middle_header; 801 packet_t next; 802 803 length = packet_get_data_length( packet ); 804 if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL; 805 header = ( ip_header_ref ) packet_get_data( packet ); 806 if( destination ){ 807 ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 809 size_t length; 810 ip_header_ref header; 811 ip_header_ref last_header; 812 ip_header_ref middle_header; 813 packet_t next; 814 815 length = packet_get_data_length(packet); 816 if((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT)){ 817 return EINVAL; 818 } 819 header = (ip_header_ref) packet_get_data(packet); 820 if(destination){ 821 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 808 822 }else{ 809 ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0));823 ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0)); 810 824 } 811 825 header->version = IPV4; … … 813 827 header->fragment_offset_low = 0; 814 828 header->header_checksum = 0; 815 if( source ) header->source_address = source->s_addr; 829 if(source){ 830 header->source_address = source->s_addr; 831 } 816 832 header->destination_address = dest.s_addr; 817 fibril_rwlock_write_lock( & ip_globals.lock);833 fibril_rwlock_write_lock(&ip_globals.lock); 818 834 ++ ip_globals.packet_counter; 819 header->identification = htons( ip_globals.packet_counter ); 820 fibril_rwlock_write_unlock( & ip_globals.lock ); 821 // length = packet_get_data_length( packet ); 822 if( pq_next( packet )){ 823 last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header )); 824 if( ! last_header ) return ENOMEM; 825 ip_create_last_header( last_header, header ); 826 next = pq_next( packet ); 827 while( pq_next( next )){ 828 middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header )); 829 if( ! middle_header ) return ENOMEM; 830 memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); 835 header->identification = htons(ip_globals.packet_counter); 836 fibril_rwlock_write_unlock(&ip_globals.lock); 837 // length = packet_get_data_length(packet); 838 if(pq_next(packet)){ 839 last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header)); 840 if(! last_header){ 841 return ENOMEM; 842 } 843 ip_create_last_header(last_header, header); 844 next = pq_next(packet); 845 while(pq_next(next)){ 846 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 847 if(! middle_header){ 848 return ENOMEM; 849 } 850 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 831 851 header->flags |= IPFLAG_MORE_FRAGMENTS; 832 middle_header->total_length = htons( packet_get_data_length( next )); 833 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length ); 834 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length ); 835 middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); 836 if( destination ){ 837 ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 838 } 839 length += packet_get_data_length( next ); 840 next = pq_next( next ); 841 } 842 middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header )); 843 if( ! middle_header ) return ENOMEM; 844 memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); 845 middle_header->total_length = htons( packet_get_data_length( next )); 846 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length ); 847 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length ); 848 middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); 849 if( destination ){ 850 ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 851 } 852 length += packet_get_data_length( next ); 853 free( last_header ); 852 middle_header->total_length = htons(packet_get_data_length(next)); 853 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 854 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 855 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 856 if(destination){ 857 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 858 } 859 length += packet_get_data_length(next); 860 next = pq_next(next); 861 } 862 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 863 if(! middle_header){ 864 return ENOMEM; 865 } 866 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 867 middle_header->total_length = htons(packet_get_data_length(next)); 868 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 869 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 870 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 871 if(destination){ 872 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 873 } 874 length += packet_get_data_length(next); 875 free(last_header); 854 876 header->flags |= IPFLAG_MORE_FRAGMENTS; 855 877 } 856 header->total_length = htons( length);878 header->total_length = htons(length); 857 879 // unnecessary for all protocols 858 header->header_checksum = IP_HEADER_CHECKSUM( header);880 header->header_checksum = IP_HEADER_CHECKSUM(header); 859 881 return EOK; 860 882 } 861 883 862 int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){884 int ip_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 863 885 ERROR_DECLARE; 864 886 865 packet_t 866 struct sockaddr * 867 size_t 868 ip_pseudo_header_ref 869 size_t 870 871 * 872 switch( IPC_GET_METHOD( * call)){887 packet_t packet; 888 struct sockaddr * addr; 889 size_t addrlen; 890 ip_pseudo_header_ref header; 891 size_t headerlen; 892 893 *answer_count = 0; 894 switch(IPC_GET_METHOD(*call)){ 873 895 case IPC_M_PHONE_HUNGUP: 874 896 return EOK; 875 897 case NET_IL_DEVICE: 876 return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call));898 return ip_device_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call)); 877 899 case IPC_M_CONNECT_TO_ME: 878 return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL);900 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call), IPC_GET_PHONE(call), NULL); 879 901 case NET_IL_SEND: 880 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call)));881 return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call));902 ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call))); 903 return ip_send_msg(0, IPC_GET_DEVICE(call), packet, 0, IPC_GET_ERROR(call)); 882 904 case NET_IL_DEVICE_STATE: 883 return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call));905 return ip_device_state_message(IPC_GET_DEVICE(call), IPC_GET_STATE(call)); 884 906 case NET_IL_RECEIVED: 885 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call)));886 return ip_receive_message( IPC_GET_DEVICE( call ), packet);907 ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call))); 908 return ip_receive_message(IPC_GET_DEVICE(call), packet); 887 909 case NET_IP_RECEIVED_ERROR: 888 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call)));889 return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call));910 ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call))); 911 return ip_received_error_msg(0, IPC_GET_DEVICE(call), packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call)); 890 912 case NET_IP_ADD_ROUTE: 891 return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call));913 return ip_add_route_req(0, IPC_GET_DEVICE(call), IP_GET_ADDRESS(call), IP_GET_NETMASK(call), IP_GET_GATEWAY(call)); 892 914 case NET_IP_SET_GATEWAY: 893 return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call));915 return ip_set_gateway_req(0, IPC_GET_DEVICE(call), IP_GET_GATEWAY(call)); 894 916 case NET_IP_GET_ROUTE: 895 ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen));896 ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen));897 * IP_SET_HEADERLEN( answer) = headerlen;898 * 899 if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen)))){900 ERROR_CODE = data_reply( header, headerlen);901 } 902 free( header);917 ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen)); 918 ERROR_PROPAGATE(ip_get_route_req(0, IP_GET_PROTOCOL(call), addr, (socklen_t) addrlen, IPC_SET_DEVICE(answer), &header, &headerlen)); 919 *IP_SET_HEADERLEN(answer) = headerlen; 920 *answer_count = 2; 921 if(! ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen)))){ 922 ERROR_CODE = data_reply(header, headerlen); 923 } 924 free(header); 903 925 return ERROR_CODE; 904 926 case NET_IL_PACKET_SPACE: 905 ERROR_PROPAGATE( ip_packet_size_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer)));906 * 927 ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), IPC_SET_ADDR(answer), IPC_SET_PREFIX(answer), IPC_SET_CONTENT(answer), IPC_SET_SUFFIX(answer))); 928 *answer_count = 3; 907 929 return EOK; 908 930 case NET_IL_MTU_CHANGED: 909 return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call));931 return ip_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 910 932 } 911 933 return ENOTSUP; 912 934 } 913 935 914 int ip_packet_size_req( int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension ){ 915 if( ! packet_dimension ) return EBADMEM; 916 return ip_packet_size_message( device_id, & packet_dimension->addr_len, & packet_dimension->prefix, & packet_dimension->content, & packet_dimension->suffix ); 917 } 918 919 int ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ 920 ip_netif_ref netif; 921 int index; 922 923 if( !( addr_len && prefix && content && suffix )) return EBADMEM; 924 * content = IP_MAX_CONTENT - IP_PREFIX; 925 fibril_rwlock_read_lock( & ip_globals.netifs_lock ); 926 if( device_id < 0 ){ 927 * addr_len = IP_ADDR; 928 * prefix = 0; 929 * suffix = 0; 930 for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){ 931 netif = ip_netifs_get_index( & ip_globals.netifs, index ); 932 if( netif ){ 933 if( netif->packet_dimension.addr_len > * addr_len ) * addr_len = netif->packet_dimension.addr_len; 934 if( netif->packet_dimension.prefix > * prefix ) * prefix = netif->packet_dimension.prefix; 935 if( netif->packet_dimension.suffix > * suffix ) * suffix = netif->packet_dimension.suffix; 936 } 937 } 938 * prefix = * prefix + IP_PREFIX; 939 * suffix = * suffix + IP_SUFFIX; 936 int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){ 937 if(! packet_dimension){ 938 return EBADMEM; 939 } 940 return ip_packet_size_message(device_id, &packet_dimension->addr_len, &packet_dimension->prefix, &packet_dimension->content, &packet_dimension->suffix); 941 } 942 943 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 944 ip_netif_ref netif; 945 int index; 946 947 if(!(addr_len && prefix && content && suffix)){ 948 return EBADMEM; 949 } 950 *content = IP_MAX_CONTENT - IP_PREFIX; 951 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 952 if(device_id < 0){ 953 *addr_len = IP_ADDR; 954 *prefix = 0; 955 *suffix = 0; 956 for(index = ip_netifs_count(&ip_globals.netifs) - 1; index >= 0; -- index){ 957 netif = ip_netifs_get_index(&ip_globals.netifs, index); 958 if(netif){ 959 if(netif->packet_dimension.addr_len > * addr_len){ 960 *addr_len = netif->packet_dimension.addr_len; 961 } 962 if(netif->packet_dimension.prefix > * prefix){ 963 *prefix = netif->packet_dimension.prefix; 964 } 965 if(netif->packet_dimension.suffix > * suffix){ 966 *suffix = netif->packet_dimension.suffix; 967 } 968 } 969 } 970 *prefix = * prefix + IP_PREFIX; 971 *suffix = * suffix + IP_SUFFIX; 940 972 }else{ 941 netif = ip_netifs_find( & ip_globals.netifs, device_id);942 if( ! netif){943 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);973 netif = ip_netifs_find(&ip_globals.netifs, device_id); 974 if(! netif){ 975 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 944 976 return ENOENT; 945 977 } 946 * addr_len = ( netif->packet_dimension.addr_len > IP_ADDR) ? netif->packet_dimension.addr_len : IP_ADDR;947 * 948 * 949 } 950 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);978 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? netif->packet_dimension.addr_len : IP_ADDR; 979 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 980 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 981 } 982 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 951 983 return EOK; 952 984 } 953 985 954 int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){955 ip_route_ref 956 ip_netif_ref 957 int 958 959 fibril_rwlock_write_lock( & ip_globals.netifs_lock);960 netif = ip_netifs_find( & ip_globals.netifs, device_id);961 if( ! netif){962 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);986 int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){ 987 ip_route_ref route; 988 ip_netif_ref netif; 989 int index; 990 991 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 992 netif = ip_netifs_find(&ip_globals.netifs, device_id); 993 if(! netif){ 994 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 963 995 return ENOENT; 964 996 } 965 route = ( ip_route_ref ) malloc( sizeof( ip_route_t));966 if( ! route){967 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);997 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 998 if(! route){ 999 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 968 1000 return ENOMEM; 969 1001 } … … 972 1004 route->gateway.s_addr = gateway.s_addr; 973 1005 route->netif = netif; 974 index = ip_routes_add( & netif->routes, route ); 975 if( index < 0 ) free( route ); 976 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1006 index = ip_routes_add(&netif->routes, route); 1007 if(index < 0){ 1008 free(route); 1009 } 1010 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 977 1011 return index; 978 1012 } 979 1013 980 ip_route_ref ip_find_route( in_addr_t destination){981 int 982 ip_route_ref 983 ip_netif_ref 1014 ip_route_ref ip_find_route(in_addr_t destination){ 1015 int index; 1016 ip_route_ref route; 1017 ip_netif_ref netif; 984 1018 985 1019 // start with the last netif - the newest one 986 index = ip_netifs_count( & ip_globals.netifs ) - 1; 987 while( index >= 0 ){ 988 netif = ip_netifs_get_index( & ip_globals.netifs, index ); 989 if( netif && ( netif->state == NETIF_ACTIVE )){ 990 route = ip_netif_find_route( netif, destination ); 991 if( route ) return route; 1020 index = ip_netifs_count(&ip_globals.netifs) - 1; 1021 while(index >= 0){ 1022 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1023 if(netif && (netif->state == NETIF_ACTIVE)){ 1024 route = ip_netif_find_route(netif, destination); 1025 if(route){ 1026 return route; 1027 } 992 1028 } 993 1029 -- index; 994 1030 } 995 return & 996 } 997 998 ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination){999 int 1000 ip_route_ref 1001 1002 if( netif){1031 return &ip_globals.gateway; 1032 } 1033 1034 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination){ 1035 int index; 1036 ip_route_ref route; 1037 1038 if(netif){ 1003 1039 // start with the first one - the direct route 1004 for( index = 0; index < ip_routes_count( & netif->routes ); ++ index){1005 route = ip_routes_get_index( & netif->routes, index);1006 if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr))){1040 for(index = 0; index < ip_routes_count(&netif->routes); ++ index){ 1041 route = ip_routes_get_index(&netif->routes, index); 1042 if(route && ((route->address.s_addr &route->netmask.s_addr) == (destination.s_addr &route->netmask.s_addr))){ 1007 1043 return route; 1008 1044 } … … 1012 1048 } 1013 1049 1014 int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway){1015 ip_netif_ref 1016 1017 fibril_rwlock_write_lock( & ip_globals.netifs_lock);1018 netif = ip_netifs_find( & ip_globals.netifs, device_id);1019 if( ! netif){1020 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);1050 int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){ 1051 ip_netif_ref netif; 1052 1053 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1054 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1055 if(! netif){ 1056 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1021 1057 return ENOENT; 1022 1058 } … … 1025 1061 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 1026 1062 ip_globals.gateway.netif = netif; 1027 fibril_rwlock_write_unlock( & ip_globals.netifs_lock);1063 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1028 1064 return EOK; 1029 1065 } 1030 1066 1031 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error){1032 size_t 1033 packet_t 1034 packet_t 1035 int 1036 int 1067 packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error){ 1068 size_t length; 1069 packet_t next; 1070 packet_t new_packet; 1071 int result; 1072 int phone; 1037 1073 1038 1074 next = packet; 1039 1075 // check all packets 1040 while( next){1041 length = packet_get_data_length( next);1076 while(next){ 1077 length = packet_get_data_length(next); 1042 1078 // too long? 1043 if( length > content){1044 result = ip_fragment_packet( next, content, prefix, suffix, addr_len);1045 if( result != EOK){1046 new_packet = pq_detach( next);1047 if( next == packet){1079 if(length > content){ 1080 result = ip_fragment_packet(next, content, prefix, suffix, addr_len); 1081 if(result != EOK){ 1082 new_packet = pq_detach(next); 1083 if(next == packet){ 1048 1084 // the new first packet of the queue 1049 1085 packet = new_packet; 1050 1086 } 1051 1087 // fragmentation needed? 1052 if( result == EPERM){1053 phone = ip_prepare_icmp_and_get_phone( error, next, NULL);1054 if( phone >= 0){1088 if(result == EPERM){ 1089 phone = ip_prepare_icmp_and_get_phone(error, next, NULL); 1090 if(phone >= 0){ 1055 1091 // fragmentation necessary ICMP 1056 icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next);1092 icmp_destination_unreachable_msg(phone, ICMP_FRAG_NEEDED, content, next); 1057 1093 } 1058 1094 }else{ 1059 pq_release( ip_globals.net_phone, packet_get_id( next));1095 pq_release(ip_globals.net_phone, packet_get_id(next)); 1060 1096 } 1061 1097 next = new_packet; … … 1063 1099 } 1064 1100 } 1065 next = pq_next( next);1101 next = pq_next(next); 1066 1102 } 1067 1103 return packet; 1068 1104 } 1069 1105 1070 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len){1106 int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len){ 1071 1107 ERROR_DECLARE; 1072 1108 1073 packet_t new_packet; 1074 ip_header_ref header; 1075 ip_header_ref middle_header; 1076 ip_header_ref last_header; 1077 struct sockaddr * src; 1078 struct sockaddr * dest; 1079 socklen_t addrlen; 1080 int result; 1081 1082 result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest ); 1083 if( result <= 0 ) return EINVAL; 1084 addrlen = ( socklen_t ) result; 1085 if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM; 1109 packet_t new_packet; 1110 ip_header_ref header; 1111 ip_header_ref middle_header; 1112 ip_header_ref last_header; 1113 struct sockaddr * src; 1114 struct sockaddr * dest; 1115 socklen_t addrlen; 1116 int result; 1117 1118 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 1119 if(result <= 0){ 1120 return EINVAL; 1121 } 1122 addrlen = (socklen_t) result; 1123 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1124 return ENOMEM; 1125 } 1086 1126 // get header 1087 header = ( ip_header_ref ) packet_get_data( packet ); 1088 if( ! header ) return EINVAL; 1127 header = (ip_header_ref) packet_get_data(packet); 1128 if(! header){ 1129 return EINVAL; 1130 } 1089 1131 // fragmentation forbidden? 1090 if( header->flags & IPFLAG_DONT_FRAGMENT){1132 if(header->flags &IPFLAG_DONT_FRAGMENT){ 1091 1133 return EPERM; 1092 1134 } 1093 1135 // create the last fragment 1094 new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len )); 1095 if( ! new_packet ) return ENOMEM; 1136 new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len)); 1137 if(! new_packet){ 1138 return ENOMEM; 1139 } 1096 1140 // allocate as much as originally 1097 last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header));1098 if( ! last_header){1099 return ip_release_and_return( packet, ENOMEM);1100 } 1101 ip_create_last_header( last_header, header);1141 last_header = (ip_header_ref) packet_suffix(new_packet, IP_HEADER_LENGTH(header)); 1142 if(! last_header){ 1143 return ip_release_and_return(packet, ENOMEM); 1144 } 1145 ip_create_last_header(last_header, header); 1102 1146 // trim the unused space 1103 if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header)))){1104 return ip_release_and_return( packet, ERROR_CODE);1147 if(ERROR_OCCURRED(packet_trim(new_packet, 0, IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))){ 1148 return ip_release_and_return(packet, ERROR_CODE); 1105 1149 } 1106 1150 // biggest multiple of 8 lower than content 1107 1151 // TODO even fragmentation? 1108 length = length & ( ~ 0x7 );// ( content / 8) * 81109 if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_HEADER_DATA_LENGTH( header ) - (( length - IP_HEADER_LENGTH( header )) & ( ~ 0x7 ))) % (( length - IP_HEADER_LENGTH( last_header )) & ( ~ 0x7 ))), src, dest, addrlen))){1110 return ip_release_and_return( packet, ERROR_CODE);1152 length = length &(~ 0x7);// (content / 8) * 8 1153 if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, last_header, ((IP_HEADER_DATA_LENGTH(header) - ((length - IP_HEADER_LENGTH(header)) &(~ 0x7))) % ((length - IP_HEADER_LENGTH(last_header)) &(~ 0x7))), src, dest, addrlen))){ 1154 return ip_release_and_return(packet, ERROR_CODE); 1111 1155 } 1112 1156 // mark the first as fragmented 1113 1157 header->flags |= IPFLAG_MORE_FRAGMENTS; 1114 1158 // create middle framgents 1115 while( IP_TOTAL_LENGTH( header ) > length ){ 1116 new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len )); 1117 if( ! new_packet ) return ENOMEM; 1118 middle_header = ip_create_middle_header( new_packet, last_header ); 1119 if( ! middle_header ){ 1120 return ip_release_and_return( packet, ENOMEM ); 1121 } 1122 if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, ( length - IP_HEADER_LENGTH( middle_header )) & ( ~ 0x7 ), src, dest, addrlen ))){ 1123 return ip_release_and_return( packet, ERROR_CODE ); 1159 while(IP_TOTAL_LENGTH(header) > length){ 1160 new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len)); 1161 if(! new_packet){ 1162 return ENOMEM; 1163 } 1164 middle_header = ip_create_middle_header(new_packet, last_header); 1165 if(! middle_header){ 1166 return ip_release_and_return(packet, ENOMEM); 1167 } 1168 if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, middle_header, (length - IP_HEADER_LENGTH(middle_header)) &(~ 0x7), src, dest, addrlen))){ 1169 return ip_release_and_return(packet, ERROR_CODE); 1124 1170 } 1125 1171 } 1126 1172 // finish the first fragment 1127 header->header_checksum = IP_HEADER_CHECKSUM( header);1173 header->header_checksum = IP_HEADER_CHECKSUM(header); 1128 1174 return EOK; 1129 1175 } 1130 1176 1131 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen){1177 int ip_fragment_packet_data(packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen){ 1132 1178 ERROR_DECLARE; 1133 1179 1134 void * data; 1135 size_t offset; 1136 1137 data = packet_suffix( new_packet, length ); 1138 if( ! data ) return ENOMEM; 1139 memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length ); 1140 ERROR_PROPAGATE( packet_trim( packet, 0, length )); 1141 header->total_length = htons( IP_TOTAL_LENGTH( header ) - length ); 1142 new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length ); 1143 offset = IP_FRAGMENT_OFFSET( header ) + IP_HEADER_DATA_LENGTH( header ); 1144 new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( offset ); 1145 new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( offset ); 1146 new_header->header_checksum = IP_HEADER_CHECKSUM( new_header ); 1147 ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen )); 1148 return pq_insert_after( packet, new_packet ); 1149 } 1150 1151 ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){ 1152 ip_header_ref middle; 1153 1154 middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last )); 1155 if( ! middle ) return NULL; 1156 memcpy( middle, last, IP_HEADER_LENGTH( last )); 1180 void * data; 1181 size_t offset; 1182 1183 data = packet_suffix(new_packet, length); 1184 if(! data){ 1185 return ENOMEM; 1186 } 1187 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, length); 1188 ERROR_PROPAGATE(packet_trim(packet, 0, length)); 1189 header->total_length = htons(IP_TOTAL_LENGTH(header) - length); 1190 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); 1191 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header); 1192 new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset); 1193 new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); 1194 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header); 1195 ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, (const uint8_t *) dest, addrlen)); 1196 return pq_insert_after(packet, new_packet); 1197 } 1198 1199 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last){ 1200 ip_header_ref middle; 1201 1202 middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last)); 1203 if(! middle){ 1204 return NULL; 1205 } 1206 memcpy(middle, last, IP_HEADER_LENGTH(last)); 1157 1207 middle->flags |= IPFLAG_MORE_FRAGMENTS; 1158 1208 return middle; 1159 1209 } 1160 1210 1161 void ip_create_last_header( ip_header_ref last, ip_header_ref first){1162 ip_option_ref 1163 size_t 1164 size_t 1211 void ip_create_last_header(ip_header_ref last, ip_header_ref first){ 1212 ip_option_ref option; 1213 size_t next; 1214 size_t length; 1165 1215 1166 1216 // copy first itself 1167 memcpy( last, first, sizeof( ip_header_t));1168 length = sizeof( ip_header_t);1169 next = sizeof( ip_header_t);1217 memcpy(last, first, sizeof(ip_header_t)); 1218 length = sizeof(ip_header_t); 1219 next = sizeof(ip_header_t); 1170 1220 // process all ip options 1171 while( next < first->header_length){1172 option = ( ip_option_ref ) ((( uint8_t * ) first ) + next);1221 while(next < first->header_length){ 1222 option = (ip_option_ref) (((uint8_t *) first) + next); 1173 1223 // skip end or noop 1174 if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP)){1224 if((option->type == IPOPT_END) || (option->type == IPOPT_NOOP)){ 1175 1225 ++ next; 1176 1226 }else{ 1177 1227 // copy if said so or skip 1178 if( IPOPT_COPIED( option->type)){1179 memcpy((( uint8_t * ) last ) + length, (( uint8_t * ) first ) + next, option->length);1228 if(IPOPT_COPIED(option->type)){ 1229 memcpy(((uint8_t *) last) + length, ((uint8_t *) first) + next, option->length); 1180 1230 length += option->length; 1181 1231 } … … 1185 1235 } 1186 1236 // align 4 byte boundary 1187 if( length % 4){1188 bzero((( uint8_t * ) last ) + length, 4 - ( length % 4));1237 if(length % 4){ 1238 bzero(((uint8_t *) last) + length, 4 - (length % 4)); 1189 1239 last->header_length = length / 4 + 1; 1190 1240 }else{ … … 1194 1244 } 1195 1245 1196 int ip_receive_message( device_id_t device_id, packet_t packet){1197 packet_t 1246 int ip_receive_message(device_id_t device_id, packet_t packet){ 1247 packet_t next; 1198 1248 1199 1249 do{ 1200 next = pq_detach( packet);1201 ip_process_packet( device_id, packet);1250 next = pq_detach(packet); 1251 ip_process_packet(device_id, packet); 1202 1252 packet = next; 1203 }while( packet);1253 }while(packet); 1204 1254 return EOK; 1205 1255 } 1206 1256 1207 int ip_process_packet( device_id_t device_id, packet_t packet){1257 int ip_process_packet(device_id_t device_id, packet_t packet){ 1208 1258 ERROR_DECLARE; 1209 1259 1210 ip_header_ref 1211 in_addr_t 1212 ip_route_ref 1213 int 1214 struct sockaddr * 1215 struct sockaddr_in 1260 ip_header_ref header; 1261 in_addr_t dest; 1262 ip_route_ref route; 1263 int phone; 1264 struct sockaddr * addr; 1265 struct sockaddr_in addr_in; 1216 1266 // struct sockaddr_in addr_in6; 1217 socklen_t 1218 1219 header = ( ip_header_ref ) packet_get_data( packet);1220 if( ! header){1221 return ip_release_and_return( packet, ENOMEM);1267 socklen_t addrlen; 1268 1269 header = (ip_header_ref) packet_get_data(packet); 1270 if(! header){ 1271 return ip_release_and_return(packet, ENOMEM); 1222 1272 } 1223 1273 // checksum 1224 if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ) != IP_CHECKSUM_ZERO)){1225 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1226 if( phone >= 0){1274 if((header->header_checksum) && (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)){ 1275 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1276 if(phone >= 0){ 1227 1277 // checksum error ICMP 1228 icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->header_checksum )) - (( size_t ) (( void * ) header )), packet);1278 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->header_checksum)) - ((size_t) ((void *) header)), packet); 1229 1279 } 1230 1280 return EINVAL; 1231 1281 } 1232 if( header->ttl <= 1){1233 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1234 if( phone >= 0){1282 if(header->ttl <= 1){ 1283 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1284 if(phone >= 0){ 1235 1285 // ttl oxceeded ICMP 1236 icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet);1286 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1237 1287 } 1238 1288 return EINVAL; 1239 1289 } 1240 1290 // process ipopt and get destination 1241 dest = ip_get_destination( header);1291 dest = ip_get_destination(header); 1242 1292 // set the addrination address 1243 switch( header->version){1293 switch(header->version){ 1244 1294 case IPVERSION: 1245 addrlen = sizeof( addr_in);1246 bzero( & addr_in, addrlen);1295 addrlen = sizeof(addr_in); 1296 bzero(&addr_in, addrlen); 1247 1297 addr_in.sin_family = AF_INET; 1248 memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest));1249 addr = ( struct sockaddr * ) &addr_in;1298 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1299 addr = (struct sockaddr *) &addr_in; 1250 1300 break; 1251 1301 /* case IPv6VERSION: 1252 addrlen = sizeof( dest_in6);1253 bzero( & dest_in6, addrlen);1302 addrlen = sizeof(dest_in6); 1303 bzero(&dest_in6, addrlen); 1254 1304 dest_in6.sin6_family = AF_INET6; 1255 memcpy( & dest_in6.sin6_addr.s6_addr,);1256 dest = ( struct sockaddr * ) &dest_in;1305 memcpy(&dest_in6.sin6_addr.s6_addr,); 1306 dest = (struct sockaddr *) &dest_in; 1257 1307 break; 1258 1308 */ default: 1259 return ip_release_and_return( packet, EAFNOSUPPORT);1260 } 1261 ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen));1262 route = ip_find_route( dest);1263 if( ! route){1264 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1265 if( phone >= 0){1309 return ip_release_and_return(packet, EAFNOSUPPORT); 1310 } 1311 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen)); 1312 route = ip_find_route(dest); 1313 if(! route){ 1314 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1315 if(phone >= 0){ 1266 1316 // unreachable ICMP 1267 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);1317 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 1268 1318 } 1269 1319 return ENOENT; 1270 1320 } 1271 if( route->address.s_addr == dest.s_addr){1321 if(route->address.s_addr == dest.s_addr){ 1272 1322 // local delivery 1273 return ip_deliver_local( device_id, packet, header, 0);1323 return ip_deliver_local(device_id, packet, header, 0); 1274 1324 }else{ 1275 1325 // only if routing enabled 1276 if( route->netif->routing){1326 if(route->netif->routing){ 1277 1327 -- header->ttl; 1278 return ip_send_route( packet, route->netif, route, NULL, dest, 0);1328 return ip_send_route(packet, route->netif, route, NULL, dest, 0); 1279 1329 }else{ 1280 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1281 if( phone >= 0){1330 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1331 if(phone >= 0){ 1282 1332 // unreachable ICMP if no routing 1283 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);1333 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 1284 1334 } 1285 1335 return ENOENT; … … 1288 1338 } 1289 1339 1290 int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){1291 uint8_t * 1292 int 1293 icmp_type_t 1294 icmp_code_t 1295 ip_netif_ref 1296 measured_string_t 1297 ip_route_ref 1298 ip_header_ref 1299 1300 switch( error){1340 int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){ 1341 uint8_t * data; 1342 int offset; 1343 icmp_type_t type; 1344 icmp_code_t code; 1345 ip_netif_ref netif; 1346 measured_string_t address; 1347 ip_route_ref route; 1348 ip_header_ref header; 1349 1350 switch(error){ 1301 1351 case SERVICE_ICMP: 1302 offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL);1303 if( offset < 0){1304 return ip_release_and_return( packet, ENOMEM);1305 } 1306 data = packet_get_data( packet);1307 header = ( ip_header_ref )( data + offset);1352 offset = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 1353 if(offset < 0){ 1354 return ip_release_and_return(packet, ENOMEM); 1355 } 1356 data = packet_get_data(packet); 1357 header = (ip_header_ref)(data + offset); 1308 1358 // destination host unreachable? 1309 if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH)){1310 fibril_rwlock_read_lock( & ip_globals.netifs_lock);1311 netif = ip_netifs_find( & ip_globals.netifs, device_id);1312 if( netif && netif->arp){1313 route = ip_routes_get_index( & netif->routes, 0);1359 if((type == ICMP_DEST_UNREACH) && (code == ICMP_HOST_UNREACH)){ 1360 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1361 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1362 if(netif && netif->arp){ 1363 route = ip_routes_get_index(&netif->routes, 0); 1314 1364 // from the same network? 1315 if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr))){1365 if(route && ((route->address.s_addr &route->netmask.s_addr) == (header->destination_address &route->netmask.s_addr))){ 1316 1366 // clear the ARP mapping if any 1317 address.value = ( char * ) &header->destination_address;1318 address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address));1319 arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address);1367 address.value = (char *) &header->destination_address; 1368 address.length = CONVERT_SIZE(uint8_t, char, sizeof(header->destination_address)); 1369 arp_clear_address_req(netif->arp->phone, netif->device_id, SERVICE_IP, &address); 1320 1370 } 1321 1371 } 1322 fibril_rwlock_read_unlock( & ip_globals.netifs_lock);1372 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1323 1373 } 1324 1374 break; 1325 1375 default: 1326 return ip_release_and_return( packet, ENOTSUP);1327 } 1328 return ip_deliver_local( device_id, packet, header, error);1329 } 1330 1331 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error){1376 return ip_release_and_return(packet, ENOTSUP); 1377 } 1378 return ip_deliver_local(device_id, packet, header, error); 1379 } 1380 1381 int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error){ 1332 1382 ERROR_DECLARE; 1333 1383 1334 ip_proto_ref 1335 int 1336 services_t 1337 tl_received_msg_t 1338 struct sockaddr * 1339 struct sockaddr * 1340 struct sockaddr_in 1341 struct sockaddr_in 1384 ip_proto_ref proto; 1385 int phone; 1386 services_t service; 1387 tl_received_msg_t received_msg; 1388 struct sockaddr * src; 1389 struct sockaddr * dest; 1390 struct sockaddr_in src_in; 1391 struct sockaddr_in dest_in; 1342 1392 // struct sockaddr_in src_in6; 1343 1393 // struct sockaddr_in dest_in6; 1344 socklen_t 1345 1346 if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || IP_FRAGMENT_OFFSET( header)){1394 socklen_t addrlen; 1395 1396 if((header->flags &IPFLAG_MORE_FRAGMENTS) || IP_FRAGMENT_OFFSET(header)){ 1347 1397 // TODO fragmented 1348 1398 return ENOTSUP; 1349 1399 }else{ 1350 switch( header->version){1400 switch(header->version){ 1351 1401 case IPVERSION: 1352 addrlen = sizeof( src_in);1353 bzero( & src_in, addrlen);1402 addrlen = sizeof(src_in); 1403 bzero(&src_in, addrlen); 1354 1404 src_in.sin_family = AF_INET; 1355 memcpy( & dest_in, & src_in, addrlen);1356 memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address));1357 memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address));1358 src = ( struct sockaddr * ) &src_in;1359 dest = ( struct sockaddr * ) &dest_in;1405 memcpy(&dest_in, &src_in, addrlen); 1406 memcpy(&src_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address)); 1407 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, sizeof(header->destination_address)); 1408 src = (struct sockaddr *) &src_in; 1409 dest = (struct sockaddr *) &dest_in; 1360 1410 break; 1361 1411 /* case IPv6VERSION: 1362 addrlen = sizeof( src_in6);1363 bzero( & src_in6, addrlen);1412 addrlen = sizeof(src_in6); 1413 bzero(&src_in6, addrlen); 1364 1414 src_in6.sin6_family = AF_INET6; 1365 memcpy( & dest_in6, & src_in6, addrlen);1366 memcpy( & src_in6.sin6_addr.s6_addr,);1367 memcpy( & dest_in6.sin6_addr.s6_addr,);1368 src = ( struct sockaddr * ) &src_in;1369 dest = ( struct sockaddr * ) &dest_in;1415 memcpy(&dest_in6, &src_in6, addrlen); 1416 memcpy(&src_in6.sin6_addr.s6_addr,); 1417 memcpy(&dest_in6.sin6_addr.s6_addr,); 1418 src = (struct sockaddr *) &src_in; 1419 dest = (struct sockaddr *) &dest_in; 1370 1420 break; 1371 1421 */ default: 1372 return ip_release_and_return( packet, EAFNOSUPPORT);1373 } 1374 if( ERROR_OCCURRED( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen))){1375 return ip_release_and_return( packet, ERROR_CODE);1422 return ip_release_and_return(packet, EAFNOSUPPORT); 1423 } 1424 if(ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, addrlen))){ 1425 return ip_release_and_return(packet, ERROR_CODE); 1376 1426 } 1377 1427 // trim padding if present 1378 if(( ! error ) && ( IP_TOTAL_LENGTH( header ) < packet_get_data_length( packet))){1379 if( ERROR_OCCURRED( packet_trim( packet, 0, packet_get_data_length( packet ) - IP_TOTAL_LENGTH( header)))){1380 return ip_release_and_return( packet, ERROR_CODE);1381 } 1382 } 1383 fibril_rwlock_read_lock( & ip_globals.protos_lock);1384 proto = ip_protos_find( & ip_globals.protos, header->protocol);1385 if( ! proto){1386 fibril_rwlock_read_unlock( & ip_globals.protos_lock);1387 phone = ip_prepare_icmp_and_get_phone( error, packet, header);1388 if( phone >= 0){1428 if((! error) && (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))){ 1429 if(ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))){ 1430 return ip_release_and_return(packet, ERROR_CODE); 1431 } 1432 } 1433 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1434 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1435 if(! proto){ 1436 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1437 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1438 if(phone >= 0){ 1389 1439 // unreachable ICMP 1390 icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet);1440 icmp_destination_unreachable_msg(phone, ICMP_PROT_UNREACH, 0, packet); 1391 1441 } 1392 1442 return ENOENT; 1393 1443 } 1394 if( proto->received_msg){1444 if(proto->received_msg){ 1395 1445 service = proto->service; 1396 1446 received_msg = proto->received_msg; 1397 fibril_rwlock_read_unlock( & ip_globals.protos_lock);1398 ERROR_CODE = received_msg( device_id, packet, service, error);1447 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1448 ERROR_CODE = received_msg(device_id, packet, service, error); 1399 1449 }else{ 1400 ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error);1401 fibril_rwlock_read_unlock( & ip_globals.protos_lock);1450 ERROR_CODE = tl_received_msg(proto->phone, device_id, packet, proto->service, error); 1451 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1402 1452 } 1403 1453 return ERROR_CODE; … … 1405 1455 } 1406 1456 1407 in_addr_t ip_get_destination( ip_header_ref header){1408 in_addr_t 1457 in_addr_t ip_get_destination(ip_header_ref header){ 1458 in_addr_t destination; 1409 1459 1410 1460 // TODO search set ipopt route? … … 1413 1463 } 1414 1464 1415 int ip_prepare_icmp( packet_t packet, ip_header_ref header){1416 packet_t 1417 struct sockaddr * 1418 struct sockaddr_in 1465 int ip_prepare_icmp(packet_t packet, ip_header_ref header){ 1466 packet_t next; 1467 struct sockaddr * dest; 1468 struct sockaddr_in dest_in; 1419 1469 // struct sockaddr_in dest_in6; 1420 socklen_t 1470 socklen_t addrlen; 1421 1471 1422 1472 // detach the first packet and release the others 1423 next = pq_detach( packet ); 1424 if( next ){ 1425 pq_release( ip_globals.net_phone, packet_get_id( next )); 1426 } 1427 if( ! header ){ 1428 if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM; 1473 next = pq_detach(packet); 1474 if(next){ 1475 pq_release(ip_globals.net_phone, packet_get_id(next)); 1476 } 1477 if(! header){ 1478 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1479 return ENOMEM; 1480 } 1429 1481 // get header 1430 header = ( ip_header_ref ) packet_get_data( packet ); 1431 if( ! header ) return EINVAL; 1482 header = (ip_header_ref) packet_get_data(packet); 1483 if(! header){ 1484 return EINVAL; 1485 } 1432 1486 } 1433 1487 // only for the first fragment 1434 if( IP_FRAGMENT_OFFSET( header )) return EINVAL; 1488 if(IP_FRAGMENT_OFFSET(header)){ 1489 return EINVAL; 1490 } 1435 1491 // not for the ICMP protocol 1436 if( header->protocol == IPPROTO_ICMP){1492 if(header->protocol == IPPROTO_ICMP){ 1437 1493 return EPERM; 1438 1494 } 1439 1495 // set the destination address 1440 switch( header->version){1496 switch(header->version){ 1441 1497 case IPVERSION: 1442 addrlen = sizeof( dest_in);1443 bzero( & dest_in, addrlen);1498 addrlen = sizeof(dest_in); 1499 bzero(&dest_in, addrlen); 1444 1500 dest_in.sin_family = AF_INET; 1445 memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address));1446 dest = ( struct sockaddr * ) &dest_in;1501 memcpy(&dest_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address)); 1502 dest = (struct sockaddr *) &dest_in; 1447 1503 break; 1448 1504 /* case IPv6VERSION: 1449 addrlen = sizeof( dest_in6);1450 bzero( & dest_in6, addrlen);1505 addrlen = sizeof(dest_in6); 1506 bzero(&dest_in6, addrlen); 1451 1507 dest_in6.sin6_family = AF_INET6; 1452 memcpy( & dest_in6.sin6_addr.s6_addr,);1453 dest = ( struct sockaddr * ) &dest_in;1508 memcpy(&dest_in6.sin6_addr.s6_addr,); 1509 dest = (struct sockaddr *) &dest_in; 1454 1510 break; 1455 1511 */ default: 1456 1512 return EAFNOSUPPORT; 1457 1513 } 1458 return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen);1459 } 1460 1461 int ip_get_icmp_phone( void){1462 ip_proto_ref 1463 int 1464 1465 fibril_rwlock_read_lock( & ip_globals.protos_lock);1466 proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP);1514 return packet_set_addr(packet, NULL, (uint8_t *) dest, addrlen); 1515 } 1516 1517 int ip_get_icmp_phone(void){ 1518 ip_proto_ref proto; 1519 int phone; 1520 1521 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1522 proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP); 1467 1523 phone = proto ? proto->phone : ENOENT; 1468 fibril_rwlock_read_unlock( & ip_globals.protos_lock);1524 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1469 1525 return phone; 1470 1526 } 1471 1527 1472 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header){1473 int 1528 int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header){ 1529 int phone; 1474 1530 1475 1531 phone = ip_get_icmp_phone(); 1476 if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header)){1477 return ip_release_and_return( packet, EINVAL);1532 if(error || (phone < 0) || ip_prepare_icmp(packet, header)){ 1533 return ip_release_and_return(packet, EINVAL); 1478 1534 } 1479 1535 return phone; 1480 1536 } 1481 1537 1482 int ip_release_and_return( packet_t packet, int result){1483 pq_release( ip_globals.net_phone, packet_get_id( packet));1538 int ip_release_and_return(packet_t packet, int result){ 1539 pq_release(ip_globals.net_phone, packet_get_id(packet)); 1484 1540 return result; 1485 1541 } 1486 1542 1487 int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){1488 struct sockaddr_in * 1543 int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){ 1544 struct sockaddr_in * address_in; 1489 1545 // struct sockaddr_in6 * address_in6; 1490 in_addr_t * dest; 1491 in_addr_t * src; 1492 ip_route_ref route; 1493 ipv4_pseudo_header_ref header_in; 1494 1495 if( !( destination && ( addrlen > 0 ))) return EINVAL; 1496 if( !( device_id && header && headerlen )) return EBADMEM; 1497 if(( size_t ) addrlen < sizeof( struct sockaddr )){ 1546 in_addr_t * dest; 1547 in_addr_t * src; 1548 ip_route_ref route; 1549 ipv4_pseudo_header_ref header_in; 1550 1551 if(!(destination && (addrlen > 0))){ 1498 1552 return EINVAL; 1499 1553 } 1500 switch( destination->sa_family ){ 1554 if(!(device_id && header && headerlen)){ 1555 return EBADMEM; 1556 } 1557 if((size_t) addrlen < sizeof(struct sockaddr)){ 1558 return EINVAL; 1559 } 1560 switch(destination->sa_family){ 1501 1561 case AF_INET: 1502 if( addrlen != sizeof( struct sockaddr_in)){1562 if(addrlen != sizeof(struct sockaddr_in)){ 1503 1563 return EINVAL; 1504 1564 } 1505 address_in = ( struct sockaddr_in *) destination;1506 dest = & 1507 if( ! dest->s_addr){1565 address_in = (struct sockaddr_in *) destination; 1566 dest = &address_in->sin_addr; 1567 if(! dest->s_addr){ 1508 1568 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1509 1569 } … … 1511 1571 // TODO IPv6 1512 1572 /* case AF_INET6: 1513 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 1514 address_in6 = ( struct sockaddr_in6 * ) dest; 1573 if(addrlen != sizeof(struct sockaddr_in6)){ 1574 return EINVAL; 1575 } 1576 address_in6 = (struct sockaddr_in6 *) dest; 1515 1577 address_in6.sin6_addr.s6_addr; 1516 1578 */ default: 1517 1579 return EAFNOSUPPORT; 1518 1580 } 1519 fibril_rwlock_read_lock( & ip_globals.lock);1520 route = ip_find_route( * dest);1521 if( !( route && route->netif)){1522 fibril_rwlock_read_unlock( & ip_globals.lock);1581 fibril_rwlock_read_lock(&ip_globals.lock); 1582 route = ip_find_route(*dest); 1583 if(!(route && route->netif)){ 1584 fibril_rwlock_read_unlock(&ip_globals.lock); 1523 1585 return ENOENT; 1524 1586 } 1525 * device_id = route->netif->device_id; 1526 src = ip_netif_address( route->netif ); 1527 fibril_rwlock_read_unlock( & ip_globals.lock ); 1528 * headerlen = sizeof( * header_in ); 1529 header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen ); 1530 if( ! header_in ) return ENOMEM; 1531 bzero( header_in, * headerlen ); 1587 *device_id = route->netif->device_id; 1588 src = ip_netif_address(route->netif); 1589 fibril_rwlock_read_unlock(&ip_globals.lock); 1590 *headerlen = sizeof(*header_in); 1591 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 1592 if(! header_in){ 1593 return ENOMEM; 1594 } 1595 bzero(header_in, * headerlen); 1532 1596 header_in->destination_address = dest->s_addr; 1533 1597 header_in->source_address = src->s_addr; 1534 1598 header_in->protocol = protocol; 1535 1599 header_in->data_length = 0; 1536 * header = ( ip_pseudo_header_ref) header_in;1600 *header = (ip_pseudo_header_ref) header_in; 1537 1601 return EOK; 1538 1602 } -
uspace/srv/net/il/ip/ip.h
raa85487 raadf01e 90 90 * @see device.h 91 91 */ 92 DEVICE_MAP_DECLARE( ip_netifs, ip_netif_t)92 DEVICE_MAP_DECLARE(ip_netifs, ip_netif_t) 93 93 94 94 /** IP registered protocols. … … 96 96 * @see int_map.h 97 97 */ 98 INT_MAP_DECLARE( ip_protos, ip_proto_t)98 INT_MAP_DECLARE(ip_protos, ip_proto_t) 99 99 100 100 /** IP routing table. 101 101 * @see generic_field.h 102 102 */ 103 GENERIC_FIELD_DECLARE( ip_routes, ip_route_t)103 GENERIC_FIELD_DECLARE(ip_routes, ip_route_t) 104 104 105 105 /** IP network interface specific data. … … 108 108 /** Device identifier. 109 109 */ 110 device_id_t 110 device_id_t device_id; 111 111 /** Netif module service. 112 112 */ 113 services_t 113 services_t service; 114 114 /** Netif module phone. 115 115 */ 116 int 116 int phone; 117 117 /** ARP module. 118 118 * Assigned if using ARP. 119 119 */ 120 module_ref 120 module_ref arp; 121 121 /** IP version. 122 122 */ 123 int 123 int ipv; 124 124 /** Indicates whether using DHCP. 125 125 */ 126 int 126 int dhcp; 127 127 /** Indicates whether IP routing is enabled. 128 128 */ 129 int 129 int routing; 130 130 /** Device state. 131 131 */ 132 device_state_t 132 device_state_t state; 133 133 /** Broadcast address. 134 134 */ 135 in_addr_t 135 in_addr_t broadcast; 136 136 /** Routing table. 137 137 */ 138 ip_routes_t 138 ip_routes_t routes; 139 139 /** Packet dimension. 140 140 */ 141 packet_dimension_t 141 packet_dimension_t packet_dimension; 142 142 }; 143 143 … … 147 147 /** Protocol number. 148 148 */ 149 int 149 int protocol; 150 150 /** Protocol module service. 151 151 */ … … 153 153 /** Protocol module phone. 154 154 */ 155 int 155 int phone; 156 156 /** Protocol packet receiving function. 157 157 */ … … 164 164 /** Target address. 165 165 */ 166 in_addr_t 166 in_addr_t address; 167 167 /** Target network mask. 168 168 */ 169 in_addr_t 169 in_addr_t netmask; 170 170 /** Gateway. 171 171 */ 172 in_addr_t 172 in_addr_t gateway; 173 173 /** Parent netif. 174 174 */ 175 ip_netif_ref 175 ip_netif_ref netif; 176 176 }; 177 177 … … 181 181 /** Networking module phone. 182 182 */ 183 int 183 int net_phone; 184 184 /** Registered network interfaces. 185 185 */ 186 ip_netifs_t 186 ip_netifs_t netifs; 187 187 /** Netifs safeyt lock. 188 188 */ 189 fibril_rwlock_t 189 fibril_rwlock_t netifs_lock; 190 190 /** Registered protocols. 191 191 */ 192 ip_protos_t 192 ip_protos_t protos; 193 193 /** Protocols safety lock. 194 194 */ 195 fibril_rwlock_t 195 fibril_rwlock_t protos_lock; 196 196 /** Default gateway. 197 197 */ 198 ip_route_t 198 ip_route_t gateway; 199 199 /** Known support modules. 200 200 */ 201 modules_t 201 modules_t modules; 202 202 /** Default client connection function for support modules. 203 203 */ … … 205 205 /** Packet counter. 206 206 */ 207 uint16_t 207 uint16_t packet_counter; 208 208 /** Safety lock. 209 209 */ 210 fibril_rwlock_t 210 fibril_rwlock_t lock; 211 211 }; 212 212 -
uspace/srv/net/il/ip/ip_client.c
raa85487 raadf01e 48 48 #include "ip_header.h" 49 49 50 int ip_client_prepare_packet( packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){51 ip_header_ref 52 uint8_t * 53 size_t 50 int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){ 51 ip_header_ref header; 52 uint8_t * data; 53 size_t padding; 54 54 55 55 padding = ipopt_length % 4; 56 if( padding){56 if(padding){ 57 57 padding = 4 - padding; 58 58 ipopt_length += padding; 59 59 } 60 data = ( uint8_t * ) packet_prefix( packet, sizeof( ip_header_t ) + padding ); 61 if( ! data ) return ENOMEM; 62 while( padding -- ) data[ sizeof( ip_header_t ) + padding ] = IPOPT_NOOP; 63 header = ( ip_header_ref ) data; 64 header->header_length = IP_COMPUTE_HEADER_LENGTH( sizeof( ip_header_t ) + ipopt_length ); 65 header->ttl = ( ttl ? ttl : IPDEFTTL ); //((( ttl ) <= MAXTTL ) ? ttl : MAXTTL ) : IPDEFTTL; 60 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 61 if(! data){ 62 return ENOMEM; 63 } 64 while(padding --){ 65 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 66 } 67 header = (ip_header_ref) data; 68 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length); 69 header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL; 66 70 header->tos = tos; 67 71 header->protocol = protocol; 68 if( dont_fragment ) header->flags = IPFLAG_DONT_FRAGMENT; 72 if(dont_fragment){ 73 header->flags = IPFLAG_DONT_FRAGMENT; 74 } 69 75 return EOK; 70 76 } 71 77 72 int ip_client_process_packet( packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){73 ip_header_ref 78 int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){ 79 ip_header_ref header; 74 80 75 header = ( ip_header_ref ) packet_get_data( packet);76 if(( ! header)77 || ( packet_get_data_length( packet ) < sizeof( ip_header_t))){81 header = (ip_header_ref) packet_get_data(packet); 82 if((! header) 83 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 78 84 return ENOMEM; 79 85 } 80 if( protocol ) * protocol = header->protocol; 81 if( ttl ) * ttl = header->ttl; 82 if( tos ) * tos = header->tos; 83 if( dont_fragment ) * dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; 84 if( ipopt_length ){ 85 * ipopt_length = IP_HEADER_LENGTH( header ) - sizeof( ip_header_t ); 86 return sizeof( ip_header_t ); 86 if(protocol){ 87 *protocol = header->protocol; 88 } 89 if(ttl){ 90 *ttl = header->ttl; 91 } 92 if(tos){ 93 *tos = header->tos; 94 } 95 if(dont_fragment){ 96 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 97 } 98 if(ipopt_length){ 99 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 100 return sizeof(ip_header_t); 87 101 }else{ 88 return IP_HEADER_LENGTH( header);102 return IP_HEADER_LENGTH(header); 89 103 } 90 104 } 91 105 92 size_t ip_client_header_length( packet_t packet){93 ip_header_ref 106 size_t ip_client_header_length(packet_t packet){ 107 ip_header_ref header; 94 108 95 header = ( ip_header_ref ) packet_get_data( packet);96 if(( ! header)97 || ( packet_get_data_length( packet ) < sizeof( ip_header_t))){109 header = (ip_header_ref) packet_get_data(packet); 110 if((! header) 111 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 98 112 return 0; 99 113 } 100 return IP_HEADER_LENGTH( header);114 return IP_HEADER_LENGTH(header); 101 115 } 102 116 103 int ip_client_set_pseudo_header_data_length( ip_pseudo_header_ref header, size_t headerlen, size_t data_length){104 ipv4_pseudo_header_ref 117 int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length){ 118 ipv4_pseudo_header_ref header_in; 105 119 106 if( ! header ) return EBADMEM; 107 if( headerlen == sizeof( ipv4_pseudo_header_t )){ 108 header_in = ( ipv4_pseudo_header_ref ) header; 109 header_in->data_length = htons( data_length ); 120 if(! header){ 121 return EBADMEM; 122 } 123 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 124 header_in = (ipv4_pseudo_header_ref) header; 125 header_in->data_length = htons(data_length); 110 126 return EOK; 111 127 }else{ … … 114 130 } 115 131 116 int ip_client_get_pseudo_header( ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, ip_pseudo_header_ref * header, size_t * headerlen){117 ipv4_pseudo_header_ref 118 struct sockaddr_in * 132 int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, ip_pseudo_header_ref * header, size_t * headerlen){ 133 ipv4_pseudo_header_ref header_in; 134 struct sockaddr_in * address_in; 119 135 120 if( !( header && headerlen )) return EBADMEM; 121 if( !( src && dest && ( srclen > 0 ) && (( size_t ) srclen >= sizeof( struct sockaddr )) && ( srclen == destlen ) && ( src->sa_family == dest->sa_family ))) return EINVAL; 122 switch( src->sa_family ){ 136 if(!(header && headerlen)){ 137 return EBADMEM; 138 } 139 if(!(src && dest && (srclen > 0) && ((size_t) srclen >= sizeof(struct sockaddr)) && (srclen == destlen) && (src->sa_family == dest->sa_family))){ 140 return EINVAL; 141 } 142 switch(src->sa_family){ 123 143 case AF_INET: 124 if( srclen != sizeof( struct sockaddr_in )) return EINVAL; 125 * headerlen = sizeof( * header_in ); 126 header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen ); 127 if( ! header_in ) return ENOMEM; 128 bzero( header_in, * headerlen ); 129 address_in = ( struct sockaddr_in * ) dest; 144 if(srclen != sizeof(struct sockaddr_in)){ 145 return EINVAL; 146 } 147 *headerlen = sizeof(*header_in); 148 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 149 if(! header_in){ 150 return ENOMEM; 151 } 152 bzero(header_in, * headerlen); 153 address_in = (struct sockaddr_in *) dest; 130 154 header_in->destination_address = address_in->sin_addr.s_addr; 131 address_in = ( struct sockaddr_in *) src;155 address_in = (struct sockaddr_in *) src; 132 156 header_in->source_address = address_in->sin_addr.s_addr; 133 157 header_in->protocol = protocol; 134 header_in->data_length = htons( data_length);135 * header = ( ip_pseudo_header_ref) header_in;158 header_in->data_length = htons(data_length); 159 *header = (ip_pseudo_header_ref) header_in; 136 160 return EOK; 137 161 // TODO IPv6 138 162 /* case AF_INET6: 139 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 140 address_in6 = ( struct sockaddr_in6 * ) addr; 163 if(addrlen != sizeof(struct sockaddr_in6)){ 164 return EINVAL; 165 } 166 address_in6 = (struct sockaddr_in6 *) addr; 141 167 return EOK; 142 168 */ default: -
uspace/srv/net/il/ip/ip_header.h
raa85487 raadf01e 45 45 * @param[in] header The IP packet header. 46 46 */ 47 #define IP_HEADER_LENGTH( header ) (( header )->header_length * 4u)47 #define IP_HEADER_LENGTH(header) ((header)->header_length * 4u) 48 48 49 49 /** Returns the IP header length. 50 50 * @param[in] length The IP header length in bytes. 51 51 */ 52 #define IP_COMPUTE_HEADER_LENGTH( length ) (( uint8_t ) (( length ) / 4u))52 #define IP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4u)) 53 53 54 54 /** Returns the actual IP packet total length. 55 55 * @param[in] header The IP packet header. 56 56 */ 57 #define IP_TOTAL_LENGTH( header ) ntohs(( header )->total_length)57 #define IP_TOTAL_LENGTH(header) ntohs((header)->total_length) 58 58 59 59 /** Returns the actual IP packet data length. 60 60 * @param[in] header The IP packet header. 61 61 */ 62 #define IP_HEADER_DATA_LENGTH( header ) ( IP_TOTAL_LENGTH( header ) - IP_HEADER_LENGTH( header))62 #define IP_HEADER_DATA_LENGTH(header) (IP_TOTAL_LENGTH(header) - IP_HEADER_LENGTH(header)) 63 63 64 64 /** Returns the IP packet header checksum. 65 65 * @param[in] header The IP packet header. 66 66 */ 67 #define IP_HEADER_CHECKSUM( header ) ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header))))67 #define IP_HEADER_CHECKSUM(header) (htons(ip_checksum((uint8_t *)(header), IP_HEADER_LENGTH(header)))) 68 68 69 69 /** Returns the fragment offest. 70 70 * @param[in] header The IP packet header. 71 71 */ 72 #define IP_FRAGMENT_OFFSET( header ) (((( header )->fragment_offset_high << 8 ) + ( header )->fragment_offset_low ) * 8u)72 #define IP_FRAGMENT_OFFSET(header) ((((header)->fragment_offset_high << 8) + (header)->fragment_offset_low) * 8u) 73 73 74 74 /** Returns the fragment offest high bits. 75 75 * @param[in] length The prefixed data total length. 76 76 */ 77 #define IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length ) (((( length ) / 8u ) & 0x1F00 ) >> 8)77 #define IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) ((((length) / 8u) &0x1F00) >> 8) 78 78 79 79 /** Returns the fragment offest low bits. 80 80 * @param[in] length The prefixed data total length. 81 81 */ 82 #define IP_COMPUTE_FRAGMENT_OFFSET_LOW( length ) ((( length ) / 8u ) & 0xFF)82 #define IP_COMPUTE_FRAGMENT_OFFSET_LOW(length) (((length) / 8u) &0xFF) 83 83 84 84 /** Type definition of the internet header. … … 99 99 /** The Version field indicates the format of the internet header. 100 100 */ 101 uint8_t 101 uint8_t version:4; 102 102 /** Internet Header Length is the length of the internet header in 32~bit words, and thus points to the beginning of the data. 103 103 * Note that the minimum value for a~correct header is~5. 104 104 */ 105 uint8_t 105 uint8_t header_length:4; 106 106 #else 107 107 /** Internet Header Length is the length of the internet header in 32~bit words, and thus points to the beginning of the data. 108 108 * Note that the minimum value for a~correct header is~5. 109 109 */ 110 uint8_t 110 uint8_t header_length:4; 111 111 /** The Version field indicates the format of the internet header. 112 112 */ 113 uint8_t 113 uint8_t version:4; 114 114 #endif 115 115 /** The Type of Service provides an indication of the abstract parameters of the quality of service desired. … … 118 118 * The major choice is a~three way tradeoff between low-delay, high-reliability, and high-throughput. 119 119 */ 120 uint8_t 120 uint8_t tos; 121 121 /** Total Length is the length of the datagram, measured in octets, including internet header and data. 122 122 * This field allows the length of a~datagram to be up to 65,535~octets. 123 123 */ 124 uint16_t 124 uint16_t total_length; 125 125 /** An identifying value assigned by the sender to aid in assembling the fragments of a~datagram. 126 126 */ 127 uint16_t 127 uint16_t identification; 128 128 #ifdef ARCH_IS_BIG_ENDIAN 129 129 /** Various control flags. 130 130 */ 131 uint8_t 131 uint8_t flags:3; 132 132 /** This field indicates where in the datagram this fragment belongs. 133 133 * High bits. 134 134 */ 135 uint8_t 135 uint8_t fragment_offset_high:5; 136 136 #else 137 137 /** This field indicates where in the datagram this fragment belongs. 138 138 * High bits. 139 139 */ 140 uint8_t 140 uint8_t fragment_offset_high:5; 141 141 /** Various control flags. 142 142 */ 143 uint8_t 143 uint8_t flags:3; 144 144 #endif 145 145 /** This field indicates where in the datagram this fragment belongs. 146 146 * Low bits. 147 147 */ 148 uint8_t 148 uint8_t fragment_offset_low; 149 149 /** This field indicates the maximum time the datagram is allowed to remain in the internet system. 150 150 * If this field contains the value zero, then the datagram must be destroyed. … … 153 153 * The intention is to cause undeliverable datagrams to be discarded, and to bound the maximum datagram lifetime. 154 154 */ 155 uint8_t 155 uint8_t ttl; 156 156 /** This field indicates the next level protocol used in the data portion of the internet datagram. 157 157 */ 158 uint8_t 158 uint8_t protocol; 159 159 /** A checksum of the header only. 160 160 * Since some header fields change (e.g., time to live), this is recomputed and verified at each point that the internet header is processed. … … 162 162 * For purposes of computing the checksum, the value of the checksum field is zero. 163 163 */ 164 uint16_t 164 uint16_t header_checksum; 165 165 /** The source address. 166 166 */ 167 uint32_t 167 uint32_t source_address; 168 168 /** The destination address. 169 169 */ 170 uint32_t 170 uint32_t destination_address; 171 171 } __attribute__ ((packed)); 172 172 … … 188 188 /** A single octet of option-type. 189 189 */ 190 uint8_t 190 uint8_t type; 191 191 /** An option length octet. 192 192 */ 193 uint8_t 193 uint8_t length; 194 194 /** A~pointer. 195 195 */ 196 uint8_t 196 uint8_t pointer; 197 197 #ifdef ARCH_IS_BIG_ENDIAN 198 198 /** The number of IP modules that cannot register timestamps due to lack of space. 199 199 */ 200 uint8_t 200 uint8_t overflow:4; 201 201 /** Various internet timestamp control flags. 202 202 */ 203 uint8_t 203 uint8_t flags:4; 204 204 #else 205 205 /** Various internet timestamp control flags. 206 206 */ 207 uint8_t 207 uint8_t flags:4; 208 208 /** The number of IP modules that cannot register timestamps due to lack of space. 209 209 */ 210 uint8_t 210 uint8_t overflow:4; 211 211 #endif 212 212 } __attribute__ ((packed)); … … 227 227 * Allows the packet fragmentation. 228 228 */ 229 #define IPFLAG_MAY_FRAGMENT ( 0x0 << IPFLAG_FRAGMENT_SHIFT)229 #define IPFLAG_MAY_FRAGMENT (0x0 << IPFLAG_FRAGMENT_SHIFT) 230 230 231 231 /** Don't fragment flag value. 232 232 * Permits the packet fragmentation. 233 233 */ 234 #define IPFLAG_DONT_FRAGMENT ( 0x1 << IPFLAG_FRAGMENT_SHIFT)234 #define IPFLAG_DONT_FRAGMENT (0x1 << IPFLAG_FRAGMENT_SHIFT) 235 235 236 236 /** Last fragment flag value. 237 237 * Indicates the last packet fragment. 238 238 */ 239 #define IPFLAG_LAST_FRAGMENT ( 0x0 << IPFLAG_FRAGMENTED_SHIFT)239 #define IPFLAG_LAST_FRAGMENT (0x0 << IPFLAG_FRAGMENTED_SHIFT) 240 240 241 241 /** More fragments flag value. 242 242 * Indicates that more packet fragments follow. 243 243 */ 244 #define IPFLAG_MORE_FRAGMENTS ( 0x1 << IPFLAG_FRAGMENTED_SHIFT)244 #define IPFLAG_MORE_FRAGMENTS (0x1 << IPFLAG_FRAGMENTED_SHIFT) 245 245 246 246 /*@}*/ … … 261 261 /** The source address. 262 262 */ 263 uint32_t 263 uint32_t source_address; 264 264 /** The destination address. 265 265 */ 266 uint32_t 266 uint32_t destination_address; 267 267 /** Reserved byte. 268 268 * Must be zero. 269 269 */ 270 uint8_t 270 uint8_t reserved; 271 271 /** This field indicates the next level protocol used in the data portion of the internet datagram. 272 272 */ 273 uint8_t 273 uint8_t protocol; 274 274 /** Data length is the length of the datagram, measured in octets. 275 275 */ 276 uint16_t 276 uint16_t data_length; 277 277 } __attribute__ ((packed)); 278 278 -
uspace/srv/net/il/ip/ip_messages.h
raa85487 raadf01e 72 72 * @param[in] call The message call structure. 73 73 */ 74 #define IP_GET_GATEWAY( call ) ({ in_addr_t addr; addr.s_addr = IPC_GET_ARG2( * call ); addr;})74 #define IP_GET_GATEWAY(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG2(*call); addr;}) 75 75 76 76 /** Returns the address message parameter. 77 77 * @param[in] call The message call structure. 78 78 */ 79 #define IP_GET_ADDRESS( call ) ({ in_addr_t addr; addr.s_addr = IPC_GET_ARG3( * call ); addr;})79 #define IP_GET_ADDRESS(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG3(*call); addr;}) 80 80 81 81 /** Returns the network mask message parameter. 82 82 * @param[in] call The message call structure. 83 83 */ 84 #define IP_GET_NETMASK( call ) ({ in_addr_t addr; addr.s_addr = IPC_GET_ARG4( * call ); addr;})84 #define IP_GET_NETMASK(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG4(*call); addr;}) 85 85 86 86 /** Returns the protocol message parameter. 87 87 * @param[in] call The message call structure. 88 88 */ 89 #define IP_GET_PROTOCOL( call ) (( ip_protocol_t ) IPC_GET_ARG1( * call))89 #define IP_GET_PROTOCOL(call) ((ip_protocol_t) IPC_GET_ARG1(*call)) 90 90 91 91 /** Sets the header length in the message answer. 92 92 * @param[out] answer The message answer structure. 93 93 */ 94 #define IP_SET_HEADERLEN( answer ) (( size_t * ) & IPC_GET_ARG2( * answer))94 #define IP_SET_HEADERLEN(answer) ((size_t *) &IPC_GET_ARG2(*answer)) 95 95 96 96 /*@}*/ -
uspace/srv/net/il/ip/ip_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the IP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the IP message. … … 80 80 * @returns Other error codes as defined for the ip_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** IP module global data. … … 86 86 extern ip_globals_t ip_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t 95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 ip_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 ERROR_PROPAGATE( 100 if( ERROR_OCCURRED( ip_initialize( client_connection))101 || ERROR_OCCURRED( REGISTER_ME( SERVICE_IP, & phonehash))){97 async_set_client_connection(client_connection); 98 ip_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 ERROR_PROPAGATE(pm_init()); 100 if(ERROR_OCCURRED(ip_initialize(client_connection)) 101 || ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))){ 102 102 pm_destroy(); 103 103 return ERROR_CODE; … … 110 110 } 111 111 112 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){113 return ip_message( callid, call, answer, answer_count);112 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 113 return ip_message(callid, call, answer, answer_count); 114 114 } 115 115 -
uspace/srv/net/il/ip/ip_module.h
raa85487 raadf01e 46 46 * @returns ENOMEM if there is not enough memory left. 47 47 */ 48 int ip_initialize( async_client_conn_t client_connection);48 int ip_initialize(async_client_conn_t client_connection); 49 49 50 50 /** Processes the IP message. … … 59 59 * @see IS_NET_IP_MESSAGE() 60 60 */ 61 int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);61 int ip_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 62 62 63 63 #endif -
uspace/srv/net/il/ip/ip_remote.c
raa85487 raadf01e 52 52 #include "ip_messages.h" 53 53 54 int ip_device_req( int ip_phone, device_id_t device_id, services_t service){55 return generic_device_req( ip_phone, NET_IL_DEVICE, device_id, 0, service);54 int ip_device_req(int ip_phone, device_id_t device_id, services_t service){ 55 return generic_device_req(ip_phone, NET_IL_DEVICE, device_id, 0, service); 56 56 } 57 57 58 int ip_send_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){59 return generic_send_msg( ip_phone, NET_IL_SEND, device_id, packet_get_id( packet ), sender, error);58 int ip_send_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){ 59 return generic_send_msg(ip_phone, NET_IL_SEND, device_id, packet_get_id(packet), sender, error); 60 60 } 61 61 62 int ip_connect_module( services_t service){63 return connect_to_service( SERVICE_IP);62 int ip_connect_module(services_t service){ 63 return connect_to_service(SERVICE_IP); 64 64 } 65 65 66 int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){67 return ( int ) async_req_4_0( ip_phone, NET_IP_ADD_ROUTE, ( ipcarg_t ) device_id, ( ipcarg_t ) gateway.s_addr, ( ipcarg_t ) address.s_addr, ( ipcarg_t ) netmask.s_addr);66 int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){ 67 return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr, (ipcarg_t) address.s_addr, (ipcarg_t) netmask.s_addr); 68 68 } 69 69 70 int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway){71 return ( int ) async_req_2_0( ip_phone, NET_IP_SET_GATEWAY, ( ipcarg_t ) device_id, ( ipcarg_t ) gateway.s_addr);70 int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){ 71 return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr); 72 72 } 73 73 74 int ip_packet_size_req( int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){75 return generic_packet_size_req( ip_phone, NET_IL_PACKET_SPACE, device_id, packet_dimension);74 int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){ 75 return generic_packet_size_req(ip_phone, NET_IL_PACKET_SPACE, device_id, packet_dimension); 76 76 } 77 77 78 int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg){79 return ( int ) bind_service( service, ( ipcarg_t ) protocol, me, service, receiver);78 int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg){ 79 return (int) bind_service(service, (ipcarg_t) protocol, me, service, receiver); 80 80 } 81 81 82 int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){83 return generic_received_msg( ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id( packet ), target, error);82 int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){ 83 return generic_received_msg(ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id(packet), target, error); 84 84 } 85 85 86 int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){87 aid_t 88 ipcarg_t 89 ipc_call_t 86 int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){ 87 aid_t message_id; 88 ipcarg_t result; 89 ipc_call_t answer; 90 90 91 if( !( destination && ( addrlen > 0 ))) return EINVAL; 92 if( !( device_id && header && headerlen )) return EBADMEM; 93 * header = NULL; 94 message_id = async_send_1( ip_phone, NET_IP_GET_ROUTE, ( ipcarg_t ) protocol, & answer ); 95 if(( async_data_write_start( ip_phone, destination, addrlen ) == EOK ) 96 && ( async_data_read_start( ip_phone, headerlen, sizeof( * headerlen )) == EOK ) 97 && ( * headerlen > 0 )){ 98 * header = ( ip_pseudo_header_ref ) malloc( * headerlen ); 99 if( * header ){ 100 if( async_data_read_start( ip_phone, * header, * headerlen ) != EOK ){ 101 free( * header ); 91 if(!(destination && (addrlen > 0))){ 92 return EINVAL; 93 } 94 if(!(device_id && header && headerlen)){ 95 return EBADMEM; 96 } 97 *header = NULL; 98 message_id = async_send_1(ip_phone, NET_IP_GET_ROUTE, (ipcarg_t) protocol, &answer); 99 if((async_data_write_start(ip_phone, destination, addrlen) == EOK) 100 && (async_data_read_start(ip_phone, headerlen, sizeof(*headerlen)) == EOK) 101 && (*headerlen > 0)){ 102 *header = (ip_pseudo_header_ref) malloc(*headerlen); 103 if(*header){ 104 if(async_data_read_start(ip_phone, * header, * headerlen) != EOK){ 105 free(*header); 102 106 } 103 107 } 104 108 } 105 async_wait_for( message_id, & result);106 if(( result != EOK ) && ( * header)){107 free( * header);109 async_wait_for(message_id, &result); 110 if((result != EOK) && (*header)){ 111 free(*header); 108 112 }else{ 109 * device_id = IPC_GET_DEVICE( & answer);113 *device_id = IPC_GET_DEVICE(&answer); 110 114 } 111 return ( int) result;115 return (int) result; 112 116 } 113 117
Note:
See TracChangeset
for help on using the changeset viewer.