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