Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision 6b8200979d8daac47bccc812f910bbf881df8e94)
+++ uspace/srv/net/il/arp/arp.c	(revision 609243f4f1d6e7562d9c9b79e38925b36e844ac0)
@@ -174,12 +174,6 @@
 		    count);
 		
-		if (device) {
+		if (device)
 			arp_clear_device(device);
-			if (device->addr_data)
-				free(device->addr_data);
-			
-			if (device->broadcast_data)
-				free(device->broadcast_data);
-		}
 	}
 	
@@ -190,6 +184,6 @@
 }
 
-static int arp_clear_address_req(device_id_t device_id, services_t protocol,
-    measured_string_t *address)
+static int arp_clear_address_req(nic_device_id_t device_id,
+    services_t protocol, measured_string_t *address)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -218,5 +212,5 @@
 }
 
-static int arp_clear_device_req(device_id_t device_id)
+static int arp_clear_device_req(nic_device_id_t device_id)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -289,5 +283,5 @@
  *
  */
-static int arp_receive_message(device_id_t device_id, packet_t *packet)
+static int arp_receive_message(nic_device_id_t device_id, packet_t *packet)
 {
 	int rc;
@@ -365,5 +359,5 @@
 			memcpy(src_proto, proto->addr->value,
 			    header->protocol_length);
-			memcpy(src_hw, device->addr->value,
+			memcpy(src_hw, device->addr,
 			    device->packet_dimension.addr_len);
 			memcpy(des_hw, trans->hw_addr->value,
@@ -393,5 +387,5 @@
  *
  */
-static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
+static int arp_mtu_changed_message(nic_device_id_t device_id, size_t mtu)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -409,4 +403,36 @@
 	printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
 	
+	return EOK;
+}
+
+static int arp_addr_changed_message(nic_device_id_t device_id)
+{
+	uint8_t addr_buffer[NIC_MAX_ADDRESS_LENGTH];
+	size_t length;
+	ipc_callid_t data_callid;
+	if (!async_data_write_receive(&data_callid, &length)) {
+		async_answer_0(data_callid, EINVAL);
+		return EINVAL;
+	}
+	if (length > NIC_MAX_ADDRESS_LENGTH) {
+		async_answer_0(data_callid, ELIMIT);
+		return ELIMIT;
+	}
+	if (async_data_write_finalize(data_callid, addr_buffer, length) != EOK) {
+		return EINVAL;
+	}
+
+	fibril_mutex_lock(&arp_globals.lock);
+
+	arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
+	if (!device) {
+		fibril_mutex_unlock(&arp_globals.lock);
+		return ENOENT;
+	}
+
+	memcpy(device->addr, addr_buffer, length);
+	device->addr_len = length;
+
+	fibril_mutex_unlock(&arp_globals.lock);
 	return EOK;
 }
@@ -456,4 +482,7 @@
 			async_answer_0(iid, (sysarg_t) rc);
 			break;
+		case NET_IL_ADDR_CHANGED:
+			rc = arp_addr_changed_message(IPC_GET_DEVICE(*icall));
+			async_answer_0(iid, (sysarg_t) rc);
 		
 		default:
@@ -483,5 +512,5 @@
  *
  */
-static int arp_device_message(device_id_t device_id, services_t service,
+static int arp_device_message(nic_device_id_t device_id, services_t service,
     services_t protocol, measured_string_t *address)
 {
@@ -586,24 +615,26 @@
 		
 		/* Get hardware address */
-		rc = nil_get_addr_req(device->sess, device_id, &device->addr,
-		    &device->addr_data);
-		if (rc != EOK) {
+		int len = nil_get_addr_req(device->sess, device_id, device->addr,
+		    NIC_MAX_ADDRESS_LENGTH);
+		if (len < 0) {
 			fibril_mutex_unlock(&arp_globals.lock);
 			arp_protos_destroy(&device->protos, free);
 			free(device);
-			return rc;
-		}
+			return len;
+		}
+		
+		device->addr_len = len;
 		
 		/* Get broadcast address */
-		rc = nil_get_broadcast_addr_req(device->sess, device_id,
-		    &device->broadcast_addr, &device->broadcast_data);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&arp_globals.lock);
-			free(device->addr);
-			free(device->addr_data);
+		len = nil_get_broadcast_addr_req(device->sess, device_id,
+		    device->broadcast_addr, NIC_MAX_ADDRESS_LENGTH);
+		if (len < 0) {
+			fibril_mutex_unlock(&arp_globals.lock);
 			arp_protos_destroy(&device->protos, free);
 			free(device);
-			return rc;
-		}
+			return len;
+		}
+		
+		device->broadcast_addr_len = len;
 		
 		rc = arp_cache_add(&arp_globals.cache, device->device_id,
@@ -611,8 +642,4 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&arp_globals.lock);
-			free(device->addr);
-			free(device->addr_data);
-			free(device->broadcast_addr);
-			free(device->broadcast_data);
 			arp_protos_destroy(&device->protos, free);
 			free(device);
@@ -640,9 +667,9 @@
 }
 
-static int arp_send_request(device_id_t device_id, services_t protocol,
+static int arp_send_request(nic_device_id_t device_id, services_t protocol,
     measured_string_t *target, arp_device_t *device, arp_proto_t *proto)
 {
 	/* ARP packet content size = header + (address + translation) * 2 */
-	size_t length = 8 + 2 * (proto->addr->length + device->addr->length);
+	size_t length = 8 + 2 * (proto->addr->length + device->addr_len);
 	if (length > device->packet_dimension.content)
 		return ELIMIT;
@@ -661,5 +688,5 @@
 	
 	header->hardware = htons(device->hardware);
-	header->hardware_length = (uint8_t) device->addr->length;
+	header->hardware_length = (uint8_t) device->addr_len;
 	header->protocol = htons(protocol_map(device->service, protocol));
 	header->protocol_length = (uint8_t) proto->addr->length;
@@ -667,17 +694,16 @@
 	
 	length = sizeof(arp_header_t);
-	
-	memcpy(((uint8_t *) header) + length, device->addr->value,
-	    device->addr->length);
-	length += device->addr->length;
+	memcpy(((uint8_t *) header) + length, device->addr,
+	    device->addr_len);
+	length += device->addr_len;
 	memcpy(((uint8_t *) header) + length, proto->addr->value,
 	    proto->addr->length);
 	length += proto->addr->length;
-	bzero(((uint8_t *) header) + length, device->addr->length);
-	length += device->addr->length;
+	bzero(((uint8_t *) header) + length, device->addr_len);
+	length += device->addr_len;
 	memcpy(((uint8_t *) header) + length, target->value, target->length);
-	
-	int rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
-	    (uint8_t *) device->broadcast_addr->value, device->addr->length);
+
+	int rc = packet_set_addr(packet, device->addr, device->broadcast_addr,
+	    device->addr_len);
 	if (rc != EOK) {
 		pq_release_remote(arp_globals.net_sess, packet_get_id(packet));
@@ -704,5 +730,5 @@
  *
  */
-static int arp_translate_message(device_id_t device_id, services_t protocol,
+static int arp_translate_message(nic_device_id_t device_id, services_t protocol,
     measured_string_t *target, measured_string_t **translation)
 {
