Changes in uspace/srv/net/il/ip/ip.c [014dd57b:ccca251] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
r014dd57b rccca251 41 41 #include <stdio.h> 42 42 #include <str.h> 43 #include <ipc/ipc.h>44 43 #include <ipc/services.h> 45 44 #include <ipc/net.h> … … 67 66 #include <net_checksum.h> 68 67 #include <icmp_client.h> 69 #include <icmp_ interface.h>68 #include <icmp_remote.h> 70 69 #include <ip_client.h> 71 70 #include <ip_interface.h> … … 177 176 socklen_t addrlen; 178 177 179 / / detach the first packet and release the others178 /* Detach the first packet and release the others */ 180 179 next = pq_detach(packet); 181 180 if (next) … … 186 185 return ENOMEM; 187 186 188 / / get header187 /* Get header */ 189 188 header = (ip_header_t *) packet_get_data(packet); 190 189 if (!header) … … 193 192 } 194 193 195 / / only for the first fragment194 /* Only for the first fragment */ 196 195 if (IP_FRAGMENT_OFFSET(header)) 197 196 return EINVAL; 198 197 199 / / not for the ICMP protocol198 /* Not for the ICMP protocol */ 200 199 if (header->protocol == IPPROTO_ICMP) 201 200 return EPERM; 202 201 203 / / set the destination address202 /* Set the destination address */ 204 203 switch (header->version) { 205 204 case IPVERSION: … … 352 351 configuration = &names[0]; 353 352 354 / / get configuration353 /* Get configuration */ 355 354 rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, 356 355 &configuration, count, &data); … … 420 419 } 421 420 422 / / binds the netif service which also initializes the device421 /* Bind netif service which also initializes the device */ 423 422 ip_netif->phone = nil_bind_service(ip_netif->service, 424 423 (sysarg_t) ip_netif->device_id, SERVICE_IP, … … 430 429 } 431 430 432 / / has to be after the device netif module initialization431 /* Has to be after the device netif module initialization */ 433 432 if (ip_netif->arp) { 434 433 if (route) { … … 446 445 } 447 446 448 / / get packet dimensions447 /* Get packet dimensions */ 449 448 rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id, 450 449 &ip_netif->packet_dimension); … … 464 463 465 464 if (gateway.s_addr) { 466 / / the default gateway465 /* The default gateway */ 467 466 ip_globals.gateway.address.s_addr = 0; 468 467 ip_globals.gateway.netmask.s_addr = 0; … … 506 505 if (rc != EOK) { 507 506 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 508 ip_routes_destroy(&ip_netif->routes );507 ip_routes_destroy(&ip_netif->routes, free); 509 508 free(ip_netif); 510 509 return rc; … … 513 512 ip_netif->arp->usage++; 514 513 515 / / print the settings514 /* Print the settings */ 516 515 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 517 516 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, … … 588 587 ip_netif_t *netif; 589 588 590 / / start with the last netif - the newest one589 /* Start with the last netif - the newest one */ 591 590 index = ip_netifs_count(&ip_globals.netifs) - 1; 592 591 while (index >= 0) { … … 630 629 size_t length; 631 630 632 / / copy first itself631 /* Copy first itself */ 633 632 memcpy(last, first, sizeof(ip_header_t)); 634 633 length = sizeof(ip_header_t); 635 634 next = sizeof(ip_header_t); 636 635 637 / / process all ip options636 /* Process all IP options */ 638 637 while (next < first->header_length) { 639 638 option = (ip_option_t *) (((uint8_t *) first) + next); 640 / / skip end or noop639 /* Skip end or noop */ 641 640 if ((option->type == IPOPT_END) || 642 641 (option->type == IPOPT_NOOP)) { 643 642 next++; 644 643 } else { 645 / / copy if told so or skip644 /* Copy if told so or skip */ 646 645 if (IPOPT_COPIED(option->type)) { 647 646 memcpy(((uint8_t *) last) + length, … … 649 648 length += option->length; 650 649 } 651 / / next option650 /* Next option */ 652 651 next += option->length; 653 652 } 654 653 } 655 654 656 / / align 4 byte boundary655 /* Align 4 byte boundary */ 657 656 if (length % 4) { 658 657 bzero(((uint8_t *) last) + length, 4 - (length % 4)); … … 790 789 791 790 header->total_length = htons(length); 792 / / unnecessary for all protocols791 /* Unnecessary for all protocols */ 793 792 header->header_checksum = IP_HEADER_CHECKSUM(header); 794 793 … … 917 916 return ENOMEM; 918 917 919 / / get header918 /* Get header */ 920 919 header = (ip_header_t *) packet_get_data(packet); 921 920 if (!header) 922 921 return EINVAL; 923 922 924 / / fragmentation forbidden?923 /* Fragmentation forbidden? */ 925 924 if(header->flags & IPFLAG_DONT_FRAGMENT) 926 925 return EPERM; 927 926 928 / / create the last fragment927 /* Create the last fragment */ 929 928 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, 930 929 suffix, ((addrlen > addr_len) ? addrlen : addr_len)); … … 932 931 return ENOMEM; 933 932 934 / / allocate as much as originally933 /* Allocate as much as originally */ 935 934 last_header = (ip_header_t *) packet_suffix(new_packet, 936 935 IP_HEADER_LENGTH(header)); … … 940 939 ip_create_last_header(last_header, header); 941 940 942 / / trim the unused space941 /* Trim the unused space */ 943 942 rc = packet_trim(new_packet, 0, 944 943 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)); … … 946 945 return ip_release_and_return(packet, rc); 947 946 948 / / biggest multiple of 8 lower than content947 /* Greatest multiple of 8 lower than content */ 949 948 // TODO even fragmentation? 950 949 length = length & ~0x7; … … 958 957 return ip_release_and_return(packet, rc); 959 958 960 / / mark the first as fragmented959 /* Mark the first as fragmented */ 961 960 header->flags |= IPFLAG_MORE_FRAGMENTS; 962 961 963 / / create middle framgents962 /* Create middle fragments */ 964 963 while (IP_TOTAL_LENGTH(header) > length) { 965 964 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, … … 982 981 } 983 982 984 / / finish the first fragment983 /* Finish the first fragment */ 985 984 header->header_checksum = IP_HEADER_CHECKSUM(header); 986 985 … … 1013 1012 1014 1013 next = packet; 1015 / / check all packets1014 /* Check all packets */ 1016 1015 while (next) { 1017 1016 length = packet_get_data_length(next); … … 1022 1021 } 1023 1022 1024 / / too long1023 /* Too long */ 1025 1024 result = ip_fragment_packet(next, content, prefix, 1026 1025 suffix, addr_len); … … 1028 1027 new_packet = pq_detach(next); 1029 1028 if (next == packet) { 1030 / / the new first packet of the queue1029 /* The new first packet of the queue */ 1031 1030 packet = new_packet; 1032 1031 } 1033 / / fragmentation needed?1032 /* Fragmentation needed? */ 1034 1033 if (result == EPERM) { 1035 1034 phone = ip_prepare_icmp_and_get_phone( 1036 1035 error, next, NULL); 1037 1036 if (phone >= 0) { 1038 / / fragmentation necessary ICMP1037 /* Fragmentation necessary ICMP */ 1039 1038 icmp_destination_unreachable_msg(phone, 1040 1039 ICMP_FRAG_NEEDED, content, next); … … 1081 1080 int rc; 1082 1081 1083 / / get destination hardware address1082 /* Get destination hardware address */ 1084 1083 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 1085 1084 destination.value = route->gateway.s_addr ? … … 1103 1102 NULL); 1104 1103 if (phone >= 0) { 1105 / / unreachable ICMP if no routing1104 /* Unreachable ICMP if no routing */ 1106 1105 icmp_destination_unreachable_msg(phone, 1107 1106 ICMP_HOST_UNREACH, 0, packet); … … 1149 1148 int rc; 1150 1149 1151 // addresses in the host byte order 1152 // should be the next hop address or the target destination address 1150 /* 1151 * Addresses in the host byte order 1152 * Should be the next hop address or the target destination address 1153 */ 1153 1154 addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr); 1154 1155 if (addrlen < 0) … … 1175 1176 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1176 1177 1177 / / device specified?1178 /* Device specified? */ 1178 1179 if (device_id > 0) { 1179 1180 netif = ip_netifs_find(&ip_globals.netifs, device_id); … … 1191 1192 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL); 1192 1193 if (phone >= 0) { 1193 / / unreachable ICMP if no routing1194 /* Unreachable ICMP if no routing */ 1194 1195 icmp_destination_unreachable_msg(phone, 1195 1196 ICMP_NET_UNREACH, 0, packet); … … 1199 1200 1200 1201 if (error) { 1201 // do not send for broadcast, anycast packets or network 1202 // broadcast 1202 /* 1203 * Do not send for broadcast, anycast packets or network 1204 * broadcast. 1205 */ 1203 1206 if (!dest->s_addr || !(~dest->s_addr) || 1204 1207 !(~((dest->s_addr & ~route->netmask.s_addr) | … … 1209 1212 } 1210 1213 1211 / / if the local host is the destination1214 /* If the local host is the destination */ 1212 1215 if ((route->address.s_addr == dest->s_addr) && 1213 1216 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) { 1214 / / find the loopback device to deliver1217 /* Find the loopback device to deliver */ 1215 1218 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1216 1219 route = ip_find_route(*dest); … … 1221 1224 NULL); 1222 1225 if (phone >= 0) { 1223 / / unreachable ICMP if no routing1226 /* Unreachable ICMP if no routing */ 1224 1227 icmp_destination_unreachable_msg(phone, 1225 1228 ICMP_HOST_UNREACH, 0, packet); … … 1253 1256 1254 1257 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1255 / / find the device1258 /* Find the device */ 1256 1259 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1257 1260 if (!netif) { … … 1345 1348 return ip_release_and_return(packet, rc); 1346 1349 1347 / / trim padding if present1350 /* Trim padding if present */ 1348 1351 if (!error && 1349 1352 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { … … 1361 1364 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1362 1365 if (phone >= 0) { 1363 / / unreachable ICMP1366 /* Unreachable ICMP */ 1364 1367 icmp_destination_unreachable_msg(phone, 1365 1368 ICMP_PROT_UNREACH, 0, packet); … … 1418 1421 return ip_release_and_return(packet, ENOMEM); 1419 1422 1420 / / checksum1423 /* Checksum */ 1421 1424 if ((header->header_checksum) && 1422 1425 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1423 1426 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1424 1427 if (phone >= 0) { 1425 / / checksum error ICMP1428 /* Checksum error ICMP */ 1426 1429 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1427 1430 ((size_t) ((void *) &header->header_checksum)) - … … 1434 1437 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1435 1438 if (phone >= 0) { 1436 / / ttl exceeded ICMP1439 /* TTL exceeded ICMP */ 1437 1440 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1438 1441 } … … 1440 1443 } 1441 1444 1442 / / process ipopt and get destination1445 /* Process ipopt and get destination */ 1443 1446 dest = ip_get_destination(header); 1444 1447 1445 / / set the addrination address1448 /* Set the destination address */ 1446 1449 switch (header->version) { 1447 1450 case IPVERSION: … … 1465 1468 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1466 1469 if (phone >= 0) { 1467 / / unreachable ICMP1470 /* Unreachable ICMP */ 1468 1471 icmp_destination_unreachable_msg(phone, 1469 1472 ICMP_HOST_UNREACH, 0, packet); … … 1473 1476 1474 1477 if (route->address.s_addr == dest.s_addr) { 1475 / / local delivery1478 /* Local delivery */ 1476 1479 return ip_deliver_local(device_id, packet, header, 0); 1477 1480 } … … 1485 1488 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1486 1489 if (phone >= 0) { 1487 / / unreachable ICMP if no routing1490 /* Unreachable ICMP if no routing */ 1488 1491 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1489 1492 packet); … … 1596 1599 rc = ip_device_state_message(IPC_GET_DEVICE(*icall), 1597 1600 IPC_GET_STATE(*icall)); 1598 ipc_answer_0(iid, (sysarg_t) rc);1601 async_answer_0(iid, (sysarg_t) rc); 1599 1602 break; 1600 1603 … … 1610 1613 } 1611 1614 1612 ipc_answer_0(iid, (sysarg_t) rc);1615 async_answer_0(iid, (sysarg_t) rc); 1613 1616 break; 1614 1617 … … 1616 1619 rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall), 1617 1620 IPC_GET_MTU(*icall)); 1618 ipc_answer_0(iid, (sysarg_t) rc);1621 async_answer_0(iid, (sysarg_t) rc); 1619 1622 break; 1620 1623 1621 1624 default: 1622 ipc_answer_0(iid, (sysarg_t) ENOTSUP);1625 async_answer_0(iid, (sysarg_t) ENOTSUP); 1623 1626 } 1624 1627 … … 1771 1774 header = (ip_header_t *)(data + offset); 1772 1775 1773 / / destination host unreachable?1776 /* Destination host unreachable? */ 1774 1777 if ((type != ICMP_DEST_UNREACH) || 1775 1778 (code != ICMP_HOST_UNREACH)) { 1776 // no, something else1779 /* No, something else */ 1777 1780 break; 1778 1781 } … … 1788 1791 route = ip_routes_get_index(&netif->routes, 0); 1789 1792 1790 / / from the same network?1793 /* From the same network? */ 1791 1794 if (route && ((route->address.s_addr & route->netmask.s_addr) == 1792 1795 (header->destination_address & route->netmask.s_addr))) { 1793 / / clear the ARP mapping if any1796 /* Clear the ARP mapping if any */ 1794 1797 address.value = (uint8_t *) &header->destination_address; 1795 1798 address.length = sizeof(header->destination_address); … … 1845 1848 fibril_rwlock_read_lock(&ip_globals.lock); 1846 1849 route = ip_find_route(*dest); 1847 / / if the local host is the destination1850 /* If the local host is the destination */ 1848 1851 if (route && (route->address.s_addr == dest->s_addr) && 1849 1852 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) { 1850 / / find the loopback device to deliver1853 /* Find the loopback device to deliver */ 1851 1854 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1852 1855 route = ip_find_route(*dest);
Note:
See TracChangeset
for help on using the changeset viewer.