status_t arp_control(net_datalink_protocol *_protocol, int32 op, void *argument, size_t length) { arp_protocol *protocol = (arp_protocol *)_protocol; if (op == SIOCSIFADDR && (protocol->interface->flags & IFF_UP) != 0) { // The interface may get a new address, so we need to update our // local entries. in_addr_t oldAddress = 0; if (protocol->interface->address != NULL) { oldAddress = ((sockaddr_in *)protocol->interface->address)->sin_addr.s_addr; } status_t status = protocol->next->module->control(protocol->next, SIOCSIFADDR, argument, length); if (status < B_OK) return status; MutexLocker locker(sCacheLock); arp_update_local(protocol); if (oldAddress == ((sockaddr_in *) protocol->interface->address)->sin_addr.s_addr) return B_OK; // remove previous address from cache arp_entry *entry = arp_entry::Lookup(oldAddress); if (entry != NULL) { hash_remove(sCache, entry); entry->flags |= ARP_FLAG_REMOVED; locker.Unlock(); delete entry; } return B_OK; } return protocol->next->module->control(protocol->next, op, argument, length); }
status_t arp_up(net_datalink_protocol* _protocol) { arp_protocol* protocol = (arp_protocol*)_protocol; status_t status = protocol->next->module->interface_up(protocol->next); if (status != B_OK) return status; // cache this device's address for later use status = arp_update_local(protocol); if (status != B_OK) { protocol->next->module->interface_down(protocol->next); return status; } return B_OK; }