Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ uspace/srv/net/il/arp/arp.c	(revision 858fc9083f1f538a864233e8551633863fb17e0b)
@@ -73,4 +73,9 @@
 arp_globals_t	arp_globals;
 
+/** Clears the device specific data.
+ *  @param[in] device The device specific data.
+ */
+void arp_clear_device(arp_device_ref device);
+
 /** Creates new protocol specific data.
  *  Allocates and returns the needed memory block as the proto parameter.
@@ -82,9 +87,4 @@
  */
 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address);
-
-/** Clears the device specific data.
- *  @param[in] device The device specific data.
- */
-void arp_clear_device(arp_device_ref device);
 
 /** @name Message processing functions
@@ -105,16 +105,11 @@
 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address);
 
-/** Returns the hardware address for the given protocol address.
- *  Sends the ARP request packet if the hardware address is not found in the cache.
+/** Updates the device content length according to the new MTU value.
  *  @param[in] device_id The device identifier.
- *  @param[in] protocol The protocol service.
- *  @param[in] target The target protocol address.
- *  @returns The hardware address of the target.
- *  @returns NULL if the target parameter is NULL.
- *  @returns NULL if the device is not found.
- *  @returns NULL if the device packet is too small to send a&nbsp;request.
- *  @returns NULL if the hardware address is not found in the cache.
- */
-measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
+ *  @param[in] mtu The new mtu value.
+ *  @returns ENOENT if device is not found.
+ *  @returns EOK on success.
+ */
+int arp_mtu_changed_message(device_id_t device_id, size_t mtu);
 
 /** Processes the received ARP packet.
@@ -133,11 +128,16 @@
 int arp_receive_message(device_id_t device_id, packet_t packet);
 
-/** Updates the device content length according to the new MTU value.
+/** Returns the hardware address for the given protocol address.
+ *  Sends the ARP request packet if the hardware address is not found in the cache.
  *  @param[in] device_id The device identifier.
- *  @param[in] mtu The new mtu value.
- *  @returns ENOENT if device is not found.
- *  @returns EOK on success.
- */
-int arp_mtu_changed_message(device_id_t device_id, size_t mtu);
+ *  @param[in] protocol The protocol service.
+ *  @param[in] target The target protocol address.
+ *  @returns The hardware address of the target.
+ *  @returns NULL if the target parameter is NULL.
+ *  @returns NULL if the device is not found.
+ *  @returns NULL if the device packet is too small to send a&nbsp;request.
+ *  @returns NULL if the hardware address is not found in the cache.
+ */
+measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
 
 /*@}*/
@@ -148,43 +148,4 @@
 
 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t)
-
-task_id_t arp_task_get_id(void){
-	return task_get_id();
-}
-
-int arp_clear_device_req(int arp_phone, device_id_t device_id){
-	arp_device_ref device;
-
-	fibril_rwlock_write_lock(&arp_globals.lock);
-	device = arp_cache_find(&arp_globals.cache, device_id);
-	if(! device){
-		fibril_rwlock_write_unlock(&arp_globals.lock);
-		return ENOENT;
-	}
-	arp_clear_device(device);
-	printf("Device %d cleared\n", device_id);
-	fibril_rwlock_write_unlock(&arp_globals.lock);
-	return EOK;
-}
-
-int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
-	arp_device_ref device;
-	arp_proto_ref proto;
-
-	fibril_rwlock_write_lock(&arp_globals.lock);
-	device = arp_cache_find(&arp_globals.cache, device_id);
-	if(! device){
-		fibril_rwlock_write_unlock(&arp_globals.lock);
-		return ENOENT;
-	}
-	proto = arp_protos_find(&device->protos, protocol);
-	if(! proto){
-		fibril_rwlock_write_unlock(&arp_globals.lock);
-		return ENOENT;
-	}
-	arp_addr_exclude(&proto->addresses, address->value, address->length);
-	fibril_rwlock_write_unlock(&arp_globals.lock);
-	return EOK;
-}
 
 int arp_clean_cache_req(int arp_phone){
@@ -211,62 +172,61 @@
 }
 
-int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
-	ERROR_DECLARE;
-
-	measured_string_ref tmp;
-
-	// copy the given address for exclusive use
-	tmp = measured_string_copy(address);
-	if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
-		free(tmp->value);
-		free(tmp);
-	}
-	return ERROR_CODE;
-}
-
-int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
-	measured_string_ref tmp;
-
-	fibril_rwlock_read_lock(&arp_globals.lock);
-	tmp = arp_translate_message(device_id, protocol, address);
-	if(tmp){
-		*translation = measured_string_copy(tmp);
-		fibril_rwlock_read_unlock(&arp_globals.lock);
-		if(*translation){
-			*data = (** translation).value;
-			return EOK;
-		}else{
-			return ENOMEM;
-		}
-	}else{
-		fibril_rwlock_read_unlock(&arp_globals.lock);
+int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
+	arp_device_ref device;
+	arp_proto_ref proto;
+
+	fibril_rwlock_write_lock(&arp_globals.lock);
+	device = arp_cache_find(&arp_globals.cache, device_id);
+	if(! device){
+		fibril_rwlock_write_unlock(&arp_globals.lock);
 		return ENOENT;
 	}
-}
-
-int arp_initialize(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
-	fibril_rwlock_initialize(&arp_globals.lock);
+	proto = arp_protos_find(&device->protos, protocol);
+	if(! proto){
+		fibril_rwlock_write_unlock(&arp_globals.lock);
+		return ENOENT;
+	}
+	arp_addr_exclude(&proto->addresses, address->value, address->length);
+	fibril_rwlock_write_unlock(&arp_globals.lock);
+	return EOK;
+}
+
+void arp_clear_device(arp_device_ref device){
+	int count;
+	arp_proto_ref proto;
+
+	for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){
+		proto = arp_protos_get_index(&device->protos, count);
+		if(proto){
+			if(proto->addr){
+				free(proto->addr);
+			}
+			if(proto->addr_data){
+				free(proto->addr_data);
+			}
+			arp_addr_destroy(&proto->addresses);
+		}
+	}
+	arp_protos_clear(&device->protos);
+}
+
+int arp_clear_device_req(int arp_phone, device_id_t device_id){
+	arp_device_ref device;
+
 	fibril_rwlock_write_lock(&arp_globals.lock);
-	arp_globals.client_connection = client_connection;
-	ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
+	device = arp_cache_find(&arp_globals.cache, device_id);
+	if(! device){
+		fibril_rwlock_write_unlock(&arp_globals.lock);
+		return ENOENT;
+	}
+	arp_clear_device(device);
+	printf("Device %d cleared\n", device_id);
 	fibril_rwlock_write_unlock(&arp_globals.lock);
 	return EOK;
 }
 
-int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
-	ERROR_DECLARE;
-
-	*proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
-	if(!(*proto)){
-		return ENOMEM;
-	}
-	(** proto).service = service;
-	(** proto).addr = address;
-	(** proto).addr_data = address->value;
-	if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
-		free(*proto);
-		return ERROR_CODE;
+int arp_connect_module(services_t service){
+	if(service != SERVICE_ARP){
+		return EINVAL;
 	}
 	return EOK;
@@ -383,168 +343,25 @@
 }
 
-measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
-	arp_device_ref device;
-	arp_proto_ref proto;
-	measured_string_ref addr;
-	size_t length;
-	packet_t packet;
-	arp_header_ref header;
-
-	if(! target){
-		return NULL;
-	}
-	device = arp_cache_find(&arp_globals.cache, device_id);
-	if(! device){
-		return NULL;
-	}
-	proto = arp_protos_find(&device->protos, protocol);
-	if((! proto) || (proto->addr->length != target->length)){
-		return NULL;
-	}
-	addr = arp_addr_find(&proto->addresses, target->value, target->length);
-	if(addr){
-		return addr;
-	}
-	// ARP packet content size = header + (address + translation) * 2
-	length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
-	if(length > device->packet_dimension.content){
-		return NULL;
-	}
-	packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
-	if(! packet){
-		return NULL;
-	}
-	header = (arp_header_ref) packet_suffix(packet, length);
-	if(! header){
-		pq_release(arp_globals.net_phone, packet_get_id(packet));
-		return NULL;
-	}
-	header->hardware = htons(device->hardware);
-	header->hardware_length = (uint8_t) device->addr->length;
-	header->protocol = htons(protocol_map(device->service, protocol));
-	header->protocol_length = (uint8_t) proto->addr->length;
-	header->operation = htons(ARPOP_REQUEST);
-	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, proto->addr->value, proto->addr->length);
-	length += proto->addr->length;
-	bzero(((uint8_t *) header) + length, device->addr->length);
-	length += device->addr->length;
-	memcpy(((uint8_t *) header) + length, target->value, target->length);
-	if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){
-		pq_release(arp_globals.net_phone, packet_get_id(packet));
-		return NULL;
-	}
-	nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
-	return NULL;
-}
-
-int arp_receive_message(device_id_t device_id, packet_t packet){
+int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
 	ERROR_DECLARE;
 
-	size_t length;
-	arp_header_ref header;
-	arp_device_ref device;
-	arp_proto_ref proto;
-	measured_string_ref hw_source;
-	uint8_t * src_hw;
-	uint8_t * src_proto;
-	uint8_t * des_hw;
-	uint8_t * des_proto;
-
-	length = packet_get_data_length(packet);
-	if(length <= sizeof(arp_header_t)){
-		return EINVAL;
-	}
-	device = arp_cache_find(&arp_globals.cache, device_id);
-	if(! device){
-		return ENOENT;
-	}
-	header = (arp_header_ref) packet_get_data(packet);
-	if((ntohs(header->hardware) != device->hardware)
-		|| (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
-		return EINVAL;
-	}
-	proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
-	if(! proto){
-		return ENOENT;
-	}
-	src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
-	src_proto = src_hw + header->hardware_length;
-	des_hw = src_proto + header->protocol_length;
-	des_proto = des_hw + header->hardware_length;
-	hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
-	// exists?
-	if(hw_source){
-		if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
-			return EINVAL;
-		}
-		memcpy(hw_source->value, src_hw, hw_source->length);
-	}
-	// is my protocol address?
-	if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
-		return EINVAL;
-	}
-	if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
-		// not already upadted?
-		if(! hw_source){
-			hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
-			if(! hw_source){
-				return ENOMEM;
-			}
-			ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
-		}
-		if(ntohs(header->operation) == ARPOP_REQUEST){
-			header->operation = htons(ARPOP_REPLY);
-			memcpy(des_proto, src_proto, header->protocol_length);
-			memcpy(src_proto, proto->addr->value, header->protocol_length);
-			memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
-			memcpy(des_hw, hw_source->value, header->hardware_length);
-			ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
-			nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
-			return 1;
-		}
-	}
-	return EOK;
-}
-
-void arp_clear_device(arp_device_ref device){
-	int count;
-	arp_proto_ref proto;
-
-	for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){
-		proto = arp_protos_get_index(&device->protos, count);
-		if(proto){
-			if(proto->addr){
-				free(proto->addr);
-			}
-			if(proto->addr_data){
-				free(proto->addr_data);
-			}
-			arp_addr_destroy(&proto->addresses);
-		}
-	}
-	arp_protos_clear(&device->protos);
-}
-
-int arp_connect_module(services_t service){
-	if(service != SERVICE_ARP){
-		return EINVAL;
-	}
-	return EOK;
-}
-
-int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
-	arp_device_ref device;
-
+	measured_string_ref tmp;
+
+	// copy the given address for exclusive use
+	tmp = measured_string_copy(address);
+	if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
+		free(tmp->value);
+		free(tmp);
+	}
+	return ERROR_CODE;
+}
+
+int arp_initialize(async_client_conn_t client_connection){
+	ERROR_DECLARE;
+
+	fibril_rwlock_initialize(&arp_globals.lock);
 	fibril_rwlock_write_lock(&arp_globals.lock);
-	device = arp_cache_find(&arp_globals.cache, device_id);
-	if(! device){
-		fibril_rwlock_write_unlock(&arp_globals.lock);
-		return ENOENT;
-	}
-	device->packet_dimension.content = mtu;
-	printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
+	arp_globals.client_connection = client_connection;
+	ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
 	fibril_rwlock_write_unlock(&arp_globals.lock);
 	return EOK;
@@ -618,4 +435,187 @@
 }
 
+int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
+	arp_device_ref device;
+
+	fibril_rwlock_write_lock(&arp_globals.lock);
+	device = arp_cache_find(&arp_globals.cache, device_id);
+	if(! device){
+		fibril_rwlock_write_unlock(&arp_globals.lock);
+		return ENOENT;
+	}
+	device->packet_dimension.content = mtu;
+	printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
+	fibril_rwlock_write_unlock(&arp_globals.lock);
+	return EOK;
+}
+
+int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
+	ERROR_DECLARE;
+
+	*proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
+	if(!(*proto)){
+		return ENOMEM;
+	}
+	(** proto).service = service;
+	(** proto).addr = address;
+	(** proto).addr_data = address->value;
+	if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
+		free(*proto);
+		return ERROR_CODE;
+	}
+	return EOK;
+}
+
+int arp_receive_message(device_id_t device_id, packet_t packet){
+	ERROR_DECLARE;
+
+	size_t length;
+	arp_header_ref header;
+	arp_device_ref device;
+	arp_proto_ref proto;
+	measured_string_ref hw_source;
+	uint8_t * src_hw;
+	uint8_t * src_proto;
+	uint8_t * des_hw;
+	uint8_t * des_proto;
+
+	length = packet_get_data_length(packet);
+	if(length <= sizeof(arp_header_t)){
+		return EINVAL;
+	}
+	device = arp_cache_find(&arp_globals.cache, device_id);
+	if(! device){
+		return ENOENT;
+	}
+	header = (arp_header_ref) packet_get_data(packet);
+	if((ntohs(header->hardware) != device->hardware)
+		|| (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
+		return EINVAL;
+	}
+	proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
+	if(! proto){
+		return ENOENT;
+	}
+	src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
+	src_proto = src_hw + header->hardware_length;
+	des_hw = src_proto + header->protocol_length;
+	des_proto = des_hw + header->hardware_length;
+	hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
+	// exists?
+	if(hw_source){
+		if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
+			return EINVAL;
+		}
+		memcpy(hw_source->value, src_hw, hw_source->length);
+	}
+	// is my protocol address?
+	if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
+		return EINVAL;
+	}
+	if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
+		// not already upadted?
+		if(! hw_source){
+			hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
+			if(! hw_source){
+				return ENOMEM;
+			}
+			ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
+		}
+		if(ntohs(header->operation) == ARPOP_REQUEST){
+			header->operation = htons(ARPOP_REPLY);
+			memcpy(des_proto, src_proto, header->protocol_length);
+			memcpy(src_proto, proto->addr->value, header->protocol_length);
+			memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
+			memcpy(des_hw, hw_source->value, header->hardware_length);
+			ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
+			nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
+			return 1;
+		}
+	}
+	return EOK;
+}
+
+task_id_t arp_task_get_id(void){
+	return task_get_id();
+}
+
+measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
+	arp_device_ref device;
+	arp_proto_ref proto;
+	measured_string_ref addr;
+	size_t length;
+	packet_t packet;
+	arp_header_ref header;
+
+	if(! target){
+		return NULL;
+	}
+	device = arp_cache_find(&arp_globals.cache, device_id);
+	if(! device){
+		return NULL;
+	}
+	proto = arp_protos_find(&device->protos, protocol);
+	if((! proto) || (proto->addr->length != target->length)){
+		return NULL;
+	}
+	addr = arp_addr_find(&proto->addresses, target->value, target->length);
+	if(addr){
+		return addr;
+	}
+	// ARP packet content size = header + (address + translation) * 2
+	length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
+	if(length > device->packet_dimension.content){
+		return NULL;
+	}
+	packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
+	if(! packet){
+		return NULL;
+	}
+	header = (arp_header_ref) packet_suffix(packet, length);
+	if(! header){
+		pq_release(arp_globals.net_phone, packet_get_id(packet));
+		return NULL;
+	}
+	header->hardware = htons(device->hardware);
+	header->hardware_length = (uint8_t) device->addr->length;
+	header->protocol = htons(protocol_map(device->service, protocol));
+	header->protocol_length = (uint8_t) proto->addr->length;
+	header->operation = htons(ARPOP_REQUEST);
+	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, proto->addr->value, proto->addr->length);
+	length += proto->addr->length;
+	bzero(((uint8_t *) header) + length, device->addr->length);
+	length += device->addr->length;
+	memcpy(((uint8_t *) header) + length, target->value, target->length);
+	if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){
+		pq_release(arp_globals.net_phone, packet_get_id(packet));
+		return NULL;
+	}
+	nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
+	return NULL;
+}
+
+int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
+	measured_string_ref tmp;
+
+	fibril_rwlock_read_lock(&arp_globals.lock);
+	tmp = arp_translate_message(device_id, protocol, address);
+	if(tmp){
+		*translation = measured_string_copy(tmp);
+		fibril_rwlock_read_unlock(&arp_globals.lock);
+		if(*translation){
+			*data = (** translation).value;
+			return EOK;
+		}else{
+			return ENOMEM;
+		}
+	}else{
+		fibril_rwlock_read_unlock(&arp_globals.lock);
+		return ENOENT;
+	}
+}
+
 /** @}
  */
