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