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