Changes in uspace/srv/net/il/ip/ip.c [7e752b2:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
r7e752b2 rffa2c8ef 36 36 */ 37 37 38 #include "ip.h"39 #include "ip_module.h"40 41 38 #include <async.h> 42 39 #include <errno.h> … … 44 41 #include <stdio.h> 45 42 #include <str.h> 46 #include <ipc/ipc.h>47 43 #include <ipc/services.h> 48 44 #include <ipc/net.h> … … 52 48 #include <sys/types.h> 53 49 #include <byteorder.h> 50 #include "ip.h" 54 51 55 52 #include <adt/measured_strings.h> … … 69 66 #include <net_checksum.h> 70 67 #include <icmp_client.h> 71 #include <icmp_interface.h> 72 #include <il_interface.h> 68 #include <icmp_remote.h> 73 69 #include <ip_client.h> 74 70 #include <ip_interface.h> 75 71 #include <ip_header.h> 76 72 #include <net_interface.h> 77 #include <nil_ interface.h>78 #include <tl_ interface.h>73 #include <nil_remote.h> 74 #include <tl_remote.h> 79 75 #include <packet_remote.h> 80 #include <il_local.h> 76 #include <il_remote.h> 77 #include <il_skel.h> 81 78 82 79 /** IP module name. */ … … 122 119 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 123 120 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 121 122 static void ip_receiver(ipc_callid_t, ipc_call_t *); 124 123 125 124 /** Releases the packet and returns the result. … … 244 243 } 245 244 246 /** Initializes the IP module. 247 * 248 * @param[in] client_connection The client connection processing function. The 249 * module skeleton propagates its own one. 250 * @return EOK on success. 251 * @return ENOMEM if there is not enough memory left. 252 */ 253 int ip_initialize(async_client_conn_t client_connection) 254 { 255 int rc; 256 245 int il_initialize(int net_phone) 246 { 257 247 fibril_rwlock_initialize(&ip_globals.lock); 258 248 fibril_rwlock_write_lock(&ip_globals.lock); 259 249 fibril_rwlock_initialize(&ip_globals.protos_lock); 260 250 fibril_rwlock_initialize(&ip_globals.netifs_lock); 251 252 ip_globals.net_phone = net_phone; 261 253 ip_globals.packet_counter = 0; 262 254 ip_globals.gateway.address.s_addr = 0; … … 264 256 ip_globals.gateway.gateway.s_addr = 0; 265 257 ip_globals.gateway.netif = NULL; 266 ip_globals.client_connection = client_connection; 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 258 259 int rc = ip_netifs_initialize(&ip_globals.netifs); 269 260 if (rc != EOK) 270 261 goto out; … … 275 266 if (rc != EOK) 276 267 goto out; 277 rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,278 SERVICE_ARP, 0, arp_connect_module);268 rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME, 269 (uint8_t *) ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module); 279 270 280 271 out: … … 312 303 measured_string_t names[] = { 313 304 { 314 ( char*) "IPV",305 (uint8_t *) "IPV", 315 306 3 316 307 }, 317 308 { 318 ( char*) "IP_CONFIG",309 (uint8_t *) "IP_CONFIG", 319 310 9 320 311 }, 321 312 { 322 ( char*) "IP_ADDR",313 (uint8_t *) "IP_ADDR", 323 314 7 324 315 }, 325 316 { 326 ( char*) "IP_NETMASK",317 (uint8_t *) "IP_NETMASK", 327 318 10 328 319 }, 329 320 { 330 ( char*) "IP_GATEWAY",321 (uint8_t *) "IP_GATEWAY", 331 322 10 332 323 }, 333 324 { 334 ( char*) "IP_BROADCAST",325 (uint8_t *) "IP_BROADCAST", 335 326 12 336 327 }, 337 328 { 338 ( char*) "ARP",329 (uint8_t *) "ARP", 339 330 3 340 331 }, 341 332 { 342 ( char*) "IP_ROUTING",333 (uint8_t *) "IP_ROUTING", 343 334 10 344 335 } … … 346 337 measured_string_t *configuration; 347 338 size_t count = sizeof(names) / sizeof(measured_string_t); 348 char*data;339 uint8_t *data; 349 340 measured_string_t address; 350 341 ip_route_t *route; … … 368 359 if (configuration) { 369 360 if (configuration[0].value) 370 ip_netif->ipv = strtol( configuration[0].value, NULL, 0);371 372 ip_netif->dhcp = !str_lcmp( configuration[1].value, "dhcp",361 ip_netif->ipv = strtol((char *) configuration[0].value, NULL, 0); 362 363 ip_netif->dhcp = !str_lcmp((char *) configuration[1].value, "dhcp", 373 364 configuration[1].length); 374 365 … … 394 385 } 395 386 396 if ((inet_pton(AF_INET, configuration[2].value,387 if ((inet_pton(AF_INET, (char *) configuration[2].value, 397 388 (uint8_t *) &route->address.s_addr) != EOK) || 398 (inet_pton(AF_INET, configuration[3].value,389 (inet_pton(AF_INET, (char *) configuration[3].value, 399 390 (uint8_t *) &route->netmask.s_addr) != EOK) || 400 (inet_pton(AF_INET, configuration[4].value,391 (inet_pton(AF_INET, (char *) configuration[4].value, 401 392 (uint8_t *) &gateway.s_addr) == EINVAL) || 402 (inet_pton(AF_INET, configuration[5].value,393 (inet_pton(AF_INET, (char *) configuration[5].value, 403 394 (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)) 404 395 { … … 430 421 // binds the netif service which also initializes the device 431 422 ip_netif->phone = nil_bind_service(ip_netif->service, 432 ( ipcarg_t) ip_netif->device_id, SERVICE_IP,433 ip_ globals.client_connection);423 (sysarg_t) ip_netif->device_id, SERVICE_IP, 424 ip_receiver); 434 425 if (ip_netif->phone < 0) { 435 426 printf("Failed to contact the nil service %d\n", … … 441 432 if (ip_netif->arp) { 442 433 if (route) { 443 address.value = ( char*) &route->address.s_addr;444 address.length = CONVERT_SIZE(in_addr_t, char, 1);434 address.value = (uint8_t *) &route->address.s_addr; 435 address.length = sizeof(in_addr_t); 445 436 446 437 rc = arp_device_req(ip_netif->arp->phone, … … 477 468 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 478 469 ip_globals.gateway.netif = ip_netif; 470 471 char defgateway[INET_ADDRSTRLEN]; 472 inet_ntop(AF_INET, (uint8_t *) &gateway.s_addr, 473 defgateway, INET_ADDRSTRLEN); 474 printf("%s: Default gateway (%s)\n", NAME, defgateway); 479 475 } 480 476 … … 482 478 } 483 479 484 /** Updates the device content length according to the new MTU value. 485 * 486 * @param[in] device_id The device identifier. 487 * @param[in] mtu The new mtu value. 488 * @return EOK on success. 489 * @return ENOENT if device is not found. 490 */ 491 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 492 { 480 static int ip_device_req_local(int il_phone, device_id_t device_id, 481 services_t netif) 482 { 483 ip_netif_t *ip_netif; 484 ip_route_t *route; 485 int index; 486 int rc; 487 488 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 489 if (!ip_netif) 490 return ENOMEM; 491 492 rc = ip_routes_initialize(&ip_netif->routes); 493 if (rc != EOK) { 494 free(ip_netif); 495 return rc; 496 } 497 498 ip_netif->device_id = device_id; 499 ip_netif->service = netif; 500 ip_netif->state = NETIF_STOPPED; 501 502 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 503 504 rc = ip_netif_initialize(ip_netif); 505 if (rc != EOK) { 506 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 507 ip_routes_destroy(&ip_netif->routes); 508 free(ip_netif); 509 return rc; 510 } 511 if (ip_netif->arp) 512 ip_netif->arp->usage++; 513 514 // print the settings 515 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 ip_netif->dhcp ? "dhcp" : "static"); 518 519 // TODO ipv6 addresses 520 521 char address[INET_ADDRSTRLEN]; 522 char netmask[INET_ADDRSTRLEN]; 523 char gateway[INET_ADDRSTRLEN]; 524 525 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 526 route = ip_routes_get_index(&ip_netif->routes, index); 527 if (route) { 528 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 529 address, INET_ADDRSTRLEN); 530 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 531 netmask, INET_ADDRSTRLEN); 532 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 533 gateway, INET_ADDRSTRLEN); 534 printf("%s: Route %d (address: %s, netmask: %s, " 535 "gateway: %s)\n", NAME, index, address, netmask, 536 gateway); 537 } 538 } 539 540 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 541 INET_ADDRSTRLEN); 542 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 543 544 printf("%s: Broadcast (%s)\n", NAME, address); 545 546 return EOK; 547 } 548 549 /** Searches the network interfaces if there is a suitable route. 550 * 551 * @param[in] netif The network interface to be searched for routes. May be 552 * NULL. 553 * @param[in] destination The destination address. 554 * @return The found route. 555 * @return NULL if no route was found. 556 */ 557 static ip_route_t *ip_netif_find_route(ip_netif_t *netif, 558 in_addr_t destination) 559 { 560 int index; 561 ip_route_t *route; 562 563 if (!netif) 564 return NULL; 565 566 /* Start with the first one (the direct route) */ 567 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 568 route = ip_routes_get_index(&netif->routes, index); 569 if ((route) && 570 ((route->address.s_addr & route->netmask.s_addr) == 571 (destination.s_addr & route->netmask.s_addr))) 572 return route; 573 } 574 575 return NULL; 576 } 577 578 /** Searches all network interfaces if there is a suitable route. 579 * 580 * @param[in] destination The destination address. 581 * @return The found route. 582 * @return NULL if no route was found. 583 */ 584 static ip_route_t *ip_find_route(in_addr_t destination) { 585 int index; 586 ip_route_t *route; 493 587 ip_netif_t *netif; 494 588 495 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 496 netif = ip_netifs_find(&ip_globals.netifs, device_id); 497 if (!netif) { 498 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 499 return ENOENT; 500 } 501 netif->packet_dimension.content = mtu; 502 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 503 504 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 505 506 return EOK; 507 } 508 509 /** Updates the device state. 510 * 511 * @param[in] device_id The device identifier. 512 * @param[in] state The new state value. 513 * @return EOK on success. 514 * @return ENOENT if device is not found. 515 */ 516 static int ip_device_state_message(device_id_t device_id, device_state_t state) 517 { 518 ip_netif_t *netif; 519 520 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 521 // find the device 522 netif = ip_netifs_find(&ip_globals.netifs, device_id); 523 if (!netif) { 524 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 525 return ENOENT; 526 } 527 netif->state = state; 528 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 529 530 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 531 532 return EOK; 533 } 534 535 536 /** Prefixes a middle fragment header based on the last fragment header to the 537 * packet. 538 * 539 * @param[in] packet The packet to be prefixed. 540 * @param[in] last The last header to be copied. 541 * @return The prefixed middle header. 542 * @return NULL on error. 543 */ 544 static ip_header_t * 545 ip_create_middle_header(packet_t *packet, ip_header_t *last) 546 { 547 ip_header_t *middle; 548 549 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last)); 550 if (!middle) 551 return NULL; 552 memcpy(middle, last, IP_HEADER_LENGTH(last)); 553 middle->flags |= IPFLAG_MORE_FRAGMENTS; 554 return middle; 589 // start with the last netif - the newest one 590 index = ip_netifs_count(&ip_globals.netifs) - 1; 591 while (index >= 0) { 592 netif = ip_netifs_get_index(&ip_globals.netifs, index); 593 if (netif && (netif->state == NETIF_ACTIVE)) { 594 route = ip_netif_find_route(netif, destination); 595 if (route) 596 return route; 597 } 598 index--; 599 } 600 601 return &ip_globals.gateway; 602 } 603 604 /** Returns the network interface's IP address. 605 * 606 * @param[in] netif The network interface. 607 * @return The IP address. 608 * @return NULL if no IP address was found. 609 */ 610 static in_addr_t *ip_netif_address(ip_netif_t *netif) 611 { 612 ip_route_t *route; 613 614 route = ip_routes_get_index(&netif->routes, 0); 615 return route ? &route->address : NULL; 555 616 } 556 617 … … 621 682 * function. 622 683 */ 623 static int 624 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet, 625 measured_string_t *destination) 684 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest, 685 packet_t *packet, measured_string_t *destination) 626 686 { 627 687 size_t length; … … 639 699 if (destination) { 640 700 rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value, 641 CONVERT_SIZE(char, uint8_t, destination->length));701 destination->length); 642 702 } else { 643 703 rc = packet_set_addr(packet, NULL, NULL, 0); … … 687 747 rc = packet_set_addr(next, NULL, 688 748 (uint8_t *) destination->value, 689 CONVERT_SIZE(char, uint8_t, 690 destination->length)); 749 destination->length); 691 750 if (rc != EOK) { 692 751 free(last_header); … … 718 777 rc = packet_set_addr(next, NULL, 719 778 (uint8_t *) destination->value, 720 CONVERT_SIZE(char, uint8_t, destination->length));779 destination->length); 721 780 if (rc != EOK) { 722 781 free(last_header); … … 753 812 * function. 754 813 */ 755 static int 756 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 814 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 757 815 ip_header_t *header, ip_header_t *new_header, size_t length, 758 816 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 788 846 789 847 return pq_insert_after(packet, new_packet); 848 } 849 850 /** Prefixes a middle fragment header based on the last fragment header to the 851 * packet. 852 * 853 * @param[in] packet The packet to be prefixed. 854 * @param[in] last The last header to be copied. 855 * @return The prefixed middle header. 856 * @return NULL on error. 857 */ 858 static ip_header_t *ip_create_middle_header(packet_t *packet, 859 ip_header_t *last) 860 { 861 ip_header_t *middle; 862 863 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last)); 864 if (!middle) 865 return NULL; 866 memcpy(middle, last, IP_HEADER_LENGTH(last)); 867 middle->flags |= IPFLAG_MORE_FRAGMENTS; 868 return middle; 790 869 } 791 870 … … 992 1071 * function. 993 1072 */ 994 static int 995 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route, 996 in_addr_t *src, in_addr_t dest, services_t error) 1073 static int ip_send_route(packet_t *packet, ip_netif_t *netif, 1074 ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error) 997 1075 { 998 1076 measured_string_t destination; 999 1077 measured_string_t *translation; 1000 char*data;1078 uint8_t *data; 1001 1079 int phone; 1002 1080 int rc; … … 1005 1083 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 1006 1084 destination.value = route->gateway.s_addr ? 1007 ( char *) &route->gateway.s_addr : (char*) &dest.s_addr;1008 destination.length = CONVERT_SIZE(dest.s_addr, char, 1);1085 (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr; 1086 destination.length = sizeof(dest.s_addr); 1009 1087 1010 1088 rc = arp_translate_req(netif->arp->phone, netif->device_id, … … 1057 1135 } 1058 1136 1059 /** Searches the network interfaces if there is a suitable route. 1060 * 1061 * @param[in] netif The network interface to be searched for routes. May be 1062 * NULL. 1063 * @param[in] destination The destination address. 1064 * @return The found route. 1065 * @return NULL if no route was found. 1066 */ 1067 static ip_route_t * 1068 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination) 1069 { 1070 int index; 1071 ip_route_t *route; 1072 1073 if (!netif) 1074 return NULL; 1075 1076 // start with the first one - the direct route 1077 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1078 route = ip_routes_get_index(&netif->routes, index); 1079 if (route && 1080 ((route->address.s_addr & route->netmask.s_addr) == 1081 (destination.s_addr & route->netmask.s_addr))) { 1082 return route; 1083 } 1084 } 1085 1086 return NULL; 1087 } 1088 1089 /** Searches all network interfaces if there is a suitable route. 1090 * 1091 * @param[in] destination The destination address. 1092 * @return The found route. 1093 * @return NULL if no route was found. 1094 */ 1095 static ip_route_t *ip_find_route(in_addr_t destination) { 1096 int index; 1097 ip_route_t *route; 1098 ip_netif_t *netif; 1099 1100 // start with the last netif - the newest one 1101 index = ip_netifs_count(&ip_globals.netifs) - 1; 1102 while (index >= 0) { 1103 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1104 if (netif && (netif->state == NETIF_ACTIVE)) { 1105 route = ip_netif_find_route(netif, destination); 1106 if (route) 1107 return route; 1108 } 1109 index--; 1110 } 1111 1112 return &ip_globals.gateway; 1113 } 1114 1115 /** Returns the network interface's IP address. 1116 * 1117 * @param[in] netif The network interface. 1118 * @return The IP address. 1119 * @return NULL if no IP address was found. 1120 */ 1121 static in_addr_t *ip_netif_address(ip_netif_t *netif) 1122 { 1123 ip_route_t *route; 1124 1125 route = ip_routes_get_index(&netif->routes, 0); 1126 return route ? &route->address : NULL; 1127 } 1128 1129 /** Registers the transport layer protocol. 1130 * 1131 * The traffic of this protocol will be supplied using either the receive 1132 * function or IPC message. 1133 * 1134 * @param[in] protocol The transport layer module protocol. 1135 * @param[in] service The transport layer module service. 1136 * @param[in] phone The transport layer module phone. 1137 * @param[in] received_msg The receiving function. 1138 * @return EOK on success. 1139 * @return EINVAL if the protocol parameter and/or the service 1140 * parameter is zero. 1141 * @return EINVAL if the phone parameter is not a positive number 1142 * and the tl_receive_msg is NULL. 1143 * @return ENOMEM if there is not enough memory left. 1144 */ 1145 static int 1146 ip_register(int protocol, services_t service, int phone, 1147 tl_received_msg_t received_msg) 1148 { 1149 ip_proto_t *proto; 1150 int index; 1151 1152 if (!protocol || !service || ((phone < 0) && !received_msg)) 1153 return EINVAL; 1154 1155 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1156 if (!proto) 1157 return ENOMEM; 1158 1159 proto->protocol = protocol; 1160 proto->service = service; 1161 proto->phone = phone; 1162 proto->received_msg = received_msg; 1163 1164 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1165 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1166 if (index < 0) { 1167 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1168 free(proto); 1169 return index; 1170 } 1171 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1172 1173 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1174 NAME, proto->protocol, proto->phone); 1175 1176 return EOK; 1177 } 1178 1179 static int 1180 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1181 { 1182 ip_netif_t *ip_netif; 1183 ip_route_t *route; 1184 int index; 1185 int rc; 1186 1187 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 1188 if (!ip_netif) 1189 return ENOMEM; 1190 1191 rc = ip_routes_initialize(&ip_netif->routes); 1192 if (rc != EOK) { 1193 free(ip_netif); 1194 return rc; 1195 } 1196 1197 ip_netif->device_id = device_id; 1198 ip_netif->service = netif; 1199 ip_netif->state = NETIF_STOPPED; 1200 1201 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1202 1203 rc = ip_netif_initialize(ip_netif); 1204 if (rc != EOK) { 1205 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1206 ip_routes_destroy(&ip_netif->routes); 1207 free(ip_netif); 1208 return rc; 1209 } 1210 if (ip_netif->arp) 1211 ip_netif->arp->usage++; 1212 1213 // print the settings 1214 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 1215 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 1216 ip_netif->dhcp ? "dhcp" : "static"); 1217 1218 // TODO ipv6 addresses 1219 1220 char address[INET_ADDRSTRLEN]; 1221 char netmask[INET_ADDRSTRLEN]; 1222 char gateway[INET_ADDRSTRLEN]; 1223 1224 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 1225 route = ip_routes_get_index(&ip_netif->routes, index); 1226 if (route) { 1227 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1228 address, INET_ADDRSTRLEN); 1229 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1230 netmask, INET_ADDRSTRLEN); 1231 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1232 gateway, INET_ADDRSTRLEN); 1233 printf("%s: Route %d (address: %s, netmask: %s, " 1234 "gateway: %s)\n", NAME, index, address, netmask, 1235 gateway); 1236 } 1237 } 1238 1239 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1240 INET_ADDRSTRLEN); 1241 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1242 1243 printf("%s: Broadcast (%s)\n", NAME, address); 1244 1245 return EOK; 1246 } 1247 1248 static int 1249 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet, 1250 services_t sender, services_t error) 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) 1251 1139 { 1252 1140 int addrlen; … … 1289 1177 if (device_id > 0) { 1290 1178 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1291 route = ip_netif_find_route(netif, * 1179 route = ip_netif_find_route(netif, *dest); 1292 1180 if (netif && !route && (ip_globals.gateway.netif == netif)) 1293 1181 route = &ip_globals.gateway; … … 1319 1207 } 1320 1208 } 1321 1209 1322 1210 // if the local host is the destination 1323 1211 if ((route->address.s_addr == dest->s_addr) && … … 1352 1240 } 1353 1241 1242 /** Updates the device state. 1243 * 1244 * @param[in] device_id The device identifier. 1245 * @param[in] state The new state value. 1246 * @return EOK on success. 1247 * @return ENOENT if device is not found. 1248 */ 1249 static int ip_device_state_message(device_id_t device_id, device_state_t state) 1250 { 1251 ip_netif_t *netif; 1252 1253 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1254 // find the device 1255 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1256 if (!netif) { 1257 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1258 return ENOENT; 1259 } 1260 netif->state = state; 1261 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1262 1263 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 1264 1265 return EOK; 1266 } 1267 1268 /** Returns the packet destination address from the IP header. 1269 * 1270 * @param[in] header The packet IP header to be read. 1271 * @return The packet destination address. 1272 */ 1273 static in_addr_t ip_get_destination(ip_header_t *header) 1274 { 1275 in_addr_t destination; 1276 1277 // TODO search set ipopt route? 1278 destination.s_addr = header->destination_address; 1279 return destination; 1280 } 1281 1282 /** Delivers the packet to the local host. 1283 * 1284 * The packet is either passed to another module or released on error. 1285 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1286 * found. 1287 * 1288 * @param[in] device_id The source device identifier. 1289 * @param[in] packet The packet to be delivered. 1290 * @param[in] header The first packet IP header. May be NULL. 1291 * @param[in] error The packet error service. 1292 * @return EOK on success. 1293 * @return ENOTSUP if the packet is a fragment. 1294 * @return EAFNOSUPPORT if the address family is not supported. 1295 * @return ENOENT if the target protocol is not found. 1296 * @return Other error codes as defined for the packet_set_addr() 1297 * function. 1298 * @return Other error codes as defined for the packet_trim() 1299 * function. 1300 * @return Other error codes as defined for the protocol specific 1301 * tl_received_msg() function. 1302 */ 1303 static int ip_deliver_local(device_id_t device_id, packet_t *packet, 1304 ip_header_t *header, services_t error) 1305 { 1306 ip_proto_t *proto; 1307 int phone; 1308 services_t service; 1309 tl_received_msg_t received_msg; 1310 struct sockaddr *src; 1311 struct sockaddr *dest; 1312 struct sockaddr_in src_in; 1313 struct sockaddr_in dest_in; 1314 socklen_t addrlen; 1315 int rc; 1316 1317 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1318 IP_FRAGMENT_OFFSET(header)) { 1319 // TODO fragmented 1320 return ENOTSUP; 1321 } 1322 1323 switch (header->version) { 1324 case IPVERSION: 1325 addrlen = sizeof(src_in); 1326 bzero(&src_in, addrlen); 1327 src_in.sin_family = AF_INET; 1328 memcpy(&dest_in, &src_in, addrlen); 1329 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1330 sizeof(header->source_address)); 1331 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1332 sizeof(header->destination_address)); 1333 src = (struct sockaddr *) &src_in; 1334 dest = (struct sockaddr *) &dest_in; 1335 break; 1336 1337 default: 1338 return ip_release_and_return(packet, EAFNOSUPPORT); 1339 } 1340 1341 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1342 addrlen); 1343 if (rc != EOK) 1344 return ip_release_and_return(packet, rc); 1345 1346 // trim padding if present 1347 if (!error && 1348 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1349 rc = packet_trim(packet, 0, 1350 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1351 if (rc != EOK) 1352 return ip_release_and_return(packet, rc); 1353 } 1354 1355 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1356 1357 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1358 if (!proto) { 1359 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 ICMP 1363 icmp_destination_unreachable_msg(phone, 1364 ICMP_PROT_UNREACH, 0, packet); 1365 } 1366 return ENOENT; 1367 } 1368 1369 if (proto->received_msg) { 1370 service = proto->service; 1371 received_msg = proto->received_msg; 1372 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1373 rc = received_msg(device_id, packet, service, error); 1374 } else { 1375 rc = tl_received_msg(proto->phone, device_id, packet, 1376 proto->service, error); 1377 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1378 } 1379 1380 return rc; 1381 } 1382 1383 /** Processes the received packet. 1384 * 1385 * The packet is either passed to another module or released on error. 1386 * 1387 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1388 * invalid. 1389 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1390 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1391 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1392 * another host and the routing is disabled. 1393 * 1394 * @param[in] device_id The source device identifier. 1395 * @param[in] packet The received packet to be processed. 1396 * @return EOK on success. 1397 * @return EINVAL if the TTL is less than two. 1398 * @return EINVAL if the checksum is invalid. 1399 * @return EAFNOSUPPORT if the address family is not supported. 1400 * @return ENOENT if no route was found. 1401 * @return ENOENT if the packet is for another host and the routing 1402 * is disabled. 1403 */ 1404 static int ip_process_packet(device_id_t device_id, packet_t *packet) 1405 { 1406 ip_header_t *header; 1407 in_addr_t dest; 1408 ip_route_t *route; 1409 int phone; 1410 struct sockaddr *addr; 1411 struct sockaddr_in addr_in; 1412 socklen_t addrlen; 1413 int rc; 1414 1415 header = (ip_header_t *) packet_get_data(packet); 1416 if (!header) 1417 return ip_release_and_return(packet, ENOMEM); 1418 1419 // checksum 1420 if ((header->header_checksum) && 1421 (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 ICMP 1425 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1426 ((size_t) ((void *) &header->header_checksum)) - 1427 ((size_t) ((void *) header)), packet); 1428 } 1429 return EINVAL; 1430 } 1431 1432 if (header->ttl <= 1) { 1433 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1434 if (phone >= 0) { 1435 // ttl exceeded ICMP 1436 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1437 } 1438 return EINVAL; 1439 } 1440 1441 // process ipopt and get destination 1442 dest = ip_get_destination(header); 1443 1444 // set the addrination address 1445 switch (header->version) { 1446 case IPVERSION: 1447 addrlen = sizeof(addr_in); 1448 bzero(&addr_in, addrlen); 1449 addr_in.sin_family = AF_INET; 1450 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1451 addr = (struct sockaddr *) &addr_in; 1452 break; 1453 1454 default: 1455 return ip_release_and_return(packet, EAFNOSUPPORT); 1456 } 1457 1458 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1459 if (rc != EOK) 1460 return rc; 1461 1462 route = ip_find_route(dest); 1463 if (!route) { 1464 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1465 if (phone >= 0) { 1466 // unreachable ICMP 1467 icmp_destination_unreachable_msg(phone, 1468 ICMP_HOST_UNREACH, 0, packet); 1469 } 1470 return ENOENT; 1471 } 1472 1473 if (route->address.s_addr == dest.s_addr) { 1474 // local delivery 1475 return ip_deliver_local(device_id, packet, header, 0); 1476 } 1477 1478 if (route->netif->routing) { 1479 header->ttl--; 1480 return ip_send_route(packet, route->netif, route, NULL, dest, 1481 0); 1482 } 1483 1484 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1485 if (phone >= 0) { 1486 // unreachable ICMP if no routing 1487 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1488 packet); 1489 } 1490 1491 return ENOENT; 1492 } 1493 1354 1494 /** Returns the device packet dimensions for sending. 1355 1495 * … … 1363 1503 * @return EOK on success. 1364 1504 */ 1365 static int 1366 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1367 size_t *content, size_t *suffix) 1505 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len, 1506 size_t *prefix, size_t *content, size_t *suffix) 1368 1507 { 1369 1508 ip_netif_t *netif; … … 1415 1554 } 1416 1555 1417 /** Returns the packet destination address from the IP header. 1418 * 1419 * @param[in] header The packet IP header to be read. 1420 * @return The packet destination address. 1421 */ 1422 static in_addr_t ip_get_destination(ip_header_t *header) 1423 { 1424 in_addr_t destination; 1425 1426 // TODO search set ipopt route? 1427 destination.s_addr = header->destination_address; 1428 return destination; 1429 } 1430 1431 /** Delivers the packet to the local host. 1432 * 1433 * The packet is either passed to another module or released on error. 1434 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1435 * found. 1436 * 1437 * @param[in] device_id The source device identifier. 1438 * @param[in] packet The packet to be delivered. 1439 * @param[in] header The first packet IP header. May be NULL. 1440 * @param[in] error The packet error service. 1556 /** Updates the device content length according to the new MTU value. 1557 * 1558 * @param[in] device_id The device identifier. 1559 * @param[in] mtu The new mtu value. 1441 1560 * @return EOK on success. 1442 * @return ENOTSUP if the packet is a fragment. 1443 * @return EAFNOSUPPORT if the address family is not supported. 1444 * @return ENOENT if the target protocol is not found. 1445 * @return Other error codes as defined for the packet_set_addr() 1446 * function. 1447 * @return Other error codes as defined for the packet_trim() 1448 * function. 1449 * @return Other error codes as defined for the protocol specific 1450 * tl_received_msg() function. 1561 * @return ENOENT if device is not found. 1562 */ 1563 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 1564 { 1565 ip_netif_t *netif; 1566 1567 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1568 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1569 if (!netif) { 1570 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1571 return ENOENT; 1572 } 1573 netif->packet_dimension.content = mtu; 1574 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1575 1576 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 1577 1578 return EOK; 1579 } 1580 1581 /** Process IPC messages from the registered device driver modules 1582 * 1583 * @param[in] iid Message identifier. 1584 * @param[in,out] icall Message parameters. 1585 * 1586 */ 1587 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall) 1588 { 1589 packet_t *packet; 1590 int rc; 1591 1592 while (true) { 1593 switch (IPC_GET_IMETHOD(*icall)) { 1594 case NET_IL_DEVICE_STATE: 1595 rc = ip_device_state_message(IPC_GET_DEVICE(*icall), 1596 IPC_GET_STATE(*icall)); 1597 async_answer_0(iid, (sysarg_t) rc); 1598 break; 1599 1600 case NET_IL_RECEIVED: 1601 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1602 IPC_GET_PACKET(*icall)); 1603 if (rc == EOK) { 1604 do { 1605 packet_t *next = pq_detach(packet); 1606 ip_process_packet(IPC_GET_DEVICE(*icall), packet); 1607 packet = next; 1608 } while (packet); 1609 } 1610 1611 async_answer_0(iid, (sysarg_t) rc); 1612 break; 1613 1614 case NET_IL_MTU_CHANGED: 1615 rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall), 1616 IPC_GET_MTU(*icall)); 1617 async_answer_0(iid, (sysarg_t) rc); 1618 break; 1619 1620 default: 1621 async_answer_0(iid, (sysarg_t) ENOTSUP); 1622 } 1623 1624 iid = async_get_call(icall); 1625 } 1626 } 1627 1628 /** Registers the transport layer protocol. 1629 * 1630 * The traffic of this protocol will be supplied using either the receive 1631 * function or IPC message. 1632 * 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. 1451 1643 */ 1452 1644 static int 1453 ip_ deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,1454 services_t error)1645 ip_register(int protocol, services_t service, int phone, 1646 tl_received_msg_t received_msg) 1455 1647 { 1456 1648 ip_proto_t *proto; 1457 int phone; 1458 services_t service; 1459 tl_received_msg_t received_msg; 1460 struct sockaddr *src; 1461 struct sockaddr *dest; 1462 struct sockaddr_in src_in; 1463 struct sockaddr_in dest_in; 1464 socklen_t addrlen; 1465 int rc; 1466 1467 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1468 IP_FRAGMENT_OFFSET(header)) { 1469 // TODO fragmented 1470 return ENOTSUP; 1471 } 1472 1473 switch (header->version) { 1474 case IPVERSION: 1475 addrlen = sizeof(src_in); 1476 bzero(&src_in, addrlen); 1477 src_in.sin_family = AF_INET; 1478 memcpy(&dest_in, &src_in, addrlen); 1479 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1480 sizeof(header->source_address)); 1481 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1482 sizeof(header->destination_address)); 1483 src = (struct sockaddr *) &src_in; 1484 dest = (struct sockaddr *) &dest_in; 1485 break; 1486 1487 default: 1488 return ip_release_and_return(packet, EAFNOSUPPORT); 1489 } 1490 1491 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1492 addrlen); 1493 if (rc != EOK) 1494 return ip_release_and_return(packet, rc); 1495 1496 // trim padding if present 1497 if (!error && 1498 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1499 rc = packet_trim(packet, 0, 1500 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1501 if (rc != EOK) 1502 return ip_release_and_return(packet, rc); 1503 } 1504 1505 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1506 1507 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1508 if (!proto) { 1509 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1510 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1511 if (phone >= 0) { 1512 // unreachable ICMP 1513 icmp_destination_unreachable_msg(phone, 1514 ICMP_PROT_UNREACH, 0, packet); 1515 } 1516 return ENOENT; 1517 } 1518 1519 if (proto->received_msg) { 1520 service = proto->service; 1521 received_msg = proto->received_msg; 1522 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1523 rc = received_msg(device_id, packet, service, error); 1524 } else { 1525 rc = tl_received_msg(proto->phone, device_id, packet, 1526 proto->service, error); 1527 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1528 } 1529 1530 return rc; 1531 } 1532 1533 /** Processes the received packet. 1534 * 1535 * The packet is either passed to another module or released on error. 1536 * 1537 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1538 * invalid. 1539 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1540 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1541 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1542 * another host and the routing is disabled. 1543 * 1544 * @param[in] device_id The source device identifier. 1545 * @param[in] packet The received packet to be processed. 1546 * @return EOK on success. 1547 * @return EINVAL if the TTL is less than two. 1548 * @return EINVAL if the checksum is invalid. 1549 * @return EAFNOSUPPORT if the address family is not supported. 1550 * @return ENOENT if no route was found. 1551 * @return ENOENT if the packet is for another host and the routing 1552 * is disabled. 1553 */ 1554 static int 1555 ip_process_packet(device_id_t device_id, packet_t *packet) 1556 { 1557 ip_header_t *header; 1558 in_addr_t dest; 1559 ip_route_t *route; 1560 int phone; 1561 struct sockaddr *addr; 1562 struct sockaddr_in addr_in; 1563 socklen_t addrlen; 1564 int rc; 1565 1566 header = (ip_header_t *) packet_get_data(packet); 1567 if (!header) 1568 return ip_release_and_return(packet, ENOMEM); 1569 1570 // checksum 1571 if ((header->header_checksum) && 1572 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1573 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1574 if (phone >= 0) { 1575 // checksum error ICMP 1576 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1577 ((size_t) ((void *) &header->header_checksum)) - 1578 ((size_t) ((void *) header)), packet); 1579 } 1649 int index; 1650 1651 if (!protocol || !service || ((phone < 0) && !received_msg)) 1580 1652 return EINVAL; 1581 } 1582 1583 if (header->ttl <= 1) { 1584 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1585 if (phone >= 0) { 1586 // ttl exceeded ICMP 1587 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1588 } 1589 return EINVAL; 1590 } 1591 1592 // process ipopt and get destination 1593 dest = ip_get_destination(header); 1594 1595 // set the addrination address 1596 switch (header->version) { 1597 case IPVERSION: 1598 addrlen = sizeof(addr_in); 1599 bzero(&addr_in, addrlen); 1600 addr_in.sin_family = AF_INET; 1601 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1602 addr = (struct sockaddr *) &addr_in; 1603 break; 1604 1605 default: 1606 return ip_release_and_return(packet, EAFNOSUPPORT); 1607 } 1608 1609 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1610 if (rc != EOK) 1611 return rc; 1612 1613 route = ip_find_route(dest); 1614 if (!route) { 1615 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1616 if (phone >= 0) { 1617 // unreachable ICMP 1618 icmp_destination_unreachable_msg(phone, 1619 ICMP_HOST_UNREACH, 0, packet); 1620 } 1621 return ENOENT; 1622 } 1623 1624 if (route->address.s_addr == dest.s_addr) { 1625 // local delivery 1626 return ip_deliver_local(device_id, packet, header, 0); 1627 } 1628 1629 if (route->netif->routing) { 1630 header->ttl--; 1631 return ip_send_route(packet, route->netif, route, NULL, dest, 1632 0); 1633 } 1634 1635 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1636 if (phone >= 0) { 1637 // unreachable ICMP if no routing 1638 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1639 packet); 1640 } 1641 1642 return ENOENT; 1643 } 1653 1654 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1655 if (!proto) 1656 return ENOMEM; 1657 1658 proto->protocol = protocol; 1659 proto->service = service; 1660 proto->phone = phone; 1661 proto->received_msg = received_msg; 1662 1663 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1664 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1665 if (index < 0) { 1666 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1667 free(proto); 1668 return index; 1669 } 1670 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1671 1672 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1673 NAME, proto->protocol, proto->phone); 1674 1675 return EOK; 1676 } 1677 1644 1678 1645 1679 static int … … 1757 1791 (header->destination_address & route->netmask.s_addr))) { 1758 1792 // clear the ARP mapping if any 1759 address.value = (char *) &header->destination_address; 1760 address.length = CONVERT_SIZE(uint8_t, char, 1761 sizeof(header->destination_address)); 1793 address.value = (uint8_t *) &header->destination_address; 1794 address.length = sizeof(header->destination_address); 1762 1795 arp_clear_address_req(netif->arp->phone, 1763 1796 netif->device_id, SERVICE_IP, &address); … … 1843 1876 } 1844 1877 1845 /** Processes the received IP packet or the packet queue one by one.1846 *1847 * The packet is either passed to another module or released on error.1848 *1849 * @param[in] device_id The source device identifier.1850 * @param[in,out] packet The received packet.1851 * @return EOK on success and the packet is no longer needed.1852 * @return EINVAL if the packet is too small to carry the IP1853 * packet.1854 * @return EINVAL if the received address lengths differs from the1855 * registered values.1856 * @return ENOENT if the device is not found in the cache.1857 * @return ENOENT if the protocol for the device is not found in1858 * the cache.1859 * @return ENOMEM if there is not enough memory left.1860 */1861 static int ip_receive_message(device_id_t device_id, packet_t *packet)1862 {1863 packet_t *next;1864 1865 do {1866 next = pq_detach(packet);1867 ip_process_packet(device_id, packet);1868 packet = next;1869 } while (packet);1870 1871 return EOK;1872 }1873 1874 1878 /** Processes the IP message. 1875 1879 * … … 1883 1887 * 1884 1888 * @see ip_interface.h 1885 * @see il_ interface.h1889 * @see il_remote.h 1886 1890 * @see IS_NET_IP_MESSAGE() 1887 1891 */ 1888 int 1889 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1890 int *answer_count) 1892 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1893 size_t *answer_count) 1891 1894 { 1892 1895 packet_t *packet; 1893 1896 struct sockaddr *addr; 1897 void *header; 1898 size_t headerlen; 1894 1899 size_t addrlen; 1895 1900 size_t prefix; 1896 1901 size_t suffix; 1897 1902 size_t content; 1898 void *header;1899 size_t headerlen;1900 1903 device_id_t device_id; 1901 1904 int rc; 1902 1905 1903 1906 *answer_count = 0; 1904 switch (IPC_GET_ METHOD(*call)) {1907 switch (IPC_GET_IMETHOD(*call)) { 1905 1908 case IPC_M_PHONE_HUNGUP: 1906 1909 return EOK; 1907 1910 1908 1911 case IPC_M_CONNECT_TO_ME: 1909 return ip_register(IL_GET_PROTO( call), IL_GET_SERVICE(call),1910 IPC_GET_PHONE( call), NULL);1911 1912 case NET_I L_DEVICE:1913 return ip_device_req_local(0, IPC_GET_DEVICE( call),1914 IPC_GET_SERVICE( call));1915 1916 case NET_I L_SEND:1912 return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call), 1913 IPC_GET_PHONE(*call), NULL); 1914 1915 case NET_IP_DEVICE: 1916 return ip_device_req_local(0, IPC_GET_DEVICE(*call), 1917 IPC_GET_SERVICE(*call)); 1918 1919 case NET_IP_RECEIVED_ERROR: 1917 1920 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1918 IPC_GET_PACKET( call));1921 IPC_GET_PACKET(*call)); 1919 1922 if (rc != EOK) 1920 1923 return rc; 1921 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 1922 IPC_GET_ERROR(call)); 1923 1924 case NET_IL_DEVICE_STATE: 1925 return ip_device_state_message(IPC_GET_DEVICE(call), 1926 IPC_GET_STATE(call)); 1927 1928 case NET_IL_RECEIVED: 1929 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1930 IPC_GET_PACKET(call)); 1931 if (rc != EOK) 1932 return rc; 1933 return ip_receive_message(IPC_GET_DEVICE(call), packet); 1934 1935 case NET_IP_RECEIVED_ERROR: 1936 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1937 IPC_GET_PACKET(call)); 1938 if (rc != EOK) 1939 return rc; 1940 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), 1941 packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call)); 1924 return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call), 1925 packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call)); 1942 1926 1943 1927 case NET_IP_ADD_ROUTE: 1944 return ip_add_route_req_local(0, IPC_GET_DEVICE( call),1945 IP_GET_ADDRESS( call), IP_GET_NETMASK(call),1946 IP_GET_GATEWAY( call));1928 return ip_add_route_req_local(0, IPC_GET_DEVICE(*call), 1929 IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call), 1930 IP_GET_GATEWAY(*call)); 1947 1931 1948 1932 case NET_IP_SET_GATEWAY: 1949 return ip_set_gateway_req_local(0, IPC_GET_DEVICE( call),1950 IP_GET_GATEWAY( call));1933 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call), 1934 IP_GET_GATEWAY(*call)); 1951 1935 1952 1936 case NET_IP_GET_ROUTE: 1953 rc = data_receive((void **) &addr, &addrlen); 1937 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, 1938 &addrlen); 1954 1939 if (rc != EOK) 1955 1940 return rc; 1956 1941 1957 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL( call), addr,1942 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr, 1958 1943 (socklen_t) addrlen, &device_id, &header, &headerlen); 1959 1944 if (rc != EOK) 1960 1945 return rc; 1961 1946 1962 IPC_SET_DEVICE( answer, device_id);1963 IP_SET_HEADERLEN( answer, headerlen);1947 IPC_SET_DEVICE(*answer, device_id); 1948 IP_SET_HEADERLEN(*answer, headerlen); 1964 1949 1965 1950 *answer_count = 2; … … 1972 1957 return rc; 1973 1958 1974 case NET_I L_PACKET_SPACE:1975 rc = ip_packet_size_message(IPC_GET_DEVICE( call), &addrlen,1959 case NET_IP_PACKET_SPACE: 1960 rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen, 1976 1961 &prefix, &content, &suffix); 1977 1962 if (rc != EOK) 1978 1963 return rc; 1979 1964 1980 IPC_SET_ADDR( answer, addrlen);1981 IPC_SET_PREFIX( answer, prefix);1982 IPC_SET_CONTENT( answer, content);1983 IPC_SET_SUFFIX( answer, suffix);1965 IPC_SET_ADDR(*answer, addrlen); 1966 IPC_SET_PREFIX(*answer, prefix); 1967 IPC_SET_CONTENT(*answer, content); 1968 IPC_SET_SUFFIX(*answer, suffix); 1984 1969 *answer_count = 4; 1985 1970 return EOK; 1986 1971 1987 case NET_IL_MTU_CHANGED: 1988 return ip_mtu_changed_message(IPC_GET_DEVICE(call), 1989 IPC_GET_MTU(call)); 1972 case NET_IP_SEND: 1973 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1974 IPC_GET_PACKET(*call)); 1975 if (rc != EOK) 1976 return rc; 1977 1978 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1979 IPC_GET_ERROR(*call)); 1990 1980 } 1991 1981 … … 1993 1983 } 1994 1984 1995 /** Default thread for new connections.1996 *1997 * @param[in] iid The initial message identifier.1998 * @param[in] icall The initial message call structure.1999 */2000 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)2001 {2002 /*2003 * Accept the connection2004 * - Answer the first IPC_M_CONNECT_ME_TO call.2005 */2006 ipc_answer_0(iid, EOK);2007 2008 while (true) {2009 ipc_call_t answer;2010 int answer_count;2011 2012 /* Clear the answer structure */2013 refresh_answer(&answer, &answer_count);2014 2015 /* Fetch the next message */2016 ipc_call_t call;2017 ipc_callid_t callid = async_get_call(&call);2018 2019 /* Process the message */2020 int res = il_module_message_standalone(callid, &call, &answer,2021 &answer_count);2022 2023 /*2024 * End if told to either by the message or the processing2025 * result.2026 */2027 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||2028 (res == EHANGUP)) {2029 return;2030 }2031 2032 /* Answer the message */2033 answer_call(callid, res, &answer, answer_count);2034 }2035 }2036 2037 /** Starts the module.2038 *2039 * @return EOK on success.2040 * @return Other error codes as defined for each specific module start function.2041 */2042 1985 int main(int argc, char *argv[]) 2043 1986 { 2044 int rc;2045 2046 1987 /* Start the module */ 2047 rc = il_module_start_standalone(il_client_connection); 2048 return rc; 1988 return il_module_start(SERVICE_IP); 2049 1989 } 2050 1990
Note:
See TracChangeset
for help on using the changeset viewer.