Rev 4743 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4743 | Rev 4756 | ||
|---|---|---|---|
| Line 31... | Line 31... | ||
| 31 | */ |
31 | */ |
| 32 | 32 | ||
| 33 | /** @file |
33 | /** @file |
| 34 | * IP module implementation. |
34 | * IP module implementation. |
| 35 | * @see arp.h |
35 | * @see arp.h |
| 36 | * \todo |
- | |
| 37 | */ |
36 | */ |
| 38 | 37 | ||
| 39 | #include <async.h> |
38 | #include <async.h> |
| 40 | #include <errno.h> |
39 | #include <errno.h> |
| 41 | #include <fibril_sync.h> |
40 | #include <fibril_sync.h> |
| Line 135... | Line 134... | ||
| 135 | INT_MAP_IMPLEMENT( ip_protos, ip_proto_t ) |
134 | INT_MAP_IMPLEMENT( ip_protos, ip_proto_t ) |
| 136 | 135 | ||
| 137 | GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t ) |
136 | GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t ) |
| 138 | 137 | ||
| 139 | /** Updates the device content length according to the new MTU value. |
138 | /** Updates the device content length according to the new MTU value. |
| 140 | * @param device_id The device identifier. Input parameter. |
139 | * @param[in] device_id The device identifier. |
| 141 | * @param mtu The new mtu value. Input parameter. |
140 | * @param[in] mtu The new mtu value. |
| 142 | * @returns EOK on success. |
141 | * @returns EOK on success. |
| 143 | * @returns ENOENT if device is not found. |
142 | * @returns ENOENT if device is not found. |
| 144 | */ |
143 | */ |
| 145 | int ip_mtu_changed_message( device_id_t device_id, size_t mtu ); |
144 | int ip_mtu_changed_message( device_id_t device_id, size_t mtu ); |
| 146 | 145 | ||
| 147 | /** Updates the device state. |
146 | /** Updates the device state. |
| 148 | * @param device_id The device identifier. Input parameter. |
147 | * @param[in] device_id The device identifier. |
| 149 | * @param state The new state value. Input parameter. |
148 | * @param[in] state The new state value. |
| 150 | * @returns EOK on success. |
149 | * @returns EOK on success. |
| 151 | * @returns ENOENT if device is not found. |
150 | * @returns ENOENT if device is not found. |
| 152 | */ |
151 | */ |
| 153 | int ip_device_state_message( device_id_t device_id, device_state_t state ); |
152 | int ip_device_state_message( device_id_t device_id, device_state_t state ); |
| 154 | 153 | ||
| - | 154 | /** Registers the transport layer protocol. |
|
| - | 155 | * The traffic of this protocol will be supplied using either the receive function or IPC message. |
|
| - | 156 | * @param[in] protocol The transport layer module protocol. |
|
| - | 157 | * @param[in] service The transport layer module service. |
|
| - | 158 | * @param[in] phone The transport layer module phone. |
|
| - | 159 | * @param[in] tl_received_msg The receiving function. |
|
| - | 160 | * @returns EOK on success. |
|
| - | 161 | * @returns EINVAL if the protocol parameter and/or the service parameter is zero (0). |
|
| - | 162 | * @returns EINVAL if the phone parameter is not a positive number and the tl_receive_msg is NULL. |
|
| - | 163 | * @returns ENOMEM if there is not enough memory left. |
|
| - | 164 | */ |
|
| 155 | int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg ); |
165 | int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg ); |
| 156 | 166 | ||
| 157 | /** Initializes a new network interface specific data. |
167 | /** Initializes a new network interface specific data. |
| 158 | * Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table. |
168 | * Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table. |
| 159 | * The device identifier and the nil service has to be set. |
169 | * The device identifier and the nil service has to be set. |
| 160 | * @param ip_netif Network interface specific data. Input/output parameter. |
170 | * @param[in,out] ip_netif Network interface specific data. |
| 161 | * @returns EOK on success. |
171 | * @returns EOK on success. |
| 162 | * @returns ENOTSUP if DHCP is configured. |
172 | * @returns ENOTSUP if DHCP is configured. |
| 163 | * @returns ENOTSUP if IPv6 is configured. |
173 | * @returns ENOTSUP if IPv6 is configured. |
| 164 | * @returns EINVAL if any of the addresses is invalid. |
174 | * @returns EINVAL if any of the addresses is invalid. |
| 165 | * @returns EINVAL if the used ARP module is not known. |
175 | * @returns EINVAL if the used ARP module is not known. |
| Line 169... | Line 179... | ||
| 169 | * @returns Other error codes as defined for the specific arp_device_req() function. |
179 | * @returns Other error codes as defined for the specific arp_device_req() function. |
| 170 | * @returns Other error codes as defined for the nil_packet_size_req() function. |
180 | * @returns Other error codes as defined for the nil_packet_size_req() function. |
| 171 | */ |
181 | */ |
| 172 | int ip_netif_initialize( ip_netif_ref ip_netif ); |
182 | int ip_netif_initialize( ip_netif_ref ip_netif ); |
| 173 | 183 | ||
| - | 184 | /** Sends the packet or the packet queue via the specified route. |
|
| - | 185 | * The ICMP_HOST_UNREACH error notification may be sent if route hardware destination address is found. |
|
| - | 186 | * @param[in,out] packet The packet to be sent. |
|
| - | 187 | * @param[in] netif The target network interface. |
|
| - | 188 | * @param[in] route The target route. |
|
| - | 189 | * @param[in] src The source address. |
|
| - | 190 | * @param[in] dest The destination address. |
|
| - | 191 | * @param[in] error The error module service. |
|
| - | 192 | * @returns EOK on success. |
|
| - | 193 | * @returns Other error codes as defined for the arp_translate_req() function. |
|
| - | 194 | * @returns Other error codes as defined for the ip_prepare_packet() function. |
|
| - | 195 | */ |
|
| 174 | 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 ); |
196 | 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 ); |
| - | 197 | ||
| - | 198 | /** Prepares the outgoing packet or the packet queue. |
|
| - | 199 | * The packet queue is a fragmented packet |
|
| - | 200 | * Updates the first packet's IP header. |
|
| - | 201 | * Prefixes the additional packets with fragment headers. |
|
| - | 202 | * @param[in] source The source address. |
|
| - | 203 | * @param[in] dest The destination address. |
|
| - | 204 | * @param[in,out] packet The packet to be sent. |
|
| - | 205 | * @param[in] destination The destination hardware address. |
|
| - | 206 | * @returns EOK on success. |
|
| - | 207 | * @returns EINVAL if the packet is too small to contain the IP header. |
|
| - | 208 | * @returns EINVAL if the packet is too long than the IP allows. |
|
| - | 209 | * @returns ENOMEM if there is not enough memory left. |
|
| - | 210 | * @returns Other error codes as defined for the packet_set_addr() function. |
|
| - | 211 | */ |
|
| 175 | int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ); |
212 | int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ); |
| 176 | 213 | ||
| - | 214 | /** Checks the packet queue lengths and fragments the packets if needed. |
|
| - | 215 | * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to be fragmented and the fragmentation is not allowed. |
|
| - | 216 | * @param[in,out] packet The packet or the packet queue to be checked. |
|
| - | 217 | * @param[in] prefix The minimum prefix size. |
|
| - | 218 | * @param[in] content The maximum content size. |
|
| - | 219 | * @param[in] suffix The minimum suffix size. |
|
| - | 220 | * @param[in] addr_len The minimum address length. |
|
| - | 221 | * @param[in] error The error module service. |
|
| - | 222 | * @returns The packet or the packet queue of the allowed length. |
|
| - | 223 | * @returns NULL if there are no packets left. |
|
| - | 224 | */ |
|
| 177 | packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ); |
225 | packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ); |
| - | 226 | ||
| - | 227 | /** Checks the packet length and fragments it if needed. |
|
| - | 228 | * The new fragments are queued before the original packet. |
|
| - | 229 | * @param[in,out] packet The packet to be checked. |
|
| - | 230 | * @param[in] length The maximum packet length. |
|
| - | 231 | * @param[in] prefix The minimum prefix size. |
|
| - | 232 | * @param[in] suffix The minimum suffix size. |
|
| - | 233 | * @param[in] addr_len The minimum address length. |
|
| - | 234 | * @returns EOK on success. |
|
| - | 235 | * @returns EINVAL if the packet_get_addr() function fails. |
|
| - | 236 | * @returns EINVAL if the packet does not contain the IP header. |
|
| - | 237 | * @returns EPERM if the packet needs to be fragmented and the fragmentation is not allowed. |
|
| - | 238 | * @returns ENOMEM if there is not enough memory left. |
|
| - | 239 | * @returns ENOMEM if there is no packet available. |
|
| - | 240 | * @returns ENOMEM if the packet is too small to contain the IP header. |
|
| - | 241 | * @returns Other error codes as defined for the packet_trim() function. |
|
| - | 242 | * @returns Other error codes as defined for the ip_create_middle_header() function. |
|
| - | 243 | * @returns Other error codes as defined for the ip_fragment_packet_data() function. |
|
| - | 244 | */ |
|
| 178 | int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ); |
245 | int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ); |
| - | 246 | ||
| - | 247 | /** Fragments the packet from the end. |
|
| - | 248 | * @param[in] packet The packet to be fragmented. |
|
| - | 249 | * @param[in,out] new_packet The new packet fragment. |
|
| - | 250 | * @param[in,out] header The original packet header. |
|
| - | 251 | * @param[in,out] new_header The new packet fragment header. |
|
| - | 252 | * @param[in] length The new fragment length. |
|
| - | 253 | * @param[in] src The source address. |
|
| - | 254 | * @param[in] dest The destiantion address. |
|
| - | 255 | * @param[in] addrlen The address length. |
|
| - | 256 | * @returns EOK on success. |
|
| - | 257 | * @returns ENOMEM if the target packet is too small. |
|
| - | 258 | * @returns Other error codes as defined for the packet_set_addr() function. |
|
| - | 259 | * @returns Other error codes as defined for the pq_insert_after() function. |
|
| - | 260 | */ |
|
| 179 | 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 ); |
261 | 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 ); |
| - | 262 | ||
| - | 263 | /** Prefixes a middle fragment header based on the last fragment header to the packet. |
|
| - | 264 | * @param[in] packet The packet to be prefixed. |
|
| - | 265 | * @param[in] last The last header to be copied. |
|
| - | 266 | * @returns The prefixed middle header. |
|
| - | 267 | * @returns NULL on error. |
|
| - | 268 | */ |
|
| 180 | ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ); |
269 | ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ); |
| - | 270 | ||
| - | 271 | /** Copies the fragment header. |
|
| - | 272 | * Copies only the header itself and relevant IP options. |
|
| - | 273 | * @param[out] last The created header. |
|
| - | 274 | * @param[in] first The original header to be copied. |
|
| - | 275 | */ |
|
| 181 | void ip_create_last_header( ip_header_ref last, ip_header_ref first ); |
276 | void ip_create_last_header( ip_header_ref last, ip_header_ref first ); |
| 182 | 277 | ||
| - | 278 | /** Returns the network interface's IP address. |
|
| - | 279 | * @param[in] netif The network interface. |
|
| - | 280 | * @returns The IP address. |
|
| - | 281 | * @returns NULL if no IP address was found. |
|
| - | 282 | */ |
|
| 183 | in_addr_t * ip_netif_address( ip_netif_ref netif ); |
283 | in_addr_t * ip_netif_address( ip_netif_ref netif ); |
| - | 284 | ||
| - | 285 | /** Searches all network interfaces if there is a suitable route. |
|
| - | 286 | * @param[in] destination The destination address. |
|
| - | 287 | * @returns The found route. |
|
| - | 288 | * @returns NULL if no route was found. |
|
| - | 289 | */ |
|
| 184 | ip_route_ref ip_find_route( in_addr_t destination ); |
290 | ip_route_ref ip_find_route( in_addr_t destination ); |
| - | 291 | ||
| - | 292 | /** Searches the network interfaces if there is a suitable route. |
|
| - | 293 | * @param[in] netif The network interface to be searched for routes. May be NULL. |
|
| - | 294 | * @param[in] destination The destination address. |
|
| - | 295 | * @returns The found route. |
|
| - | 296 | * @returns NULL if no route was found. |
|
| - | 297 | */ |
|
| 185 | ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ); |
298 | ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ); |
| 186 | 299 | ||
| 187 | /** Processes the received IP packet. |
300 | /** Processes the received IP packet or the packet queue one by one. |
| - | 301 | * The packet is either passed to another module or released on error. |
|
| 188 | * @param device_id The source device identifier. Input parameter. |
302 | * @param[in] device_id The source device identifier. |
| 189 | * @param packet The received packet. Input/output parameter. |
303 | * @param[in,out] packet The received packet. |
| 190 | * @returns EOK on success and the packet is no longer needed. |
304 | * @returns EOK on success and the packet is no longer needed. |
| 191 | * @returns EINVAL if the packet is too small to carry the IP packet. |
305 | * @returns EINVAL if the packet is too small to carry the IP packet. |
| 192 | * @returns EINVAL if the received address lengths differs from the registered values. |
306 | * @returns EINVAL if the received address lengths differs from the registered values. |
| 193 | * @returns ENOENT if the device is not found in the cache. |
307 | * @returns ENOENT if the device is not found in the cache. |
| 194 | * @returns ENOENT if the protocol for the device is not found in the cache. |
308 | * @returns ENOENT if the protocol for the device is not found in the cache. |
| 195 | * @returns ENOMEM if there is not enough memory left. |
309 | * @returns ENOMEM if there is not enough memory left. |
| 196 | */ |
310 | */ |
| 197 | int ip_receive_message( device_id_t device_id, packet_t packet ); |
311 | int ip_receive_message( device_id_t device_id, packet_t packet ); |
| 198 | 312 | ||
| - | 313 | /** Processes the received packet. |
|
| - | 314 | * The packet is either passed to another module or released on error. |
|
| - | 315 | * The ICMP_PARAM_POINTER error notification may be sent if the checksum is invalid. |
|
| - | 316 | * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two (2). |
|
| - | 317 | * The ICMP_HOST_UNREACH error notification may be sent if no route was found. |
|
| - | 318 | * The ICMP_HOST_UNREACH error notification may be sent if the packet is for another host and the routing is disabled. |
|
| - | 319 | * @param[in] device_id The source device identifier. |
|
| - | 320 | * @param[in] packet The received packet to be processed. |
|
| - | 321 | * @returns EOK on success. |
|
| - | 322 | * @returns EINVAL if the TTL is less than two (2). |
|
| - | 323 | * @returns EINVAL if the checksum is invalid. |
|
| - | 324 | * @returns EAFNOSUPPORT if the address family is not supported. |
|
| - | 325 | * @returns ENOENT if no route was found. |
|
| - | 326 | * @returns ENOENT if the packet is for another host and the routing is disabled. |
|
| - | 327 | */ |
|
| 199 | int ip_process_packet( device_id_t device_id, packet_t packet ); |
328 | int ip_process_packet( device_id_t device_id, packet_t packet ); |
| - | 329 | ||
| - | 330 | /** Returns the packet destination address from the IP header. |
|
| - | 331 | * @param[in] header The packet IP header to be read. |
|
| - | 332 | * @returns The packet destination address. |
|
| - | 333 | */ |
|
| 200 | in_addr_t ip_get_destination( ip_header_ref header ); |
334 | in_addr_t ip_get_destination( ip_header_ref header ); |
| - | 335 | ||
| - | 336 | /** Delivers the packet to the local host. |
|
| - | 337 | * The packet is either passed to another module or released on error. |
|
| - | 338 | * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not found. |
|
| - | 339 | * @param[in] device_id The source device identifier. |
|
| - | 340 | * @param[in] packet The packet to be delivered. |
|
| - | 341 | * @param[in] header The first packet IP header. May be NULL. |
|
| - | 342 | * @param[in] error The packet error service. |
|
| - | 343 | * @returns EOK on success. |
|
| - | 344 | * @returns ENOTSUP if the packet is a fragment. |
|
| - | 345 | * @returns EAFNOSUPPORT if the address family is not supported. |
|
| - | 346 | * @returns ENOENT if the target protocol is not found. |
|
| - | 347 | * @returns Other error codes as defined for the packet_set_addr() function. |
|
| - | 348 | * @returns Other error codes as defined for the packet_trim() function. |
|
| - | 349 | * @returns Other error codes as defined for the protocol specific tl_received_msg function. |
|
| - | 350 | */ |
|
| 201 | int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ); |
351 | int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ); |
| 202 | 352 | ||
| - | 353 | /** Prepares the ICMP notification packet. |
|
| - | 354 | * Releases additional packets and keeps only the first one. |
|
| - | 355 | * All packets is released on error. |
|
| - | 356 | * @param[in] error The packet error service. |
|
| - | 357 | * @param[in] packet The packet or the packet queue to be reported as faulty. |
|
| - | 358 | * @param[in] header The first packet IP header. May be NULL. |
|
| - | 359 | * @returns The found ICMP phone. |
|
| - | 360 | * @returns EINVAL if the error parameter is set. |
|
| - | 361 | * @returns EINVAL if the ICMP phone is not found. |
|
| - | 362 | * @returns EINVAL if the ip_prepare_icmp() fails. |
|
| - | 363 | */ |
|
| 203 | int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ); |
364 | int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ); |
| - | 365 | ||
| - | 366 | /** Returns the ICMP phone. |
|
| - | 367 | * Searches the registered protocols. |
|
| - | 368 | * @returns The found ICMP phone. |
|
| - | 369 | * @returns ENOENT if the ICMP is not registered. |
|
| - | 370 | */ |
|
| 204 | int ip_get_icmp_phone( void ); |
371 | int ip_get_icmp_phone( void ); |
| - | 372 | ||
| - | 373 | /** Prepares the ICMP notification packet. |
|
| - | 374 | * Releases additional packets and keeps only the first one. |
|
| - | 375 | * @param[in] packet The packet or the packet queue to be reported as faulty. |
|
| - | 376 | * @param[in] header The first packet IP header. May be NULL. |
|
| - | 377 | * @returns EOK on success. |
|
| - | 378 | * @returns EINVAL if there are no data in the packet. |
|
| - | 379 | * @returns EINVAL if the packet is a fragment. |
|
| - | 380 | * @returns ENOMEM if the packet is too short to contain the IP header. |
|
| - | 381 | * @returns EAFNOSUPPORT if the address family is not supported. |
|
| - | 382 | * @returns Other error codes as defined for the packet_set_addr(). |
|
| - | 383 | */ |
|
| 205 | int ip_prepare_icmp( packet_t packet, ip_header_ref header ); |
384 | int ip_prepare_icmp( packet_t packet, ip_header_ref header ); |
| 206 | 385 | ||
| - | 386 | /** Releases the packet and returns the result. |
|
| - | 387 | * @param[in] packet The packet queue to be released. |
|
| - | 388 | * @param[in] result The result to be returned. |
|
| - | 389 | * @return The result parameter. |
|
| - | 390 | */ |
|
| 207 | int ip_release_and_return( packet_t packet, int result ); |
391 | int ip_release_and_return( packet_t packet, int result ); |
| 208 | 392 | ||
| 209 | int ip_initialize( async_client_conn_t client_connection ){ |
393 | int ip_initialize( async_client_conn_t client_connection ){ |
| 210 | ERROR_DECLARE; |
394 | ERROR_DECLARE; |
| 211 | 395 | ||
| Line 1048... | Line 1232... | ||
| 1048 | dest_in6.sin6_family = AF_INET6; |
1232 | dest_in6.sin6_family = AF_INET6; |
| 1049 | memcpy( & dest_in6.sin6_addr.s6_addr, ); |
1233 | memcpy( & dest_in6.sin6_addr.s6_addr, ); |
| 1050 | dest = ( struct sockaddr * ) & dest_in; |
1234 | dest = ( struct sockaddr * ) & dest_in; |
| 1051 | break; |
1235 | break; |
| 1052 | */ default: |
1236 | */ default: |
| 1053 | return EAFNOSUPPORT; |
1237 | return ip_release_and_return( packet, EAFNOSUPPORT ); |
| 1054 | } |
1238 | } |
| 1055 | ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen )); |
1239 | ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen )); |
| 1056 | route = ip_find_route( dest ); |
1240 | route = ip_find_route( dest ); |
| 1057 | if( ! route ){ |
1241 | if( ! route ){ |
| 1058 | phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); |
1242 | phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); |