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