Changes in uspace/srv/net/il/ip/ip.c [014dd57b:774e6d1a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
r014dd57b r774e6d1a 35 35 * @see arp.h 36 36 */ 37 38 #include "ip.h" 39 #include "ip_module.h" 37 40 38 41 #include <async.h> … … 49 52 #include <sys/types.h> 50 53 #include <byteorder.h> 51 #include "ip.h"52 54 53 55 #include <adt/measured_strings.h> … … 68 70 #include <icmp_client.h> 69 71 #include <icmp_interface.h> 72 #include <il_interface.h> 70 73 #include <ip_client.h> 71 74 #include <ip_interface.h> 72 75 #include <ip_header.h> 73 76 #include <net_interface.h> 74 #include <nil_ remote.h>75 #include <tl_ remote.h>77 #include <nil_interface.h> 78 #include <tl_interface.h> 76 79 #include <packet_remote.h> 77 #include <il_remote.h> 78 #include <il_skel.h> 80 #include <il_local.h> 79 81 80 82 /** IP module name. */ … … 120 122 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 121 123 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 122 123 static void ip_receiver(ipc_callid_t, ipc_call_t *);124 124 125 125 /** Releases the packet and returns the result. … … 244 244 } 245 245 246 int il_initialize(int net_phone) 247 { 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 248 257 fibril_rwlock_initialize(&ip_globals.lock); 249 258 fibril_rwlock_write_lock(&ip_globals.lock); 250 259 fibril_rwlock_initialize(&ip_globals.protos_lock); 251 260 fibril_rwlock_initialize(&ip_globals.netifs_lock); 252 253 ip_globals.net_phone = net_phone;254 261 ip_globals.packet_counter = 0; 255 262 ip_globals.gateway.address.s_addr = 0; … … 257 264 ip_globals.gateway.gateway.s_addr = 0; 258 265 ip_globals.gateway.netif = NULL; 259 260 int rc = ip_netifs_initialize(&ip_globals.netifs); 266 ip_globals.client_connection = client_connection; 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 261 269 if (rc != EOK) 262 270 goto out; … … 423 431 ip_netif->phone = nil_bind_service(ip_netif->service, 424 432 (sysarg_t) ip_netif->device_id, SERVICE_IP, 425 ip_ receiver);433 ip_globals.client_connection); 426 434 if (ip_netif->phone < 0) { 427 435 printf("Failed to contact the nil service %d\n", … … 479 487 } 480 488 481 static int ip_device_req_local(int il_phone, device_id_t device_id, 482 services_t netif) 483 { 484 ip_netif_t *ip_netif; 485 ip_route_t *route; 486 int index; 487 int rc; 488 489 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 490 if (!ip_netif) 491 return ENOMEM; 492 493 rc = ip_routes_initialize(&ip_netif->routes); 494 if (rc != EOK) { 495 free(ip_netif); 496 return rc; 497 } 498 499 ip_netif->device_id = device_id; 500 ip_netif->service = netif; 501 ip_netif->state = NETIF_STOPPED; 489 /** Updates the device content length according to the new MTU value. 490 * 491 * @param[in] device_id The device identifier. 492 * @param[in] mtu The new mtu value. 493 * @return EOK on success. 494 * @return ENOENT if device is not found. 495 */ 496 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 497 { 498 ip_netif_t *netif; 502 499 503 500 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 504 505 rc = ip_netif_initialize(ip_netif); 506 if (rc != EOK) { 501 netif = ip_netifs_find(&ip_globals.netifs, device_id); 502 if (!netif) { 507 503 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 508 ip_routes_destroy(&ip_netif->routes); 509 free(ip_netif); 510 return rc; 511 } 512 if (ip_netif->arp) 513 ip_netif->arp->usage++; 514 515 // print the settings 516 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 517 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 518 ip_netif->dhcp ? "dhcp" : "static"); 519 520 // TODO ipv6 addresses 521 522 char address[INET_ADDRSTRLEN]; 523 char netmask[INET_ADDRSTRLEN]; 524 char gateway[INET_ADDRSTRLEN]; 525 526 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 527 route = ip_routes_get_index(&ip_netif->routes, index); 528 if (route) { 529 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 530 address, INET_ADDRSTRLEN); 531 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 532 netmask, INET_ADDRSTRLEN); 533 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 534 gateway, INET_ADDRSTRLEN); 535 printf("%s: Route %d (address: %s, netmask: %s, " 536 "gateway: %s)\n", NAME, index, address, netmask, 537 gateway); 538 } 539 } 540 541 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 542 INET_ADDRSTRLEN); 504 return ENOENT; 505 } 506 netif->packet_dimension.content = mtu; 543 507 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 544 508 545 printf("%s: Broadcast (%s)\n", NAME, address);509 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 546 510 547 511 return EOK; 548 512 } 549 513 550 /** Searches the network interfaces if there is a suitable route. 551 * 552 * @param[in] netif The network interface to be searched for routes. May be 553 * NULL. 554 * @param[in] destination The destination address. 555 * @return The found route. 556 * @return NULL if no route was found. 557 */ 558 static ip_route_t *ip_netif_find_route(ip_netif_t *netif, 559 in_addr_t destination) 560 { 561 int index; 562 ip_route_t *route; 563 564 if (!netif) 514 /** Updates the device state. 515 * 516 * @param[in] device_id The device identifier. 517 * @param[in] state The new state value. 518 * @return EOK on success. 519 * @return ENOENT if device is not found. 520 */ 521 static int ip_device_state_message(device_id_t device_id, device_state_t state) 522 { 523 ip_netif_t *netif; 524 525 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 526 // find the device 527 netif = ip_netifs_find(&ip_globals.netifs, device_id); 528 if (!netif) { 529 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 530 return ENOENT; 531 } 532 netif->state = state; 533 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 534 535 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 536 537 return EOK; 538 } 539 540 541 /** Prefixes a middle fragment header based on the last fragment header to the 542 * packet. 543 * 544 * @param[in] packet The packet to be prefixed. 545 * @param[in] last The last header to be copied. 546 * @return The prefixed middle header. 547 * @return NULL on error. 548 */ 549 static ip_header_t * 550 ip_create_middle_header(packet_t *packet, ip_header_t *last) 551 { 552 ip_header_t *middle; 553 554 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last)); 555 if (!middle) 565 556 return NULL; 566 567 /* Start with the first one (the direct route) */ 568 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 569 route = ip_routes_get_index(&netif->routes, index); 570 if ((route) && 571 ((route->address.s_addr & route->netmask.s_addr) == 572 (destination.s_addr & route->netmask.s_addr))) 573 return route; 574 } 575 576 return NULL; 577 } 578 579 /** Searches all network interfaces if there is a suitable route. 580 * 581 * @param[in] destination The destination address. 582 * @return The found route. 583 * @return NULL if no route was found. 584 */ 585 static ip_route_t *ip_find_route(in_addr_t destination) { 586 int index; 587 ip_route_t *route; 588 ip_netif_t *netif; 589 590 // start with the last netif - the newest one 591 index = ip_netifs_count(&ip_globals.netifs) - 1; 592 while (index >= 0) { 593 netif = ip_netifs_get_index(&ip_globals.netifs, index); 594 if (netif && (netif->state == NETIF_ACTIVE)) { 595 route = ip_netif_find_route(netif, destination); 596 if (route) 597 return route; 598 } 599 index--; 600 } 601 602 return &ip_globals.gateway; 603 } 604 605 /** Returns the network interface's IP address. 606 * 607 * @param[in] netif The network interface. 608 * @return The IP address. 609 * @return NULL if no IP address was found. 610 */ 611 static in_addr_t *ip_netif_address(ip_netif_t *netif) 612 { 613 ip_route_t *route; 614 615 route = ip_routes_get_index(&netif->routes, 0); 616 return route ? &route->address : NULL; 557 memcpy(middle, last, IP_HEADER_LENGTH(last)); 558 middle->flags |= IPFLAG_MORE_FRAGMENTS; 559 return middle; 617 560 } 618 561 … … 683 626 * function. 684 627 */ 685 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest, 686 packet_t *packet, measured_string_t *destination) 628 static int 629 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet, 630 measured_string_t *destination) 687 631 { 688 632 size_t length; … … 813 757 * function. 814 758 */ 815 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 759 static int 760 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 816 761 ip_header_t *header, ip_header_t *new_header, size_t length, 817 762 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 847 792 848 793 return pq_insert_after(packet, new_packet); 849 }850 851 /** Prefixes a middle fragment header based on the last fragment header to the852 * packet.853 *854 * @param[in] packet The packet to be prefixed.855 * @param[in] last The last header to be copied.856 * @return The prefixed middle header.857 * @return NULL on error.858 */859 static ip_header_t *ip_create_middle_header(packet_t *packet,860 ip_header_t *last)861 {862 ip_header_t *middle;863 864 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));865 if (!middle)866 return NULL;867 memcpy(middle, last, IP_HEADER_LENGTH(last));868 middle->flags |= IPFLAG_MORE_FRAGMENTS;869 return middle;870 794 } 871 795 … … 1072 996 * function. 1073 997 */ 1074 static int ip_send_route(packet_t *packet, ip_netif_t *netif, 1075 ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error) 998 static int 999 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route, 1000 in_addr_t *src, in_addr_t dest, services_t error) 1076 1001 { 1077 1002 measured_string_t destination; … … 1136 1061 } 1137 1062 1138 static int ip_send_msg_local(int il_phone, device_id_t device_id, 1139 packet_t *packet, services_t sender, services_t error) 1063 /** Searches the network interfaces if there is a suitable route. 1064 * 1065 * @param[in] netif The network interface to be searched for routes. May be 1066 * NULL. 1067 * @param[in] destination The destination address. 1068 * @return The found route. 1069 * @return NULL if no route was found. 1070 */ 1071 static ip_route_t * 1072 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination) 1073 { 1074 int index; 1075 ip_route_t *route; 1076 1077 if (!netif) 1078 return NULL; 1079 1080 /* Start with the first one (the direct route) */ 1081 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1082 route = ip_routes_get_index(&netif->routes, index); 1083 if ((route) && 1084 ((route->address.s_addr & route->netmask.s_addr) == 1085 (destination.s_addr & route->netmask.s_addr))) 1086 return route; 1087 } 1088 1089 return NULL; 1090 } 1091 1092 /** Searches all network interfaces if there is a suitable route. 1093 * 1094 * @param[in] destination The destination address. 1095 * @return The found route. 1096 * @return NULL if no route was found. 1097 */ 1098 static ip_route_t *ip_find_route(in_addr_t destination) { 1099 int index; 1100 ip_route_t *route; 1101 ip_netif_t *netif; 1102 1103 // start with the last netif - the newest one 1104 index = ip_netifs_count(&ip_globals.netifs) - 1; 1105 while (index >= 0) { 1106 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1107 if (netif && (netif->state == NETIF_ACTIVE)) { 1108 route = ip_netif_find_route(netif, destination); 1109 if (route) 1110 return route; 1111 } 1112 index--; 1113 } 1114 1115 return &ip_globals.gateway; 1116 } 1117 1118 /** Returns the network interface's IP address. 1119 * 1120 * @param[in] netif The network interface. 1121 * @return The IP address. 1122 * @return NULL if no IP address was found. 1123 */ 1124 static in_addr_t *ip_netif_address(ip_netif_t *netif) 1125 { 1126 ip_route_t *route; 1127 1128 route = ip_routes_get_index(&netif->routes, 0); 1129 return route ? &route->address : NULL; 1130 } 1131 1132 /** Registers the transport layer protocol. 1133 * 1134 * The traffic of this protocol will be supplied using either the receive 1135 * function or IPC message. 1136 * 1137 * @param[in] protocol The transport layer module protocol. 1138 * @param[in] service The transport layer module service. 1139 * @param[in] phone The transport layer module phone. 1140 * @param[in] received_msg The receiving function. 1141 * @return EOK on success. 1142 * @return EINVAL if the protocol parameter and/or the service 1143 * parameter is zero. 1144 * @return EINVAL if the phone parameter is not a positive number 1145 * and the tl_receive_msg is NULL. 1146 * @return ENOMEM if there is not enough memory left. 1147 */ 1148 static int 1149 ip_register(int protocol, services_t service, int phone, 1150 tl_received_msg_t received_msg) 1151 { 1152 ip_proto_t *proto; 1153 int index; 1154 1155 if (!protocol || !service || ((phone < 0) && !received_msg)) 1156 return EINVAL; 1157 1158 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1159 if (!proto) 1160 return ENOMEM; 1161 1162 proto->protocol = protocol; 1163 proto->service = service; 1164 proto->phone = phone; 1165 proto->received_msg = received_msg; 1166 1167 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1168 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1169 if (index < 0) { 1170 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1171 free(proto); 1172 return index; 1173 } 1174 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1175 1176 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1177 NAME, proto->protocol, proto->phone); 1178 1179 return EOK; 1180 } 1181 1182 static int 1183 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1184 { 1185 ip_netif_t *ip_netif; 1186 ip_route_t *route; 1187 int index; 1188 int rc; 1189 1190 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 1191 if (!ip_netif) 1192 return ENOMEM; 1193 1194 rc = ip_routes_initialize(&ip_netif->routes); 1195 if (rc != EOK) { 1196 free(ip_netif); 1197 return rc; 1198 } 1199 1200 ip_netif->device_id = device_id; 1201 ip_netif->service = netif; 1202 ip_netif->state = NETIF_STOPPED; 1203 1204 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1205 1206 rc = ip_netif_initialize(ip_netif); 1207 if (rc != EOK) { 1208 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1209 ip_routes_destroy(&ip_netif->routes); 1210 free(ip_netif); 1211 return rc; 1212 } 1213 if (ip_netif->arp) 1214 ip_netif->arp->usage++; 1215 1216 // print the settings 1217 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 1218 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 1219 ip_netif->dhcp ? "dhcp" : "static"); 1220 1221 // TODO ipv6 addresses 1222 1223 char address[INET_ADDRSTRLEN]; 1224 char netmask[INET_ADDRSTRLEN]; 1225 char gateway[INET_ADDRSTRLEN]; 1226 1227 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 1228 route = ip_routes_get_index(&ip_netif->routes, index); 1229 if (route) { 1230 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1231 address, INET_ADDRSTRLEN); 1232 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1233 netmask, INET_ADDRSTRLEN); 1234 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1235 gateway, INET_ADDRSTRLEN); 1236 printf("%s: Route %d (address: %s, netmask: %s, " 1237 "gateway: %s)\n", NAME, index, address, netmask, 1238 gateway); 1239 } 1240 } 1241 1242 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1243 INET_ADDRSTRLEN); 1244 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1245 1246 printf("%s: Broadcast (%s)\n", NAME, address); 1247 1248 return EOK; 1249 } 1250 1251 static int 1252 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet, 1253 services_t sender, services_t error) 1140 1254 { 1141 1255 int addrlen; … … 1241 1355 } 1242 1356 1243 /** Updates the device state. 1244 * 1357 /** Returns the device packet dimensions for sending. 1358 * 1359 * @param[in] phone The service module phone. 1360 * @param[in] message The service specific message. 1245 1361 * @param[in] device_id The device identifier. 1246 * @param[in] state The new state value. 1362 * @param[out] addr_len The minimum reserved address length. 1363 * @param[out] prefix The minimum reserved prefix size. 1364 * @param[out] content The maximum content size. 1365 * @param[out] suffix The minimum reserved suffix size. 1247 1366 * @return EOK on success. 1248 * @return ENOENT if device is not found. 1249 */ 1250 static int ip_device_state_message(device_id_t device_id, device_state_t state) 1367 */ 1368 static int 1369 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1370 size_t *content, size_t *suffix) 1251 1371 { 1252 1372 ip_netif_t *netif; 1253 1254 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1255 // find the device 1256 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1257 if (!netif) { 1258 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1259 return ENOENT; 1260 } 1261 netif->state = state; 1262 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1263 1264 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 1373 int index; 1374 1375 if (!addr_len || !prefix || !content || !suffix) 1376 return EBADMEM; 1377 1378 *content = IP_MAX_CONTENT - IP_PREFIX; 1379 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1380 if (device_id < 0) { 1381 *addr_len = IP_ADDR; 1382 *prefix = 0; 1383 *suffix = 0; 1384 1385 for (index = ip_netifs_count(&ip_globals.netifs) - 1; 1386 index >= 0; index--) { 1387 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1388 if (!netif) 1389 continue; 1390 1391 if (netif->packet_dimension.addr_len > *addr_len) 1392 *addr_len = netif->packet_dimension.addr_len; 1393 1394 if (netif->packet_dimension.prefix > *prefix) 1395 *prefix = netif->packet_dimension.prefix; 1396 1397 if (netif->packet_dimension.suffix > *suffix) 1398 *suffix = netif->packet_dimension.suffix; 1399 } 1400 1401 *prefix = *prefix + IP_PREFIX; 1402 *suffix = *suffix + IP_SUFFIX; 1403 } else { 1404 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1405 if (!netif) { 1406 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1407 return ENOENT; 1408 } 1409 1410 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? 1411 netif->packet_dimension.addr_len : IP_ADDR; 1412 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 1413 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 1414 } 1415 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1265 1416 1266 1417 return EOK; … … 1302 1453 * tl_received_msg() function. 1303 1454 */ 1304 static int ip_deliver_local(device_id_t device_id, packet_t *packet, 1305 ip_header_t *header, services_t error) 1455 static int 1456 ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header, 1457 services_t error) 1306 1458 { 1307 1459 ip_proto_t *proto; … … 1403 1555 * is disabled. 1404 1556 */ 1405 static int ip_process_packet(device_id_t device_id, packet_t *packet) 1557 static int 1558 ip_process_packet(device_id_t device_id, packet_t *packet) 1406 1559 { 1407 1560 ip_header_t *header; … … 1493 1646 } 1494 1647 1495 /** Returns the device packet dimensions for sending.1496 *1497 * @param[in] phone The service module phone.1498 * @param[in] message The service specific message.1499 * @param[in] device_id The device identifier.1500 * @param[out] addr_len The minimum reserved address length.1501 * @param[out] prefix The minimum reserved prefix size.1502 * @param[out] content The maximum content size.1503 * @param[out] suffix The minimum reserved suffix size.1504 * @return EOK on success.1505 */1506 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,1507 size_t *prefix, size_t *content, size_t *suffix)1508 {1509 ip_netif_t *netif;1510 int index;1511 1512 if (!addr_len || !prefix || !content || !suffix)1513 return EBADMEM;1514 1515 *content = IP_MAX_CONTENT - IP_PREFIX;1516 fibril_rwlock_read_lock(&ip_globals.netifs_lock);1517 if (device_id < 0) {1518 *addr_len = IP_ADDR;1519 *prefix = 0;1520 *suffix = 0;1521 1522 for (index = ip_netifs_count(&ip_globals.netifs) - 1;1523 index >= 0; index--) {1524 netif = ip_netifs_get_index(&ip_globals.netifs, index);1525 if (!netif)1526 continue;1527 1528 if (netif->packet_dimension.addr_len > *addr_len)1529 *addr_len = netif->packet_dimension.addr_len;1530 1531 if (netif->packet_dimension.prefix > *prefix)1532 *prefix = netif->packet_dimension.prefix;1533 1534 if (netif->packet_dimension.suffix > *suffix)1535 *suffix = netif->packet_dimension.suffix;1536 }1537 1538 *prefix = *prefix + IP_PREFIX;1539 *suffix = *suffix + IP_SUFFIX;1540 } else {1541 netif = ip_netifs_find(&ip_globals.netifs, device_id);1542 if (!netif) {1543 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1544 return ENOENT;1545 }1546 1547 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?1548 netif->packet_dimension.addr_len : IP_ADDR;1549 *prefix = netif->packet_dimension.prefix + IP_PREFIX;1550 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;1551 }1552 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1553 1554 return EOK;1555 }1556 1557 /** Updates the device content length according to the new MTU value.1558 *1559 * @param[in] device_id The device identifier.1560 * @param[in] mtu The new mtu value.1561 * @return EOK on success.1562 * @return ENOENT if device is not found.1563 */1564 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)1565 {1566 ip_netif_t *netif;1567 1568 fibril_rwlock_write_lock(&ip_globals.netifs_lock);1569 netif = ip_netifs_find(&ip_globals.netifs, device_id);1570 if (!netif) {1571 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1572 return ENOENT;1573 }1574 netif->packet_dimension.content = mtu;1575 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1576 1577 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);1578 1579 return EOK;1580 }1581 1582 /** Process IPC messages from the registered device driver modules1583 *1584 * @param[in] iid Message identifier.1585 * @param[in,out] icall Message parameters.1586 *1587 */1588 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)1589 {1590 packet_t *packet;1591 int rc;1592 1593 while (true) {1594 switch (IPC_GET_IMETHOD(*icall)) {1595 case NET_IL_DEVICE_STATE:1596 rc = ip_device_state_message(IPC_GET_DEVICE(*icall),1597 IPC_GET_STATE(*icall));1598 ipc_answer_0(iid, (sysarg_t) rc);1599 break;1600 1601 case NET_IL_RECEIVED:1602 rc = packet_translate_remote(ip_globals.net_phone, &packet,1603 IPC_GET_PACKET(*icall));1604 if (rc == EOK) {1605 do {1606 packet_t *next = pq_detach(packet);1607 ip_process_packet(IPC_GET_DEVICE(*icall), packet);1608 packet = next;1609 } while (packet);1610 }1611 1612 ipc_answer_0(iid, (sysarg_t) rc);1613 break;1614 1615 case NET_IL_MTU_CHANGED:1616 rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),1617 IPC_GET_MTU(*icall));1618 ipc_answer_0(iid, (sysarg_t) rc);1619 break;1620 1621 default:1622 ipc_answer_0(iid, (sysarg_t) ENOTSUP);1623 }1624 1625 iid = async_get_call(icall);1626 }1627 }1628 1629 /** Registers the transport layer protocol.1630 *1631 * The traffic of this protocol will be supplied using either the receive1632 * function or IPC message.1633 *1634 * @param[in] protocol The transport layer module protocol.1635 * @param[in] service The transport layer module service.1636 * @param[in] phone The transport layer module phone.1637 * @param[in] received_msg The receiving function.1638 * @return EOK on success.1639 * @return EINVAL if the protocol parameter and/or the service1640 * parameter is zero.1641 * @return EINVAL if the phone parameter is not a positive number1642 * and the tl_receive_msg is NULL.1643 * @return ENOMEM if there is not enough memory left.1644 */1645 static int1646 ip_register(int protocol, services_t service, int phone,1647 tl_received_msg_t received_msg)1648 {1649 ip_proto_t *proto;1650 int index;1651 1652 if (!protocol || !service || ((phone < 0) && !received_msg))1653 return EINVAL;1654 1655 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));1656 if (!proto)1657 return ENOMEM;1658 1659 proto->protocol = protocol;1660 proto->service = service;1661 proto->phone = phone;1662 proto->received_msg = received_msg;1663 1664 fibril_rwlock_write_lock(&ip_globals.protos_lock);1665 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);1666 if (index < 0) {1667 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1668 free(proto);1669 return index;1670 }1671 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1672 1673 printf("%s: Protocol registered (protocol: %d, phone: %d)\n",1674 NAME, proto->protocol, proto->phone);1675 1676 return EOK;1677 }1678 1679 1680 1648 static int 1681 1649 ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, … … 1877 1845 } 1878 1846 1847 /** Processes the received IP packet or the packet queue one by one. 1848 * 1849 * The packet is either passed to another module or released on error. 1850 * 1851 * @param[in] device_id The source device identifier. 1852 * @param[in,out] packet The received packet. 1853 * @return EOK on success and the packet is no longer needed. 1854 * @return EINVAL if the packet is too small to carry the IP 1855 * packet. 1856 * @return EINVAL if the received address lengths differs from the 1857 * registered values. 1858 * @return ENOENT if the device is not found in the cache. 1859 * @return ENOENT if the protocol for the device is not found in 1860 * the cache. 1861 * @return ENOMEM if there is not enough memory left. 1862 */ 1863 static int ip_receive_message(device_id_t device_id, packet_t *packet) 1864 { 1865 packet_t *next; 1866 1867 do { 1868 next = pq_detach(packet); 1869 ip_process_packet(device_id, packet); 1870 packet = next; 1871 } while (packet); 1872 1873 return EOK; 1874 } 1875 1879 1876 /** Processes the IP message. 1880 1877 * … … 1888 1885 * 1889 1886 * @see ip_interface.h 1890 * @see il_ remote.h1887 * @see il_interface.h 1891 1888 * @see IS_NET_IP_MESSAGE() 1892 1889 */ 1893 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1890 int 1891 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1894 1892 size_t *answer_count) 1895 1893 { 1896 1894 packet_t *packet; 1897 1895 struct sockaddr *addr; 1898 void *header;1899 size_t headerlen;1900 1896 size_t addrlen; 1901 1897 size_t prefix; 1902 1898 size_t suffix; 1903 1899 size_t content; 1900 void *header; 1901 size_t headerlen; 1904 1902 device_id_t device_id; 1905 1903 int rc; … … 1914 1912 IPC_GET_PHONE(*call), NULL); 1915 1913 1916 case NET_I P_DEVICE:1914 case NET_IL_DEVICE: 1917 1915 return ip_device_req_local(0, IPC_GET_DEVICE(*call), 1918 1916 IPC_GET_SERVICE(*call)); 1917 1918 case NET_IL_SEND: 1919 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1920 IPC_GET_PACKET(*call)); 1921 if (rc != EOK) 1922 return rc; 1923 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1924 IPC_GET_ERROR(*call)); 1925 1926 case NET_IL_DEVICE_STATE: 1927 return ip_device_state_message(IPC_GET_DEVICE(*call), 1928 IPC_GET_STATE(*call)); 1929 1930 case NET_IL_RECEIVED: 1931 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1932 IPC_GET_PACKET(*call)); 1933 if (rc != EOK) 1934 return rc; 1935 return ip_receive_message(IPC_GET_DEVICE(*call), packet); 1919 1936 1920 1937 case NET_IP_RECEIVED_ERROR: … … 1958 1975 return rc; 1959 1976 1960 case NET_I P_PACKET_SPACE:1977 case NET_IL_PACKET_SPACE: 1961 1978 rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen, 1962 1979 &prefix, &content, &suffix); … … 1971 1988 return EOK; 1972 1989 1973 case NET_IP_SEND: 1974 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1975 IPC_GET_PACKET(*call)); 1976 if (rc != EOK) 1977 return rc; 1990 case NET_IL_MTU_CHANGED: 1991 return ip_mtu_changed_message(IPC_GET_DEVICE(*call), 1992 IPC_GET_MTU(*call)); 1993 } 1994 1995 return ENOTSUP; 1996 } 1997 1998 /** Default thread for new connections. 1999 * 2000 * @param[in] iid The initial message identifier. 2001 * @param[in] icall The initial message call structure. 2002 */ 2003 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 2004 { 2005 /* 2006 * Accept the connection 2007 * - Answer the first IPC_M_CONNECT_ME_TO call. 2008 */ 2009 ipc_answer_0(iid, EOK); 2010 2011 while (true) { 2012 ipc_call_t answer; 2013 size_t count; 1978 2014 1979 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1980 IPC_GET_ERROR(*call)); 1981 } 1982 1983 return ENOTSUP; 1984 } 1985 2015 /* Clear the answer structure */ 2016 refresh_answer(&answer, &count); 2017 2018 /* Fetch the next message */ 2019 ipc_call_t call; 2020 ipc_callid_t callid = async_get_call(&call); 2021 2022 /* Process the message */ 2023 int res = il_module_message_standalone(callid, &call, &answer, 2024 &count); 2025 2026 /* 2027 * End if told to either by the message or the processing 2028 * result. 2029 */ 2030 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 2031 (res == EHANGUP)) { 2032 return; 2033 } 2034 2035 /* Answer the message */ 2036 answer_call(callid, res, &answer, count); 2037 } 2038 } 2039 2040 /** Starts the module. 2041 * 2042 * @return EOK on success. 2043 * @return Other error codes as defined for each specific module start function. 2044 */ 1986 2045 int main(int argc, char *argv[]) 1987 2046 { 2047 int rc; 2048 1988 2049 /* Start the module */ 1989 return il_module_start(SERVICE_IP); 2050 rc = il_module_start_standalone(il_client_connection); 2051 return rc; 1990 2052 } 1991 2053
Note:
See TracChangeset
for help on using the changeset viewer.