Changes in uspace/srv/net/il/ip/ip.c [ffa2c8ef:6b82009] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
rffa2c8ef r6b82009 120 120 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 121 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. 122 static void ip_receiver(ipc_callid_t, ipc_call_t *, void *); 123 124 /** Release the packet and returns the result. 125 * 126 * @param[in] packet Packet queue to be released. 127 * @param[in] result Result to be returned. 128 * 129 * @return Result parameter. 130 * 129 131 */ 130 132 static int ip_release_and_return(packet_t *packet, int result) 131 133 { 132 pq_release_remote(ip_globals.net_ phone, packet_get_id(packet));134 pq_release_remote(ip_globals.net_sess, packet_get_id(packet)); 133 135 return result; 134 136 } 135 137 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 138 /** Return the ICMP session. 139 * 140 * Search the registered protocols. 141 * 142 * @return Found ICMP session. 143 * @return NULL if the ICMP is not registered. 144 * 145 */ 146 static async_sess_t *ip_get_icmp_session(void) 147 { 148 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;149 ip_proto_t *proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP); 150 async_sess_t *sess = proto ? proto->sess : NULL; 151 151 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 152 return phone; 152 153 return sess; 153 154 } 154 155 … … 176 177 socklen_t addrlen; 177 178 178 / / detach the first packet and release the others179 /* Detach the first packet and release the others */ 179 180 next = pq_detach(packet); 180 181 if (next) 181 pq_release_remote(ip_globals.net_ phone, packet_get_id(next));182 pq_release_remote(ip_globals.net_sess, packet_get_id(next)); 182 183 183 184 if (!header) { … … 185 186 return ENOMEM; 186 187 187 / / get header188 /* 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 fragment195 /* Only for the first fragment */ 195 196 if (IP_FRAGMENT_OFFSET(header)) 196 197 return EINVAL; 197 198 198 / / not for the ICMP protocol199 /* Not for the ICMP protocol */ 199 200 if (header->protocol == IPPROTO_ICMP) 200 201 return EPERM; 201 202 202 / / set the destination address203 switch ( header->version) {203 /* Set the destination address */ 204 switch (GET_IP_HEADER_VERSION(header)) { 204 205 case IPVERSION: 205 206 addrlen = sizeof(dest_in); … … 218 219 } 219 220 220 /** Prepare sthe ICMP notification packet.221 * 222 * Release s additional packets and keepsonly the first one.221 /** Prepare the ICMP notification packet. 222 * 223 * Release additional packets and keep only the first one. 223 224 * All packets are released on error. 224 225 * 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) 226 * @param[in] error Packet error service. 227 * @param[in] packet Packet or the packet queue to be reported as faulty. 228 * @param[in] header First packet IP header. May be NULL. 229 * 230 * @return Found ICMP session. 231 * @return NULL if the error parameter is set. 232 * @return NULL if the ICMP session is not found. 233 * @return NULL if the ip_prepare_icmp() fails. 234 * 235 */ 236 static async_sess_t *ip_prepare_icmp_and_get_session(services_t error, 237 packet_t *packet, ip_header_t *header) 238 { 239 async_sess_t *sess = ip_get_icmp_session(); 240 241 if ((error) || (!sess) || (ip_prepare_icmp(packet, header))) { 242 pq_release_remote(ip_globals.net_sess, packet_get_id(packet)); 243 return NULL; 244 } 245 246 return sess; 247 } 248 249 int il_initialize(async_sess_t *net_sess) 246 250 { 247 251 fibril_rwlock_initialize(&ip_globals.lock); … … 250 254 fibril_rwlock_initialize(&ip_globals.netifs_lock); 251 255 252 ip_globals.net_ phone = net_phone;256 ip_globals.net_sess = net_sess; 253 257 ip_globals.packet_counter = 0; 254 258 ip_globals.gateway.address.s_addr = 0; … … 351 355 configuration = &names[0]; 352 356 353 / / get configuration354 rc = net_get_device_conf_req(ip_globals.net_ phone, ip_netif->device_id,357 /* Get configuration */ 358 rc = net_get_device_conf_req(ip_globals.net_sess, ip_netif->device_id, 355 359 &configuration, count, &data); 356 360 if (rc != EOK) … … 419 423 } 420 424 421 / / binds the netif service which also initializes the device422 ip_netif-> phone= nil_bind_service(ip_netif->service,425 /* Bind netif service which also initializes the device */ 426 ip_netif->sess = nil_bind_service(ip_netif->service, 423 427 (sysarg_t) ip_netif->device_id, SERVICE_IP, 424 428 ip_receiver); 425 if (ip_netif-> phone < 0) {429 if (ip_netif->sess == NULL) { 426 430 printf("Failed to contact the nil service %d\n", 427 431 ip_netif->service); 428 return ip_netif->phone;429 } 430 431 / / has to be after the device netif module initialization432 return ENOENT; 433 } 434 435 /* Has to be after the device netif module initialization */ 432 436 if (ip_netif->arp) { 433 437 if (route) { … … 435 439 address.length = sizeof(in_addr_t); 436 440 437 rc = arp_device_req(ip_netif->arp-> phone,441 rc = arp_device_req(ip_netif->arp->sess, 438 442 ip_netif->device_id, SERVICE_IP, ip_netif->service, 439 443 &address); … … 445 449 } 446 450 447 / / get packet dimensions448 rc = nil_packet_size_req(ip_netif-> phone, ip_netif->device_id,451 /* Get packet dimensions */ 452 rc = nil_packet_size_req(ip_netif->sess, ip_netif->device_id, 449 453 &ip_netif->packet_dimension); 450 454 if (rc != EOK) … … 463 467 464 468 if (gateway.s_addr) { 465 / / the default gateway469 /* The default gateway */ 466 470 ip_globals.gateway.address.s_addr = 0; 467 471 ip_globals.gateway.netmask.s_addr = 0; … … 478 482 } 479 483 480 static int ip_device_req_local(int il_phone, device_id_t device_id, 481 services_t netif) 484 static int ip_device_req_local(device_id_t device_id, services_t netif) 482 485 { 483 486 ip_netif_t *ip_netif; … … 505 508 if (rc != EOK) { 506 509 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 507 ip_routes_destroy(&ip_netif->routes );510 ip_routes_destroy(&ip_netif->routes, free); 508 511 free(ip_netif); 509 512 return rc; … … 512 515 ip_netif->arp->usage++; 513 516 514 / / print the settings515 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 /* Print the settings */ 518 printf("%s: Device registered (id: %d, ipv: %d, conf: %s)\n", 519 NAME, ip_netif->device_id, ip_netif->ipv, 517 520 ip_netif->dhcp ? "dhcp" : "static"); 518 521 … … 587 590 ip_netif_t *netif; 588 591 589 / / start with the last netif - the newest one592 /* Start with the last netif - the newest one */ 590 593 index = ip_netifs_count(&ip_globals.netifs) - 1; 591 594 while (index >= 0) { … … 629 632 size_t length; 630 633 631 / / copy first itself634 /* Copy first itself */ 632 635 memcpy(last, first, sizeof(ip_header_t)); 633 636 length = sizeof(ip_header_t); 634 637 next = sizeof(ip_header_t); 635 638 636 / / process all ip options637 while (next < first->header_length) {639 /* Process all IP options */ 640 while (next < GET_IP_HEADER_LENGTH(first)) { 638 641 option = (ip_option_t *) (((uint8_t *) first) + next); 639 / / skip end or noop642 /* Skip end or noop */ 640 643 if ((option->type == IPOPT_END) || 641 644 (option->type == IPOPT_NOOP)) { 642 645 next++; 643 646 } else { 644 / / copy if told so or skip647 /* Copy if told so or skip */ 645 648 if (IPOPT_COPIED(option->type)) { 646 649 memcpy(((uint8_t *) last) + length, … … 648 651 length += option->length; 649 652 } 650 / / next option653 /* Next option */ 651 654 next += option->length; 652 655 } 653 656 } 654 657 655 / / align 4 byte boundary658 /* Align 4 byte boundary */ 656 659 if (length % 4) { 657 660 bzero(((uint8_t *) last) + length, 4 - (length % 4)); 658 last->header_length = length / 4 + 1;661 SET_IP_HEADER_LENGTH(last, (length / 4 + 1)); 659 662 } else { 660 last->header_length = length / 4;663 SET_IP_HEADER_LENGTH(last, (length / 4)); 661 664 } 662 665 … … 706 709 return rc; 707 710 708 header->version = IPV4;709 header->fragment_offset_high = 0;711 SET_IP_HEADER_VERSION(header, IPV4); 712 SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header, 0); 710 713 header->fragment_offset_low = 0; 711 714 header->header_checksum = 0; … … 735 738 memcpy(middle_header, last_header, 736 739 IP_HEADER_LENGTH(last_header)); 737 header->flags |= IPFLAG_MORE_FRAGMENTS; 740 SET_IP_HEADER_FLAGS(header, 741 (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS)); 738 742 middle_header->total_length = 739 743 htons(packet_get_data_length(next)); 740 middle_header->fragment_offset_high =741 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) ;744 SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(middle_header, 745 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length)); 742 746 middle_header->fragment_offset_low = 743 747 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); … … 768 772 middle_header->total_length = 769 773 htons(packet_get_data_length(next)); 770 middle_header->fragment_offset_high =771 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) ;774 SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(middle_header, 775 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length)); 772 776 middle_header->fragment_offset_low = 773 777 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); … … 785 789 length += packet_get_data_length(next); 786 790 free(last_header); 787 header->flags |= IPFLAG_MORE_FRAGMENTS; 791 SET_IP_HEADER_FLAGS(header, 792 (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS)); 788 793 } 789 794 790 795 header->total_length = htons(length); 791 / / unnecessary for all protocols796 /* Unnecessary for all protocols */ 792 797 header->header_checksum = IP_HEADER_CHECKSUM(header); 793 798 … … 834 839 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); 835 840 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header); 836 new_header->fragment_offset_high =837 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset) ;841 SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(new_header, 842 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset)); 838 843 new_header->fragment_offset_low = 839 844 IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); … … 865 870 return NULL; 866 871 memcpy(middle, last, IP_HEADER_LENGTH(last)); 867 middle->flags |= IPFLAG_MORE_FRAGMENTS; 872 SET_IP_HEADER_FLAGS(middle, 873 (GET_IP_HEADER_FLAGS(middle) | IPFLAG_MORE_FRAGMENTS)); 868 874 return middle; 869 875 } … … 916 922 return ENOMEM; 917 923 918 / / get header924 /* Get header */ 919 925 header = (ip_header_t *) packet_get_data(packet); 920 926 if (!header) 921 927 return EINVAL; 922 928 923 / / fragmentation forbidden?924 if( header->flags& IPFLAG_DONT_FRAGMENT)929 /* Fragmentation forbidden? */ 930 if(GET_IP_HEADER_FLAGS(header) & IPFLAG_DONT_FRAGMENT) 925 931 return EPERM; 926 932 927 / / create the last fragment928 new_packet = packet_get_4_remote(ip_globals.net_ phone, prefix, length,933 /* Create the last fragment */ 934 new_packet = packet_get_4_remote(ip_globals.net_sess, prefix, length, 929 935 suffix, ((addrlen > addr_len) ? addrlen : addr_len)); 930 936 if (!new_packet) 931 937 return ENOMEM; 932 938 933 / / allocate as much as originally939 /* Allocate as much as originally */ 934 940 last_header = (ip_header_t *) packet_suffix(new_packet, 935 941 IP_HEADER_LENGTH(header)); … … 939 945 ip_create_last_header(last_header, header); 940 946 941 / / trim the unused space947 /* Trim the unused space */ 942 948 rc = packet_trim(new_packet, 0, 943 949 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)); … … 945 951 return ip_release_and_return(packet, rc); 946 952 947 / / biggest multiple of 8 lower than content953 /* Greatest multiple of 8 lower than content */ 948 954 // TODO even fragmentation? 949 955 length = length & ~0x7; … … 957 963 return ip_release_and_return(packet, rc); 958 964 959 // mark the first as fragmented 960 header->flags |= IPFLAG_MORE_FRAGMENTS; 961 962 // create middle framgents 965 /* Mark the first as fragmented */ 966 SET_IP_HEADER_FLAGS(header, 967 (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS)); 968 969 /* Create middle fragments */ 963 970 while (IP_TOTAL_LENGTH(header) > length) { 964 new_packet = packet_get_4_remote(ip_globals.net_ phone, prefix,971 new_packet = packet_get_4_remote(ip_globals.net_sess, prefix, 965 972 length, suffix, 966 973 ((addrlen >= addr_len) ? addrlen : addr_len)); … … 981 988 } 982 989 983 / / finish the first fragment990 /* Finish the first fragment */ 984 991 header->header_checksum = IP_HEADER_CHECKSUM(header); 985 992 … … 987 994 } 988 995 989 /** Check sthe packet queue lengths and fragments the packets if needed.996 /** Check the packet queue lengths and fragments the packets if needed. 990 997 * 991 998 * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to 992 999 * be fragmented and the fragmentation is not allowed. 993 1000 * 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) 1001 * @param[in,out] packet Packet or the packet queue to be checked. 1002 * @param[in] prefix Minimum prefix size. 1003 * @param[in] content Maximum content size. 1004 * @param[in] suffix Minimum suffix size. 1005 * @param[in] addr_len Minimum address length. 1006 * @param[in] error Error module service. 1007 * 1008 * @return The packet or the packet queue of the allowed length. 1009 * @return NULL if there are no packets left. 1010 * 1011 */ 1012 static packet_t *ip_split_packet(packet_t *packet, size_t prefix, size_t content, 1013 size_t suffix, socklen_t addr_len, services_t error) 1006 1014 { 1007 1015 size_t length; … … 1009 1017 packet_t *new_packet; 1010 1018 int result; 1011 int phone;1012 1019 async_sess_t *sess; 1020 1013 1021 next = packet; 1014 / / check all packets1022 /* Check all packets */ 1015 1023 while (next) { 1016 1024 length = packet_get_data_length(next); … … 1021 1029 } 1022 1030 1023 / / too long1031 /* Too long */ 1024 1032 result = ip_fragment_packet(next, content, prefix, 1025 1033 suffix, addr_len); … … 1027 1035 new_packet = pq_detach(next); 1028 1036 if (next == packet) { 1029 / / the new first packet of the queue1037 /* The new first packet of the queue */ 1030 1038 packet = new_packet; 1031 1039 } 1032 / / fragmentation needed?1040 /* Fragmentation needed? */ 1033 1041 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, 1042 sess = ip_prepare_icmp_and_get_session(error, next, NULL); 1043 if (sess) { 1044 /* Fragmentation necessary ICMP */ 1045 icmp_destination_unreachable_msg(sess, 1039 1046 ICMP_FRAG_NEEDED, content, next); 1040 1047 } 1041 1048 } else { 1042 pq_release_remote(ip_globals.net_ phone,1049 pq_release_remote(ip_globals.net_sess, 1043 1050 packet_get_id(next)); 1044 1051 } … … 1054 1061 } 1055 1062 1056 /** Send sthe packet or the packet queue via the specified route.1063 /** Send the packet or the packet queue via the specified route. 1057 1064 * 1058 1065 * The ICMP_HOST_UNREACH error notification may be sent if route hardware 1059 1066 * destination address is found. 1060 1067 * 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.1068 * @param[in,out] packet Packet to be sent. 1069 * @param[in] netif Target network interface. 1070 * @param[in] route Target route. 1071 * @param[in] src Source address. 1072 * @param[in] dest Destination address. 1073 * @param[in] error Error module service. 1074 * 1075 * @return EOK on success. 1076 * @return Other error codes as defined for arp_translate_req(). 1077 * @return Other error codes as defined for ip_prepare_packet(). 1078 * 1072 1079 */ 1073 1080 static int ip_send_route(packet_t *packet, ip_netif_t *netif, … … 1077 1084 measured_string_t *translation; 1078 1085 uint8_t *data; 1079 int phone;1086 async_sess_t *sess; 1080 1087 int rc; 1081 1088 1082 / / get destination hardware address1089 /* Get destination hardware address */ 1083 1090 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 1084 1091 destination.value = route->gateway.s_addr ? … … 1086 1093 destination.length = sizeof(dest.s_addr); 1087 1094 1088 rc = arp_translate_req(netif->arp-> phone, netif->device_id,1095 rc = arp_translate_req(netif->arp->sess, netif->device_id, 1089 1096 SERVICE_IP, &destination, &translation, &data); 1090 1097 if (rc != EOK) { 1091 pq_release_remote(ip_globals.net_ phone,1098 pq_release_remote(ip_globals.net_sess, 1092 1099 packet_get_id(packet)); 1093 1100 return rc; … … 1099 1106 free(data); 1100 1107 } 1101 phone = ip_prepare_icmp_and_get_phone(error, packet,1108 sess = ip_prepare_icmp_and_get_session(error, packet, 1102 1109 NULL); 1103 if ( phone >= 0) {1104 / / unreachable ICMP if no routing1105 icmp_destination_unreachable_msg( phone,1110 if (sess) { 1111 /* Unreachable ICMP if no routing */ 1112 icmp_destination_unreachable_msg(sess, 1106 1113 ICMP_HOST_UNREACH, 0, packet); 1107 1114 } … … 1115 1122 rc = ip_prepare_packet(src, dest, packet, translation); 1116 1123 if (rc != EOK) { 1117 pq_release_remote(ip_globals.net_ phone, packet_get_id(packet));1124 pq_release_remote(ip_globals.net_sess, packet_get_id(packet)); 1118 1125 } else { 1119 1126 packet = ip_split_packet(packet, netif->packet_dimension.prefix, … … 1122 1129 netif->packet_dimension.addr_len, error); 1123 1130 if (packet) { 1124 nil_send_msg(netif-> phone, netif->device_id, packet,1131 nil_send_msg(netif->sess, netif->device_id, packet, 1125 1132 SERVICE_IP); 1126 1133 } … … 1135 1142 } 1136 1143 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)1144 static int ip_send_msg_local(device_id_t device_id, packet_t *packet, 1145 services_t sender, services_t error) 1139 1146 { 1140 1147 int addrlen; … … 1145 1152 in_addr_t *dest; 1146 1153 in_addr_t *src; 1147 int phone;1154 async_sess_t *sess; 1148 1155 int rc; 1149 1156 1150 // addresses in the host byte order 1151 // should be the next hop address or the target destination address 1157 /* 1158 * Addresses in the host byte order 1159 * Should be the next hop address or the target destination address 1160 */ 1152 1161 addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr); 1153 1162 if (addrlen < 0) … … 1174 1183 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1175 1184 1176 / / device specified?1185 /* Device specified? */ 1177 1186 if (device_id > 0) { 1178 1187 netif = ip_netifs_find(&ip_globals.netifs, device_id); … … 1188 1197 if (!netif || !route) { 1189 1198 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1190 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);1191 if ( phone >= 0) {1192 / / unreachable ICMP if no routing1193 icmp_destination_unreachable_msg( phone,1199 sess = ip_prepare_icmp_and_get_session(error, packet, NULL); 1200 if (sess) { 1201 /* Unreachable ICMP if no routing */ 1202 icmp_destination_unreachable_msg(sess, 1194 1203 ICMP_NET_UNREACH, 0, packet); 1195 1204 } … … 1198 1207 1199 1208 if (error) { 1200 // do not send for broadcast, anycast packets or network 1201 // broadcast 1209 /* 1210 * Do not send for broadcast, anycast packets or network 1211 * broadcast. 1212 */ 1202 1213 if (!dest->s_addr || !(~dest->s_addr) || 1203 1214 !(~((dest->s_addr & ~route->netmask.s_addr) | … … 1208 1219 } 1209 1220 1210 / / if the local host is the destination1221 /* If the local host is the destination */ 1211 1222 if ((route->address.s_addr == dest->s_addr) && 1212 1223 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) { 1213 / / find the loopback device to deliver1224 /* Find the loopback device to deliver */ 1214 1225 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1215 1226 route = ip_find_route(*dest); … … 1217 1228 if (!netif || !route) { 1218 1229 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1219 phone = ip_prepare_icmp_and_get_phone(error, packet,1230 sess = ip_prepare_icmp_and_get_session(error, packet, 1220 1231 NULL); 1221 if ( phone >= 0) {1222 / / unreachable ICMP if no routing1223 icmp_destination_unreachable_msg( phone,1232 if (sess) { 1233 /* Unreachable ICMP if no routing */ 1234 icmp_destination_unreachable_msg(sess, 1224 1235 ICMP_HOST_UNREACH, 0, packet); 1225 1236 } … … 1252 1263 1253 1264 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1254 / / find the device1265 /* Find the device */ 1255 1266 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1256 1267 if (!netif) { … … 1305 1316 { 1306 1317 ip_proto_t *proto; 1307 int phone;1318 async_sess_t *sess; 1308 1319 services_t service; 1309 1320 tl_received_msg_t received_msg; … … 1315 1326 int rc; 1316 1327 1317 if (( header->flags& IPFLAG_MORE_FRAGMENTS) ||1328 if ((GET_IP_HEADER_FLAGS(header) & IPFLAG_MORE_FRAGMENTS) || 1318 1329 IP_FRAGMENT_OFFSET(header)) { 1319 1330 // TODO fragmented … … 1321 1332 } 1322 1333 1323 switch ( header->version) {1334 switch (GET_IP_HEADER_VERSION(header)) { 1324 1335 case IPVERSION: 1325 1336 addrlen = sizeof(src_in); … … 1344 1355 return ip_release_and_return(packet, rc); 1345 1356 1346 / / trim padding if present1357 /* Trim padding if present */ 1347 1358 if (!error && 1348 1359 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { … … 1358 1369 if (!proto) { 1359 1370 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1360 phone = ip_prepare_icmp_and_get_phone(error, packet, header);1361 if ( phone >= 0) {1362 / / unreachable ICMP1363 icmp_destination_unreachable_msg( phone,1371 sess = ip_prepare_icmp_and_get_session(error, packet, header); 1372 if (sess) { 1373 /* Unreachable ICMP */ 1374 icmp_destination_unreachable_msg(sess, 1364 1375 ICMP_PROT_UNREACH, 0, packet); 1365 1376 } … … 1373 1384 rc = received_msg(device_id, packet, service, error); 1374 1385 } else { 1375 rc = tl_received_msg(proto-> phone, device_id, packet,1386 rc = tl_received_msg(proto->sess, device_id, packet, 1376 1387 proto->service, error); 1377 1388 fibril_rwlock_read_unlock(&ip_globals.protos_lock); … … 1407 1418 in_addr_t dest; 1408 1419 ip_route_t *route; 1409 int phone;1420 async_sess_t *sess; 1410 1421 struct sockaddr *addr; 1411 1422 struct sockaddr_in addr_in; … … 1417 1428 return ip_release_and_return(packet, ENOMEM); 1418 1429 1419 / / checksum1430 /* Checksum */ 1420 1431 if ((header->header_checksum) && 1421 1432 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1422 phone = ip_prepare_icmp_and_get_phone(0, packet, header);1423 if ( phone >= 0) {1424 / / checksum error ICMP1425 icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER,1433 sess = ip_prepare_icmp_and_get_session(0, packet, header); 1434 if (sess) { 1435 /* Checksum error ICMP */ 1436 icmp_parameter_problem_msg(sess, ICMP_PARAM_POINTER, 1426 1437 ((size_t) ((void *) &header->header_checksum)) - 1427 1438 ((size_t) ((void *) header)), packet); … … 1431 1442 1432 1443 if (header->ttl <= 1) { 1433 phone = ip_prepare_icmp_and_get_phone(0, packet, header);1434 if ( phone >= 0) {1435 / / ttl exceeded ICMP1436 icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet);1444 sess = ip_prepare_icmp_and_get_session(0, packet, header); 1445 if (sess) { 1446 /* TTL exceeded ICMP */ 1447 icmp_time_exceeded_msg(sess, ICMP_EXC_TTL, packet); 1437 1448 } 1438 1449 return EINVAL; 1439 1450 } 1440 1451 1441 / / process ipopt and get destination1452 /* Process ipopt and get destination */ 1442 1453 dest = ip_get_destination(header); 1443 1454 1444 / / set the addrination address1445 switch ( header->version) {1455 /* Set the destination address */ 1456 switch (GET_IP_HEADER_VERSION(header)) { 1446 1457 case IPVERSION: 1447 1458 addrlen = sizeof(addr_in); … … 1462 1473 route = ip_find_route(dest); 1463 1474 if (!route) { 1464 phone = ip_prepare_icmp_and_get_phone(0, packet, header);1465 if ( phone >= 0) {1466 / / unreachable ICMP1467 icmp_destination_unreachable_msg( phone,1475 sess = ip_prepare_icmp_and_get_session(0, packet, header); 1476 if (sess) { 1477 /* Unreachable ICMP */ 1478 icmp_destination_unreachable_msg(sess, 1468 1479 ICMP_HOST_UNREACH, 0, packet); 1469 1480 } … … 1472 1483 1473 1484 if (route->address.s_addr == dest.s_addr) { 1474 / / local delivery1485 /* Local delivery */ 1475 1486 return ip_deliver_local(device_id, packet, header, 0); 1476 1487 } … … 1482 1493 } 1483 1494 1484 phone = ip_prepare_icmp_and_get_phone(0, packet, header);1485 if ( phone >= 0) {1486 / / unreachable ICMP if no routing1487 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0,1495 sess = ip_prepare_icmp_and_get_session(0, packet, header); 1496 if (sess) { 1497 /* Unreachable ICMP if no routing */ 1498 icmp_destination_unreachable_msg(sess, ICMP_HOST_UNREACH, 0, 1488 1499 packet); 1489 1500 } … … 1492 1503 } 1493 1504 1494 /** Return sthe device packet dimensions for sending.1495 * 1496 * @param[in] phone The service module phone.1497 * @param[ in] message The service specific message.1498 * @param[ in] device_id The device identifier.1499 * @param[out] addr_len The minimum reserved address length.1500 * @param[out] prefix The minimum reserved prefix size.1501 * @param[out] content The maximum content size.1502 * @ param[out] suffix The minimum reserved suffix size.1503 * @return EOK on success.1505 /** Return the device packet dimensions for sending. 1506 * 1507 * @param[in] device_id Device identifier. 1508 * @param[out] addr_len Minimum reserved address length. 1509 * @param[out] prefix Minimum reserved prefix size. 1510 * @param[out] content Maximum content size. 1511 * @param[out] suffix Minimum reserved suffix size. 1512 * 1513 * @return EOK on success. 1514 * 1504 1515 */ 1505 1516 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len, … … 1583 1594 * @param[in] iid Message identifier. 1584 1595 * @param[in,out] icall Message parameters. 1585 * 1586 */ 1587 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall) 1596 * @param[in] arg Local argument. 1597 * 1598 */ 1599 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg) 1588 1600 { 1589 1601 packet_t *packet; … … 1599 1611 1600 1612 case NET_IL_RECEIVED: 1601 rc = packet_translate_remote(ip_globals.net_ phone, &packet,1613 rc = packet_translate_remote(ip_globals.net_sess, &packet, 1602 1614 IPC_GET_PACKET(*icall)); 1603 1615 if (rc == EOK) { … … 1626 1638 } 1627 1639 1628 /** Register sthe transport layer protocol.1640 /** Register the transport layer protocol. 1629 1641 * 1630 1642 * The traffic of this protocol will be supplied using either the receive 1631 1643 * function or IPC message. 1632 1644 * 1633 * @param[in] protocol The transport layer module protocol. 1634 * @param[in] service The transport layer module service. 1635 * @param[in] phone The transport layer module phone. 1636 * @param[in] received_msg The receiving function. 1637 * @return EOK on success. 1638 * @return EINVAL if the protocol parameter and/or the service 1639 * parameter is zero. 1640 * @return EINVAL if the phone parameter is not a positive number 1641 * and the tl_receive_msg is NULL. 1642 * @return ENOMEM if there is not enough memory left. 1643 */ 1644 static int 1645 ip_register(int protocol, services_t service, int phone, 1645 * @param[in] protocol Transport layer module protocol. 1646 * @param[in] service Transport layer module service. 1647 * @param[in] sess Transport layer module session. 1648 * @param[in] received_msg Receiving function. 1649 * 1650 * @return EOK on success. 1651 * @return EINVAL if the protocol parameter and/or the service 1652 * parameter is zero. 1653 * @return EINVAL if the phone parameter is not a positive number 1654 * and the tl_receive_msg is NULL. 1655 * @return ENOMEM if there is not enough memory left. 1656 * 1657 */ 1658 static int ip_register(int protocol, services_t service, async_sess_t *sess, 1646 1659 tl_received_msg_t received_msg) 1647 1660 { … … 1649 1662 int index; 1650 1663 1651 if ( !protocol || !service || ((phone < 0) && !received_msg))1664 if ((!protocol) || (!service) || ((!sess) && (!received_msg))) 1652 1665 return EINVAL; 1653 1666 1654 1667 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1655 1668 if (!proto) … … 1658 1671 proto->protocol = protocol; 1659 1672 proto->service = service; 1660 proto-> phone = phone;1673 proto->sess = sess; 1661 1674 proto->received_msg = received_msg; 1662 1675 … … 1670 1683 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1671 1684 1672 printf("%s: Protocol registered (protocol: %d , phone: %d)\n",1673 NAME, proto->protocol , proto->phone);1685 printf("%s: Protocol registered (protocol: %d)\n", 1686 NAME, proto->protocol); 1674 1687 1675 1688 return EOK; 1676 1689 } 1677 1690 1678 1679 static int 1680 ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, 1691 static int ip_add_route_req_local(device_id_t device_id, in_addr_t address, 1681 1692 in_addr_t netmask, in_addr_t gateway) 1682 1693 { … … 1712 1723 } 1713 1724 1714 static int 1715 ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway) 1725 static int ip_set_gateway_req_local(device_id_t device_id, in_addr_t gateway) 1716 1726 { 1717 1727 ip_netif_t *netif; … … 1737 1747 /** Notify the IP module about the received error notification packet. 1738 1748 * 1739 * @param[in] ip_phone The IP module phone used for (semi)remote calls. 1740 * @param[in] device_id The device identifier. 1741 * @param[in] packet The received packet or the received packet queue. 1742 * @param[in] target The target internetwork module service to be 1743 * delivered to. 1744 * @param[in] error The packet error reporting service. Prefixes the 1745 * received packet. 1746 * @return EOK on success. 1747 * 1748 */ 1749 static int 1750 ip_received_error_msg_local(int ip_phone, device_id_t device_id, 1749 * @param[in] device_id Device identifier. 1750 * @param[in] packet Received packet or the received packet queue. 1751 * @param[in] target Target internetwork module service to be 1752 * delivered to. 1753 * @param[in] error Packet error reporting service. Prefixes the 1754 * received packet. 1755 * 1756 * @return EOK on success. 1757 * 1758 */ 1759 static int ip_received_error_msg_local(device_id_t device_id, 1751 1760 packet_t *packet, services_t target, services_t error) 1752 1761 { … … 1770 1779 header = (ip_header_t *)(data + offset); 1771 1780 1772 / / destination host unreachable?1781 /* Destination host unreachable? */ 1773 1782 if ((type != ICMP_DEST_UNREACH) || 1774 1783 (code != ICMP_HOST_UNREACH)) { 1775 // no, something else1784 /* No, something else */ 1776 1785 break; 1777 1786 } … … 1787 1796 route = ip_routes_get_index(&netif->routes, 0); 1788 1797 1789 / / from the same network?1798 /* From the same network? */ 1790 1799 if (route && ((route->address.s_addr & route->netmask.s_addr) == 1791 1800 (header->destination_address & route->netmask.s_addr))) { 1792 / / clear the ARP mapping if any1801 /* Clear the ARP mapping if any */ 1793 1802 address.value = (uint8_t *) &header->destination_address; 1794 1803 address.length = sizeof(header->destination_address); 1795 arp_clear_address_req(netif->arp-> phone,1804 arp_clear_address_req(netif->arp->sess, 1796 1805 netif->device_id, SERVICE_IP, &address); 1797 1806 } … … 1807 1816 } 1808 1817 1809 static int 1810 ip_get_route_req_local(int ip_phone, ip_protocol_t protocol, 1818 static int ip_get_route_req_local(ip_protocol_t protocol, 1811 1819 const struct sockaddr *destination, socklen_t addrlen, 1812 1820 device_id_t *device_id, void **header, size_t *headerlen) … … 1844 1852 fibril_rwlock_read_lock(&ip_globals.lock); 1845 1853 route = ip_find_route(*dest); 1846 / / if the local host is the destination1854 /* If the local host is the destination */ 1847 1855 if (route && (route->address.s_addr == dest->s_addr) && 1848 1856 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) { 1849 / / find the loopback device to deliver1857 /* Find the loopback device to deliver */ 1850 1858 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1851 1859 route = ip_find_route(*dest); … … 1905 1913 1906 1914 *answer_count = 0; 1915 1916 if (!IPC_GET_IMETHOD(*call)) 1917 return EOK; 1918 1919 async_sess_t *callback = 1920 async_callback_receive_start(EXCHANGE_SERIALIZE, call); 1921 if (callback) 1922 return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call), 1923 callback, NULL); 1924 1907 1925 switch (IPC_GET_IMETHOD(*call)) { 1908 case IPC_M_PHONE_HUNGUP:1909 return EOK;1910 1911 case IPC_M_CONNECT_TO_ME:1912 return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),1913 IPC_GET_PHONE(*call), NULL);1914 1915 1926 case NET_IP_DEVICE: 1916 return ip_device_req_local( 0,IPC_GET_DEVICE(*call),1927 return ip_device_req_local(IPC_GET_DEVICE(*call), 1917 1928 IPC_GET_SERVICE(*call)); 1918 1929 1919 1930 case NET_IP_RECEIVED_ERROR: 1920 rc = packet_translate_remote(ip_globals.net_ phone, &packet,1931 rc = packet_translate_remote(ip_globals.net_sess, &packet, 1921 1932 IPC_GET_PACKET(*call)); 1922 1933 if (rc != EOK) 1923 1934 return rc; 1924 return ip_received_error_msg_local( 0,IPC_GET_DEVICE(*call),1935 return ip_received_error_msg_local(IPC_GET_DEVICE(*call), 1925 1936 packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call)); 1926 1937 1927 1938 case NET_IP_ADD_ROUTE: 1928 return ip_add_route_req_local( 0,IPC_GET_DEVICE(*call),1939 return ip_add_route_req_local(IPC_GET_DEVICE(*call), 1929 1940 IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call), 1930 1941 IP_GET_GATEWAY(*call)); 1931 1942 1932 1943 case NET_IP_SET_GATEWAY: 1933 return ip_set_gateway_req_local( 0,IPC_GET_DEVICE(*call),1944 return ip_set_gateway_req_local(IPC_GET_DEVICE(*call), 1934 1945 IP_GET_GATEWAY(*call)); 1935 1946 … … 1940 1951 return rc; 1941 1952 1942 rc = ip_get_route_req_local( 0,IP_GET_PROTOCOL(*call), addr,1953 rc = ip_get_route_req_local(IP_GET_PROTOCOL(*call), addr, 1943 1954 (socklen_t) addrlen, &device_id, &header, &headerlen); 1944 1955 if (rc != EOK) … … 1971 1982 1972 1983 case NET_IP_SEND: 1973 rc = packet_translate_remote(ip_globals.net_ phone, &packet,1984 rc = packet_translate_remote(ip_globals.net_sess, &packet, 1974 1985 IPC_GET_PACKET(*call)); 1975 1986 if (rc != EOK) 1976 1987 return rc; 1977 1988 1978 return ip_send_msg_local( 0,IPC_GET_DEVICE(*call), packet, 0,1989 return ip_send_msg_local(IPC_GET_DEVICE(*call), packet, 0, 1979 1990 IPC_GET_ERROR(*call)); 1980 1991 }
Note:
See TracChangeset
for help on using the changeset viewer.