Changes in uspace/srv/net/il/ip/ip.c [7880d58:5fe7692] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
r7880d58 r5fe7692 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 { … … 431 422 ip_netif->phone = nil_bind_service(ip_netif->service, 432 423 (sysarg_t) ip_netif->device_id, SERVICE_IP, 433 ip_ globals.client_connection);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;434 address.value = (uint8_t *) &route->address.s_addr; 444 435 address.length = sizeof(in_addr_t); 445 436 … … 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, free); 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; … … 752 812 * function. 753 813 */ 754 static int 755 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, 756 815 ip_header_t *header, ip_header_t *new_header, size_t length, 757 816 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 787 846 788 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; 789 869 } 790 870 … … 991 1071 * function. 992 1072 */ 993 static int 994 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route, 995 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) 996 1075 { 997 1076 measured_string_t destination; 998 1077 measured_string_t *translation; 999 char*data;1078 uint8_t *data; 1000 1079 int phone; 1001 1080 int rc; … … 1004 1083 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 1005 1084 destination.value = route->gateway.s_addr ? 1006 ( char *) &route->gateway.s_addr : (char*) &dest.s_addr;1085 (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr; 1007 1086 destination.length = sizeof(dest.s_addr); 1008 1087 … … 1056 1135 } 1057 1136 1058 /** Searches the network interfaces if there is a suitable route. 1059 * 1060 * @param[in] netif The network interface to be searched for routes. May be 1061 * NULL. 1062 * @param[in] destination The destination address. 1063 * @return The found route. 1064 * @return NULL if no route was found. 1065 */ 1066 static ip_route_t * 1067 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination) 1068 { 1069 int index; 1070 ip_route_t *route; 1071 1072 if (!netif) 1073 return NULL; 1074 1075 // start with the first one - the direct route 1076 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1077 route = ip_routes_get_index(&netif->routes, index); 1078 if (route && 1079 ((route->address.s_addr & route->netmask.s_addr) == 1080 (destination.s_addr & route->netmask.s_addr))) { 1081 return route; 1082 } 1083 } 1084 1085 return NULL; 1086 } 1087 1088 /** Searches all network interfaces if there is a suitable route. 1089 * 1090 * @param[in] destination The destination address. 1091 * @return The found route. 1092 * @return NULL if no route was found. 1093 */ 1094 static ip_route_t *ip_find_route(in_addr_t destination) { 1095 int index; 1096 ip_route_t *route; 1097 ip_netif_t *netif; 1098 1099 // start with the last netif - the newest one 1100 index = ip_netifs_count(&ip_globals.netifs) - 1; 1101 while (index >= 0) { 1102 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1103 if (netif && (netif->state == NETIF_ACTIVE)) { 1104 route = ip_netif_find_route(netif, destination); 1105 if (route) 1106 return route; 1107 } 1108 index--; 1109 } 1110 1111 return &ip_globals.gateway; 1112 } 1113 1114 /** Returns the network interface's IP address. 1115 * 1116 * @param[in] netif The network interface. 1117 * @return The IP address. 1118 * @return NULL if no IP address was found. 1119 */ 1120 static in_addr_t *ip_netif_address(ip_netif_t *netif) 1121 { 1122 ip_route_t *route; 1123 1124 route = ip_routes_get_index(&netif->routes, 0); 1125 return route ? &route->address : NULL; 1126 } 1127 1128 /** Registers the transport layer protocol. 1129 * 1130 * The traffic of this protocol will be supplied using either the receive 1131 * function or IPC message. 1132 * 1133 * @param[in] protocol The transport layer module protocol. 1134 * @param[in] service The transport layer module service. 1135 * @param[in] phone The transport layer module phone. 1136 * @param[in] received_msg The receiving function. 1137 * @return EOK on success. 1138 * @return EINVAL if the protocol parameter and/or the service 1139 * parameter is zero. 1140 * @return EINVAL if the phone parameter is not a positive number 1141 * and the tl_receive_msg is NULL. 1142 * @return ENOMEM if there is not enough memory left. 1143 */ 1144 static int 1145 ip_register(int protocol, services_t service, int phone, 1146 tl_received_msg_t received_msg) 1147 { 1148 ip_proto_t *proto; 1149 int index; 1150 1151 if (!protocol || !service || ((phone < 0) && !received_msg)) 1152 return EINVAL; 1153 1154 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1155 if (!proto) 1156 return ENOMEM; 1157 1158 proto->protocol = protocol; 1159 proto->service = service; 1160 proto->phone = phone; 1161 proto->received_msg = received_msg; 1162 1163 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1164 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1165 if (index < 0) { 1166 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1167 free(proto); 1168 return index; 1169 } 1170 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1171 1172 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1173 NAME, proto->protocol, proto->phone); 1174 1175 return EOK; 1176 } 1177 1178 static int 1179 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1180 { 1181 ip_netif_t *ip_netif; 1182 ip_route_t *route; 1183 int index; 1184 int rc; 1185 1186 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 1187 if (!ip_netif) 1188 return ENOMEM; 1189 1190 rc = ip_routes_initialize(&ip_netif->routes); 1191 if (rc != EOK) { 1192 free(ip_netif); 1193 return rc; 1194 } 1195 1196 ip_netif->device_id = device_id; 1197 ip_netif->service = netif; 1198 ip_netif->state = NETIF_STOPPED; 1199 1200 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1201 1202 rc = ip_netif_initialize(ip_netif); 1203 if (rc != EOK) { 1204 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1205 ip_routes_destroy(&ip_netif->routes); 1206 free(ip_netif); 1207 return rc; 1208 } 1209 if (ip_netif->arp) 1210 ip_netif->arp->usage++; 1211 1212 // print the settings 1213 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 1214 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 1215 ip_netif->dhcp ? "dhcp" : "static"); 1216 1217 // TODO ipv6 addresses 1218 1219 char address[INET_ADDRSTRLEN]; 1220 char netmask[INET_ADDRSTRLEN]; 1221 char gateway[INET_ADDRSTRLEN]; 1222 1223 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 1224 route = ip_routes_get_index(&ip_netif->routes, index); 1225 if (route) { 1226 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1227 address, INET_ADDRSTRLEN); 1228 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1229 netmask, INET_ADDRSTRLEN); 1230 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1231 gateway, INET_ADDRSTRLEN); 1232 printf("%s: Route %d (address: %s, netmask: %s, " 1233 "gateway: %s)\n", NAME, index, address, netmask, 1234 gateway); 1235 } 1236 } 1237 1238 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1239 INET_ADDRSTRLEN); 1240 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1241 1242 printf("%s: Broadcast (%s)\n", NAME, address); 1243 1244 return EOK; 1245 } 1246 1247 static int 1248 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet, 1249 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) 1250 1139 { 1251 1140 int addrlen; … … 1288 1177 if (device_id > 0) { 1289 1178 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1290 route = ip_netif_find_route(netif, * 1179 route = ip_netif_find_route(netif, *dest); 1291 1180 if (netif && !route && (ip_globals.gateway.netif == netif)) 1292 1181 route = &ip_globals.gateway; … … 1318 1207 } 1319 1208 } 1320 1209 1321 1210 // if the local host is the destination 1322 1211 if ((route->address.s_addr == dest->s_addr) && … … 1351 1240 } 1352 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 1353 1494 /** Returns the device packet dimensions for sending. 1354 1495 * … … 1362 1503 * @return EOK on success. 1363 1504 */ 1364 static int 1365 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1366 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) 1367 1507 { 1368 1508 ip_netif_t *netif; … … 1414 1554 } 1415 1555 1416 /** Returns the packet destination address from the IP header. 1417 * 1418 * @param[in] header The packet IP header to be read. 1419 * @return The packet destination address. 1420 */ 1421 static in_addr_t ip_get_destination(ip_header_t *header) 1422 { 1423 in_addr_t destination; 1424 1425 // TODO search set ipopt route? 1426 destination.s_addr = header->destination_address; 1427 return destination; 1428 } 1429 1430 /** Delivers the packet to the local host. 1431 * 1432 * The packet is either passed to another module or released on error. 1433 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1434 * found. 1435 * 1436 * @param[in] device_id The source device identifier. 1437 * @param[in] packet The packet to be delivered. 1438 * @param[in] header The first packet IP header. May be NULL. 1439 * @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. 1440 1560 * @return EOK on success. 1441 * @return ENOTSUP if the packet is a fragment. 1442 * @return EAFNOSUPPORT if the address family is not supported. 1443 * @return ENOENT if the target protocol is not found. 1444 * @return Other error codes as defined for the packet_set_addr() 1445 * function. 1446 * @return Other error codes as defined for the packet_trim() 1447 * function. 1448 * @return Other error codes as defined for the protocol specific 1449 * 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. 1450 1643 */ 1451 1644 static int 1452 ip_ deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,1453 services_t error)1645 ip_register(int protocol, services_t service, int phone, 1646 tl_received_msg_t received_msg) 1454 1647 { 1455 1648 ip_proto_t *proto; 1456 int phone; 1457 services_t service; 1458 tl_received_msg_t received_msg; 1459 struct sockaddr *src; 1460 struct sockaddr *dest; 1461 struct sockaddr_in src_in; 1462 struct sockaddr_in dest_in; 1463 socklen_t addrlen; 1464 int rc; 1465 1466 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1467 IP_FRAGMENT_OFFSET(header)) { 1468 // TODO fragmented 1469 return ENOTSUP; 1470 } 1471 1472 switch (header->version) { 1473 case IPVERSION: 1474 addrlen = sizeof(src_in); 1475 bzero(&src_in, addrlen); 1476 src_in.sin_family = AF_INET; 1477 memcpy(&dest_in, &src_in, addrlen); 1478 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1479 sizeof(header->source_address)); 1480 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1481 sizeof(header->destination_address)); 1482 src = (struct sockaddr *) &src_in; 1483 dest = (struct sockaddr *) &dest_in; 1484 break; 1485 1486 default: 1487 return ip_release_and_return(packet, EAFNOSUPPORT); 1488 } 1489 1490 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1491 addrlen); 1492 if (rc != EOK) 1493 return ip_release_and_return(packet, rc); 1494 1495 // trim padding if present 1496 if (!error && 1497 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1498 rc = packet_trim(packet, 0, 1499 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1500 if (rc != EOK) 1501 return ip_release_and_return(packet, rc); 1502 } 1503 1504 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1505 1506 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1507 if (!proto) { 1508 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1509 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1510 if (phone >= 0) { 1511 // unreachable ICMP 1512 icmp_destination_unreachable_msg(phone, 1513 ICMP_PROT_UNREACH, 0, packet); 1514 } 1515 return ENOENT; 1516 } 1517 1518 if (proto->received_msg) { 1519 service = proto->service; 1520 received_msg = proto->received_msg; 1521 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1522 rc = received_msg(device_id, packet, service, error); 1523 } else { 1524 rc = tl_received_msg(proto->phone, device_id, packet, 1525 proto->service, error); 1526 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1527 } 1528 1529 return rc; 1530 } 1531 1532 /** Processes the received packet. 1533 * 1534 * The packet is either passed to another module or released on error. 1535 * 1536 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1537 * invalid. 1538 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1539 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1540 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1541 * another host and the routing is disabled. 1542 * 1543 * @param[in] device_id The source device identifier. 1544 * @param[in] packet The received packet to be processed. 1545 * @return EOK on success. 1546 * @return EINVAL if the TTL is less than two. 1547 * @return EINVAL if the checksum is invalid. 1548 * @return EAFNOSUPPORT if the address family is not supported. 1549 * @return ENOENT if no route was found. 1550 * @return ENOENT if the packet is for another host and the routing 1551 * is disabled. 1552 */ 1553 static int 1554 ip_process_packet(device_id_t device_id, packet_t *packet) 1555 { 1556 ip_header_t *header; 1557 in_addr_t dest; 1558 ip_route_t *route; 1559 int phone; 1560 struct sockaddr *addr; 1561 struct sockaddr_in addr_in; 1562 socklen_t addrlen; 1563 int rc; 1564 1565 header = (ip_header_t *) packet_get_data(packet); 1566 if (!header) 1567 return ip_release_and_return(packet, ENOMEM); 1568 1569 // checksum 1570 if ((header->header_checksum) && 1571 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1572 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1573 if (phone >= 0) { 1574 // checksum error ICMP 1575 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1576 ((size_t) ((void *) &header->header_checksum)) - 1577 ((size_t) ((void *) header)), packet); 1578 } 1649 int index; 1650 1651 if (!protocol || !service || ((phone < 0) && !received_msg)) 1579 1652 return EINVAL; 1580 } 1581 1582 if (header->ttl <= 1) { 1583 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1584 if (phone >= 0) { 1585 // ttl exceeded ICMP 1586 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1587 } 1588 return EINVAL; 1589 } 1590 1591 // process ipopt and get destination 1592 dest = ip_get_destination(header); 1593 1594 // set the addrination address 1595 switch (header->version) { 1596 case IPVERSION: 1597 addrlen = sizeof(addr_in); 1598 bzero(&addr_in, addrlen); 1599 addr_in.sin_family = AF_INET; 1600 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1601 addr = (struct sockaddr *) &addr_in; 1602 break; 1603 1604 default: 1605 return ip_release_and_return(packet, EAFNOSUPPORT); 1606 } 1607 1608 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1609 if (rc != EOK) 1610 return rc; 1611 1612 route = ip_find_route(dest); 1613 if (!route) { 1614 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1615 if (phone >= 0) { 1616 // unreachable ICMP 1617 icmp_destination_unreachable_msg(phone, 1618 ICMP_HOST_UNREACH, 0, packet); 1619 } 1620 return ENOENT; 1621 } 1622 1623 if (route->address.s_addr == dest.s_addr) { 1624 // local delivery 1625 return ip_deliver_local(device_id, packet, header, 0); 1626 } 1627 1628 if (route->netif->routing) { 1629 header->ttl--; 1630 return ip_send_route(packet, route->netif, route, NULL, dest, 1631 0); 1632 } 1633 1634 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1635 if (phone >= 0) { 1636 // unreachable ICMP if no routing 1637 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1638 packet); 1639 } 1640 1641 return ENOENT; 1642 } 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 1643 1678 1644 1679 static int … … 1756 1791 (header->destination_address & route->netmask.s_addr))) { 1757 1792 // clear the ARP mapping if any 1758 address.value = ( char*) &header->destination_address;1793 address.value = (uint8_t *) &header->destination_address; 1759 1794 address.length = sizeof(header->destination_address); 1760 1795 arp_clear_address_req(netif->arp->phone, … … 1841 1876 } 1842 1877 1843 /** Processes the received IP packet or the packet queue one by one.1844 *1845 * The packet is either passed to another module or released on error.1846 *1847 * @param[in] device_id The source device identifier.1848 * @param[in,out] packet The received packet.1849 * @return EOK on success and the packet is no longer needed.1850 * @return EINVAL if the packet is too small to carry the IP1851 * packet.1852 * @return EINVAL if the received address lengths differs from the1853 * registered values.1854 * @return ENOENT if the device is not found in the cache.1855 * @return ENOENT if the protocol for the device is not found in1856 * the cache.1857 * @return ENOMEM if there is not enough memory left.1858 */1859 static int ip_receive_message(device_id_t device_id, packet_t *packet)1860 {1861 packet_t *next;1862 1863 do {1864 next = pq_detach(packet);1865 ip_process_packet(device_id, packet);1866 packet = next;1867 } while (packet);1868 1869 return EOK;1870 }1871 1872 1878 /** Processes the IP message. 1873 1879 * … … 1881 1887 * 1882 1888 * @see ip_interface.h 1883 * @see il_ interface.h1889 * @see il_remote.h 1884 1890 * @see IS_NET_IP_MESSAGE() 1885 1891 */ 1886 int 1887 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1888 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) 1889 1894 { 1890 1895 packet_t *packet; 1891 1896 struct sockaddr *addr; 1897 void *header; 1898 size_t headerlen; 1892 1899 size_t addrlen; 1893 1900 size_t prefix; 1894 1901 size_t suffix; 1895 1902 size_t content; 1896 void *header;1897 size_t headerlen;1898 1903 device_id_t device_id; 1899 1904 int rc; … … 1905 1910 1906 1911 case IPC_M_CONNECT_TO_ME: 1907 return ip_register(IL_GET_PROTO( call), IL_GET_SERVICE(call),1908 IPC_GET_PHONE( call), NULL);1909 1910 case NET_I L_DEVICE:1911 return ip_device_req_local(0, IPC_GET_DEVICE( call),1912 IPC_GET_SERVICE( call));1913 1914 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: 1915 1920 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1916 IPC_GET_PACKET( call));1921 IPC_GET_PACKET(*call)); 1917 1922 if (rc != EOK) 1918 1923 return rc; 1919 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 1920 IPC_GET_ERROR(call)); 1921 1922 case NET_IL_DEVICE_STATE: 1923 return ip_device_state_message(IPC_GET_DEVICE(call), 1924 IPC_GET_STATE(call)); 1925 1926 case NET_IL_RECEIVED: 1927 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1928 IPC_GET_PACKET(call)); 1929 if (rc != EOK) 1930 return rc; 1931 return ip_receive_message(IPC_GET_DEVICE(call), packet); 1932 1933 case NET_IP_RECEIVED_ERROR: 1934 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1935 IPC_GET_PACKET(call)); 1936 if (rc != EOK) 1937 return rc; 1938 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), 1939 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)); 1940 1926 1941 1927 case NET_IP_ADD_ROUTE: 1942 return ip_add_route_req_local(0, IPC_GET_DEVICE( call),1943 IP_GET_ADDRESS( call), IP_GET_NETMASK(call),1944 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)); 1945 1931 1946 1932 case NET_IP_SET_GATEWAY: 1947 return ip_set_gateway_req_local(0, IPC_GET_DEVICE( call),1948 IP_GET_GATEWAY( call));1933 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call), 1934 IP_GET_GATEWAY(*call)); 1949 1935 1950 1936 case NET_IP_GET_ROUTE: … … 1954 1940 return rc; 1955 1941 1956 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, 1957 1943 (socklen_t) addrlen, &device_id, &header, &headerlen); 1958 1944 if (rc != EOK) 1959 1945 return rc; 1960 1946 1961 IPC_SET_DEVICE( answer, device_id);1962 IP_SET_HEADERLEN( answer, headerlen);1947 IPC_SET_DEVICE(*answer, device_id); 1948 IP_SET_HEADERLEN(*answer, headerlen); 1963 1949 1964 1950 *answer_count = 2; … … 1971 1957 return rc; 1972 1958 1973 case NET_I L_PACKET_SPACE:1974 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, 1975 1961 &prefix, &content, &suffix); 1976 1962 if (rc != EOK) 1977 1963 return rc; 1978 1964 1979 IPC_SET_ADDR( answer, addrlen);1980 IPC_SET_PREFIX( answer, prefix);1981 IPC_SET_CONTENT( answer, content);1982 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); 1983 1969 *answer_count = 4; 1984 1970 return EOK; 1985 1971 1986 case NET_IL_MTU_CHANGED: 1987 return ip_mtu_changed_message(IPC_GET_DEVICE(call), 1988 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)); 1989 1980 } 1990 1981 … … 1992 1983 } 1993 1984 1994 /** Default thread for new connections.1995 *1996 * @param[in] iid The initial message identifier.1997 * @param[in] icall The initial message call structure.1998 */1999 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)2000 {2001 /*2002 * Accept the connection2003 * - Answer the first IPC_M_CONNECT_ME_TO call.2004 */2005 ipc_answer_0(iid, EOK);2006 2007 while (true) {2008 ipc_call_t answer;2009 int answer_count;2010 2011 /* Clear the answer structure */2012 refresh_answer(&answer, &answer_count);2013 2014 /* Fetch the next message */2015 ipc_call_t call;2016 ipc_callid_t callid = async_get_call(&call);2017 2018 /* Process the message */2019 int res = il_module_message_standalone(callid, &call, &answer,2020 &answer_count);2021 2022 /*2023 * End if told to either by the message or the processing2024 * result.2025 */2026 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||2027 (res == EHANGUP)) {2028 return;2029 }2030 2031 /* Answer the message */2032 answer_call(callid, res, &answer, answer_count);2033 }2034 }2035 2036 /** Starts the module.2037 *2038 * @return EOK on success.2039 * @return Other error codes as defined for each specific module start function.2040 */2041 1985 int main(int argc, char *argv[]) 2042 1986 { 2043 int rc;2044 2045 1987 /* Start the module */ 2046 rc = il_module_start_standalone(il_client_connection); 2047 return rc; 1988 return il_module_start(SERVICE_IP); 2048 1989 } 2049 1990
Note:
See TracChangeset
for help on using the changeset viewer.