Changes in / [069015f2:f2d2c604] in mainline
- Location:
- uspace
- Files:
-
- 1 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/il/ip_remote.c
r069015f2 rf2d2c604 57 57 * The target network is routed using this device. 58 58 * 59 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 60 * @param[in] device_id The device identifier. 61 * @param[in] address The target network address. 62 * @param[in] netmask The target network mask. 63 * @param[in] gateway The target network gateway. Not used if zero. 59 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 60 * @param[in] device_id The device identifier. 61 * @param[in] address The target network address. 62 * @param[in] netmask The target network mask. 63 * @param[in] gateway The target network gateway. Not used if zero. 64 * 64 65 */ 65 66 int ip_add_route_req_remote(int ip_phone, device_id_t device_id, … … 105 106 * If the device uses ARP registers also the new ARP device. 106 107 * 107 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 108 * @param[in] device_id The new device identifier. 109 * @param[in] netif The underlying device network interface layer service. 110 * @return EOK on success. 111 * @return ENOMEM if there is not enough memory left. 112 * @return EINVAL if the device configuration is invalid. 113 * @return ENOTSUP if the device uses IPv6. 114 * @return ENOTSUP if the device uses DHCP. 115 * @return Other error codes as defined for the 116 * net_get_device_conf_req() function. 117 * @return Other error codes as defined for the arp_device_req() 118 * function. 108 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 109 * @param[in] device_id The new device identifier. 110 * @param[in] netif The underlying device network interface layer service. 111 * 112 * @return EOK on success. 113 * @return ENOMEM if there is not enough memory left. 114 * @return EINVAL if the device configuration is invalid. 115 * @return ENOTSUP if the device uses IPv6. 116 * @return ENOTSUP if the device uses DHCP. 117 * @return Other error codes as defined for the net_get_device_conf_req() 118 * function. 119 * @return Other error codes as defined for the arp_device_req() function. 120 * 119 121 */ 120 122 int ip_device_req_remote(int ip_phone, device_id_t device_id, … … 128 130 * destination address. 129 131 * 130 * @param[in] ip_phoneThe IP module phone used for (semi)remote calls.131 * @param[in] protocolThe transport protocol.132 * @param[in] destination The destination address.133 * @param[in] addrlenThe destination address length.134 * @param[out] device_id The device identifier.135 * @param[out] header 136 * @param[out] headerlen The IP pseudo header length.132 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 133 * @param[in] protocol The transport protocol. 134 * @param[in] destination The destination address. 135 * @param[in] addrlen The destination address length. 136 * @param[out] device_id The device identifier. 137 * @param[out] header The constructed IP pseudo header. 138 * @param[out] headerlen The IP pseudo header length. 137 139 * 138 140 */ … … 141 143 device_id_t *device_id, void **header, size_t *headerlen) 142 144 { 143 if ( !destination|| (addrlen == 0))145 if ((!destination) || (addrlen == 0)) 144 146 return EINVAL; 145 147 146 if ( !device_id || !header || !headerlen)148 if ((!device_id) || (!header) || (!headerlen)) 147 149 return EBADMEM; 148 150 … … 167 169 async_wait_for(message_id, &result); 168 170 169 if ((result != EOK) && *header)171 if ((result != EOK) && (*header)) 170 172 free(*header); 171 173 else … … 177 179 /** Return the device packet dimension for sending. 178 180 * 179 * @param[in] ip_phoneThe IP module phone used for (semi)remote calls.180 * @param[in] device_idThe device identifier.181 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 182 * @param[in] device_id The device identifier. 181 183 * @param[out] packet_dimension The packet dimension. 182 * @return EOK on success. 183 * @return ENOENT if there is no such device. 184 * @return Other error codes as defined for the 185 * generic_packet_size_req_remote() function. 184 * 185 * @return EOK on success. 186 * @return ENOENT if there is no such device. 187 * @return Other error codes as defined for the 188 * generic_packet_size_req_remote() function. 189 * 186 190 */ 187 191 int ip_packet_size_req_remote(int ip_phone, device_id_t device_id, … … 194 198 /** Notify the IP module about the received error notification packet. 195 199 * 196 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 197 * @param[in] device_id The device identifier. 198 * @param[in] packet The received packet or the received packet queue. 199 * @param[in] target The target internetwork module service to be 200 * delivered to. 201 * @param[in] error The packet error reporting service. Prefixes the 202 * received packet. 203 * @return EOK on success. 200 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 201 * @param[in] device_id The device identifier. 202 * @param[in] packet The received packet or the received packet queue. 203 * @param[in] target The target internetwork module service to be 204 * delivered to. 205 * @param[in] error The packet error reporting service. Prefixes the 206 * received packet. 207 * 208 * @return EOK on success. 209 * 204 210 */ 205 211 int ip_received_error_msg_remote(int ip_phone, device_id_t device_id, … … 214 220 * The packets may get fragmented if needed. 215 221 * 216 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 217 * @param[in] device_id The device identifier. 218 * @param[in] packet The packet fragments as a packet queue. All the 219 * packets have to have the same destination address. 220 * @param[in] sender The sending module service. 221 * @param[in] error The packet error reporting service. Prefixes the 222 * received packet. 223 * @return EOK on success. 224 * @return Other error codes as defined for the generic_send_msg() 225 * function. 222 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 223 * @param[in] device_id The device identifier. 224 * @param[in] packet The packet fragments as a packet queue. All the 225 * packets have to have the same destination address. 226 * @param[in] sender The sending module service. 227 * @param[in] error The packet error reporting service. Prefixes the 228 * received packet. 229 * 230 * @return EOK on success. 231 * @return Other error codes as defined for the generic_send_msg() function. 232 * 226 233 */ 227 234 int ip_send_msg_remote(int ip_phone, device_id_t device_id, packet_t packet, … … 236 243 * This gateway is used if no other route is found. 237 244 * 238 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 239 * @param[in] device_id The device identifier. 240 * @param[in] gateway The default gateway. 245 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 246 * @param[in] device_id The device identifier. 247 * @param[in] gateway The default gateway. 248 * 241 249 */ 242 250 int ip_set_gateway_req_remote(int ip_phone, device_id_t device_id, -
uspace/srv/net/il/arp/arp.c
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup arp 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * ARP module implementation. 35 * @see arp.h 36 */ 37 38 #include "arp.h" 39 #include "arp_header.h" 40 #include "arp_oc.h" 41 #include "arp_module.h" 34 * ARP module implementation. 35 * @see arp.h 36 */ 42 37 43 38 #include <async.h> … … 48 43 #include <str.h> 49 44 #include <task.h> 50 #include <adt/measured_strings.h>51 45 #include <ipc/ipc.h> 52 46 #include <ipc/services.h> … … 59 53 #include <net/modules.h> 60 54 #include <net/device.h> 61 #include <net/packet.h> 62 55 #include <arp_interface.h> 63 56 #include <nil_interface.h> 64 57 #include <protocol_map.h> 58 #include <adt/measured_strings.h> 59 #include <net/packet.h> 65 60 #include <packet_client.h> 66 61 #include <packet_remote.h> … … 68 63 #include <il_local.h> 69 64 70 71 /** ARP module name. */ 65 #include "arp.h" 66 #include "arp_header.h" 67 #include "arp_oc.h" 68 #include "arp_module.h" 69 70 71 /** ARP module name. 72 */ 72 73 #define NAME "arp" 73 74 74 /** ARP global data. */ 75 arp_globals_t arp_globals; 76 77 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t); 78 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t); 79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t); 75 /** ARP global data. 76 */ 77 arp_globals_t arp_globals; 80 78 81 79 /** Clears the device specific data. 82 * 83 * @param[in] device The device specific data. 84 */ 85 static void arp_clear_device(arp_device_ref device) 86 { 87 int count; 88 arp_proto_ref proto; 89 90 for (count = arp_protos_count(&device->protos) - 1; count >= 0; 91 count--) { 92 proto = arp_protos_get_index(&device->protos, count); 93 if (proto) { 94 if (proto->addr) 95 free(proto->addr); 96 if (proto->addr_data) 97 free(proto->addr_data); 98 arp_addr_destroy(&proto->addresses); 99 } 100 } 101 arp_protos_clear(&device->protos); 102 } 103 104 static int arp_clean_cache_req(int arp_phone) 105 { 80 * @param[in] device The device specific data. 81 */ 82 void arp_clear_device(arp_device_ref device); 83 84 /** Creates new protocol specific data. 85 * Allocates and returns the needed memory block as the proto parameter. 86 * @param[out] proto The allocated protocol specific data. 87 * @param[in] service The protocol module service. 88 * @param[in] address The actual protocol device address. 89 * @returns EOK on success. 90 * @returns ENOMEM if there is not enough memory left. 91 */ 92 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 93 94 /** @name Message processing functions 95 */ 96 /*@{*/ 97 98 /** Registers the device. 99 * Creates new device entry in the cache or updates the protocol address if the device with the device identifier and the driver service exists. 100 * @param[in] device_id The device identifier. 101 * @param[in] service The device driver service. 102 * @param[in] protocol The protocol service. 103 * @param[in] address The actual device protocol address. 104 * @returns EOK on success. 105 * @returns EEXIST if another device with the same device identifier and different driver service exists. 106 * @returns ENOMEM if there is not enough memory left. 107 * @returns Other error codes as defined for the measured_strings_return() function. 108 */ 109 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 110 111 /** Updates the device content length according to the new MTU value. 112 * @param[in] device_id The device identifier. 113 * @param[in] mtu The new mtu value. 114 * @returns ENOENT if device is not found. 115 * @returns EOK on success. 116 */ 117 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 118 119 /** Processes the received ARP packet. 120 * Updates the source hardware address if the source entry exists or the packet is targeted to my protocol address. 121 * Responses to the ARP request if the packet is the ARP request and is targeted to my address. 122 * @param[in] device_id The source device identifier. 123 * @param[in,out] packet The received packet. 124 * @returns EOK on success and the packet is no longer needed. 125 * @returns 1 on success and the packet has been reused. 126 * @returns EINVAL if the packet is too small to carry an ARP packet. 127 * @returns EINVAL if the received address lengths differs from the registered values. 128 * @returns ENOENT if the device is not found in the cache. 129 * @returns ENOENT if the protocol for the device is not found in the cache. 130 * @returns ENOMEM if there is not enough memory left. 131 */ 132 int arp_receive_message(device_id_t device_id, packet_t packet); 133 134 /** Returns the hardware address for the given protocol address. 135 * Sends the ARP request packet if the hardware address is not found in the cache. 136 * @param[in] device_id The device identifier. 137 * @param[in] protocol The protocol service. 138 * @param[in] target The target protocol address. 139 * @returns The hardware address of the target. 140 * @returns NULL if the target parameter is NULL. 141 * @returns NULL if the device is not found. 142 * @returns NULL if the device packet is too small to send a request. 143 * @returns NULL if the hardware address is not found in the cache. 144 */ 145 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 146 147 /*@}*/ 148 149 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t) 150 151 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t) 152 153 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t) 154 155 int arp_clean_cache_req(int arp_phone){ 106 156 int count; 107 157 arp_device_ref device; 108 158 109 159 fibril_rwlock_write_lock(&arp_globals.lock); 110 for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; 111 count--) { 160 for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){ 112 161 device = arp_cache_get_index(&arp_globals.cache, count); 113 if (device){162 if(device){ 114 163 arp_clear_device(device); 115 if (device->addr_data)164 if(device->addr_data){ 116 165 free(device->addr_data); 117 if (device->broadcast_data) 166 } 167 if(device->broadcast_data){ 118 168 free(device->broadcast_data); 169 } 119 170 } 120 171 } … … 125 176 } 126 177 127 static int 128 arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, 129 measured_string_ref address) 130 { 178 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 131 179 arp_device_ref device; 132 180 arp_proto_ref proto; … … 134 182 fibril_rwlock_write_lock(&arp_globals.lock); 135 183 device = arp_cache_find(&arp_globals.cache, device_id); 136 if (!device){184 if(! device){ 137 185 fibril_rwlock_write_unlock(&arp_globals.lock); 138 186 return ENOENT; 139 187 } 140 188 proto = arp_protos_find(&device->protos, protocol); 141 if (!proto){189 if(! proto){ 142 190 fibril_rwlock_write_unlock(&arp_globals.lock); 143 191 return ENOENT; … … 148 196 } 149 197 150 151 static int arp_clear_device_req(int arp_phone, device_id_t device_id) 152 { 198 void arp_clear_device(arp_device_ref device){ 199 int count; 200 arp_proto_ref proto; 201 202 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 203 proto = arp_protos_get_index(&device->protos, count); 204 if(proto){ 205 if(proto->addr){ 206 free(proto->addr); 207 } 208 if(proto->addr_data){ 209 free(proto->addr_data); 210 } 211 arp_addr_destroy(&proto->addresses); 212 } 213 } 214 arp_protos_clear(&device->protos); 215 } 216 217 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 153 218 arp_device_ref device; 154 219 155 220 fibril_rwlock_write_lock(&arp_globals.lock); 156 221 device = arp_cache_find(&arp_globals.cache, device_id); 157 if (!device){222 if(! device){ 158 223 fibril_rwlock_write_unlock(&arp_globals.lock); 159 224 return ENOENT; … … 165 230 } 166 231 167 /** Creates new protocol specific data. 168 * 169 * Allocates and returns the needed memory block as the proto parameter. 170 * 171 * @param[out] proto The allocated protocol specific data. 172 * @param[in] service The protocol module service. 173 * @param[in] address The actual protocol device address. 174 * @returns EOK on success. 175 * @returns ENOMEM if there is not enough memory left. 176 */ 177 static int 178 arp_proto_create(arp_proto_ref *proto, services_t service, 179 measured_string_ref address) 180 { 181 ERROR_DECLARE; 182 183 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 184 if (!*proto) 185 return ENOMEM; 186 (*proto)->service = service; 187 (*proto)->addr = address; 188 (*proto)->addr_data = address->value; 189 if (ERROR_OCCURRED(arp_addr_initialize(&(*proto)->addresses))) { 190 free(*proto); 191 return ERROR_CODE; 192 } 193 return EOK; 194 } 195 196 /** Registers the device. 197 * 198 * Creates new device entry in the cache or updates the protocol address if the 199 * device with the device identifier and the driver service exists. 200 * 201 * @param[in] device_id The device identifier. 202 * @param[in] service The device driver service. 203 * @param[in] protocol The protocol service. 204 * @param[in] address The actual device protocol address. 205 * @returns EOK on success. 206 * @returns EEXIST if another device with the same device identifier 207 * and different driver service exists. 208 * @returns ENOMEM if there is not enough memory left. 209 * @returns Other error codes as defined for the 210 * measured_strings_return() function. 211 */ 212 static int 213 arp_device_message(device_id_t device_id, services_t service, 214 services_t protocol, measured_string_ref address) 215 { 232 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 216 233 ERROR_DECLARE; 217 234 … … 224 241 // an existing device? 225 242 device = arp_cache_find(&arp_globals.cache, device_id); 226 if (device){227 if (device->service != service){243 if(device){ 244 if(device->service != service){ 228 245 printf("Device %d already exists\n", device->device_id); 229 246 fibril_rwlock_write_unlock(&arp_globals.lock); … … 231 248 } 232 249 proto = arp_protos_find(&device->protos, protocol); 233 if (proto){250 if(proto){ 234 251 free(proto->addr); 235 252 free(proto->addr_data); 236 253 proto->addr = address; 237 254 proto->addr_data = address->value; 238 } else { 239 if (ERROR_OCCURRED(arp_proto_create(&proto, protocol, 240 address))) { 255 }else{ 256 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 241 257 fibril_rwlock_write_unlock(&arp_globals.lock); 242 258 return ERROR_CODE; 243 259 } 244 index = arp_protos_add(&device->protos, proto->service, 245 proto); 246 if (index < 0) { 260 index = arp_protos_add(&device->protos, proto->service, proto); 261 if(index < 0){ 247 262 fibril_rwlock_write_unlock(&arp_globals.lock); 248 263 free(proto); 249 264 return index; 250 265 } 251 printf("New protocol added:\n\tdevice id\t= " 252 "%d\n\tproto\t= %d", device_id, protocol); 253 } 254 } else { 266 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol); 267 } 268 }else{ 255 269 hardware = hardware_map(service); 256 if (!hardware)270 if(! hardware){ 257 271 return ENOENT; 258 272 } 259 273 // create a new device 260 274 device = (arp_device_ref) malloc(sizeof(arp_device_t)); 261 if (!device){275 if(! device){ 262 276 fibril_rwlock_write_unlock(&arp_globals.lock); 263 277 return ENOMEM; … … 265 279 device->hardware = hardware; 266 280 device->device_id = device_id; 267 if (ERROR_OCCURRED(arp_protos_initialize(&device->protos)) || 268 ERROR_OCCURRED(arp_proto_create(&proto, protocol, 269 address))) { 281 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos)) 282 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 270 283 fibril_rwlock_write_unlock(&arp_globals.lock); 271 284 free(device); … … 273 286 } 274 287 index = arp_protos_add(&device->protos, proto->service, proto); 275 if (index < 0){288 if(index < 0){ 276 289 fibril_rwlock_write_unlock(&arp_globals.lock); 277 290 arp_protos_destroy(&device->protos); … … 280 293 } 281 294 device->service = service; 282 283 295 // bind the new one 284 device->phone = nil_bind_service(device->service, 285 (ipcarg_t) device->device_id, SERVICE_ARP, 286 arp_globals.client_connection); 287 if (device->phone < 0) { 296 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection); 297 if(device->phone < 0){ 288 298 fibril_rwlock_write_unlock(&arp_globals.lock); 289 299 arp_protos_destroy(&device->protos); … … 291 301 return EREFUSED; 292 302 } 293 294 303 // get packet dimensions 295 if (ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, 296 &device->packet_dimension))) { 304 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){ 297 305 fibril_rwlock_write_unlock(&arp_globals.lock); 298 306 arp_protos_destroy(&device->protos); … … 300 308 return ERROR_CODE; 301 309 } 302 303 310 // get hardware address 304 if (ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, 305 &device->addr, &device->addr_data))) { 311 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){ 306 312 fibril_rwlock_write_unlock(&arp_globals.lock); 307 313 arp_protos_destroy(&device->protos); … … 309 315 return ERROR_CODE; 310 316 } 311 312 317 // get broadcast address 313 if (ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, 314 device_id, &device->broadcast_addr, 315 &device->broadcast_data))) { 318 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){ 316 319 fibril_rwlock_write_unlock(&arp_globals.lock); 317 320 free(device->addr); … … 321 324 return ERROR_CODE; 322 325 } 323 324 if (ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, 325 device->device_id, device))) { 326 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){ 326 327 fibril_rwlock_write_unlock(&arp_globals.lock); 327 328 free(device->addr); … … 333 334 return ERROR_CODE; 334 335 } 335 printf("%s: Device registered (id: %d, type: 0x%x, service: %d," 336 " proto: %d)\n", NAME, device->device_id, device->hardware, 337 device->service, protocol); 336 printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n", 337 NAME, device->device_id, device->hardware, device->service, protocol); 338 338 } 339 339 fibril_rwlock_write_unlock(&arp_globals.lock); 340 341 return EOK; 342 } 343 344 /** Initializes the ARP module. 345 * 346 * @param[in] client_connection The client connection processing function. 347 * The module skeleton propagates its own one. 348 * @returns EOK on success. 349 * @returns ENOMEM if there is not enough memory left. 350 */ 351 int arp_initialize(async_client_conn_t client_connection) 352 { 340 return EOK; 341 } 342 343 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 344 ERROR_DECLARE; 345 346 measured_string_ref tmp; 347 348 // copy the given address for exclusive use 349 tmp = measured_string_copy(address); 350 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 351 free(tmp->value); 352 free(tmp); 353 } 354 return ERROR_CODE; 355 } 356 357 int arp_initialize(async_client_conn_t client_connection){ 353 358 ERROR_DECLARE; 354 359 … … 361 366 } 362 367 363 /** Updates the device content length according to the new MTU value. 364 * 365 * @param[in] device_id The device identifier. 366 * @param[in] mtu The new mtu value. 367 * @returns ENOENT if device is not found. 368 * @returns EOK on success. 369 */ 370 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu) 368 int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 369 ipc_call_t *answer, int *answer_count) 371 370 { 371 ERROR_DECLARE; 372 373 measured_string_ref address; 374 measured_string_ref translation; 375 char * data; 376 packet_t packet; 377 packet_t next; 378 379 *answer_count = 0; 380 switch (IPC_GET_METHOD(*call)) { 381 case IPC_M_PHONE_HUNGUP: 382 return EOK; 383 case NET_ARP_DEVICE: 384 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 385 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 386 free(address); 387 free(data); 388 } 389 return ERROR_CODE; 390 case NET_ARP_TRANSLATE: 391 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 392 fibril_rwlock_read_lock(&arp_globals.lock); 393 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 394 free(address); 395 free(data); 396 if(! translation){ 397 fibril_rwlock_read_unlock(&arp_globals.lock); 398 return ENOENT; 399 } 400 ERROR_CODE = measured_strings_reply(translation, 1); 401 fibril_rwlock_read_unlock(&arp_globals.lock); 402 return ERROR_CODE; 403 case NET_ARP_CLEAR_DEVICE: 404 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 405 case NET_ARP_CLEAR_ADDRESS: 406 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 407 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 408 free(address); 409 free(data); 410 return EOK; 411 case NET_ARP_CLEAN_CACHE: 412 return arp_clean_cache_req(0); 413 case NET_IL_DEVICE_STATE: 414 // do nothing - keep the cache 415 return EOK; 416 case NET_IL_RECEIVED: 417 if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 418 fibril_rwlock_read_lock(&arp_globals.lock); 419 do{ 420 next = pq_detach(packet); 421 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 422 if(ERROR_CODE != 1){ 423 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 424 } 425 packet = next; 426 }while(packet); 427 fibril_rwlock_read_unlock(&arp_globals.lock); 428 } 429 return ERROR_CODE; 430 case NET_IL_MTU_CHANGED: 431 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 432 } 433 434 return ENOTSUP; 435 } 436 437 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 372 438 arp_device_ref device; 373 439 374 440 fibril_rwlock_write_lock(&arp_globals.lock); 375 441 device = arp_cache_find(&arp_globals.cache, device_id); 376 if (!device){442 if(! device){ 377 443 fibril_rwlock_write_unlock(&arp_globals.lock); 378 444 return ENOENT; 379 445 } 380 446 device->packet_dimension.content = mtu; 447 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 381 448 fibril_rwlock_write_unlock(&arp_globals.lock); 382 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 383 return EOK; 384 } 385 386 /** Processes the received ARP packet. 387 * 388 * Updates the source hardware address if the source entry exists or the packet 389 * is targeted to my protocol address. 390 * Responses to the ARP request if the packet is the ARP request and is 391 * targeted to my address. 392 * 393 * @param[in] device_id The source device identifier. 394 * @param[in,out] packet The received packet. 395 * @returns EOK on success and the packet is no longer needed. 396 * @returns One on success and the packet has been reused. 397 * @returns EINVAL if the packet is too small to carry an ARP 398 * packet. 399 * @returns EINVAL if the received address lengths differs from 400 * the registered values. 401 * @returns ENOENT if the device is not found in the cache. 402 * @returns ENOENT if the protocol for the device is not found in 403 * the cache. 404 * @returns ENOMEM if there is not enough memory left. 405 */ 406 static int arp_receive_message(device_id_t device_id, packet_t packet) 407 { 449 return EOK; 450 } 451 452 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 453 ERROR_DECLARE; 454 455 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 456 if(!(*proto)){ 457 return ENOMEM; 458 } 459 (** proto).service = service; 460 (** proto).addr = address; 461 (** proto).addr_data = address->value; 462 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 463 free(*proto); 464 return ERROR_CODE; 465 } 466 return EOK; 467 } 468 469 int arp_receive_message(device_id_t device_id, packet_t packet){ 408 470 ERROR_DECLARE; 409 471 … … 413 475 arp_proto_ref proto; 414 476 measured_string_ref hw_source; 415 uint8_t * src_hw;416 uint8_t * src_proto;417 uint8_t * des_hw;418 uint8_t * des_proto;477 uint8_t * src_hw; 478 uint8_t * src_proto; 479 uint8_t * des_hw; 480 uint8_t * des_proto; 419 481 420 482 length = packet_get_data_length(packet); 421 if (length <= sizeof(arp_header_t))483 if(length <= sizeof(arp_header_t)){ 422 484 return EINVAL; 423 485 } 424 486 device = arp_cache_find(&arp_globals.cache, device_id); 425 if (!device)487 if(! device){ 426 488 return ENOENT; 427 489 } 428 490 header = (arp_header_ref) packet_get_data(packet); 429 if ((ntohs(header->hardware) != device->hardware) || 430 (length < sizeof(arp_header_t) + header->hardware_length * 2U + 431 header->protocol_length * 2U)) { 491 if((ntohs(header->hardware) != device->hardware) 492 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 432 493 return EINVAL; 433 494 } 434 435 proto = arp_protos_find(&device->protos, 436 protocol_unmap(device->service, ntohs(header->protocol))); 437 if (!proto) 495 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 496 if(! proto){ 438 497 return ENOENT; 439 498 } 440 499 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 441 500 src_proto = src_hw + header->hardware_length; 442 501 des_hw = src_proto + header->protocol_length; 443 502 des_proto = des_hw + header->hardware_length; 444 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, 445 CONVERT_SIZE(uint8_t, char, header->protocol_length)); 503 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 446 504 // exists? 447 if (hw_source) { 448 if (hw_source->length != CONVERT_SIZE(uint8_t, char, 449 header->hardware_length)) { 505 if(hw_source){ 506 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 450 507 return EINVAL; 451 508 } … … 453 510 } 454 511 // is my protocol address? 455 if (proto->addr->length != CONVERT_SIZE(uint8_t, char, 456 header->protocol_length)) { 512 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 457 513 return EINVAL; 458 514 } 459 if (!str_lcmp(proto->addr->value, (char *) des_proto, 460 proto->addr->length)) { 515 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 461 516 // not already upadted? 462 if (!hw_source) { 463 hw_source = measured_string_create_bulk((char *) src_hw, 464 CONVERT_SIZE(uint8_t, char, 465 header->hardware_length)); 466 if (!hw_source) 517 if(! hw_source){ 518 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 519 if(! hw_source){ 467 520 return ENOMEM; 468 469 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, 470 (char *) src_proto, CONVERT_SIZE(uint8_t, char, 471 header->protocol_length), hw_source)); 472 } 473 if (ntohs(header->operation) == ARPOP_REQUEST) { 521 } 522 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 523 } 524 if(ntohs(header->operation) == ARPOP_REQUEST){ 474 525 header->operation = htons(ARPOP_REPLY); 475 526 memcpy(des_proto, src_proto, header->protocol_length); 476 memcpy(src_proto, proto->addr->value, 477 header->protocol_length); 478 memcpy(src_hw, device->addr->value, 479 device->packet_dimension.addr_len); 480 memcpy(des_hw, hw_source->value, 481 header->hardware_length); 482 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, 483 header->hardware_length)); 484 nil_send_msg(device->phone, device_id, packet, 485 SERVICE_ARP); 527 memcpy(src_proto, proto->addr->value, header->protocol_length); 528 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 529 memcpy(des_hw, hw_source->value, header->hardware_length); 530 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 531 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 486 532 return 1; 487 533 } 488 534 } 489 490 return EOK; 491 } 492 493 494 /** Returns the hardware address for the given protocol address. 495 * 496 * Sends the ARP request packet if the hardware address is not found in the 497 * cache. 498 * 499 * @param[in] device_id The device identifier. 500 * @param[in] protocol The protocol service. 501 * @param[in] target The target protocol address. 502 * @returns The hardware address of the target. 503 * @returns NULL if the target parameter is NULL. 504 * @returns NULL if the device is not found. 505 * @returns NULL if the device packet is too small to send a 506 * request. 507 * @returns NULL if the hardware address is not found in the cache. 508 */ 509 static measured_string_ref 510 arp_translate_message(device_id_t device_id, services_t protocol, 511 measured_string_ref target) 512 { 535 return EOK; 536 } 537 538 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 513 539 arp_device_ref device; 514 540 arp_proto_ref proto; … … 518 544 arp_header_ref header; 519 545 520 if (!target)546 if(! target){ 521 547 return NULL; 522 548 } 523 549 device = arp_cache_find(&arp_globals.cache, device_id); 524 if (!device)550 if(! device){ 525 551 return NULL; 526 552 } 527 553 proto = arp_protos_find(&device->protos, protocol); 528 if (!proto || (proto->addr->length != target->length))554 if((! proto) || (proto->addr->length != target->length)){ 529 555 return NULL; 530 556 } 531 557 addr = arp_addr_find(&proto->addresses, target->value, target->length); 532 if (addr)558 if(addr){ 533 559 return addr; 534 560 } 535 561 // ARP packet content size = header + (address + translation) * 2 536 length = 8 + 2 * (CONVERT_SIZE(char, uint8_t, proto->addr->length) + 537 CONVERT_SIZE(char, uint8_t, device->addr->length)); 538 if (length > device->packet_dimension.content) 562 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 563 if(length > device->packet_dimension.content){ 539 564 return NULL; 540 541 packet = packet_get_4_remote(arp_globals.net_phone, 542 device->packet_dimension.addr_len, device->packet_dimension.prefix, 543 length, device->packet_dimension.suffix); 544 if (!packet) 565 } 566 packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 567 if(! packet){ 545 568 return NULL; 546 569 } 547 570 header = (arp_header_ref) packet_suffix(packet, length); 548 if (!header){571 if(! header){ 549 572 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 550 573 return NULL; 551 574 } 552 553 575 header->hardware = htons(device->hardware); 554 576 header->hardware_length = (uint8_t) device->addr->length; … … 557 579 header->operation = htons(ARPOP_REQUEST); 558 580 length = sizeof(arp_header_t); 559 memcpy(((uint8_t *) header) + length, device->addr->value, 560 device->addr->length); 581 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 561 582 length += device->addr->length; 562 memcpy(((uint8_t *) header) + length, proto->addr->value, 563 proto->addr->length); 583 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 564 584 length += proto->addr->length; 565 585 bzero(((uint8_t *) header) + length, device->addr->length); 566 586 length += device->addr->length; 567 587 memcpy(((uint8_t *) header) + length, target->value, target->length); 568 569 if (packet_set_addr(packet, (uint8_t *) device->addr->value, 570 (uint8_t *) device->broadcast_addr->value, 571 CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) { 588 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){ 572 589 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 573 590 return NULL; 574 591 } 575 576 592 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 577 593 return NULL; 578 594 } 579 595 580 581 /** Processes the ARP message.582 *583 * @param[in] callid The message identifier.584 * @param[in] call The message parameters.585 * @param[out] answer The message answer parameters.586 * @param[out] answer_count The last parameter for the actual answer in the587 * answer parameter.588 * @returns EOK on success.589 * @returns ENOTSUP if the message is not known.590 *591 * @see arp_interface.h592 * @see IS_NET_ARP_MESSAGE()593 */594 int595 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,596 ipc_call_t *answer, int *answer_count)597 {598 ERROR_DECLARE;599 600 measured_string_ref address;601 measured_string_ref translation;602 char *data;603 packet_t packet;604 packet_t next;605 606 *answer_count = 0;607 switch (IPC_GET_METHOD(*call)) {608 case IPC_M_PHONE_HUNGUP:609 return EOK;610 611 case NET_ARP_DEVICE:612 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));613 if (ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call),614 IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))) {615 free(address);616 free(data);617 }618 return ERROR_CODE;619 620 case NET_ARP_TRANSLATE:621 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));622 fibril_rwlock_read_lock(&arp_globals.lock);623 translation = arp_translate_message(IPC_GET_DEVICE(call),624 IPC_GET_SERVICE(call), address);625 free(address);626 free(data);627 if (!translation) {628 fibril_rwlock_read_unlock(&arp_globals.lock);629 return ENOENT;630 }631 ERROR_CODE = measured_strings_reply(translation, 1);632 fibril_rwlock_read_unlock(&arp_globals.lock);633 return ERROR_CODE;634 635 case NET_ARP_CLEAR_DEVICE:636 return arp_clear_device_req(0, IPC_GET_DEVICE(call));637 638 case NET_ARP_CLEAR_ADDRESS:639 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));640 arp_clear_address_req(0, IPC_GET_DEVICE(call),641 IPC_GET_SERVICE(call), address);642 free(address);643 free(data);644 return EOK;645 646 case NET_ARP_CLEAN_CACHE:647 return arp_clean_cache_req(0);648 649 case NET_IL_DEVICE_STATE:650 // do nothing - keep the cache651 return EOK;652 653 case NET_IL_RECEIVED:654 if (ERROR_NONE(packet_translate_remote(arp_globals.net_phone,655 &packet, IPC_GET_PACKET(call)))) {656 fibril_rwlock_read_lock(&arp_globals.lock);657 do {658 next = pq_detach(packet);659 ERROR_CODE =660 arp_receive_message(IPC_GET_DEVICE(call),661 packet);662 if (ERROR_CODE != 1) {663 pq_release_remote(arp_globals.net_phone,664 packet_get_id(packet));665 }666 packet = next;667 } while (packet);668 fibril_rwlock_read_unlock(&arp_globals.lock);669 }670 return ERROR_CODE;671 672 case NET_IL_MTU_CHANGED:673 return arp_mtu_changed_message(IPC_GET_DEVICE(call),674 IPC_GET_MTU(call));675 }676 677 return ENOTSUP;678 }679 680 596 /** Default thread for new connections. 681 597 * 682 * @param[in] iid The initial message identifier. 683 * @param[in] icall The initial message call structure. 684 */ 685 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 598 * @param[in] iid The initial message identifier. 599 * @param[in] icall The initial message call structure. 600 * 601 */ 602 static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall) 686 603 { 687 604 /* … … 691 608 ipc_answer_0(iid, EOK); 692 609 693 while 610 while(true) { 694 611 ipc_call_t answer; 695 612 int answer_count; … … 706 623 &answer_count); 707 624 708 /* 709 * End if told to either by the message or the processing 710 * result. 711 */ 712 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 713 (res == EHANGUP)) 625 /* End if said to either by the message or the processing result */ 626 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 714 627 return; 715 628 … … 721 634 /** Starts the module. 722 635 * 723 * @returns EOK on success. 724 * @returns Other error codes as defined for each specific module 725 * start function. 636 * @param argc The count of the command line arguments. Ignored parameter. 637 * @param argv The command line parameters. Ignored parameter. 638 * 639 * @returns EOK on success. 640 * @returns Other error codes as defined for each specific module start function. 641 * 726 642 */ 727 643 int main(int argc, char *argv[]) … … 730 646 731 647 /* Start the module */ 732 ERROR_PROPAGATE(il_module_start_standalone(il_client_connection)); 648 if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection))) 649 return ERROR_CODE; 650 733 651 return EOK; 734 652 } … … 736 654 /** @} 737 655 */ 738 -
uspace/srv/net/il/arp/arp.h
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup arp 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * ARP module.34 * ARP module. 35 35 */ 36 36 37 #ifndef NET_ARP_H_38 #define NET_ARP_H_37 #ifndef __NET_ARP_H__ 38 #define __NET_ARP_H__ 39 39 40 40 #include <fibril_synch.h> … … 44 44 45 45 #include <net/device.h> 46 #include <net/packet.h>47 46 #include <net_hardware.h> 48 47 #include <adt/generic_char_map.h> … … 50 49 #include <adt/measured_strings.h> 51 50 51 52 52 /** Type definition of the ARP device specific data. 53 * @see arp_device53 * @see arp_device 54 54 */ 55 typedef struct arp_device 55 typedef struct arp_device arp_device_t; 56 56 57 57 /** Type definition of the ARP device specific data pointer. 58 * @see arp_device58 * @see arp_device 59 59 */ 60 typedef arp_device_t * arp_device_ref;60 typedef arp_device_t * arp_device_ref; 61 61 62 62 /** Type definition of the ARP global data. 63 * @see arp_globals63 * @see arp_globals 64 64 */ 65 typedef struct arp_globals 65 typedef struct arp_globals arp_globals_t; 66 66 67 67 /** Type definition of the ARP protocol specific data. 68 * @see arp_proto68 * @see arp_proto 69 69 */ 70 typedef struct arp_proto 70 typedef struct arp_proto arp_proto_t; 71 71 72 72 /** Type definition of the ARP protocol specific data pointer. 73 * @see arp_proto73 * @see arp_proto 74 74 */ 75 typedef arp_proto_t * arp_proto_ref;75 typedef arp_proto_t * arp_proto_ref; 76 76 77 77 /** ARP address map. 78 * 79 * Translates addresses. 80 * @see generic_char_map.h 78 * Translates addresses. 79 * @see generic_char_map.h 81 80 */ 82 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t) ;81 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t) 83 82 84 83 /** ARP address cache. 85 * 86 * Maps devices to the ARP device specific data. 87 * @see device.h 84 * Maps devices to the ARP device specific data. 85 * @see device.h 88 86 */ 89 DEVICE_MAP_DECLARE(arp_cache, arp_device_t) ;87 DEVICE_MAP_DECLARE(arp_cache, arp_device_t) 90 88 91 89 /** ARP protocol map. 92 * 93 * Maps protocol identifiers to the ARP protocol specific data. 94 * @see int_map.h 90 * Maps protocol identifiers to the ARP protocol specific data. 91 * @see int_map.h 95 92 */ 96 INT_MAP_DECLARE(arp_protos, arp_proto_t) ;93 INT_MAP_DECLARE(arp_protos, arp_proto_t) 97 94 98 /** ARP device specific data. */ 99 struct arp_device { 100 /** Actual device hardware address. */ 95 /** ARP device specific data. 96 */ 97 struct arp_device{ 98 /** Actual device hardware address. 99 */ 101 100 measured_string_ref addr; 102 /** Actual device hardware address data. */ 103 char *addr_data; 104 /** Broadcast device hardware address. */ 101 /** Actual device hardware address data. 102 */ 103 char * addr_data; 104 /** Broadcast device hardware address. 105 */ 105 106 measured_string_ref broadcast_addr; 106 /** Broadcast device hardware address data. */ 107 char *broadcast_data; 108 /** Device identifier. */ 107 /** Broadcast device hardware address data. 108 */ 109 char * broadcast_data; 110 /** Device identifier. 111 */ 109 112 device_id_t device_id; 110 /** Hardware type. */ 113 /** Hardware type. 114 */ 111 115 hw_type_t hardware; 112 /** Packet dimension. */ 116 /** Packet dimension. 117 */ 113 118 packet_dimension_t packet_dimension; 114 /** Device module phone. */ 119 /** Device module phone. 120 */ 115 121 int phone; 116 117 /** 118 * Protocol map. 119 * Address map for each protocol. 122 /** Protocol map. 123 * Address map for each protocol. 120 124 */ 121 125 arp_protos_t protos; 122 123 /** Device module service.*/126 /** Device module service. 127 */ 124 128 services_t service; 125 129 }; 126 130 127 /** ARP global data. */ 128 struct arp_globals { 129 /** ARP address cache. */ 131 /** ARP global data. 132 */ 133 struct arp_globals{ 134 /** ARP address cache. 135 */ 130 136 arp_cache_t cache; 131 132 /** 133 * The client connection processing function. 134 * The module skeleton propagates its own one. 137 /** The client connection processing function. 138 * The module skeleton propagates its own one. 135 139 */ 136 140 async_client_conn_t client_connection; 137 138 /** Networking module phone.*/141 /** Networking module phone. 142 */ 139 143 int net_phone; 140 /** Safety lock. */ 144 /** Safety lock. 145 */ 141 146 fibril_rwlock_t lock; 142 147 }; 143 148 144 /** ARP protocol specific data. */ 145 struct arp_proto { 146 /** Actual device protocol address. */ 149 /** ARP protocol specific data. 150 */ 151 struct arp_proto{ 152 /** Actual device protocol address. 153 */ 147 154 measured_string_ref addr; 148 /** Actual device protocol address data. */ 149 char *addr_data; 150 /** Address map. */ 155 /** Actual device protocol address data. 156 */ 157 char * addr_data; 158 /** Address map. 159 */ 151 160 arp_addr_t addresses; 152 /** Protocol service. */ 161 /** Protocol service. 162 */ 153 163 services_t service; 154 164 }; -
uspace/srv/net/il/arp/arp_header.h
r069015f2 rf2d2c604 32 32 33 33 /** @file 34 * ARP protocol header.35 * Based on the RFC826.34 * ARP protocol header. 35 * Based on the RFC~826. 36 36 */ 37 37 38 #ifndef NET_ARP_HEADER_H_39 #define NET_ARP_HEADER_H_38 #ifndef __NET_ARP_HEADER_H__ 39 #define __NET_ARP_HEADER_H__ 40 40 41 41 #include <sys/types.h> 42 42 43 43 /** Type definition of an ARP protocol header. 44 * @see arp_header44 * @see arp_header 45 45 */ 46 typedef struct arp_header 46 typedef struct arp_header arp_header_t; 47 47 48 48 /** Type definition of an ARP protocol header pointer. 49 * @see arp_header49 * @see arp_header 50 50 */ 51 typedef arp_header_t * arp_header_ref;51 typedef arp_header_t * arp_header_ref; 52 52 53 /** ARP protocol header. */54 struct arp_header { 55 /** 56 57 * @see hardware.h53 /** ARP protocol header. 54 */ 55 struct arp_header{ 56 /** Hardware type identifier. 57 * @see hardware.h 58 58 */ 59 59 uint16_t hardware; 60 61 /** Protocol identifier.*/60 /** Protocol identifier. 61 */ 62 62 uint16_t protocol; 63 /** Hardware address length in bytes. */ 63 /** Hardware address length in bytes. 64 */ 64 65 uint8_t hardware_length; 65 /** Protocol address length in bytes. */ 66 /** Protocol address length in bytes. 67 */ 66 68 uint8_t protocol_length; 67 68 /** 69 * ARP packet type. 70 * @see arp_oc.h 69 /** ARP packet type. 70 * @see arp_oc.h 71 71 */ 72 72 uint16_t operation; -
uspace/srv/net/il/arp/arp_module.c
r069015f2 rf2d2c604 32 32 33 33 /** @file 34 * ARP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * @see module.c 34 * ARP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 39 38 */ 40 39 … … 54 53 #include "arp_module.h" 55 54 56 /** ARP module global data. */ 57 extern arp_globals_t arp_globals; 55 /** ARP module global data. 56 */ 57 extern arp_globals_t arp_globals; 58 58 59 int 60 il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 61 ipc_call_t *answer, int *answer_count) 62 { 59 int il_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 63 60 return arp_message_standalone(callid, call, answer, answer_count); 64 61 } 65 62 66 int il_module_start_standalone(async_client_conn_t client_connection) 67 { 63 int il_module_start_standalone(async_client_conn_t client_connection){ 68 64 ERROR_DECLARE; 69 65 … … 73 69 74 70 ipcarg_t phonehash; 75 if (ERROR_OCCURRED(arp_initialize(client_connection)) ||76 ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))) {71 if (ERROR_OCCURRED(arp_initialize(client_connection)) 72 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))) { 77 73 pm_destroy(); 78 74 return ERROR_CODE; -
uspace/srv/net/il/arp/arp_module.h
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup arp 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * ARP module functions.35 * The functions are used as ARP module entry points.34 * ARP module functions. 35 * The functions are used as ARP module entry points. 36 36 */ 37 37 38 #ifndef NET_ARP_MODULE_H_39 #define NET_ARP_MODULE_H_38 #ifndef __NET_ARP_MODULE_H__ 39 #define __NET_ARP_MODULE_H__ 40 40 41 41 #include <ipc/ipc.h> 42 #include <async.h>43 42 44 extern int arp_initialize(async_client_conn_t); 45 extern int arp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 43 /** Initializes the ARP module. 44 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 45 * @returns EOK on success. 46 * @returns ENOMEM if there is not enough memory left. 47 */ 48 int arp_initialize(async_client_conn_t client_connection); 49 50 /** Processes the ARP message. 51 * @param[in] callid The message identifier. 52 * @param[in] call The message parameters. 53 * @param[out] answer The message answer parameters. 54 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 55 * @returns EOK on success. 56 * @returns ENOTSUP if the message is not known. 57 * @see arp_interface.h 58 * @see IS_NET_ARP_MESSAGE() 59 */ 60 int arp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 47 61 48 62 #endif -
uspace/srv/net/il/arp/arp_oc.h
r069015f2 rf2d2c604 32 32 33 33 /** @file 34 * ARP operation codes according to the on-line IANA - Address Resolution 35 * Protocol (ARP) Parameters 36 * http://www.iana.org/assignments/arp-parameters/arp-parameters.xml 37 * cited January 14 2009. 34 * ARP operation codes according to the on-line IANA - Address Resolution Protocol (ARP) Parameters - <http://www.iana.org/assignments/arp-parameters/arp-parameters.xml>, cited January 14 2009. 38 35 */ 39 36 40 #ifndef NET_ARP_ARPOP_H_41 #define NET_ARP_ARPOP_H_37 #ifndef __NET_ARP_ARPOP_H__ 38 #define __NET_ARP_ARPOP_H__ 42 39 43 /** @name ARP operation codes definitions */ 40 /** @name ARP operation codes definitions 41 */ 44 42 /*@{*/ 45 43 46 /** REQUEST operation code. */ 47 #define ARPOP_REQUEST 1 44 /** REQUEST operation code. 45 */ 46 #define ARPOP_REQUEST 1 48 47 49 /** REPLY operation code. */ 50 #define ARPOP_REPLY 2 48 /** REPLY operation code. 49 */ 50 #define ARPOP_REPLY 2 51 52 /** Reverse request operation code. 53 */ 54 #define ARPOP_RREQUEST 3 55 56 /** Reverse reply operation code. 57 */ 58 #define ARPOP_RREPLY 4 59 60 /** DRARP-Request operation code. 61 */ 62 #define ARPOP_DRARP_Request 5 63 64 /** DRARP-Reply operation code. 65 */ 66 #define ARPOP_DRARP_Reply 6 67 68 /** DRARP-Error operation code. 69 */ 70 #define ARPOP_DRARP_Error 7 71 72 /** InARP-Request operation code. 73 */ 74 #define ARPOP_InREQUEST 8 75 76 /** InARP-Reply operation code. 77 */ 78 #define ARPOP_InREPLY 9 79 80 /** ARP-NAK operation code. 81 */ 82 #define ARPOP_NAK 10 83 84 /** MARS-Request operation code. 85 */ 86 #define ARPOP_MARS_Request 11 87 88 /** MARS-Multi operation code. 89 */ 90 #define ARPOP_MARS_Multi 12 91 92 /** MARS-MServ operation code. 93 */ 94 #define ARPOP_MARS_MServ 13 95 96 /** MARS-Join operation code. 97 */ 98 #define ARPOP_MARS_Join 14 99 100 /** MARS-Leave operation code. 101 */ 102 #define ARPOP_MARS_Leave 15 103 104 /** MARS-NAK operation code. 105 */ 106 #define ARPOP_MARS_NAK 16 107 108 /** MARS-Unserv operation code. 109 */ 110 #define ARPOP_MARS_Unserv 17 111 112 /** MARS-SJoin operation code. 113 */ 114 #define ARPOP_MARS_SJoin 18 115 116 /** MARS-SLeave operation code. 117 */ 118 #define ARPOP_MARS_SLeave 19 119 120 /** MARS-Grouplist-Request operation code. 121 */ 122 #define ARPOP_MARS_Grouplist_Request 20 123 124 /** MARS-Grouplist-Reply operation code. 125 */ 126 #define ARPOP_MARS_Grouplist_Reply 21 127 128 /** MARS-Redirect-Map operation code. 129 */ 130 #define ARPOP_MARS_Redirect_Map 22 131 132 /** MAPOS-UNARP operation code. 133 */ 134 #define ARPOP_MAPOS_UNARP 23 51 135 52 136 /*@}*/ -
uspace/srv/net/il/ip/ip.c
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup ip 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * IP module implementation. 35 * @see arp.h 36 */ 37 38 #include "ip.h" 39 #include "ip_module.h" 34 * IP module implementation. 35 * @see arp.h 36 */ 40 37 41 38 #include <async.h> … … 54 51 #include <byteorder.h> 55 52 56 #include <adt/measured_strings.h>57 #include <adt/module_map.h>58 59 #include <packet_client.h>60 53 #include <net/socket_codes.h> 61 54 #include <net/in.h> … … 78 71 #include <nil_interface.h> 79 72 #include <tl_interface.h> 73 #include <adt/measured_strings.h> 74 #include <adt/module_map.h> 75 #include <packet_client.h> 80 76 #include <packet_remote.h> 81 77 #include <il_local.h> 82 78 83 /** IP module name. */ 84 #define NAME "ip" 85 86 /** IP version 4. */ 87 #define IPV4 4 88 89 /** Default network interface IP version. */ 79 #include "ip.h" 80 #include "ip_module.h" 81 #include "ip_local.h" 82 83 /** IP module name. 84 */ 85 #define NAME "ip" 86 87 /** IP version 4. 88 */ 89 #define IPV4 4 90 91 /** Default network interface IP version. 92 */ 90 93 #define NET_DEFAULT_IPV IPV4 91 94 92 /** Default network interface IP routing. */ 95 /** Default network interface IP routing. 96 */ 93 97 #define NET_DEFAULT_IP_ROUTING false 94 98 95 /** Minimum IP packet content. */ 96 #define IP_MIN_CONTENT 576 97 98 /** ARP module name. */ 99 #define ARP_NAME "arp" 100 101 /** ARP module filename. */ 102 #define ARP_FILENAME "/srv/arp" 103 104 /** IP packet address length. */ 105 #define IP_ADDR sizeof(struct sockaddr_in6) 106 107 /** IP packet prefix length. */ 108 #define IP_PREFIX sizeof(ip_header_t) 109 110 /** IP packet suffix length. */ 111 #define IP_SUFFIX 0 112 113 /** IP packet maximum content length. */ 114 #define IP_MAX_CONTENT 65535 115 116 /** The IP localhost address. */ 99 /** Minimum IP packet content. 100 */ 101 #define IP_MIN_CONTENT 576 102 103 /** ARP module name. 104 */ 105 #define ARP_NAME "arp" 106 107 /** ARP module filename. 108 */ 109 #define ARP_FILENAME "/srv/arp" 110 111 /** IP packet address length. 112 */ 113 #define IP_ADDR sizeof(struct sockaddr_in6) 114 115 /** IP packet prefix length. 116 */ 117 #define IP_PREFIX sizeof(ip_header_t) 118 119 /** IP packet suffix length. 120 */ 121 #define IP_SUFFIX 0 122 123 /** IP packet maximum content length. 124 */ 125 #define IP_MAX_CONTENT 65535 126 127 /** The IP localhost address. 128 */ 117 129 #define IPV4_LOCALHOST_ADDRESS htonl((127 << 24) + 1) 118 130 119 /** IP global data. */ 120 ip_globals_t ip_globals; 121 122 DEVICE_MAP_IMPLEMENT(ip_netifs, ip_netif_t); 123 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 124 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 131 /** IP global data. 132 */ 133 ip_globals_t ip_globals; 134 135 DEVICE_MAP_IMPLEMENT(ip_netifs, ip_netif_t) 136 137 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t) 138 139 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t) 140 141 /** Updates the device content length according to the new MTU value. 142 * @param[in] device_id The device identifier. 143 * @param[in] mtu The new mtu value. 144 * @returns EOK on success. 145 * @returns ENOENT if device is not found. 146 */ 147 int ip_mtu_changed_message(device_id_t device_id, size_t mtu); 148 149 /** Updates the device state. 150 * @param[in] device_id The device identifier. 151 * @param[in] state The new state value. 152 * @returns EOK on success. 153 * @returns ENOENT if device is not found. 154 */ 155 int ip_device_state_message(device_id_t device_id, device_state_t state); 156 157 /** Returns the device packet dimensions for sending. 158 * @param[in] phone The service module phone. 159 * @param[in] message The service specific message. 160 * @param[in] device_id The device identifier. 161 * @param[out] addr_len The minimum reserved address length. 162 * @param[out] prefix The minimum reserved prefix size. 163 * @param[out] content The maximum content size. 164 * @param[out] suffix The minimum reserved suffix size. 165 * @returns EOK on success. 166 */ 167 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix); 168 169 /** Registers the transport layer protocol. 170 * The traffic of this protocol will be supplied using either the receive function or IPC message. 171 * @param[in] protocol The transport layer module protocol. 172 * @param[in] service The transport layer module service. 173 * @param[in] phone The transport layer module phone. 174 * @param[in] tl_received_msg The receiving function. 175 * @returns EOK on success. 176 * @returns EINVAL if the protocol parameter and/or the service parameter is zero (0). 177 * @returns EINVAL if the phone parameter is not a positive number and the tl_receive_msg is NULL. 178 * @returns ENOMEM if there is not enough memory left. 179 */ 180 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg); 181 182 /** Initializes a new network interface specific data. 183 * Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table. 184 * The device identifier and the nil service has to be set. 185 * @param[in,out] ip_netif Network interface specific data. 186 * @returns EOK on success. 187 * @returns ENOTSUP if DHCP is configured. 188 * @returns ENOTSUP if IPv6 is configured. 189 * @returns EINVAL if any of the addresses is invalid. 190 * @returns EINVAL if the used ARP module is not known. 191 * @returns ENOMEM if there is not enough memory left. 192 * @returns Other error codes as defined for the net_get_device_conf_req() function. 193 * @returns Other error codes as defined for the bind_service() function. 194 * @returns Other error codes as defined for the specific arp_device_req() function. 195 * @returns Other error codes as defined for the nil_packet_size_req() function. 196 */ 197 int ip_netif_initialize(ip_netif_ref ip_netif); 198 199 /** Sends the packet or the packet queue via the specified route. 200 * The ICMP_HOST_UNREACH error notification may be sent if route hardware destination address is found. 201 * @param[in,out] packet The packet to be sent. 202 * @param[in] netif The target network interface. 203 * @param[in] route The target route. 204 * @param[in] src The source address. 205 * @param[in] dest The destination address. 206 * @param[in] error The error module service. 207 * @returns EOK on success. 208 * @returns Other error codes as defined for the arp_translate_req() function. 209 * @returns Other error codes as defined for the ip_prepare_packet() function. 210 */ 211 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); 212 213 /** Prepares the outgoing packet or the packet queue. 214 * The packet queue is a fragmented packet 215 * Updates the first packet's IP header. 216 * Prefixes the additional packets with fragment headers. 217 * @param[in] source The source address. 218 * @param[in] dest The destination address. 219 * @param[in,out] packet The packet to be sent. 220 * @param[in] destination The destination hardware address. 221 * @returns EOK on success. 222 * @returns EINVAL if the packet is too small to contain the IP header. 223 * @returns EINVAL if the packet is too long than the IP allows. 224 * @returns ENOMEM if there is not enough memory left. 225 * @returns Other error codes as defined for the packet_set_addr() function. 226 */ 227 int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination); 228 229 /** Checks the packet queue lengths and fragments the packets if needed. 230 * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to be fragmented and the fragmentation is not allowed. 231 * @param[in,out] packet The packet or the packet queue to be checked. 232 * @param[in] prefix The minimum prefix size. 233 * @param[in] content The maximum content size. 234 * @param[in] suffix The minimum suffix size. 235 * @param[in] addr_len The minimum address length. 236 * @param[in] error The error module service. 237 * @returns The packet or the packet queue of the allowed length. 238 * @returns NULL if there are no packets left. 239 */ 240 packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error); 241 242 /** Checks the packet length and fragments it if needed. 243 * The new fragments are queued before the original packet. 244 * @param[in,out] packet The packet to be checked. 245 * @param[in] length The maximum packet length. 246 * @param[in] prefix The minimum prefix size. 247 * @param[in] suffix The minimum suffix size. 248 * @param[in] addr_len The minimum address length. 249 * @returns EOK on success. 250 * @returns EINVAL if the packet_get_addr() function fails. 251 * @returns EINVAL if the packet does not contain the IP header. 252 * @returns EPERM if the packet needs to be fragmented and the fragmentation is not allowed. 253 * @returns ENOMEM if there is not enough memory left. 254 * @returns ENOMEM if there is no packet available. 255 * @returns ENOMEM if the packet is too small to contain the IP header. 256 * @returns Other error codes as defined for the packet_trim() function. 257 * @returns Other error codes as defined for the ip_create_middle_header() function. 258 * @returns Other error codes as defined for the ip_fragment_packet_data() function. 259 */ 260 int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len); 261 262 /** Fragments the packet from the end. 263 * @param[in] packet The packet to be fragmented. 264 * @param[in,out] new_packet The new packet fragment. 265 * @param[in,out] header The original packet header. 266 * @param[in,out] new_header The new packet fragment header. 267 * @param[in] length The new fragment length. 268 * @param[in] src The source address. 269 * @param[in] dest The destiantion address. 270 * @param[in] addrlen The address length. 271 * @returns EOK on success. 272 * @returns ENOMEM if the target packet is too small. 273 * @returns Other error codes as defined for the packet_set_addr() function. 274 * @returns Other error codes as defined for the pq_insert_after() function. 275 */ 276 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); 277 278 /** Prefixes a middle fragment header based on the last fragment header to the packet. 279 * @param[in] packet The packet to be prefixed. 280 * @param[in] last The last header to be copied. 281 * @returns The prefixed middle header. 282 * @returns NULL on error. 283 */ 284 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last); 285 286 /** Copies the fragment header. 287 * Copies only the header itself and relevant IP options. 288 * @param[out] last The created header. 289 * @param[in] first The original header to be copied. 290 */ 291 void ip_create_last_header(ip_header_ref last, ip_header_ref first); 292 293 /** Returns the network interface's IP address. 294 * @param[in] netif The network interface. 295 * @returns The IP address. 296 * @returns NULL if no IP address was found. 297 */ 298 in_addr_t * ip_netif_address(ip_netif_ref netif); 299 300 /** Searches all network interfaces if there is a suitable route. 301 * @param[in] destination The destination address. 302 * @returns The found route. 303 * @returns NULL if no route was found. 304 */ 305 ip_route_ref ip_find_route(in_addr_t destination); 306 307 /** Searches the network interfaces if there is a suitable route. 308 * @param[in] netif The network interface to be searched for routes. May be NULL. 309 * @param[in] destination The destination address. 310 * @returns The found route. 311 * @returns NULL if no route was found. 312 */ 313 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination); 314 315 /** Processes the received IP packet or the packet queue one by one. 316 * The packet is either passed to another module or released on error. 317 * @param[in] device_id The source device identifier. 318 * @param[in,out] packet The received packet. 319 * @returns EOK on success and the packet is no longer needed. 320 * @returns EINVAL if the packet is too small to carry the IP packet. 321 * @returns EINVAL if the received address lengths differs from the registered values. 322 * @returns ENOENT if the device is not found in the cache. 323 * @returns ENOENT if the protocol for the device is not found in the cache. 324 * @returns ENOMEM if there is not enough memory left. 325 */ 326 int ip_receive_message(device_id_t device_id, packet_t packet); 327 328 /** Processes the received packet. 329 * The packet is either passed to another module or released on error. 330 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is invalid. 331 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two (2). 332 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 333 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for another host and the routing is disabled. 334 * @param[in] device_id The source device identifier. 335 * @param[in] packet The received packet to be processed. 336 * @returns EOK on success. 337 * @returns EINVAL if the TTL is less than two (2). 338 * @returns EINVAL if the checksum is invalid. 339 * @returns EAFNOSUPPORT if the address family is not supported. 340 * @returns ENOENT if no route was found. 341 * @returns ENOENT if the packet is for another host and the routing is disabled. 342 */ 343 int ip_process_packet(device_id_t device_id, packet_t packet); 344 345 /** Returns the packet destination address from the IP header. 346 * @param[in] header The packet IP header to be read. 347 * @returns The packet destination address. 348 */ 349 in_addr_t ip_get_destination(ip_header_ref header); 350 351 /** Delivers the packet to the local host. 352 * The packet is either passed to another module or released on error. 353 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not found. 354 * @param[in] device_id The source device identifier. 355 * @param[in] packet The packet to be delivered. 356 * @param[in] header The first packet IP header. May be NULL. 357 * @param[in] error The packet error service. 358 * @returns EOK on success. 359 * @returns ENOTSUP if the packet is a fragment. 360 * @returns EAFNOSUPPORT if the address family is not supported. 361 * @returns ENOENT if the target protocol is not found. 362 * @returns Other error codes as defined for the packet_set_addr() function. 363 * @returns Other error codes as defined for the packet_trim() function. 364 * @returns Other error codes as defined for the protocol specific tl_received_msg function. 365 */ 366 int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error); 367 368 /** Prepares the ICMP notification packet. 369 * Releases additional packets and keeps only the first one. 370 * All packets is released on error. 371 * @param[in] error The packet error service. 372 * @param[in] packet The packet or the packet queue to be reported as faulty. 373 * @param[in] header The first packet IP header. May be NULL. 374 * @returns The found ICMP phone. 375 * @returns EINVAL if the error parameter is set. 376 * @returns EINVAL if the ICMP phone is not found. 377 * @returns EINVAL if the ip_prepare_icmp() fails. 378 */ 379 int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header); 380 381 /** Returns the ICMP phone. 382 * Searches the registered protocols. 383 * @returns The found ICMP phone. 384 * @returns ENOENT if the ICMP is not registered. 385 */ 386 int ip_get_icmp_phone(void); 387 388 /** Prepares the ICMP notification packet. 389 * Releases additional packets and keeps only the first one. 390 * @param[in] packet The packet or the packet queue to be reported as faulty. 391 * @param[in] header The first packet IP header. May be NULL. 392 * @returns EOK on success. 393 * @returns EINVAL if there are no data in the packet. 394 * @returns EINVAL if the packet is a fragment. 395 * @returns ENOMEM if the packet is too short to contain the IP header. 396 * @returns EAFNOSUPPORT if the address family is not supported. 397 * @returns EPERM if the protocol is not allowed to send ICMP notifications. The ICMP protocol itself. 398 * @returns Other error codes as defined for the packet_set_addr(). 399 */ 400 int ip_prepare_icmp(packet_t packet, ip_header_ref header); 125 401 126 402 /** Releases the packet and returns the result. 127 * 128 * @param[in] packet The packet queue to be released. 129 * @param[in] result The result to be returned. 130 * @return The result parameter. 131 */ 132 static int ip_release_and_return(packet_t packet, int result) 133 { 134 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 135 return result; 136 } 137 138 /** Returns the ICMP phone. 139 * 140 * Searches the registered protocols. 141 * 142 * @returns The found ICMP phone. 143 * @returns ENOENT if the ICMP is not registered. 144 */ 145 static int ip_get_icmp_phone(void) 146 { 147 ip_proto_ref proto; 148 int phone; 149 150 fibril_rwlock_read_lock(&ip_globals.protos_lock); 151 proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP); 152 phone = proto ? proto->phone : ENOENT; 153 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 154 return phone; 155 } 156 157 /** Prepares the ICMP notification packet. 158 * 159 * Releases additional packets and keeps only the first one. 160 * 161 * @param[in] packet The packet or the packet queue to be reported as faulty. 162 * @param[in] header The first packet IP header. May be NULL. 163 * @returns EOK on success. 164 * @returns EINVAL if there are no data in the packet. 165 * @returns EINVAL if the packet is a fragment. 166 * @returns ENOMEM if the packet is too short to contain the IP 167 * header. 168 * @returns EAFNOSUPPORT if the address family is not supported. 169 * @returns EPERM if the protocol is not allowed to send ICMP 170 * notifications. The ICMP protocol itself. 171 * @returns Other error codes as defined for the packet_set_addr(). 172 */ 173 static int ip_prepare_icmp(packet_t packet, ip_header_ref header) 174 { 175 packet_t next; 176 struct sockaddr *dest; 177 struct sockaddr_in dest_in; 178 socklen_t addrlen; 179 180 // detach the first packet and release the others 181 next = pq_detach(packet); 182 if (next) 183 pq_release_remote(ip_globals.net_phone, packet_get_id(next)); 184 185 if (!header) { 186 if (packet_get_data_length(packet) <= sizeof(ip_header_t)) 187 return ENOMEM; 188 189 // get header 190 header = (ip_header_ref) packet_get_data(packet); 191 if (!header) 192 return EINVAL; 193 194 } 195 196 // only for the first fragment 197 if (IP_FRAGMENT_OFFSET(header)) 198 return EINVAL; 199 200 // not for the ICMP protocol 201 if (header->protocol == IPPROTO_ICMP) 202 return EPERM; 203 204 // set the destination address 205 switch (header->version) { 206 case IPVERSION: 207 addrlen = sizeof(dest_in); 208 bzero(&dest_in, addrlen); 209 dest_in.sin_family = AF_INET; 210 memcpy(&dest_in.sin_addr.s_addr, &header->source_address, 211 sizeof(header->source_address)); 212 dest = (struct sockaddr *) &dest_in; 213 break; 214 215 default: 216 return EAFNOSUPPORT; 217 } 218 219 return packet_set_addr(packet, NULL, (uint8_t *) dest, addrlen); 220 } 221 222 /** Prepares the ICMP notification packet. 223 * 224 * Releases additional packets and keeps only the first one. 225 * All packets are released on error. 226 * 227 * @param[in] error The packet error service. 228 * @param[in] packet The packet or the packet queue to be reported as faulty. 229 * @param[in] header The first packet IP header. May be NULL. 230 * @returns The found ICMP phone. 231 * @returns EINVAL if the error parameter is set. 232 * @returns EINVAL if the ICMP phone is not found. 233 * @returns EINVAL if the ip_prepare_icmp() fails. 234 */ 235 static int 236 ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, 237 ip_header_ref header) 238 { 239 int phone; 240 241 phone = ip_get_icmp_phone(); 242 if (error || (phone < 0) || ip_prepare_icmp(packet, header)) 243 return ip_release_and_return(packet, EINVAL); 244 return phone; 245 } 246 247 /** Initializes the IP module. 248 * 249 * @param[in] client_connection The client connection processing function. The 250 * module skeleton propagates its own one. 251 * @returns EOK on success. 252 * @returns ENOMEM if there is not enough memory left. 253 */ 254 int ip_initialize(async_client_conn_t client_connection) 255 { 403 * @param[in] packet The packet queue to be released. 404 * @param[in] result The result to be returned. 405 * @return The result parameter. 406 */ 407 int ip_release_and_return(packet_t packet, int result); 408 409 int ip_initialize(async_client_conn_t client_connection){ 256 410 ERROR_DECLARE; 257 411 … … 269 423 ip_globals.client_connection = client_connection; 270 424 ERROR_PROPAGATE(modules_initialize(&ip_globals.modules)); 271 ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, 272 ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module)); 425 ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module)); 273 426 fibril_rwlock_write_unlock(&ip_globals.lock); 274 275 427 return EOK; 276 428 } 277 429 278 /** Initializes a new network interface specific data. 279 * 280 * Connects to the network interface layer module, reads the netif 281 * configuration, starts an ARP module if needed and sets the netif routing 282 * table. 283 * 284 * The device identifier and the nil service has to be set. 285 * 286 * @param[in,out] ip_netif Network interface specific data. 287 * @returns EOK on success. 288 * @returns ENOTSUP if DHCP is configured. 289 * @returns ENOTSUP if IPv6 is configured. 290 * @returns EINVAL if any of the addresses is invalid. 291 * @returns EINVAL if the used ARP module is not known. 292 * @returns ENOMEM if there is not enough memory left. 293 * @returns Other error codes as defined for the 294 * net_get_device_conf_req() function. 295 * @returns Other error codes as defined for the bind_service() 296 * function. 297 * @returns Other error codes as defined for the specific 298 * arp_device_req() function. 299 * @returns Other error codes as defined for the 300 * nil_packet_size_req() function. 301 */ 302 static int ip_netif_initialize(ip_netif_ref ip_netif) 303 { 304 ERROR_DECLARE; 305 306 measured_string_t names[] = { 307 { 308 (char *) "IPV", 309 3 310 }, 311 { 312 (char *) "IP_CONFIG", 313 9 314 }, 315 { 316 (char *) "IP_ADDR", 317 7 318 }, 319 { 320 (char *) "IP_NETMASK", 321 10 322 }, 323 { 324 (char *) "IP_GATEWAY", 325 10 326 }, 327 { 328 (char *) "IP_BROADCAST", 329 12 330 }, 331 { 332 (char *) "ARP", 333 3 334 }, 335 { 336 (char *) "IP_ROUTING", 337 10 338 } 339 }; 340 measured_string_ref configuration; 341 size_t count = sizeof(names) / sizeof(measured_string_t); 342 char *data; 343 measured_string_t address; 344 int index; 345 ip_route_ref route; 346 in_addr_t gateway; 347 348 ip_netif->arp = NULL; 349 route = NULL; 350 ip_netif->ipv = NET_DEFAULT_IPV; 351 ip_netif->dhcp = false; 352 ip_netif->routing = NET_DEFAULT_IP_ROUTING; 353 configuration = &names[0]; 354 355 // get configuration 356 ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone, 357 ip_netif->device_id, &configuration, count, &data)); 358 if (configuration) { 359 if (configuration[0].value) 360 ip_netif->ipv = strtol(configuration[0].value, NULL, 0); 361 362 ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp", 363 configuration[1].length); 364 365 if (ip_netif->dhcp) { 366 // TODO dhcp 367 net_free_settings(configuration, data); 368 return ENOTSUP; 369 } else if (ip_netif->ipv == IPV4) { 370 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 371 if (!route) { 372 net_free_settings(configuration, data); 373 return ENOMEM; 374 } 375 route->address.s_addr = 0; 376 route->netmask.s_addr = 0; 377 route->gateway.s_addr = 0; 378 route->netif = ip_netif; 379 index = ip_routes_add(&ip_netif->routes, route); 380 if (index < 0) { 381 net_free_settings(configuration, data); 382 free(route); 383 return index; 384 } 385 if (ERROR_OCCURRED(inet_pton(AF_INET, 386 configuration[2].value, 387 (uint8_t *) &route->address.s_addr)) || 388 ERROR_OCCURRED(inet_pton(AF_INET, 389 configuration[3].value, 390 (uint8_t *) &route->netmask.s_addr)) || 391 (inet_pton(AF_INET, configuration[4].value, 392 (uint8_t *) &gateway.s_addr) == EINVAL) || 393 (inet_pton(AF_INET, configuration[5].value, 394 (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)) 395 { 396 net_free_settings(configuration, data); 397 return EINVAL; 398 } 399 } else { 400 // TODO ipv6 in separate module 401 net_free_settings(configuration, data); 402 return ENOTSUP; 403 } 404 405 if (configuration[6].value) { 406 ip_netif->arp = get_running_module(&ip_globals.modules, 407 configuration[6].value); 408 if (!ip_netif->arp) { 409 printf("Failed to start the arp %s\n", 410 configuration[6].value); 411 net_free_settings(configuration, data); 412 return EINVAL; 413 } 414 } 415 if (configuration[7].value) 416 ip_netif->routing = (configuration[7].value[0] == 'y'); 417 418 net_free_settings(configuration, data); 419 } 420 421 // binds the netif service which also initializes the device 422 ip_netif->phone = nil_bind_service(ip_netif->service, 423 (ipcarg_t) ip_netif->device_id, SERVICE_IP, 424 ip_globals.client_connection); 425 if (ip_netif->phone < 0) { 426 printf("Failed to contact the nil service %d\n", 427 ip_netif->service); 428 return ip_netif->phone; 429 } 430 431 // has to be after the device netif module initialization 432 if (ip_netif->arp) { 433 if (route) { 434 address.value = (char *) &route->address.s_addr; 435 address.length = CONVERT_SIZE(in_addr_t, char, 1); 436 ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone, 437 ip_netif->device_id, SERVICE_IP, ip_netif->service, 438 &address)); 439 } else { 440 ip_netif->arp = 0; 441 } 442 } 443 444 // get packet dimensions 445 ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone, 446 ip_netif->device_id, &ip_netif->packet_dimension)); 447 if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) { 448 printf("Maximum transmission unit %d bytes is too small, at " 449 "least %d bytes are needed\n", 450 ip_netif->packet_dimension.content, IP_MIN_CONTENT); 451 ip_netif->packet_dimension.content = IP_MIN_CONTENT; 452 } 453 454 index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif); 455 if (index < 0) 456 return index; 457 458 if (gateway.s_addr) { 459 // the default gateway 460 ip_globals.gateway.address.s_addr = 0; 461 ip_globals.gateway.netmask.s_addr = 0; 462 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 463 ip_globals.gateway.netif = ip_netif; 464 } 465 466 return EOK; 467 } 468 469 /** Updates the device content length according to the new MTU value. 470 * 471 * @param[in] device_id The device identifier. 472 * @param[in] mtu The new mtu value. 473 * @returns EOK on success. 474 * @returns ENOENT if device is not found. 475 */ 476 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 477 { 478 ip_netif_ref netif; 479 480 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 481 netif = ip_netifs_find(&ip_globals.netifs, device_id); 482 if (!netif) { 483 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 484 return ENOENT; 485 } 486 netif->packet_dimension.content = mtu; 487 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 488 489 printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu); 490 491 return EOK; 492 } 493 494 /** Updates the device state. 495 * 496 * @param[in] device_id The device identifier. 497 * @param[in] state The new state value. 498 * @returns EOK on success. 499 * @returns ENOENT if device is not found. 500 */ 501 static int ip_device_state_message(device_id_t device_id, device_state_t state) 502 { 503 ip_netif_ref netif; 504 505 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 506 // find the device 507 netif = ip_netifs_find(&ip_globals.netifs, device_id); 508 if (!netif) { 509 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 510 return ENOENT; 511 } 512 netif->state = state; 513 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 514 515 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 516 517 return EOK; 518 } 519 520 521 /** Prefixes a middle fragment header based on the last fragment header to the 522 * packet. 523 * 524 * @param[in] packet The packet to be prefixed. 525 * @param[in] last The last header to be copied. 526 * @returns The prefixed middle header. 527 * @returns NULL on error. 528 */ 529 static ip_header_ref 530 ip_create_middle_header(packet_t packet, ip_header_ref last) 531 { 532 ip_header_ref middle; 533 534 middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last)); 535 if (!middle) 536 return NULL; 537 memcpy(middle, last, IP_HEADER_LENGTH(last)); 538 middle->flags |= IPFLAG_MORE_FRAGMENTS; 539 return middle; 540 } 541 542 /** Copies the fragment header. 543 * 544 * Copies only the header itself and relevant IP options. 545 * 546 * @param[out] last The created header. 547 * @param[in] first The original header to be copied. 548 */ 549 static void ip_create_last_header(ip_header_ref last, ip_header_ref first) 550 { 551 ip_option_ref option; 552 size_t next; 553 size_t length; 554 555 // copy first itself 556 memcpy(last, first, sizeof(ip_header_t)); 557 length = sizeof(ip_header_t); 558 next = sizeof(ip_header_t); 559 560 // process all ip options 561 while (next < first->header_length) { 562 option = (ip_option_ref) (((uint8_t *) first) + next); 563 // skip end or noop 564 if ((option->type == IPOPT_END) || 565 (option->type == IPOPT_NOOP)) { 566 next++; 567 } else { 568 // copy if told so or skip 569 if (IPOPT_COPIED(option->type)) { 570 memcpy(((uint8_t *) last) + length, 571 ((uint8_t *) first) + next, option->length); 572 length += option->length; 573 } 574 // next option 575 next += option->length; 576 } 577 } 578 579 // align 4 byte boundary 580 if (length % 4) { 581 bzero(((uint8_t *) last) + length, 4 - (length % 4)); 582 last->header_length = length / 4 + 1; 583 } else { 584 last->header_length = length / 4; 585 } 586 587 last->header_checksum = 0; 588 } 589 590 /** Prepares the outgoing packet or the packet queue. 591 * 592 * The packet queue is a fragmented packet 593 * Updates the first packet's IP header. 594 * Prefixes the additional packets with fragment headers. 595 * 596 * @param[in] source The source address. 597 * @param[in] dest The destination address. 598 * @param[in,out] packet The packet to be sent. 599 * @param[in] destination The destination hardware address. 600 * @returns EOK on success. 601 * @returns EINVAL if the packet is too small to contain the IP 602 * header. 603 * @returns EINVAL if the packet is too long than the IP allows. 604 * @returns ENOMEM if there is not enough memory left. 605 * @returns Other error codes as defined for the packet_set_addr() 606 * function. 607 */ 608 static int 609 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t packet, 610 measured_string_ref destination) 611 { 612 ERROR_DECLARE; 613 614 size_t length; 615 ip_header_ref header; 616 ip_header_ref last_header; 617 ip_header_ref middle_header; 618 packet_t next; 619 620 length = packet_get_data_length(packet); 621 if ((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT)) 622 return EINVAL; 623 624 header = (ip_header_ref) packet_get_data(packet); 625 if (destination) { 626 ERROR_PROPAGATE(packet_set_addr(packet, NULL, 627 (uint8_t *) destination->value, 628 CONVERT_SIZE(char, uint8_t, destination->length))); 629 } else { 630 ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0)); 631 } 632 header->version = IPV4; 633 header->fragment_offset_high = 0; 634 header->fragment_offset_low = 0; 635 header->header_checksum = 0; 636 if (source) 637 header->source_address = source->s_addr; 638 header->destination_address = dest.s_addr; 639 640 fibril_rwlock_write_lock(&ip_globals.lock); 641 ip_globals.packet_counter++; 642 header->identification = htons(ip_globals.packet_counter); 643 fibril_rwlock_write_unlock(&ip_globals.lock); 644 645 if (pq_next(packet)) { 646 last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header)); 647 if (!last_header) 648 return ENOMEM; 649 ip_create_last_header(last_header, header); 650 next = pq_next(packet); 651 while (pq_next(next)) { 652 middle_header = (ip_header_ref) packet_prefix(next, 653 IP_HEADER_LENGTH(last_header)); 654 if (!middle_header) { 655 free(last_header); 656 return ENOMEM; 657 } 658 659 memcpy(middle_header, last_header, 660 IP_HEADER_LENGTH(last_header)); 661 header->flags |= IPFLAG_MORE_FRAGMENTS; 662 middle_header->total_length = 663 htons(packet_get_data_length(next)); 664 middle_header->fragment_offset_high = 665 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 666 middle_header->fragment_offset_low = 667 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 668 middle_header->header_checksum = 669 IP_HEADER_CHECKSUM(middle_header); 670 if (destination) { 671 if (ERROR_OCCURRED(packet_set_addr(next, NULL, 672 (uint8_t *) destination->value, 673 CONVERT_SIZE(char, uint8_t, 674 destination->length)))) { 675 free(last_header); 676 return ERROR_CODE; 677 } 678 } 679 length += packet_get_data_length(next); 680 next = pq_next(next); 681 } 682 683 middle_header = (ip_header_ref) packet_prefix(next, 684 IP_HEADER_LENGTH(last_header)); 685 if (!middle_header) { 686 free(last_header); 687 return ENOMEM; 688 } 689 690 memcpy(middle_header, last_header, 691 IP_HEADER_LENGTH(last_header)); 692 middle_header->total_length = 693 htons(packet_get_data_length(next)); 694 middle_header->fragment_offset_high = 695 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 696 middle_header->fragment_offset_low = 697 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 698 middle_header->header_checksum = 699 IP_HEADER_CHECKSUM(middle_header); 700 if (destination) { 701 if (ERROR_OCCURRED(packet_set_addr(next, NULL, 702 (uint8_t *) destination->value, 703 CONVERT_SIZE(char, uint8_t, 704 destination->length)))) { 705 free(last_header); 706 return ERROR_CODE; 707 } 708 } 709 length += packet_get_data_length(next); 710 free(last_header); 711 header->flags |= IPFLAG_MORE_FRAGMENTS; 712 } 713 714 header->total_length = htons(length); 715 // unnecessary for all protocols 716 header->header_checksum = IP_HEADER_CHECKSUM(header); 717 718 return EOK; 719 } 720 721 /** Fragments the packet from the end. 722 * 723 * @param[in] packet The packet to be fragmented. 724 * @param[in,out] new_packet The new packet fragment. 725 * @param[in,out] header The original packet header. 726 * @param[in,out] new_header The new packet fragment header. 727 * @param[in] length The new fragment length. 728 * @param[in] src The source address. 729 * @param[in] dest The destiantion address. 730 * @param[in] addrlen The address length. 731 * @returns EOK on success. 732 * @returns ENOMEM if the target packet is too small. 733 * @returns Other error codes as defined for the packet_set_addr() 734 * function. 735 * @returns Other error codes as defined for the pq_insert_after() 736 * function. 737 */ 738 static int 739 ip_fragment_packet_data(packet_t packet, packet_t new_packet, 740 ip_header_ref header, ip_header_ref new_header, size_t length, 741 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) 742 { 743 ERROR_DECLARE; 744 745 void *data; 746 size_t offset; 747 748 data = packet_suffix(new_packet, length); 749 if (!data) 750 return ENOMEM; 751 752 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, 753 length); 754 ERROR_PROPAGATE(packet_trim(packet, 0, length)); 755 header->total_length = htons(IP_TOTAL_LENGTH(header) - length); 756 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); 757 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header); 758 new_header->fragment_offset_high = 759 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset); 760 new_header->fragment_offset_low = 761 IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); 762 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header); 763 ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, 764 (const uint8_t *) dest, addrlen)); 765 766 return pq_insert_after(packet, new_packet); 767 } 768 769 /** Checks the packet length and fragments it if needed. 770 * 771 * The new fragments are queued before the original packet. 772 * 773 * @param[in,out] packet The packet to be checked. 774 * @param[in] length The maximum packet length. 775 * @param[in] prefix The minimum prefix size. 776 * @param[in] suffix The minimum suffix size. 777 * @param[in] addr_len The minimum address length. 778 * @returns EOK on success. 779 * @returns EINVAL if the packet_get_addr() function fails. 780 * @returns EINVAL if the packet does not contain the IP header. 781 * @returns EPERM if the packet needs to be fragmented and the 782 * fragmentation is not allowed. 783 * @returns ENOMEM if there is not enough memory left. 784 * @returns ENOMEM if there is no packet available. 785 * @returns ENOMEM if the packet is too small to contain the IP 786 * header. 787 * @returns Other error codes as defined for the packet_trim() 788 * function. 789 * @returns Other error codes as defined for the 790 * ip_create_middle_header() function. 791 * @returns Other error codes as defined for the 792 * ip_fragment_packet_data() function. 793 */ 794 static int 795 ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, 796 socklen_t addr_len) 797 { 798 ERROR_DECLARE; 799 800 packet_t new_packet; 801 ip_header_ref header; 802 ip_header_ref middle_header; 803 ip_header_ref last_header; 804 struct sockaddr *src; 805 struct sockaddr *dest; 806 socklen_t addrlen; 807 int result; 808 809 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 810 if (result <= 0) 811 return EINVAL; 812 813 addrlen = (socklen_t) result; 814 if (packet_get_data_length(packet) <= sizeof(ip_header_t)) 815 return ENOMEM; 816 817 // get header 818 header = (ip_header_ref) packet_get_data(packet); 819 if (!header) 820 return EINVAL; 821 822 // fragmentation forbidden? 823 if(header->flags & IPFLAG_DONT_FRAGMENT) 824 return EPERM; 825 826 // create the last fragment 827 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, 828 suffix, ((addrlen > addr_len) ? addrlen : addr_len)); 829 if (!new_packet) 830 return ENOMEM; 831 832 // allocate as much as originally 833 last_header = (ip_header_ref) packet_suffix(new_packet, 834 IP_HEADER_LENGTH(header)); 835 if (!last_header) 836 return ip_release_and_return(packet, ENOMEM); 837 838 ip_create_last_header(last_header, header); 839 840 // trim the unused space 841 if (ERROR_OCCURRED(packet_trim(new_packet, 0, 842 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))) { 843 return ip_release_and_return(packet, ERROR_CODE); 844 } 845 846 // biggest multiple of 8 lower than content 847 // TODO even fragmentation? 848 length = length & ~0x7; 849 if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, 850 last_header, 851 ((IP_HEADER_DATA_LENGTH(header) - 852 ((length - IP_HEADER_LENGTH(header)) & ~0x7)) % 853 ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)), src, dest, 854 addrlen))) { 855 return ip_release_and_return(packet, ERROR_CODE); 856 } 857 858 // mark the first as fragmented 859 header->flags |= IPFLAG_MORE_FRAGMENTS; 860 861 // create middle framgents 862 while (IP_TOTAL_LENGTH(header) > length) { 863 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, 864 length, suffix, 865 ((addrlen >= addr_len) ? addrlen : addr_len)); 866 if (!new_packet) 867 return ENOMEM; 868 869 middle_header = ip_create_middle_header(new_packet, 870 last_header); 871 if (!middle_header) 872 return ip_release_and_return(packet, ENOMEM); 873 874 if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, 875 header, middle_header, 876 (length - IP_HEADER_LENGTH(middle_header)) & ~0x7, src, 877 dest, addrlen))) { 878 return ip_release_and_return(packet, ERROR_CODE); 879 } 880 } 881 882 // finish the first fragment 883 header->header_checksum = IP_HEADER_CHECKSUM(header); 884 885 return EOK; 886 } 887 888 /** Checks the packet queue lengths and fragments the packets if needed. 889 * 890 * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to 891 * be fragmented and the fragmentation is not allowed. 892 * 893 * @param[in,out] packet The packet or the packet queue to be checked. 894 * @param[in] prefix The minimum prefix size. 895 * @param[in] content The maximum content size. 896 * @param[in] suffix The minimum suffix size. 897 * @param[in] addr_len The minimum address length. 898 * @param[in] error The error module service. 899 * @returns The packet or the packet queue of the allowed length. 900 * @returns NULL if there are no packets left. 901 */ 902 static packet_t 903 ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, 904 socklen_t addr_len, services_t error) 905 { 906 size_t length; 907 packet_t next; 908 packet_t new_packet; 909 int result; 910 int phone; 911 912 next = packet; 913 // check all packets 914 while (next) { 915 length = packet_get_data_length(next); 916 917 if (length <= content) { 918 next = pq_next(next); 919 continue; 920 } 921 922 // too long 923 result = ip_fragment_packet(next, content, prefix, 924 suffix, addr_len); 925 if (result != EOK) { 926 new_packet = pq_detach(next); 927 if (next == packet) { 928 // the new first packet of the queue 929 packet = new_packet; 930 } 931 // fragmentation needed? 932 if (result == EPERM) { 933 phone = ip_prepare_icmp_and_get_phone( 934 error, next, NULL); 935 if (phone >= 0) { 936 // fragmentation necessary ICMP 937 icmp_destination_unreachable_msg(phone, 938 ICMP_FRAG_NEEDED, content, next); 939 } 940 } else { 941 pq_release_remote(ip_globals.net_phone, 942 packet_get_id(next)); 943 } 944 945 next = new_packet; 946 continue; 947 } 948 949 next = pq_next(next); 950 } 951 952 return packet; 953 } 954 955 /** Sends the packet or the packet queue via the specified route. 956 * 957 * The ICMP_HOST_UNREACH error notification may be sent if route hardware 958 * destination address is found. 959 * 960 * @param[in,out] packet The packet to be sent. 961 * @param[in] netif The target network interface. 962 * @param[in] route The target route. 963 * @param[in] src The source address. 964 * @param[in] dest The destination address. 965 * @param[in] error The error module service. 966 * @returns EOK on success. 967 * @returns Other error codes as defined for the arp_translate_req() 968 * function. 969 * @returns Other error codes as defined for the ip_prepare_packet() 970 * function. 971 */ 972 static int 973 ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, 974 in_addr_t *src, in_addr_t dest, services_t error) 975 { 976 ERROR_DECLARE; 977 978 measured_string_t destination; 979 measured_string_ref translation; 980 char *data; 981 int phone; 982 983 // get destination hardware address 984 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 985 destination.value = route->gateway.s_addr ? 986 (char *) &route->gateway.s_addr : (char *) &dest.s_addr; 987 destination.length = CONVERT_SIZE(dest.s_addr, char, 1); 988 989 if (ERROR_OCCURRED(arp_translate_req(netif->arp->phone, 990 netif->device_id, SERVICE_IP, &destination, &translation, 991 &data))) { 992 pq_release_remote(ip_globals.net_phone, 993 packet_get_id(packet)); 994 return ERROR_CODE; 995 } 996 997 if (!translation || !translation->value) { 998 if (translation) { 999 free(translation); 1000 free(data); 1001 } 1002 phone = ip_prepare_icmp_and_get_phone(error, packet, 1003 NULL); 1004 if (phone >= 0) { 1005 // unreachable ICMP if no routing 1006 icmp_destination_unreachable_msg(phone, 1007 ICMP_HOST_UNREACH, 0, packet); 1008 } 1009 return EINVAL; 1010 } 1011 1012 } else { 1013 translation = NULL; 1014 } 1015 1016 if (ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))) { 1017 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 1018 } else { 1019 packet = ip_split_packet(packet, netif->packet_dimension.prefix, 1020 netif->packet_dimension.content, 1021 netif->packet_dimension.suffix, 1022 netif->packet_dimension.addr_len, error); 1023 if (packet) { 1024 nil_send_msg(netif->phone, netif->device_id, packet, 1025 SERVICE_IP); 1026 } 1027 } 1028 1029 if (translation) { 1030 free(translation); 1031 free(data); 1032 } 1033 1034 return ERROR_CODE; 1035 } 1036 1037 /** Searches the network interfaces if there is a suitable route. 1038 * 1039 * @param[in] netif The network interface to be searched for routes. May be 1040 * NULL. 1041 * @param[in] destination The destination address. 1042 * @returns The found route. 1043 * @returns NULL if no route was found. 1044 */ 1045 static ip_route_ref 1046 ip_netif_find_route(ip_netif_ref netif, in_addr_t destination) 1047 { 1048 int index; 1049 ip_route_ref route; 1050 1051 if (!netif) 1052 return NULL; 1053 1054 // start with the first one - the direct route 1055 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1056 route = ip_routes_get_index(&netif->routes, index); 1057 if (route && 1058 ((route->address.s_addr & route->netmask.s_addr) == 1059 (destination.s_addr & route->netmask.s_addr))) { 1060 return route; 1061 } 1062 } 1063 1064 return NULL; 1065 } 1066 1067 /** Searches all network interfaces if there is a suitable route. 1068 * 1069 * @param[in] destination The destination address. 1070 * @returns The found route. 1071 * @returns NULL if no route was found. 1072 */ 1073 static ip_route_ref ip_find_route(in_addr_t destination) { 1074 int index; 1075 ip_route_ref route; 1076 ip_netif_ref netif; 1077 1078 // start with the last netif - the newest one 1079 index = ip_netifs_count(&ip_globals.netifs) - 1; 1080 while (index >= 0) { 1081 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1082 if (netif && (netif->state == NETIF_ACTIVE)) { 1083 route = ip_netif_find_route(netif, destination); 1084 if (route) 1085 return route; 1086 } 1087 index--; 1088 } 1089 1090 return &ip_globals.gateway; 1091 } 1092 1093 /** Returns the network interface's IP address. 1094 * 1095 * @param[in] netif The network interface. 1096 * @returns The IP address. 1097 * @returns NULL if no IP address was found. 1098 */ 1099 static in_addr_t *ip_netif_address(ip_netif_ref netif) 1100 { 1101 ip_route_ref route; 1102 1103 route = ip_routes_get_index(&netif->routes, 0); 1104 return route ? &route->address : NULL; 1105 } 1106 1107 /** Registers the transport layer protocol. 1108 * 1109 * The traffic of this protocol will be supplied using either the receive 1110 * function or IPC message. 1111 * 1112 * @param[in] protocol The transport layer module protocol. 1113 * @param[in] service The transport layer module service. 1114 * @param[in] phone The transport layer module phone. 1115 * @param[in] received_msg The receiving function. 1116 * @returns EOK on success. 1117 * @returns EINVAL if the protocol parameter and/or the service 1118 * parameter is zero. 1119 * @returns EINVAL if the phone parameter is not a positive number 1120 * and the tl_receive_msg is NULL. 1121 * @returns ENOMEM if there is not enough memory left. 1122 */ 1123 static int 1124 ip_register(int protocol, services_t service, int phone, 1125 tl_received_msg_t received_msg) 1126 { 1127 ip_proto_ref proto; 1128 int index; 1129 1130 if (!protocol || !service || ((phone < 0) && !received_msg)) 1131 return EINVAL; 1132 1133 proto = (ip_proto_ref) malloc(sizeof(ip_protos_t)); 1134 if (!proto) 1135 return ENOMEM; 1136 1137 proto->protocol = protocol; 1138 proto->service = service; 1139 proto->phone = phone; 1140 proto->received_msg = received_msg; 1141 1142 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1143 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1144 if (index < 0) { 1145 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1146 free(proto); 1147 return index; 1148 } 1149 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1150 1151 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1152 NAME, proto->protocol, proto->phone); 1153 1154 return EOK; 1155 } 1156 1157 static int 1158 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1159 { 430 int ip_device_req_local(int il_phone, device_id_t device_id, services_t netif){ 1160 431 ERROR_DECLARE; 1161 432 … … 1165 436 1166 437 ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t)); 1167 if (!ip_netif)438 if(! ip_netif){ 1168 439 return ENOMEM; 1169 1170 if (ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))){440 } 441 if(ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))){ 1171 442 free(ip_netif); 1172 443 return ERROR_CODE; 1173 444 } 1174 1175 445 ip_netif->device_id = device_id; 1176 446 ip_netif->service = netif; 1177 447 ip_netif->state = NETIF_STOPPED; 1178 1179 448 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1180 if (ERROR_OCCURRED(ip_netif_initialize(ip_netif))){449 if(ERROR_OCCURRED(ip_netif_initialize(ip_netif))){ 1181 450 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1182 451 ip_routes_destroy(&ip_netif->routes); … … 1184 453 return ERROR_CODE; 1185 454 } 1186 if (ip_netif->arp)1187 ip_netif->arp->usage++;1188 455 if(ip_netif->arp){ 456 ++ ip_netif->arp->usage; 457 } 1189 458 // print the settings 1190 459 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", … … 1198 467 char gateway[INET_ADDRSTRLEN]; 1199 468 1200 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++){469 for (index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){ 1201 470 route = ip_routes_get_index(&ip_netif->routes, index); 1202 471 if (route) { 1203 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1204 address, INET_ADDRSTRLEN); 1205 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1206 netmask, INET_ADDRSTRLEN); 1207 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1208 gateway, INET_ADDRSTRLEN); 1209 printf("%s: Route %d (address: %s, netmask: %s, " 1210 "gateway: %s)\n", NAME, index, address, netmask, 1211 gateway); 472 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, address, INET_ADDRSTRLEN); 473 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, netmask, INET_ADDRSTRLEN); 474 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, gateway, INET_ADDRSTRLEN); 475 printf("%s: Route %d (address: %s, netmask: %s, gateway: %s)\n", 476 NAME, index, address, netmask, gateway); 1212 477 } 1213 478 } 1214 479 1215 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1216 INET_ADDRSTRLEN); 480 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, INET_ADDRSTRLEN); 481 printf("%s: Broadcast (%s)\n", NAME, address); 482 1217 483 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1218 1219 printf("%s: Broadcast (%s)\n", NAME, address);1220 1221 484 return EOK; 1222 485 } 1223 486 1224 static int 1225 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t packet, 1226 services_t sender, services_t error) 1227 { 487 int ip_netif_initialize(ip_netif_ref ip_netif){ 488 ERROR_DECLARE; 489 490 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}}; 491 measured_string_ref configuration; 492 size_t count = sizeof(names) / sizeof(measured_string_t); 493 char * data; 494 measured_string_t address; 495 int index; 496 ip_route_ref route; 497 in_addr_t gateway; 498 499 ip_netif->arp = NULL; 500 route = NULL; 501 ip_netif->ipv = NET_DEFAULT_IPV; 502 ip_netif->dhcp = false; 503 ip_netif->routing = NET_DEFAULT_IP_ROUTING; 504 configuration = &names[0]; 505 // get configuration 506 ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, &configuration, count, &data)); 507 if(configuration){ 508 if(configuration[0].value){ 509 ip_netif->ipv = strtol(configuration[0].value, NULL, 0); 510 } 511 ip_netif->dhcp = ! str_lcmp(configuration[1].value, "dhcp", configuration[1].length); 512 if(ip_netif->dhcp){ 513 // TODO dhcp 514 net_free_settings(configuration, data); 515 return ENOTSUP; 516 }else if(ip_netif->ipv == IPV4){ 517 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 518 if(! route){ 519 net_free_settings(configuration, data); 520 return ENOMEM; 521 } 522 route->address.s_addr = 0; 523 route->netmask.s_addr = 0; 524 route->gateway.s_addr = 0; 525 route->netif = ip_netif; 526 index = ip_routes_add(&ip_netif->routes, route); 527 if(index < 0){ 528 net_free_settings(configuration, data); 529 free(route); 530 return index; 531 } 532 if(ERROR_OCCURRED(inet_pton(AF_INET, configuration[2].value, (uint8_t *) &route->address.s_addr)) 533 || ERROR_OCCURRED(inet_pton(AF_INET, configuration[3].value, (uint8_t *) &route->netmask.s_addr)) 534 || (inet_pton(AF_INET, configuration[4].value, (uint8_t *) &gateway.s_addr) == EINVAL) 535 || (inet_pton(AF_INET, configuration[5].value, (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)){ 536 net_free_settings(configuration, data); 537 return EINVAL; 538 } 539 }else{ 540 // TODO ipv6 in separate module 541 net_free_settings(configuration, data); 542 return ENOTSUP; 543 } 544 if(configuration[6].value){ 545 ip_netif->arp = get_running_module(&ip_globals.modules, configuration[6].value); 546 if(! ip_netif->arp){ 547 printf("Failed to start the arp %s\n", configuration[6].value); 548 net_free_settings(configuration, data); 549 return EINVAL; 550 } 551 } 552 if(configuration[7].value){ 553 ip_netif->routing = (configuration[7].value[0] == 'y'); 554 } 555 net_free_settings(configuration, data); 556 } 557 // binds the netif service which also initializes the device 558 ip_netif->phone = nil_bind_service(ip_netif->service, (ipcarg_t) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection); 559 if(ip_netif->phone < 0){ 560 printf("Failed to contact the nil service %d\n", ip_netif->service); 561 return ip_netif->phone; 562 } 563 // has to be after the device netif module initialization 564 if(ip_netif->arp){ 565 if(route){ 566 address.value = (char *) &route->address.s_addr; 567 address.length = CONVERT_SIZE(in_addr_t, char, 1); 568 ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, &address)); 569 }else{ 570 ip_netif->arp = 0; 571 } 572 } 573 // get packet dimensions 574 ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone, ip_netif->device_id, &ip_netif->packet_dimension)); 575 if(ip_netif->packet_dimension.content < IP_MIN_CONTENT){ 576 printf("Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT); 577 ip_netif->packet_dimension.content = IP_MIN_CONTENT; 578 } 579 index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif); 580 if(index < 0){ 581 return index; 582 } 583 if(gateway.s_addr){ 584 // the default gateway 585 ip_globals.gateway.address.s_addr = 0; 586 ip_globals.gateway.netmask.s_addr = 0; 587 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 588 ip_globals.gateway.netif = ip_netif; 589 } 590 return EOK; 591 } 592 593 int ip_mtu_changed_message(device_id_t device_id, size_t mtu){ 594 ip_netif_ref netif; 595 596 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 597 netif = ip_netifs_find(&ip_globals.netifs, device_id); 598 if(! netif){ 599 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 600 return ENOENT; 601 } 602 netif->packet_dimension.content = mtu; 603 printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu); 604 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 605 return EOK; 606 } 607 608 int ip_device_state_message(device_id_t device_id, device_state_t state){ 609 ip_netif_ref netif; 610 611 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 612 // find the device 613 netif = ip_netifs_find(&ip_globals.netifs, device_id); 614 if(! netif){ 615 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 616 return ENOENT; 617 } 618 netif->state = state; 619 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 620 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 621 return EOK; 622 } 623 624 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t received_msg){ 625 ip_proto_ref proto; 626 int index; 627 628 if(!(protocol && service && ((phone > 0) || (received_msg)))){ 629 return EINVAL; 630 } 631 proto = (ip_proto_ref) malloc(sizeof(ip_protos_t)); 632 if(! proto){ 633 return ENOMEM; 634 } 635 proto->protocol = protocol; 636 proto->service = service; 637 proto->phone = phone; 638 proto->received_msg = received_msg; 639 fibril_rwlock_write_lock(&ip_globals.protos_lock); 640 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 641 if(index < 0){ 642 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 643 free(proto); 644 return index; 645 } 646 647 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 648 NAME, proto->protocol, proto->phone); 649 650 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 651 return EOK; 652 } 653 654 int ip_send_msg_local(int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){ 1228 655 ERROR_DECLARE; 1229 656 … … 1231 658 ip_netif_ref netif; 1232 659 ip_route_ref route; 1233 struct sockaddr *addr; 1234 struct sockaddr_in *address_in; 1235 in_addr_t *dest; 1236 in_addr_t *src; 660 struct sockaddr * addr; 661 struct sockaddr_in * address_in; 662 // struct sockaddr_in6 * address_in6; 663 in_addr_t * dest; 664 in_addr_t * src; 1237 665 int phone; 1238 666 … … 1240 668 // should be the next hop address or the target destination address 1241 669 addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr); 1242 if (addrlen < 0)670 if(addrlen < 0){ 1243 671 return ip_release_and_return(packet, addrlen); 1244 if ((size_t) addrlen < sizeof(struct sockaddr)) 672 } 673 if((size_t) addrlen < sizeof(struct sockaddr)){ 1245 674 return ip_release_and_return(packet, EINVAL); 1246 1247 switch (addr->sa_family) { 1248 case AF_INET: 1249 if (addrlen != sizeof(struct sockaddr_in)) 1250 return ip_release_and_return(packet, EINVAL); 1251 address_in = (struct sockaddr_in *) addr; 1252 dest = &address_in->sin_addr; 1253 if (!dest->s_addr) 1254 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1255 break; 1256 case AF_INET6: 1257 default: 1258 return ip_release_and_return(packet, EAFNOSUPPORT); 1259 } 1260 675 } 676 switch(addr->sa_family){ 677 case AF_INET: 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){ 684 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 685 } 686 break; 687 // TODO IPv6 688 /* case AF_INET6: 689 if(addrlen != sizeof(struct sockaddr_in6)){ 690 return EINVAL; 691 } 692 address_in6 = (struct sockaddr_in6 *) dest; 693 address_in6.sin6_addr.s6_addr; 694 IPV6_LOCALHOST_ADDRESS; 695 */ default: 696 return ip_release_and_return(packet, EAFNOSUPPORT); 697 } 1261 698 netif = NULL; 1262 699 route = NULL; 1263 700 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1264 1265 701 // device specified? 1266 if (device_id > 0){702 if(device_id > 0){ 1267 703 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1268 704 route = ip_netif_find_route(netif, * dest); 1269 if (netif && !route && (ip_globals.gateway.netif == netif))705 if(netif && (! route) && (ip_globals.gateway.netif == netif)){ 1270 706 route = &ip_globals.gateway; 1271 }1272 1273 if (!route){707 } 708 } 709 if(! route){ 1274 710 route = ip_find_route(*dest); 1275 711 netif = route ? route->netif : NULL; 1276 712 } 1277 if (!netif || !route){713 if(!(netif && route)){ 1278 714 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1279 715 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 1280 if (phone >= 0){716 if(phone >= 0){ 1281 717 // unreachable ICMP if no routing 1282 icmp_destination_unreachable_msg(phone, 1283 ICMP_NET_UNREACH, 0, packet); 718 icmp_destination_unreachable_msg(phone, ICMP_NET_UNREACH, 0, packet); 1284 719 } 1285 720 return ENOENT; 1286 721 } 1287 1288 if (error) { 1289 // do not send for broadcast, anycast packets or network 1290 // broadcast 1291 if (!dest->s_addr || !(~dest->s_addr) || 1292 !(~((dest->s_addr & ~route->netmask.s_addr) | 1293 route->netmask.s_addr)) || 1294 (!(dest->s_addr & ~route->netmask.s_addr))) { 722 if(error){ 723 // do not send for broadcast, anycast packets or network broadcast 724 if((! dest->s_addr) 725 || (!(~ dest->s_addr)) 726 || (!(~((dest->s_addr &(~ route->netmask.s_addr)) | route->netmask.s_addr))) 727 || (!(dest->s_addr &(~ route->netmask.s_addr)))){ 1295 728 return ip_release_and_return(packet, EINVAL); 1296 729 } 1297 730 } 1298 1299 731 // if the local host is the destination 1300 if ((route->address.s_addr == dest->s_addr) &&1301 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){732 if((route->address.s_addr == dest->s_addr) 733 && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){ 1302 734 // find the loopback device to deliver 1303 735 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1304 736 route = ip_find_route(*dest); 1305 737 netif = route ? route->netif : NULL; 1306 if (!netif || !route){738 if(!(netif && route)){ 1307 739 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1308 phone = ip_prepare_icmp_and_get_phone(error, packet, 1309 NULL); 1310 if (phone >= 0) { 740 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 741 if(phone >= 0){ 1311 742 // unreachable ICMP if no routing 1312 icmp_destination_unreachable_msg(phone, 1313 ICMP_HOST_UNREACH, 0, packet); 743 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 1314 744 } 1315 745 return ENOENT; 1316 746 } 1317 747 } 1318 1319 748 src = ip_netif_address(netif); 1320 if (!src){749 if(! src){ 1321 750 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1322 751 return ip_release_and_return(packet, ENOENT); 1323 752 } 1324 1325 ERROR_CODE = ip_send_route(packet, netif, route, src, *dest, error); 753 ERROR_CODE = ip_send_route(packet, netif, route, src, * dest, error); 1326 754 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1327 1328 755 return ERROR_CODE; 1329 756 } 1330 757 1331 /** Returns the device packet dimensions for sending. 1332 * 1333 * @param[in] phone The service module phone. 1334 * @param[in] message The service specific message. 1335 * @param[in] device_id The device identifier. 1336 * @param[out] addr_len The minimum reserved address length. 1337 * @param[out] prefix The minimum reserved prefix size. 1338 * @param[out] content The maximum content size. 1339 * @param[out] suffix The minimum reserved suffix size. 1340 * @returns EOK on success. 1341 */ 1342 static int 1343 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1344 size_t *content, size_t *suffix) 1345 { 1346 ip_netif_ref netif; 1347 int index; 1348 1349 if (!addr_len || !prefix || !content || !suffix) 1350 return EBADMEM; 1351 1352 *content = IP_MAX_CONTENT - IP_PREFIX; 1353 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1354 if (device_id < 0) { 1355 *addr_len = IP_ADDR; 1356 *prefix = 0; 1357 *suffix = 0; 1358 1359 for (index = ip_netifs_count(&ip_globals.netifs) - 1; 1360 index >= 0; index--) { 1361 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1362 if (!netif) 1363 continue; 1364 1365 if (netif->packet_dimension.addr_len > *addr_len) 1366 *addr_len = netif->packet_dimension.addr_len; 1367 1368 if (netif->packet_dimension.prefix > *prefix) 1369 *prefix = netif->packet_dimension.prefix; 1370 1371 if (netif->packet_dimension.suffix > *suffix) 1372 *suffix = netif->packet_dimension.suffix; 1373 } 1374 1375 *prefix = *prefix + IP_PREFIX; 1376 *suffix = *suffix + IP_SUFFIX; 1377 } else { 1378 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1379 if (!netif) { 1380 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1381 return ENOENT; 1382 } 1383 1384 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? 1385 netif->packet_dimension.addr_len : IP_ADDR; 1386 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 1387 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 1388 } 1389 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1390 758 in_addr_t * ip_netif_address(ip_netif_ref netif){ 759 ip_route_ref route; 760 761 route = ip_routes_get_index(&netif->routes, 0); 762 return route ? &route->address : NULL; 763 } 764 765 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){ 766 ERROR_DECLARE; 767 768 measured_string_t destination; 769 measured_string_ref translation; 770 char * data; 771 int phone; 772 773 // get destination hardware address 774 if(netif->arp && (route->address.s_addr != dest.s_addr)){ 775 destination.value = route->gateway.s_addr ? (char *) &route->gateway.s_addr : (char *) &dest.s_addr; 776 destination.length = CONVERT_SIZE(dest.s_addr, char, 1); 777 if(ERROR_OCCURRED(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data))){ 778 // sleep(1); 779 // ERROR_PROPAGATE(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data)); 780 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 781 return ERROR_CODE; 782 } 783 if(!(translation && translation->value)){ 784 if(translation){ 785 free(translation); 786 free(data); 787 } 788 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 789 if(phone >= 0){ 790 // unreachable ICMP if no routing 791 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 792 } 793 return EINVAL; 794 } 795 }else translation = NULL; 796 if(ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))){ 797 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 798 }else{ 799 packet = ip_split_packet(packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error); 800 if(packet){ 801 nil_send_msg(netif->phone, netif->device_id, packet, SERVICE_IP); 802 } 803 } 804 if(translation){ 805 free(translation); 806 free(data); 807 } 808 return ERROR_CODE; 809 } 810 811 int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination){ 812 ERROR_DECLARE; 813 814 size_t length; 815 ip_header_ref header; 816 ip_header_ref last_header; 817 ip_header_ref middle_header; 818 packet_t next; 819 820 length = packet_get_data_length(packet); 821 if((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT)){ 822 return EINVAL; 823 } 824 header = (ip_header_ref) packet_get_data(packet); 825 if(destination){ 826 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 827 }else{ 828 ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0)); 829 } 830 header->version = IPV4; 831 header->fragment_offset_high = 0; 832 header->fragment_offset_low = 0; 833 header->header_checksum = 0; 834 if(source){ 835 header->source_address = source->s_addr; 836 } 837 header->destination_address = dest.s_addr; 838 fibril_rwlock_write_lock(&ip_globals.lock); 839 ++ ip_globals.packet_counter; 840 header->identification = htons(ip_globals.packet_counter); 841 fibril_rwlock_write_unlock(&ip_globals.lock); 842 // length = packet_get_data_length(packet); 843 if(pq_next(packet)){ 844 last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header)); 845 if(! last_header){ 846 return ENOMEM; 847 } 848 ip_create_last_header(last_header, header); 849 next = pq_next(packet); 850 while(pq_next(next)){ 851 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 852 if(! middle_header){ 853 return ENOMEM; 854 } 855 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 856 header->flags |= IPFLAG_MORE_FRAGMENTS; 857 middle_header->total_length = htons(packet_get_data_length(next)); 858 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 859 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 860 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 861 if(destination){ 862 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 863 } 864 length += packet_get_data_length(next); 865 next = pq_next(next); 866 } 867 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 868 if(! middle_header){ 869 return ENOMEM; 870 } 871 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 872 middle_header->total_length = htons(packet_get_data_length(next)); 873 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 874 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 875 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 876 if(destination){ 877 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 878 } 879 length += packet_get_data_length(next); 880 free(last_header); 881 header->flags |= IPFLAG_MORE_FRAGMENTS; 882 } 883 header->total_length = htons(length); 884 // unnecessary for all protocols 885 header->header_checksum = IP_HEADER_CHECKSUM(header); 1391 886 return EOK; 1392 887 } 1393 888 1394 /** Returns the packet destination address from the IP header. 1395 * 1396 * @param[in] header The packet IP header to be read. 1397 * @returns The packet destination address. 1398 */ 1399 static in_addr_t ip_get_destination(ip_header_ref header) 1400 { 1401 in_addr_t destination; 1402 1403 // TODO search set ipopt route? 1404 destination.s_addr = header->destination_address; 1405 return destination; 1406 } 1407 1408 /** Delivers the packet to the local host. 1409 * 1410 * The packet is either passed to another module or released on error. 1411 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1412 * found. 1413 * 1414 * @param[in] device_id The source device identifier. 1415 * @param[in] packet The packet to be delivered. 1416 * @param[in] header The first packet IP header. May be NULL. 1417 * @param[in] error The packet error service. 1418 * @returns EOK on success. 1419 * @returns ENOTSUP if the packet is a fragment. 1420 * @returns EAFNOSUPPORT if the address family is not supported. 1421 * @returns ENOENT if the target protocol is not found. 1422 * @returns Other error codes as defined for the packet_set_addr() 1423 * function. 1424 * @returns Other error codes as defined for the packet_trim() 1425 * function. 1426 * @returns Other error codes as defined for the protocol specific 1427 * tl_received_msg() function. 1428 */ 1429 static int 1430 ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, 1431 services_t error) 1432 { 1433 ERROR_DECLARE; 1434 1435 ip_proto_ref proto; 1436 int phone; 1437 services_t service; 1438 tl_received_msg_t received_msg; 1439 struct sockaddr *src; 1440 struct sockaddr *dest; 1441 struct sockaddr_in src_in; 1442 struct sockaddr_in dest_in; 1443 socklen_t addrlen; 1444 1445 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1446 IP_FRAGMENT_OFFSET(header)) { 1447 // TODO fragmented 1448 return ENOTSUP; 1449 } 1450 1451 switch (header->version) { 1452 case IPVERSION: 1453 addrlen = sizeof(src_in); 1454 bzero(&src_in, addrlen); 1455 src_in.sin_family = AF_INET; 1456 memcpy(&dest_in, &src_in, addrlen); 1457 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1458 sizeof(header->source_address)); 1459 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1460 sizeof(header->destination_address)); 1461 src = (struct sockaddr *) &src_in; 1462 dest = (struct sockaddr *) &dest_in; 1463 break; 1464 1465 default: 1466 return ip_release_and_return(packet, EAFNOSUPPORT); 1467 } 1468 1469 if (ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src, 1470 (uint8_t *) dest, addrlen))) { 1471 return ip_release_and_return(packet, ERROR_CODE); 1472 } 1473 1474 // trim padding if present 1475 if (!error && 1476 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1477 if (ERROR_OCCURRED(packet_trim(packet, 0, 1478 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))) 1479 return ip_release_and_return(packet, ERROR_CODE); 1480 } 1481 1482 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1483 1484 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1485 if (!proto) { 1486 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1487 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1488 if (phone >= 0) { 1489 // unreachable ICMP 1490 icmp_destination_unreachable_msg(phone, 1491 ICMP_PROT_UNREACH, 0, packet); 1492 } 1493 return ENOENT; 1494 } 1495 1496 if (proto->received_msg) { 1497 service = proto->service; 1498 received_msg = proto->received_msg; 1499 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1500 ERROR_CODE = received_msg(device_id, packet, service, error); 1501 } else { 1502 ERROR_CODE = tl_received_msg(proto->phone, device_id, packet, 1503 proto->service, error); 1504 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1505 } 1506 1507 return ERROR_CODE; 1508 } 1509 1510 /** Processes the received packet. 1511 * 1512 * The packet is either passed to another module or released on error. 1513 * 1514 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1515 * invalid. 1516 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1517 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1518 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1519 * another host and the routing is disabled. 1520 * 1521 * @param[in] device_id The source device identifier. 1522 * @param[in] packet The received packet to be processed. 1523 * @returns EOK on success. 1524 * @returns EINVAL if the TTL is less than two. 1525 * @returns EINVAL if the checksum is invalid. 1526 * @returns EAFNOSUPPORT if the address family is not supported. 1527 * @returns ENOENT if no route was found. 1528 * @returns ENOENT if the packet is for another host and the routing 1529 * is disabled. 1530 */ 1531 static int 1532 ip_process_packet(device_id_t device_id, packet_t packet) 1533 { 1534 ERROR_DECLARE; 1535 1536 ip_header_ref header; 1537 in_addr_t dest; 1538 ip_route_ref route; 1539 int phone; 1540 struct sockaddr *addr; 1541 struct sockaddr_in addr_in; 1542 socklen_t addrlen; 1543 1544 header = (ip_header_ref) packet_get_data(packet); 1545 if (!header) 1546 return ip_release_and_return(packet, ENOMEM); 1547 1548 // checksum 1549 if ((header->header_checksum) && 1550 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1551 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1552 if (phone >= 0) { 1553 // checksum error ICMP 1554 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1555 ((size_t) ((void *) &header->header_checksum)) - 1556 ((size_t) ((void *) header)), packet); 1557 } 1558 return EINVAL; 1559 } 1560 1561 if (header->ttl <= 1) { 1562 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1563 if (phone >= 0) { 1564 // ttl exceeded ICMP 1565 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1566 } 1567 return EINVAL; 1568 } 1569 1570 // process ipopt and get destination 1571 dest = ip_get_destination(header); 1572 1573 // set the addrination address 1574 switch (header->version) { 1575 case IPVERSION: 1576 addrlen = sizeof(addr_in); 1577 bzero(&addr_in, addrlen); 1578 addr_in.sin_family = AF_INET; 1579 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1580 addr = (struct sockaddr *) &addr_in; 1581 break; 1582 1583 default: 1584 return ip_release_and_return(packet, EAFNOSUPPORT); 1585 } 1586 1587 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr, 1588 addrlen)); 1589 1590 route = ip_find_route(dest); 1591 if (!route) { 1592 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1593 if (phone >= 0) { 1594 // unreachable ICMP 1595 icmp_destination_unreachable_msg(phone, 1596 ICMP_HOST_UNREACH, 0, packet); 1597 } 1598 return ENOENT; 1599 } 1600 1601 if (route->address.s_addr == dest.s_addr) { 1602 // local delivery 1603 return ip_deliver_local(device_id, packet, header, 0); 1604 } 1605 1606 if (route->netif->routing) { 1607 header->ttl--; 1608 return ip_send_route(packet, route->netif, route, NULL, dest, 1609 0); 1610 } 1611 1612 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1613 if (phone >= 0) { 1614 // unreachable ICMP if no routing 1615 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1616 packet); 1617 } 1618 1619 return ENOENT; 1620 } 1621 1622 static int 1623 ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, 1624 in_addr_t netmask, in_addr_t gateway) 1625 { 1626 ip_route_ref route; 1627 ip_netif_ref netif; 1628 int index; 1629 1630 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1631 1632 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1633 if (!netif) { 1634 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1635 return ENOENT; 1636 } 1637 1638 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 1639 if (!route) { 1640 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1641 return ENOMEM; 1642 } 1643 1644 route->address.s_addr = address.s_addr; 1645 route->netmask.s_addr = netmask.s_addr; 1646 route->gateway.s_addr = gateway.s_addr; 1647 route->netif = netif; 1648 index = ip_routes_add(&netif->routes, route); 1649 if (index < 0) 1650 free(route); 1651 1652 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1653 1654 return index; 1655 } 1656 1657 static int 1658 ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway) 1659 { 1660 ip_netif_ref netif; 1661 1662 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1663 1664 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1665 if (!netif) { 1666 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1667 return ENOENT; 1668 } 1669 1670 ip_globals.gateway.address.s_addr = 0; 1671 ip_globals.gateway.netmask.s_addr = 0; 1672 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 1673 ip_globals.gateway.netif = netif; 1674 1675 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1676 1677 return EOK; 1678 } 1679 1680 /** Notify the IP module about the received error notification packet. 1681 * 1682 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 1683 * @param[in] device_id The device identifier. 1684 * @param[in] packet The received packet or the received packet queue. 1685 * @param[in] target The target internetwork module service to be 1686 * delivered to. 1687 * @param[in] error The packet error reporting service. Prefixes the 1688 * received packet. 1689 * @return EOK on success. 1690 * 1691 */ 1692 static int 1693 ip_received_error_msg_local(int ip_phone, device_id_t device_id, 1694 packet_t packet, services_t target, services_t error) 1695 { 1696 uint8_t *data; 1697 int offset; 1698 icmp_type_t type; 1699 icmp_code_t code; 1700 ip_netif_ref netif; 1701 measured_string_t address; 1702 ip_route_ref route; 1703 ip_header_ref header; 1704 1705 switch (error) { 1706 case SERVICE_ICMP: 1707 offset = icmp_client_process_packet(packet, &type, &code, NULL, 1708 NULL); 1709 if (offset < 0) 1710 return ip_release_and_return(packet, ENOMEM); 1711 1712 data = packet_get_data(packet); 1713 header = (ip_header_ref)(data + offset); 1714 1715 // destination host unreachable? 1716 if ((type != ICMP_DEST_UNREACH) || 1717 (code != ICMP_HOST_UNREACH)) { 1718 // no, something else 1719 break; 1720 } 1721 1722 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1723 1724 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1725 if (!netif || !netif->arp) { 1726 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1727 break; 1728 } 1729 1730 route = ip_routes_get_index(&netif->routes, 0); 1731 1732 // from the same network? 1733 if (route && ((route->address.s_addr & route->netmask.s_addr) == 1734 (header->destination_address & route->netmask.s_addr))) { 1735 // clear the ARP mapping if any 1736 address.value = (char *) &header->destination_address; 1737 address.length = CONVERT_SIZE(uint8_t, char, 1738 sizeof(header->destination_address)); 1739 arp_clear_address_req(netif->arp->phone, 1740 netif->device_id, SERVICE_IP, &address); 1741 } 1742 1743 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1744 break; 1745 1746 default: 1747 return ip_release_and_return(packet, ENOTSUP); 1748 } 1749 1750 return ip_deliver_local(device_id, packet, header, error); 1751 } 1752 1753 static int 1754 ip_get_route_req_local(int ip_phone, ip_protocol_t protocol, 1755 const struct sockaddr *destination, socklen_t addrlen, 1756 device_id_t *device_id, void **header, size_t *headerlen) 1757 { 1758 struct sockaddr_in *address_in; 1759 in_addr_t *dest; 1760 in_addr_t *src; 1761 ip_route_ref route; 1762 ipv4_pseudo_header_ref header_in; 1763 1764 if (!destination || (addrlen <= 0)) 1765 return EINVAL; 1766 1767 if (!device_id || !header || !headerlen) 1768 return EBADMEM; 1769 1770 if ((size_t) addrlen < sizeof(struct sockaddr)) 1771 return EINVAL; 1772 1773 switch (destination->sa_family) { 1774 case AF_INET: 1775 if (addrlen != sizeof(struct sockaddr_in)) 1776 return EINVAL; 1777 address_in = (struct sockaddr_in *) destination; 1778 dest = &address_in->sin_addr; 1779 if (!dest->s_addr) 1780 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1781 break; 1782 1783 case AF_INET6: 1784 default: 1785 return EAFNOSUPPORT; 1786 } 1787 1788 fibril_rwlock_read_lock(&ip_globals.lock); 1789 route = ip_find_route(*dest); 1790 // if the local host is the destination 1791 if (route && (route->address.s_addr == dest->s_addr) && 1792 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) { 1793 // find the loopback device to deliver 1794 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1795 route = ip_find_route(*dest); 1796 } 1797 1798 if (!route || !route->netif) { 1799 fibril_rwlock_read_unlock(&ip_globals.lock); 1800 return ENOENT; 1801 } 1802 1803 *device_id = route->netif->device_id; 1804 src = ip_netif_address(route->netif); 1805 fibril_rwlock_read_unlock(&ip_globals.lock); 1806 1807 *headerlen = sizeof(*header_in); 1808 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 1809 if (!header_in) 1810 return ENOMEM; 1811 1812 bzero(header_in, *headerlen); 1813 header_in->destination_address = dest->s_addr; 1814 header_in->source_address = src->s_addr; 1815 header_in->protocol = protocol; 1816 header_in->data_length = 0; 1817 *header = header_in; 1818 1819 return EOK; 1820 } 1821 1822 /** Processes the received IP packet or the packet queue one by one. 1823 * 1824 * The packet is either passed to another module or released on error. 1825 * 1826 * @param[in] device_id The source device identifier. 1827 * @param[in,out] packet The received packet. 1828 * @returns EOK on success and the packet is no longer needed. 1829 * @returns EINVAL if the packet is too small to carry the IP 1830 * packet. 1831 * @returns EINVAL if the received address lengths differs from the 1832 * registered values. 1833 * @returns ENOENT if the device is not found in the cache. 1834 * @returns ENOENT if the protocol for the device is not found in 1835 * the cache. 1836 * @returns ENOMEM if there is not enough memory left. 1837 */ 1838 static int ip_receive_message(device_id_t device_id, packet_t packet) 1839 { 1840 packet_t next; 1841 1842 do { 1843 next = pq_detach(packet); 1844 ip_process_packet(device_id, packet); 1845 packet = next; 1846 } while (packet); 1847 1848 return EOK; 1849 } 1850 1851 /** Processes the IP message. 1852 * 1853 * @param[in] callid The message identifier. 1854 * @param[in] call The message parameters. 1855 * @param[out] answer The message answer parameters. 1856 * @param[out] answer_count The last parameter for the actual answer in the 1857 * answer parameter. 1858 * @returns EOK on success. 1859 * @returns ENOTSUP if the message is not known. 1860 * 1861 * @see ip_interface.h 1862 * @see il_interface.h 1863 * @see IS_NET_IP_MESSAGE() 1864 */ 1865 int 1866 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1867 int *answer_count) 889 int ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, 890 ipc_call_t *answer, int * answer_count) 1868 891 { 1869 892 ERROR_DECLARE; … … 1881 904 *answer_count = 0; 1882 905 switch (IPC_GET_METHOD(*call)) { 1883 case IPC_M_PHONE_HUNGUP: 1884 return EOK; 1885 1886 case IPC_M_CONNECT_TO_ME: 1887 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call), 1888 IPC_GET_PHONE(call), NULL); 1889 1890 case NET_IL_DEVICE: 1891 return ip_device_req_local(0, IPC_GET_DEVICE(call), 1892 IPC_GET_SERVICE(call)); 1893 1894 case NET_IL_SEND: 1895 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1896 &packet, IPC_GET_PACKET(call))); 1897 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 1898 IPC_GET_ERROR(call)); 1899 1900 case NET_IL_DEVICE_STATE: 1901 return ip_device_state_message(IPC_GET_DEVICE(call), 1902 IPC_GET_STATE(call)); 1903 1904 case NET_IL_RECEIVED: 1905 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1906 &packet, IPC_GET_PACKET(call))); 1907 return ip_receive_message(IPC_GET_DEVICE(call), packet); 1908 1909 case NET_IP_RECEIVED_ERROR: 1910 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1911 &packet, IPC_GET_PACKET(call))); 1912 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), 1913 packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call)); 1914 1915 case NET_IP_ADD_ROUTE: 1916 return ip_add_route_req_local(0, IPC_GET_DEVICE(call), 1917 IP_GET_ADDRESS(call), IP_GET_NETMASK(call), 1918 IP_GET_GATEWAY(call)); 1919 1920 case NET_IP_SET_GATEWAY: 1921 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call), 1922 IP_GET_GATEWAY(call)); 1923 1924 case NET_IP_GET_ROUTE: 1925 ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen)); 1926 ERROR_PROPAGATE(ip_get_route_req_local(0, IP_GET_PROTOCOL(call), 1927 addr, (socklen_t) addrlen, &device_id, &header, 1928 &headerlen)); 1929 IPC_SET_DEVICE(answer, device_id); 1930 IP_SET_HEADERLEN(answer, headerlen); 1931 1932 *answer_count = 2; 906 case IPC_M_PHONE_HUNGUP: 907 return EOK; 908 case NET_IL_DEVICE: 909 return ip_device_req_local(0, IPC_GET_DEVICE(call), 910 IPC_GET_SERVICE(call)); 911 case IPC_M_CONNECT_TO_ME: 912 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call), 913 IPC_GET_PHONE(call), NULL); 914 case NET_IL_SEND: 915 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet, 916 IPC_GET_PACKET(call))); 917 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 918 IPC_GET_ERROR(call)); 919 case NET_IL_DEVICE_STATE: 920 return ip_device_state_message(IPC_GET_DEVICE(call), 921 IPC_GET_STATE(call)); 922 case NET_IL_RECEIVED: 923 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet, 924 IPC_GET_PACKET(call))); 925 return ip_receive_message(IPC_GET_DEVICE(call), packet); 926 case NET_IP_RECEIVED_ERROR: 927 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet, 928 IPC_GET_PACKET(call))); 929 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), packet, 930 IPC_GET_TARGET(call), IPC_GET_ERROR(call)); 931 case NET_IP_ADD_ROUTE: 932 return ip_add_route_req_local(0, IPC_GET_DEVICE(call), 933 IP_GET_ADDRESS(call), IP_GET_NETMASK(call), IP_GET_GATEWAY(call)); 934 case NET_IP_SET_GATEWAY: 935 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call), 936 IP_GET_GATEWAY(call)); 937 case NET_IP_GET_ROUTE: 938 ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen)); 939 ERROR_PROPAGATE(ip_get_route_req_local(0, IP_GET_PROTOCOL(call), 940 addr, (socklen_t) addrlen, &device_id, &header, &headerlen)); 941 IPC_SET_DEVICE(answer, device_id); 942 IP_SET_HEADERLEN(answer, headerlen); 1933 943 1934 if (ERROR_NONE(data_reply(&headerlen, sizeof(headerlen)))) 1935 ERROR_CODE = data_reply(header, headerlen); 944 *answer_count = 2; 1936 945 1937 free(header); 1938 return ERROR_CODE; 1939 1940 case NET_IL_PACKET_SPACE: 1941 ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), 1942 &addrlen, &prefix, &content, &suffix)); 1943 IPC_SET_ADDR(answer, addrlen); 1944 IPC_SET_PREFIX(answer, prefix); 1945 IPC_SET_CONTENT(answer, content); 1946 IPC_SET_SUFFIX(answer, suffix); 1947 *answer_count = 4; 1948 return EOK; 1949 1950 case NET_IL_MTU_CHANGED: 1951 return ip_mtu_changed_message(IPC_GET_DEVICE(call), 1952 IPC_GET_MTU(call)); 946 if (!ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen)))) 947 ERROR_CODE = data_reply(header, headerlen); 948 949 free(header); 950 return ERROR_CODE; 951 case NET_IL_PACKET_SPACE: 952 ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), 953 &addrlen, &prefix, &content, &suffix)); 954 IPC_SET_ADDR(answer, addrlen); 955 IPC_SET_PREFIX(answer, prefix); 956 IPC_SET_CONTENT(answer, content); 957 IPC_SET_SUFFIX(answer, suffix); 958 *answer_count = 4; 959 return EOK; 960 case NET_IL_MTU_CHANGED: 961 return ip_mtu_changed_message(IPC_GET_DEVICE(call), 962 IPC_GET_MTU(call)); 1953 963 } 1954 964 … … 1956 966 } 1957 967 968 int ip_packet_size_req_local(int ip_phone, device_id_t device_id, 969 packet_dimension_ref packet_dimension) 970 { 971 if (!packet_dimension) 972 return EBADMEM; 973 974 return ip_packet_size_message(device_id, &packet_dimension->addr_len, 975 &packet_dimension->prefix, &packet_dimension->content, 976 &packet_dimension->suffix); 977 } 978 979 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 980 ip_netif_ref netif; 981 int index; 982 983 if(!(addr_len && prefix && content && suffix)){ 984 return EBADMEM; 985 } 986 *content = IP_MAX_CONTENT - IP_PREFIX; 987 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 988 if(device_id < 0){ 989 *addr_len = IP_ADDR; 990 *prefix = 0; 991 *suffix = 0; 992 for(index = ip_netifs_count(&ip_globals.netifs) - 1; index >= 0; -- index){ 993 netif = ip_netifs_get_index(&ip_globals.netifs, index); 994 if(netif){ 995 if(netif->packet_dimension.addr_len > * addr_len){ 996 *addr_len = netif->packet_dimension.addr_len; 997 } 998 if(netif->packet_dimension.prefix > * prefix){ 999 *prefix = netif->packet_dimension.prefix; 1000 } 1001 if(netif->packet_dimension.suffix > * suffix){ 1002 *suffix = netif->packet_dimension.suffix; 1003 } 1004 } 1005 } 1006 *prefix = * prefix + IP_PREFIX; 1007 *suffix = * suffix + IP_SUFFIX; 1008 }else{ 1009 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1010 if(! netif){ 1011 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1012 return ENOENT; 1013 } 1014 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? netif->packet_dimension.addr_len : IP_ADDR; 1015 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 1016 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 1017 } 1018 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1019 return EOK; 1020 } 1021 1022 int ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){ 1023 ip_route_ref route; 1024 ip_netif_ref netif; 1025 int index; 1026 1027 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1028 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1029 if(! netif){ 1030 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1031 return ENOENT; 1032 } 1033 route = (ip_route_ref) malloc(sizeof(ip_route_t)); 1034 if(! route){ 1035 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1036 return ENOMEM; 1037 } 1038 route->address.s_addr = address.s_addr; 1039 route->netmask.s_addr = netmask.s_addr; 1040 route->gateway.s_addr = gateway.s_addr; 1041 route->netif = netif; 1042 index = ip_routes_add(&netif->routes, route); 1043 if(index < 0){ 1044 free(route); 1045 } 1046 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1047 return index; 1048 } 1049 1050 ip_route_ref ip_find_route(in_addr_t destination){ 1051 int index; 1052 ip_route_ref route; 1053 ip_netif_ref netif; 1054 1055 // start with the last netif - the newest one 1056 index = ip_netifs_count(&ip_globals.netifs) - 1; 1057 while(index >= 0){ 1058 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1059 if(netif && (netif->state == NETIF_ACTIVE)){ 1060 route = ip_netif_find_route(netif, destination); 1061 if(route){ 1062 return route; 1063 } 1064 } 1065 -- index; 1066 } 1067 return &ip_globals.gateway; 1068 } 1069 1070 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination){ 1071 int index; 1072 ip_route_ref route; 1073 1074 if(netif){ 1075 // start with the first one - the direct route 1076 for(index = 0; index < ip_routes_count(&netif->routes); ++ index){ 1077 route = ip_routes_get_index(&netif->routes, index); 1078 if(route && ((route->address.s_addr &route->netmask.s_addr) == (destination.s_addr &route->netmask.s_addr))){ 1079 return route; 1080 } 1081 } 1082 } 1083 return NULL; 1084 } 1085 1086 int ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway) 1087 { 1088 ip_netif_ref netif; 1089 1090 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1091 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1092 if(! netif){ 1093 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1094 return ENOENT; 1095 } 1096 ip_globals.gateway.address.s_addr = 0; 1097 ip_globals.gateway.netmask.s_addr = 0; 1098 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 1099 ip_globals.gateway.netif = netif; 1100 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1101 return EOK; 1102 } 1103 1104 packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error){ 1105 size_t length; 1106 packet_t next; 1107 packet_t new_packet; 1108 int result; 1109 int phone; 1110 1111 next = packet; 1112 // check all packets 1113 while(next){ 1114 length = packet_get_data_length(next); 1115 // too long? 1116 if(length > content){ 1117 result = ip_fragment_packet(next, content, prefix, suffix, addr_len); 1118 if(result != EOK){ 1119 new_packet = pq_detach(next); 1120 if(next == packet){ 1121 // the new first packet of the queue 1122 packet = new_packet; 1123 } 1124 // fragmentation needed? 1125 if(result == EPERM){ 1126 phone = ip_prepare_icmp_and_get_phone(error, next, NULL); 1127 if(phone >= 0){ 1128 // fragmentation necessary ICMP 1129 icmp_destination_unreachable_msg(phone, ICMP_FRAG_NEEDED, content, next); 1130 } 1131 }else{ 1132 pq_release_remote(ip_globals.net_phone, packet_get_id(next)); 1133 } 1134 next = new_packet; 1135 continue; 1136 } 1137 } 1138 next = pq_next(next); 1139 } 1140 return packet; 1141 } 1142 1143 int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len){ 1144 ERROR_DECLARE; 1145 1146 packet_t new_packet; 1147 ip_header_ref header; 1148 ip_header_ref middle_header; 1149 ip_header_ref last_header; 1150 struct sockaddr * src; 1151 struct sockaddr * dest; 1152 socklen_t addrlen; 1153 int result; 1154 1155 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 1156 if(result <= 0){ 1157 return EINVAL; 1158 } 1159 addrlen = (socklen_t) result; 1160 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1161 return ENOMEM; 1162 } 1163 // get header 1164 header = (ip_header_ref) packet_get_data(packet); 1165 if(! header){ 1166 return EINVAL; 1167 } 1168 // fragmentation forbidden? 1169 if(header->flags &IPFLAG_DONT_FRAGMENT){ 1170 return EPERM; 1171 } 1172 // create the last fragment 1173 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len)); 1174 if(! new_packet){ 1175 return ENOMEM; 1176 } 1177 // allocate as much as originally 1178 last_header = (ip_header_ref) packet_suffix(new_packet, IP_HEADER_LENGTH(header)); 1179 if(! last_header){ 1180 return ip_release_and_return(packet, ENOMEM); 1181 } 1182 ip_create_last_header(last_header, header); 1183 // trim the unused space 1184 if(ERROR_OCCURRED(packet_trim(new_packet, 0, IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))){ 1185 return ip_release_and_return(packet, ERROR_CODE); 1186 } 1187 // biggest multiple of 8 lower than content 1188 // TODO even fragmentation? 1189 length = length &(~ 0x7);// (content / 8) * 8 1190 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))){ 1191 return ip_release_and_return(packet, ERROR_CODE); 1192 } 1193 // mark the first as fragmented 1194 header->flags |= IPFLAG_MORE_FRAGMENTS; 1195 // create middle framgents 1196 while(IP_TOTAL_LENGTH(header) > length){ 1197 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len)); 1198 if(! new_packet){ 1199 return ENOMEM; 1200 } 1201 middle_header = ip_create_middle_header(new_packet, last_header); 1202 if(! middle_header){ 1203 return ip_release_and_return(packet, ENOMEM); 1204 } 1205 if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, middle_header, (length - IP_HEADER_LENGTH(middle_header)) &(~ 0x7), src, dest, addrlen))){ 1206 return ip_release_and_return(packet, ERROR_CODE); 1207 } 1208 } 1209 // finish the first fragment 1210 header->header_checksum = IP_HEADER_CHECKSUM(header); 1211 return EOK; 1212 } 1213 1214 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){ 1215 ERROR_DECLARE; 1216 1217 void * data; 1218 size_t offset; 1219 1220 data = packet_suffix(new_packet, length); 1221 if(! data){ 1222 return ENOMEM; 1223 } 1224 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, length); 1225 ERROR_PROPAGATE(packet_trim(packet, 0, length)); 1226 header->total_length = htons(IP_TOTAL_LENGTH(header) - length); 1227 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); 1228 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header); 1229 new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset); 1230 new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); 1231 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header); 1232 ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, (const uint8_t *) dest, addrlen)); 1233 return pq_insert_after(packet, new_packet); 1234 } 1235 1236 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last){ 1237 ip_header_ref middle; 1238 1239 middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last)); 1240 if(! middle){ 1241 return NULL; 1242 } 1243 memcpy(middle, last, IP_HEADER_LENGTH(last)); 1244 middle->flags |= IPFLAG_MORE_FRAGMENTS; 1245 return middle; 1246 } 1247 1248 void ip_create_last_header(ip_header_ref last, ip_header_ref first){ 1249 ip_option_ref option; 1250 size_t next; 1251 size_t length; 1252 1253 // copy first itself 1254 memcpy(last, first, sizeof(ip_header_t)); 1255 length = sizeof(ip_header_t); 1256 next = sizeof(ip_header_t); 1257 // process all ip options 1258 while(next < first->header_length){ 1259 option = (ip_option_ref) (((uint8_t *) first) + next); 1260 // skip end or noop 1261 if((option->type == IPOPT_END) || (option->type == IPOPT_NOOP)){ 1262 ++ next; 1263 }else{ 1264 // copy if said so or skip 1265 if(IPOPT_COPIED(option->type)){ 1266 memcpy(((uint8_t *) last) + length, ((uint8_t *) first) + next, option->length); 1267 length += option->length; 1268 } 1269 // next option 1270 next += option->length; 1271 } 1272 } 1273 // align 4 byte boundary 1274 if(length % 4){ 1275 bzero(((uint8_t *) last) + length, 4 - (length % 4)); 1276 last->header_length = length / 4 + 1; 1277 }else{ 1278 last->header_length = length / 4; 1279 } 1280 last->header_checksum = 0; 1281 } 1282 1283 int ip_receive_message(device_id_t device_id, packet_t packet){ 1284 packet_t next; 1285 1286 do{ 1287 next = pq_detach(packet); 1288 ip_process_packet(device_id, packet); 1289 packet = next; 1290 }while(packet); 1291 return EOK; 1292 } 1293 1294 int ip_process_packet(device_id_t device_id, packet_t packet){ 1295 ERROR_DECLARE; 1296 1297 ip_header_ref header; 1298 in_addr_t dest; 1299 ip_route_ref route; 1300 int phone; 1301 struct sockaddr * addr; 1302 struct sockaddr_in addr_in; 1303 // struct sockaddr_in addr_in6; 1304 socklen_t addrlen; 1305 1306 header = (ip_header_ref) packet_get_data(packet); 1307 if(! header){ 1308 return ip_release_and_return(packet, ENOMEM); 1309 } 1310 // checksum 1311 if((header->header_checksum) && (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)){ 1312 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1313 if(phone >= 0){ 1314 // checksum error ICMP 1315 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->header_checksum)) - ((size_t) ((void *) header)), packet); 1316 } 1317 return EINVAL; 1318 } 1319 if(header->ttl <= 1){ 1320 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1321 if(phone >= 0){ 1322 // ttl oxceeded ICMP 1323 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1324 } 1325 return EINVAL; 1326 } 1327 // process ipopt and get destination 1328 dest = ip_get_destination(header); 1329 // set the addrination address 1330 switch(header->version){ 1331 case IPVERSION: 1332 addrlen = sizeof(addr_in); 1333 bzero(&addr_in, addrlen); 1334 addr_in.sin_family = AF_INET; 1335 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1336 addr = (struct sockaddr *) &addr_in; 1337 break; 1338 /* case IPv6VERSION: 1339 addrlen = sizeof(dest_in6); 1340 bzero(&dest_in6, addrlen); 1341 dest_in6.sin6_family = AF_INET6; 1342 memcpy(&dest_in6.sin6_addr.s6_addr,); 1343 dest = (struct sockaddr *) &dest_in; 1344 break; 1345 */ default: 1346 return ip_release_and_return(packet, EAFNOSUPPORT); 1347 } 1348 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen)); 1349 route = ip_find_route(dest); 1350 if(! route){ 1351 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1352 if(phone >= 0){ 1353 // unreachable ICMP 1354 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 1355 } 1356 return ENOENT; 1357 } 1358 if(route->address.s_addr == dest.s_addr){ 1359 // local delivery 1360 return ip_deliver_local(device_id, packet, header, 0); 1361 }else{ 1362 // only if routing enabled 1363 if(route->netif->routing){ 1364 -- header->ttl; 1365 return ip_send_route(packet, route->netif, route, NULL, dest, 0); 1366 }else{ 1367 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1368 if(phone >= 0){ 1369 // unreachable ICMP if no routing 1370 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet); 1371 } 1372 return ENOENT; 1373 } 1374 } 1375 } 1376 1377 /** Notify the IP module about the received error notification packet. 1378 * 1379 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 1380 * @param[in] device_id The device identifier. 1381 * @param[in] packet The received packet or the received packet queue. 1382 * @param[in] target The target internetwork module service to be 1383 * delivered to. 1384 * @param[in] error The packet error reporting service. Prefixes the 1385 * received packet. 1386 * 1387 * @return EOK on success. 1388 * 1389 */ 1390 int ip_received_error_msg_local(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){ 1391 uint8_t * data; 1392 int offset; 1393 icmp_type_t type; 1394 icmp_code_t code; 1395 ip_netif_ref netif; 1396 measured_string_t address; 1397 ip_route_ref route; 1398 ip_header_ref header; 1399 1400 switch(error){ 1401 case SERVICE_ICMP: 1402 offset = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 1403 if(offset < 0){ 1404 return ip_release_and_return(packet, ENOMEM); 1405 } 1406 data = packet_get_data(packet); 1407 header = (ip_header_ref)(data + offset); 1408 // destination host unreachable? 1409 if((type == ICMP_DEST_UNREACH) && (code == ICMP_HOST_UNREACH)){ 1410 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1411 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1412 if(netif && netif->arp){ 1413 route = ip_routes_get_index(&netif->routes, 0); 1414 // from the same network? 1415 if(route && ((route->address.s_addr &route->netmask.s_addr) == (header->destination_address &route->netmask.s_addr))){ 1416 // clear the ARP mapping if any 1417 address.value = (char *) &header->destination_address; 1418 address.length = CONVERT_SIZE(uint8_t, char, sizeof(header->destination_address)); 1419 arp_clear_address_req(netif->arp->phone, netif->device_id, SERVICE_IP, &address); 1420 } 1421 } 1422 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1423 } 1424 break; 1425 default: 1426 return ip_release_and_return(packet, ENOTSUP); 1427 } 1428 return ip_deliver_local(device_id, packet, header, error); 1429 } 1430 1431 int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error){ 1432 ERROR_DECLARE; 1433 1434 ip_proto_ref proto; 1435 int phone; 1436 services_t service; 1437 tl_received_msg_t received_msg; 1438 struct sockaddr * src; 1439 struct sockaddr * dest; 1440 struct sockaddr_in src_in; 1441 struct sockaddr_in dest_in; 1442 // struct sockaddr_in src_in6; 1443 // struct sockaddr_in dest_in6; 1444 socklen_t addrlen; 1445 1446 if((header->flags &IPFLAG_MORE_FRAGMENTS) || IP_FRAGMENT_OFFSET(header)){ 1447 // TODO fragmented 1448 return ENOTSUP; 1449 }else{ 1450 switch(header->version){ 1451 case IPVERSION: 1452 addrlen = sizeof(src_in); 1453 bzero(&src_in, addrlen); 1454 src_in.sin_family = AF_INET; 1455 memcpy(&dest_in, &src_in, addrlen); 1456 memcpy(&src_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address)); 1457 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, sizeof(header->destination_address)); 1458 src = (struct sockaddr *) &src_in; 1459 dest = (struct sockaddr *) &dest_in; 1460 break; 1461 /* case IPv6VERSION: 1462 addrlen = sizeof(src_in6); 1463 bzero(&src_in6, addrlen); 1464 src_in6.sin6_family = AF_INET6; 1465 memcpy(&dest_in6, &src_in6, addrlen); 1466 memcpy(&src_in6.sin6_addr.s6_addr,); 1467 memcpy(&dest_in6.sin6_addr.s6_addr,); 1468 src = (struct sockaddr *) &src_in; 1469 dest = (struct sockaddr *) &dest_in; 1470 break; 1471 */ default: 1472 return ip_release_and_return(packet, EAFNOSUPPORT); 1473 } 1474 if(ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, addrlen))){ 1475 return ip_release_and_return(packet, ERROR_CODE); 1476 } 1477 // trim padding if present 1478 if((! error) && (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))){ 1479 if(ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))){ 1480 return ip_release_and_return(packet, ERROR_CODE); 1481 } 1482 } 1483 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1484 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1485 if(! proto){ 1486 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1487 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1488 if(phone >= 0){ 1489 // unreachable ICMP 1490 icmp_destination_unreachable_msg(phone, ICMP_PROT_UNREACH, 0, packet); 1491 } 1492 return ENOENT; 1493 } 1494 if(proto->received_msg){ 1495 service = proto->service; 1496 received_msg = proto->received_msg; 1497 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1498 ERROR_CODE = received_msg(device_id, packet, service, error); 1499 }else{ 1500 ERROR_CODE = tl_received_msg(proto->phone, device_id, packet, proto->service, error); 1501 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1502 } 1503 return ERROR_CODE; 1504 } 1505 } 1506 1507 in_addr_t ip_get_destination(ip_header_ref header){ 1508 in_addr_t destination; 1509 1510 // TODO search set ipopt route? 1511 destination.s_addr = header->destination_address; 1512 return destination; 1513 } 1514 1515 int ip_prepare_icmp(packet_t packet, ip_header_ref header){ 1516 packet_t next; 1517 struct sockaddr * dest; 1518 struct sockaddr_in dest_in; 1519 // struct sockaddr_in dest_in6; 1520 socklen_t addrlen; 1521 1522 // detach the first packet and release the others 1523 next = pq_detach(packet); 1524 if(next){ 1525 pq_release_remote(ip_globals.net_phone, packet_get_id(next)); 1526 } 1527 if(! header){ 1528 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1529 return ENOMEM; 1530 } 1531 // get header 1532 header = (ip_header_ref) packet_get_data(packet); 1533 if(! header){ 1534 return EINVAL; 1535 } 1536 } 1537 // only for the first fragment 1538 if(IP_FRAGMENT_OFFSET(header)){ 1539 return EINVAL; 1540 } 1541 // not for the ICMP protocol 1542 if(header->protocol == IPPROTO_ICMP){ 1543 return EPERM; 1544 } 1545 // set the destination address 1546 switch(header->version){ 1547 case IPVERSION: 1548 addrlen = sizeof(dest_in); 1549 bzero(&dest_in, addrlen); 1550 dest_in.sin_family = AF_INET; 1551 memcpy(&dest_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address)); 1552 dest = (struct sockaddr *) &dest_in; 1553 break; 1554 /* case IPv6VERSION: 1555 addrlen = sizeof(dest_in6); 1556 bzero(&dest_in6, addrlen); 1557 dest_in6.sin6_family = AF_INET6; 1558 memcpy(&dest_in6.sin6_addr.s6_addr,); 1559 dest = (struct sockaddr *) &dest_in; 1560 break; 1561 */ default: 1562 return EAFNOSUPPORT; 1563 } 1564 return packet_set_addr(packet, NULL, (uint8_t *) dest, addrlen); 1565 } 1566 1567 int ip_get_icmp_phone(void){ 1568 ip_proto_ref proto; 1569 int phone; 1570 1571 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1572 proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP); 1573 phone = proto ? proto->phone : ENOENT; 1574 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1575 return phone; 1576 } 1577 1578 int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header){ 1579 int phone; 1580 1581 phone = ip_get_icmp_phone(); 1582 if(error || (phone < 0) || ip_prepare_icmp(packet, header)){ 1583 return ip_release_and_return(packet, EINVAL); 1584 } 1585 return phone; 1586 } 1587 1588 int ip_release_and_return(packet_t packet, int result){ 1589 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 1590 return result; 1591 } 1592 1593 int ip_get_route_req_local(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, void **header, size_t * headerlen){ 1594 struct sockaddr_in * address_in; 1595 // struct sockaddr_in6 * address_in6; 1596 in_addr_t * dest; 1597 in_addr_t * src; 1598 ip_route_ref route; 1599 ipv4_pseudo_header_ref header_in; 1600 1601 if(!(destination && (addrlen > 0))){ 1602 return EINVAL; 1603 } 1604 if(!(device_id && header && headerlen)){ 1605 return EBADMEM; 1606 } 1607 if((size_t) addrlen < sizeof(struct sockaddr)){ 1608 return EINVAL; 1609 } 1610 switch(destination->sa_family){ 1611 case AF_INET: 1612 if(addrlen != sizeof(struct sockaddr_in)){ 1613 return EINVAL; 1614 } 1615 address_in = (struct sockaddr_in *) destination; 1616 dest = &address_in->sin_addr; 1617 if(! dest->s_addr){ 1618 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1619 } 1620 break; 1621 // TODO IPv6 1622 /* case AF_INET6: 1623 if(addrlen != sizeof(struct sockaddr_in6)){ 1624 return EINVAL; 1625 } 1626 address_in6 = (struct sockaddr_in6 *) dest; 1627 address_in6.sin6_addr.s6_addr; 1628 */ default: 1629 return EAFNOSUPPORT; 1630 } 1631 fibril_rwlock_read_lock(&ip_globals.lock); 1632 route = ip_find_route(*dest); 1633 // if the local host is the destination 1634 if(route && (route->address.s_addr == dest->s_addr) 1635 && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){ 1636 // find the loopback device to deliver 1637 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1638 route = ip_find_route(*dest); 1639 } 1640 if(!(route && route->netif)){ 1641 fibril_rwlock_read_unlock(&ip_globals.lock); 1642 return ENOENT; 1643 } 1644 *device_id = route->netif->device_id; 1645 src = ip_netif_address(route->netif); 1646 fibril_rwlock_read_unlock(&ip_globals.lock); 1647 *headerlen = sizeof(*header_in); 1648 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 1649 if(! header_in){ 1650 return ENOMEM; 1651 } 1652 bzero(header_in, * headerlen); 1653 header_in->destination_address = dest->s_addr; 1654 header_in->source_address = src->s_addr; 1655 header_in->protocol = protocol; 1656 header_in->data_length = 0; 1657 *header = header_in; 1658 return EOK; 1659 } 1660 1958 1661 /** Default thread for new connections. 1959 1662 * 1960 * @param[in] iid The initial message identifier. 1961 * @param[in] icall The initial message call structure. 1962 */ 1963 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 1663 * @param[in] iid The initial message identifier. 1664 * @param[in] icall The initial message call structure. 1665 * 1666 */ 1667 static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall) 1964 1668 { 1965 1669 /* … … 1969 1673 ipc_answer_0(iid, EOK); 1970 1674 1971 while 1675 while(true) { 1972 1676 ipc_call_t answer; 1973 1677 int answer_count; … … 1984 1688 &answer_count); 1985 1689 1986 /* 1987 * End if told to either by the message or the processing 1988 * result. 1989 */ 1990 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 1991 (res == EHANGUP)) { 1690 /* End if said to either by the message or the processing result */ 1691 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 1992 1692 return; 1993 }1994 1693 1995 1694 /* Answer the message */ … … 2000 1699 /** Starts the module. 2001 1700 * 2002 * @returns EOK on success. 2003 * @returns Other error codes as defined for each specific module start function. 1701 * @param argc The count of the command line arguments. Ignored parameter. 1702 * @param argv The command line parameters. Ignored parameter. 1703 * 1704 * @returns EOK on success. 1705 * @returns Other error codes as defined for each specific module start function. 1706 * 2004 1707 */ 2005 1708 int main(int argc, char *argv[]) … … 2008 1711 2009 1712 /* Start the module */ 2010 ERROR_PROPAGATE(il_module_start_standalone(il_client_connection)); 1713 if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection))) 1714 return ERROR_CODE; 1715 2011 1716 return EOK; 2012 1717 } -
uspace/srv/net/il/ip/ip.h
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup ip 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * IP module.35 */ 36 37 #ifndef NET_IP_H_38 #define NET_IP_H_34 * IP module. 35 */ 36 37 #ifndef __NET_IP_H__ 38 #define __NET_IP_H__ 39 39 40 40 #include <fibril_synch.h> … … 50 50 51 51 /** Type definition of the IP global data. 52 * @see ip_globals53 */ 54 typedef struct ip_globals 52 * @see ip_globals 53 */ 54 typedef struct ip_globals ip_globals_t; 55 55 56 56 /** Type definition of the IP network interface specific data. 57 * @see ip_netif58 */ 59 typedef struct ip_netif 57 * @see ip_netif 58 */ 59 typedef struct ip_netif ip_netif_t; 60 60 61 61 /** Type definition of the IP network interface specific data pointer. 62 * @see ip_netif63 */ 64 typedef ip_netif_t * ip_netif_ref;62 * @see ip_netif 63 */ 64 typedef ip_netif_t * ip_netif_ref; 65 65 66 66 /** Type definition of the IP protocol specific data. 67 * @see ip_proto68 */ 69 typedef struct ip_proto 67 * @see ip_proto 68 */ 69 typedef struct ip_proto ip_proto_t; 70 70 71 71 /** Type definition of the IP protocol specific data pointer. 72 * @see ip_proto73 */ 74 typedef ip_proto_t * ip_proto_ref;72 * @see ip_proto 73 */ 74 typedef ip_proto_t * ip_proto_ref; 75 75 76 76 /** Type definition of the IP route specific data. … … 82 82 * @see ip_route 83 83 */ 84 typedef ip_route_t * ip_route_ref;84 typedef ip_route_t * ip_route_ref; 85 85 86 86 /** IP network interfaces. 87 * Maps devices to the IP network interface specific data.88 * @see device.h89 */ 90 DEVICE_MAP_DECLARE(ip_netifs, ip_netif_t) ;87 * Maps devices to the IP network interface specific data. 88 * @see device.h 89 */ 90 DEVICE_MAP_DECLARE(ip_netifs, ip_netif_t) 91 91 92 92 /** IP registered protocols. 93 * Maps protocols to the IP protocol specific data.94 * @see int_map.h95 */ 96 INT_MAP_DECLARE(ip_protos, ip_proto_t) ;93 * Maps protocols to the IP protocol specific data. 94 * @see int_map.h 95 */ 96 INT_MAP_DECLARE(ip_protos, ip_proto_t) 97 97 98 98 /** IP routing table. 99 * @see generic_field.h 100 */ 101 GENERIC_FIELD_DECLARE(ip_routes, ip_route_t); 102 103 /** IP network interface specific data. */ 104 struct ip_netif { 105 /** ARP module. Assigned if using ARP. */ 99 * @see generic_field.h 100 */ 101 GENERIC_FIELD_DECLARE(ip_routes, ip_route_t) 102 103 /** IP network interface specific data. 104 */ 105 struct ip_netif{ 106 /** ARP module. 107 * Assigned if using ARP. 108 */ 106 109 module_ref arp; 107 /** Broadcast address. */ 110 /** Broadcast address. 111 */ 108 112 in_addr_t broadcast; 109 /** Device identifier. */ 113 /** Device identifier. 114 */ 110 115 device_id_t device_id; 111 /** Indicates whether using DHCP. */ 116 /** Indicates whether using DHCP. 117 */ 112 118 int dhcp; 113 /** IP version. */ 119 /** IP version. 120 */ 114 121 int ipv; 115 /** Packet dimension. */ 122 /** Packet dimension. 123 */ 116 124 packet_dimension_t packet_dimension; 117 /** Netif module phone. */ 125 /** Netif module phone. 126 */ 118 127 int phone; 119 /** Routing table. */ 128 /** Routing table. 129 */ 120 130 ip_routes_t routes; 121 /** Indicates whether IP routing is enabled. */ 131 /** Indicates whether IP routing is enabled. 132 */ 122 133 int routing; 123 /** Netif module service. */ 134 /** Netif module service. 135 */ 124 136 services_t service; 125 /** Device state. */ 137 /** Device state. 138 */ 126 139 device_state_t state; 127 140 }; 128 141 129 /** IP protocol specific data. */ 130 struct ip_proto { 131 /** Protocol module phone. */ 142 /** IP protocol specific data. 143 */ 144 struct ip_proto{ 145 /** Protocol module phone. 146 */ 132 147 int phone; 133 /** Protocol number. */ 148 /** Protocol number. 149 */ 134 150 int protocol; 135 /** Protocol packet receiving function. */ 151 /** Protocol packet receiving function. 152 */ 136 153 tl_received_msg_t received_msg; 137 /** Protocol module service. */ 154 /** Protocol module service. 155 */ 138 156 services_t service; 139 157 }; 140 158 141 /** IP route specific data. */ 142 struct ip_route { 143 /** Target address. */ 159 /** IP route specific data. 160 */ 161 struct ip_route{ 162 /** Target address. 163 */ 144 164 in_addr_t address; 145 /** Gateway. */ 165 /** Gateway. 166 */ 146 167 in_addr_t gateway; 147 /** Parent netif. */ 168 /** Parent netif. 169 */ 148 170 ip_netif_ref netif; 149 /** Target network mask. */ 171 /** Target network mask. 172 */ 150 173 in_addr_t netmask; 151 174 }; 152 175 153 /** IP global data. */ 154 struct ip_globals { 155 /** Default client connection function for support modules. */ 176 /** IP global data. 177 */ 178 struct ip_globals{ 179 /** Default client connection function for support modules. 180 */ 156 181 async_client_conn_t client_connection; 157 /** Default gateway. */ 182 /** Default gateway. 183 */ 158 184 ip_route_t gateway; 159 /** Safety lock. */ 185 /** Safety lock. 186 */ 160 187 fibril_rwlock_t lock; 161 /** Known support modules. */ 188 /** Known support modules. 189 */ 162 190 modules_t modules; 163 /** Networking module phone. */ 191 /** Networking module phone. 192 */ 164 193 int net_phone; 165 /** Registered network interfaces. */ 194 /** Registered network interfaces. 195 */ 166 196 ip_netifs_t netifs; 167 /** Netifs safeyt lock. */ 197 /** Netifs safeyt lock. 198 */ 168 199 fibril_rwlock_t netifs_lock; 169 /** Packet counter. */ 200 /** Packet counter. 201 */ 170 202 uint16_t packet_counter; 171 /** Registered protocols. */ 203 /** Registered protocols. 204 */ 172 205 ip_protos_t protos; 173 /** Protocols safety lock. */ 206 /** Protocols safety lock. 207 */ 174 208 fibril_rwlock_t protos_lock; 175 209 }; -
uspace/srv/net/il/ip/ip_module.c
r069015f2 rf2d2c604 32 32 33 33 /** @file 34 * IP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * 39 * @see module.c 34 * IP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 40 38 */ 41 39 … … 54 52 #include "ip_module.h" 55 53 56 /** IP module global data. */ 54 /** IP module global data. 55 */ 57 56 extern ip_globals_t ip_globals; 58 57 59 int 60 il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 61 ipc_call_t *answer, int *answer_count) 62 { 58 int il_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 63 59 return ip_message_standalone(callid, call, answer, answer_count); 64 60 } 65 61 66 int il_module_start_standalone(async_client_conn_t client_connection) 67 { 62 int il_module_start_standalone(async_client_conn_t client_connection){ 68 63 ERROR_DECLARE; 69 64 … … 73 68 74 69 ipcarg_t phonehash; 75 if (ERROR_OCCURRED(ip_initialize(client_connection)) ||76 ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))) {70 if (ERROR_OCCURRED(ip_initialize(client_connection)) 71 || ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))) { 77 72 pm_destroy(); 78 73 return ERROR_CODE; -
uspace/srv/net/il/ip/ip_module.h
r069015f2 rf2d2c604 28 28 29 29 /** @addtogroup ip 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * IP module functions.35 * The functions are used as IP module entry points.34 * IP module functions. 35 * The functions are used as IP module entry points. 36 36 */ 37 37 38 #ifndef NET_IP_MODULE_H_39 #define NET_IP_MODULE_H_38 #ifndef __NET_IP_MODULE_H__ 39 #define __NET_IP_MODULE_H__ 40 40 41 41 #include <ipc/ipc.h> 42 42 43 extern int ip_initialize(async_client_conn_t); 44 extern int ip_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 45 int *); 43 /** Initializes the IP module. 44 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 45 * @returns EOK on success. 46 * @returns ENOMEM if there is not enough memory left. 47 */ 48 int ip_initialize(async_client_conn_t client_connection); 49 50 /** Processes the IP message. 51 * @param[in] callid The message identifier. 52 * @param[in] call The message parameters. 53 * @param[out] answer The message answer parameters. 54 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 55 * @returns EOK on success. 56 * @returns ENOTSUP if the message is not known. 57 * @see ip_interface.h 58 * @see il_interface.h 59 * @see IS_NET_IP_MESSAGE() 60 */ 61 int ip_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 46 62 47 63 #endif
Note:
See TracChangeset
for help on using the changeset viewer.