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