Changeset 597c948 in mainline
- Timestamp:
- 2011-01-11T07:24:04Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f902d36
- Parents:
- bddec0c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
rbddec0c r597c948 542 542 } 543 543 544 545 /** Returns the hardware address for the given protocol address. 546 * 547 * Sends the ARP request packet if the hardware address is not found in the 548 * cache. 549 * 550 * @param[in] device_id The device identifier. 551 * @param[in] protocol The protocol service. 552 * @param[in] target The target protocol address. 553 * @param[out] translation Where the hardware address of the target is stored. 554 * @return EOK on success. 555 * @return EAGAIN if the caller should try again. 556 * @return Other error codes in case of error. 557 */ 558 static int 559 arp_translate_message(device_id_t device_id, services_t protocol, 560 measured_string_t *target, measured_string_t **translation) 561 { 562 arp_device_t *device; 563 arp_proto_t *proto; 564 arp_trans_t *trans; 565 size_t length; 566 packet_t *packet; 567 arp_header_t *header; 568 bool retry = false; 569 int rc; 570 571 restart: 572 if (!target || !translation) 573 return EBADMEM; 574 575 device = arp_cache_find(&arp_globals.cache, device_id); 576 if (!device) 577 return ENOENT; 578 579 proto = arp_protos_find(&device->protos, protocol); 580 if (!proto || (proto->addr->length != target->length)) 581 return ENOENT; 582 583 trans = arp_addr_find(&proto->addresses, target->value, target->length); 584 if (trans) { 585 if (trans->hw_addr) { 586 *translation = trans->hw_addr; 587 return EOK; 588 } 589 if (retry) 590 return EAGAIN; 591 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 592 ARP_TRANS_WAIT); 593 if (rc == ETIMEOUT) 594 return ENOENT; 595 retry = true; 596 goto restart; 597 } 598 if (retry) 599 return EAGAIN; 600 544 static int arp_send_request(device_id_t device_id, services_t protocol, 545 measured_string_t *target, arp_device_t *device, arp_proto_t *proto) 546 { 601 547 /* ARP packet content size = header + (address + translation) * 2 */ 602 length = 8 + 2 * (proto->addr->length + device->addr->length);548 size_t length = 8 + 2 * (proto->addr->length + device->addr->length); 603 549 if (length > device->packet_dimension.content) 604 550 return ELIMIT; 605 606 packet = packet_get_4_remote(arp_globals.net_phone,551 552 packet_t *packet = packet_get_4_remote(arp_globals.net_phone, 607 553 device->packet_dimension.addr_len, device->packet_dimension.prefix, 608 554 length, device->packet_dimension.suffix); 609 555 if (!packet) 610 556 return ENOMEM; 611 612 header = (arp_header_t *) packet_suffix(packet, length);557 558 arp_header_t *header = (arp_header_t *) packet_suffix(packet, length); 613 559 if (!header) { 614 560 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 615 561 return ENOMEM; 616 562 } 617 563 618 564 header->hardware = htons(device->hardware); 619 565 header->hardware_length = (uint8_t) device->addr->length; … … 631 577 length += device->addr->length; 632 578 memcpy(((uint8_t *) header) + length, target->value, target->length); 633 634 rc = packet_set_addr(packet, (uint8_t *) device->addr->value,579 580 int rc = packet_set_addr(packet, (uint8_t *) device->addr->value, 635 581 (uint8_t *) device->broadcast_addr->value, device->addr->length); 636 582 if (rc != EOK) { … … 638 584 return rc; 639 585 } 640 586 641 587 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 642 588 return EOK; 589 } 590 591 /** Return the hardware address for the given protocol address. 592 * 593 * Send the ARP request packet if the hardware address is not found in the 594 * cache. 595 * 596 * @param[in] device_id Device identifier. 597 * @param[in] protocol Protocol service. 598 * @param[in] target Target protocol address. 599 * @param[out] translation Where the hardware address of the target is stored. 600 * 601 * @return EOK on success. 602 * @return EAGAIN if the caller should try again. 603 * @return Other error codes in case of error. 604 * 605 */ 606 static int 607 arp_translate_message(device_id_t device_id, services_t protocol, 608 measured_string_t *target, measured_string_t **translation) 609 { 610 arp_device_t *device; 611 arp_proto_t *proto; 612 arp_trans_t *trans; 613 bool retry = false; 614 int rc; 615 616 restart: 617 if ((!target) || (!translation)) 618 return EBADMEM; 619 620 device = arp_cache_find(&arp_globals.cache, device_id); 621 if (!device) 622 return ENOENT; 623 624 proto = arp_protos_find(&device->protos, protocol); 625 if ((!proto) || (proto->addr->length != target->length)) 626 return ENOENT; 627 628 trans = arp_addr_find(&proto->addresses, target->value, target->length); 629 if (trans) { 630 if (trans->hw_addr) { 631 *translation = trans->hw_addr; 632 return EOK; 633 } 634 635 if (retry) 636 return EAGAIN; 637 638 rc = arp_send_request(device_id, protocol, target, device, proto); 639 if (rc != EOK) 640 return rc; 641 642 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 643 ARP_TRANS_WAIT); 644 if (rc == ETIMEOUT) 645 return ENOENT; 646 647 retry = true; 648 goto restart; 649 } 650 651 if (retry) 652 return EAGAIN; 653 643 654 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); 644 655 if (!trans) … … 653 664 } 654 665 666 rc = arp_send_request(device_id, protocol, target, device, proto); 667 if (rc != EOK) 668 return rc; 669 655 670 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 656 671 ARP_TRANS_WAIT); 657 672 if (rc == ETIMEOUT) 658 673 return ENOENT; 674 659 675 retry = true; 660 676 goto restart;
Note:
See TracChangeset
for help on using the changeset viewer.