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