Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision fe5a9fc4b7984d760b15c9c1dd964a5b0f138bed)
+++ uspace/srv/net/il/arp/arp.c	(revision 797b704b28bced20e17a9eb959845c20363ce662)
@@ -35,9 +35,4 @@
  * @see arp.h
  */
-
-#include "arp.h"
-#include "arp_header.h"
-#include "arp_oc.h"
-#include "arp_module.h"
 
 #include <async.h>
@@ -64,7 +59,7 @@
 #include <packet_client.h>
 #include <packet_remote.h>
-#include <il_interface.h>
-#include <il_local.h>
-
+#include <il_remote.h>
+#include <il_skel.h>
+#include "arp.h"
 
 /** ARP module name. */
@@ -73,4 +68,42 @@
 /** Number of microseconds to wait for an ARP reply. */
 #define ARP_TRANS_WAIT  1000000
+
+/** @name ARP operation codes definitions */
+/*@{*/
+
+/** REQUEST operation code. */
+#define ARPOP_REQUEST  1
+
+/** REPLY operation code. */
+#define ARPOP_REPLY  2
+
+/*@}*/
+
+/** Type definition of an ARP protocol header.
+ * @see arp_header
+ */
+typedef struct arp_header arp_header_t;
+
+/** ARP protocol header. */
+struct arp_header {
+	/**
+	 * Hardware type identifier.
+	 * @see hardware.h
+	 */
+	uint16_t hardware;
+	
+	/** Protocol identifier. */
+	uint16_t protocol;
+	/** Hardware address length in bytes. */
+	uint8_t hardware_length;
+	/** Protocol address length in bytes. */
+	uint8_t protocol_length;
+	
+	/**
+	 * ARP packet type.
+	 * @see arp_oc.h
+	 */
+	uint16_t operation;
+} __attribute__ ((packed));
 
 /** ARP global data. */
@@ -231,4 +264,202 @@
 	
 	return EOK;
+}
+
+/** Process the received ARP packet.
+ *
+ * Update the source hardware address if the source entry exists or the packet
+ * is targeted to my protocol address.
+ *
+ * Respond to the ARP request if the packet is the ARP request and is
+ * targeted to my address.
+ *
+ * @param[in]     device_id Source device identifier.
+ * @param[in,out] packet    Received packet.
+ *
+ * @return EOK on success and the packet is no longer needed.
+ * @return One on success and the packet has been reused.
+ * @return EINVAL if the packet is too small to carry an ARP
+ *         packet.
+ * @return EINVAL if the received address lengths differs from
+ *         the registered values.
+ * @return ENOENT if the device is not found in the cache.
+ * @return ENOENT if the protocol for the device is not found in
+ *         the cache.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int arp_receive_message(device_id_t device_id, packet_t *packet)
+{
+	int rc;
+	
+	size_t length = packet_get_data_length(packet);
+	if (length <= sizeof(arp_header_t))
+		return EINVAL;
+	
+	arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
+	if (!device)
+		return ENOENT;
+	
+	arp_header_t *header = (arp_header_t *) 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;
+	}
+	
+	arp_proto_t *proto = arp_protos_find(&device->protos,
+	    protocol_unmap(device->service, ntohs(header->protocol)));
+	if (!proto)
+		return ENOENT;
+	
+	uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
+	uint8_t *src_proto = src_hw + header->hardware_length;
+	uint8_t *des_hw = src_proto + header->protocol_length;
+	uint8_t *des_proto = des_hw + header->hardware_length;
+	
+	arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
+	    header->protocol_length);
+	
+	if ((trans) && (trans->hw_addr)) {
+		/* Translation exists */
+		if (trans->hw_addr->length != header->hardware_length)
+			return EINVAL;
+		
+		memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
+	}
+	
+	/* Is my protocol address? */
+	if (proto->addr->length != header->protocol_length)
+		return EINVAL;
+	
+	if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
+		if (!trans) {
+			/* Update the translation */
+			trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
+			if (!trans)
+				return ENOMEM;
+			
+			trans->hw_addr = NULL;
+			fibril_condvar_initialize(&trans->cv);
+			rc = arp_addr_add(&proto->addresses, src_proto,
+			    header->protocol_length, trans);
+			if (rc != EOK) {
+				/* The generic char map has already freed trans! */
+				return rc;
+			}
+		}
+		
+		if (!trans->hw_addr) {
+			trans->hw_addr = measured_string_create_bulk(src_hw,
+			    header->hardware_length);
+			if (!trans->hw_addr)
+				return ENOMEM;
+			
+			/* Notify the fibrils that wait for the translation. */
+			fibril_condvar_broadcast(&trans->cv);
+		}
+		
+		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, trans->hw_addr->value,
+			    header->hardware_length);
+			
+			rc = packet_set_addr(packet, src_hw, des_hw,
+			    header->hardware_length);
+			if (rc != EOK)
+				return rc;
+			
+			nil_send_msg(device->phone, device_id, packet,
+			    SERVICE_ARP);
+			return 1;
+		}
+	}
+	
+	return EOK;
+}
+
+/** Update the device content length according to the new MTU value.
+ *
+ * @param[in] device_id Device identifier.
+ * @param[in] mtu       New MTU value.
+ *
+ * @return ENOENT if device is not found.
+ * @return EOK on success.
+ *
+ */
+static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
+{
+	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;
+	}
+	
+	device->packet_dimension.content = mtu;
+	
+	fibril_mutex_unlock(&arp_globals.lock);
+	
+	printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
+	
+	return EOK;
+}
+
+/** Process IPC messages from the registered device driver modules
+ *
+ * @param[in]     iid   Message identifier.
+ * @param[in,out] icall Message parameters.
+ *
+ */
+static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
+{
+	packet_t *packet;
+	int rc;
+	
+	while (true) {
+		switch (IPC_GET_IMETHOD(*icall)) {
+		case NET_IL_DEVICE_STATE:
+			/* Do nothing - keep the cache */
+			ipc_answer_0(iid, (sysarg_t) EOK);
+			break;
+		
+		case NET_IL_RECEIVED:
+			rc = packet_translate_remote(arp_globals.net_phone, &packet,
+			    IPC_GET_PACKET(*icall));
+			if (rc == EOK) {
+				fibril_mutex_lock(&arp_globals.lock);
+				do {
+					packet_t *next = pq_detach(packet);
+					rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
+					if (rc != 1) {
+						pq_release_remote(arp_globals.net_phone,
+						    packet_get_id(packet));
+					}
+					
+					packet = next;
+				} while (packet);
+				fibril_mutex_unlock(&arp_globals.lock);
+			}
+			ipc_answer_0(iid, (sysarg_t) rc);
+			break;
+		
+		case NET_IL_MTU_CHANGED:
+			rc = arp_mtu_changed_message(IPC_GET_DEVICE(*icall),
+			    IPC_GET_MTU(*icall));
+			ipc_answer_0(iid, (sysarg_t) rc);
+			break;
+		
+		default:
+			ipc_answer_0(iid, (sysarg_t) ENOTSUP);
+		}
+		
+		iid = async_get_call(icall);
+	}
 }
 
@@ -335,5 +566,5 @@
 		device->phone = nil_bind_service(device->service,
 		    (sysarg_t) device->device_id, SERVICE_ARP,
-		    arp_globals.client_connection);
+		    arp_receiver);
 		if (device->phone < 0) {
 			fibril_mutex_unlock(&arp_globals.lock);
@@ -396,169 +627,14 @@
 }
 
-/** Initialize the ARP module.
- *
- *  @param[in] client_connection The client connection processing function.
- *                               The module skeleton propagates its own one.
- *
- *  @return EOK on success.
- *  @return ENOMEM if there is not enough memory left.
- *
- */
-int arp_initialize(async_client_conn_t client_connection)
+int il_initialize(int net_phone)
 {
 	fibril_mutex_initialize(&arp_globals.lock);
 	
 	fibril_mutex_lock(&arp_globals.lock);
-	arp_globals.client_connection = client_connection;
+	arp_globals.net_phone = net_phone;
 	int rc = arp_cache_initialize(&arp_globals.cache);
 	fibril_mutex_unlock(&arp_globals.lock);
 	
 	return rc;
-}
-
-/** Update the device content length according to the new MTU value.
- *
- * @param[in] device_id Device identifier.
- * @param[in] mtu       New MTU value.
- *
- * @return ENOENT if device is not found.
- * @return EOK on success.
- *
- */
-static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
-{
-	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;
-	}
-	
-	device->packet_dimension.content = mtu;
-	
-	fibril_mutex_unlock(&arp_globals.lock);
-	
-	printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
-	
-	return EOK;
-}
-
-/** Process the received ARP packet.
- *
- * Update the source hardware address if the source entry exists or the packet
- * is targeted to my protocol address.
- *
- * Respond to the ARP request if the packet is the ARP request and is
- * targeted to my address.
- *
- * @param[in]     device_id Source device identifier.
- * @param[in,out] packet    Received packet.
- *
- * @return EOK on success and the packet is no longer needed.
- * @return One on success and the packet has been reused.
- * @return EINVAL if the packet is too small to carry an ARP
- *         packet.
- * @return EINVAL if the received address lengths differs from
- *         the registered values.
- * @return ENOENT if the device is not found in the cache.
- * @return ENOENT if the protocol for the device is not found in
- *         the cache.
- * @return ENOMEM if there is not enough memory left.
- *
- */
-static int arp_receive_message(device_id_t device_id, packet_t *packet)
-{
-	int rc;
-	
-	size_t length = packet_get_data_length(packet);
-	if (length <= sizeof(arp_header_t))
-		return EINVAL;
-	
-	arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
-	if (!device)
-		return ENOENT;
-	
-	arp_header_t *header = (arp_header_t *) 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;
-	}
-	
-	arp_proto_t *proto = arp_protos_find(&device->protos,
-	    protocol_unmap(device->service, ntohs(header->protocol)));
-	if (!proto)
-		return ENOENT;
-	
-	uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
-	uint8_t *src_proto = src_hw + header->hardware_length;
-	uint8_t *des_hw = src_proto + header->protocol_length;
-	uint8_t *des_proto = des_hw + header->hardware_length;
-	
-	arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
-	    header->protocol_length);
-	
-	if ((trans) && (trans->hw_addr)) {
-		/* Translation exists */
-		if (trans->hw_addr->length != header->hardware_length)
-			return EINVAL;
-		
-		memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
-	}
-	
-	/* Is my protocol address? */
-	if (proto->addr->length != header->protocol_length)
-		return EINVAL;
-	
-	if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
-		if (!trans) {
-			/* Update the translation */
-			trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
-			if (!trans)
-				return ENOMEM;
-			
-			trans->hw_addr = NULL;
-			fibril_condvar_initialize(&trans->cv);
-			rc = arp_addr_add(&proto->addresses, src_proto,
-			    header->protocol_length, trans);
-			if (rc != EOK) {
-				/* The generic char map has already freed trans! */
-				return rc;
-			}
-		}
-		
-		if (!trans->hw_addr) {
-			trans->hw_addr = measured_string_create_bulk(src_hw,
-			    header->hardware_length);
-			if (!trans->hw_addr)
-				return ENOMEM;
-			
-			/* Notify the fibrils that wait for the translation. */
-			fibril_condvar_broadcast(&trans->cv);
-		}
-		
-		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, trans->hw_addr->value,
-			    header->hardware_length);
-			
-			rc = packet_set_addr(packet, src_hw, des_hw,
-			    header->hardware_length);
-			if (rc != EOK)
-				return rc;
-			
-			nil_send_msg(device->phone, device_id, packet,
-			    SERVICE_ARP);
-			return 1;
-		}
-	}
-	
-	return EOK;
 }
 
@@ -714,5 +790,5 @@
  *
  */
-int arp_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
+int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     size_t *count)
 {
@@ -720,6 +796,4 @@
 	measured_string_t *translation;
 	uint8_t *data;
-	packet_t *packet;
-	packet_t *next;
 	int rc;
 	
@@ -784,33 +858,4 @@
 	case NET_ARP_CLEAN_CACHE:
 		return arp_clean_cache_req(0);
-	
-	case NET_IL_DEVICE_STATE:
-		/* Do nothing - keep the cache */
-		return EOK;
-	
-	case NET_IL_RECEIVED:
-		
-		rc = packet_translate_remote(arp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(*call));
-		if (rc != EOK)
-			return rc;
-		
-		fibril_mutex_lock(&arp_globals.lock);
-		do {
-			next = pq_detach(packet);
-			rc = arp_receive_message(IPC_GET_DEVICE(*call), packet);
-			if (rc != 1) {
-				pq_release_remote(arp_globals.net_phone,
-				    packet_get_id(packet));
-			}
-			packet = next;
-		} while (packet);
-		fibril_mutex_unlock(&arp_globals.lock);
-		
-		return EOK;
-	
-	case NET_IL_MTU_CHANGED:
-		return arp_mtu_changed_message(IPC_GET_DEVICE(*call),
-		    IPC_GET_MTU(*call));
 	}
 	
@@ -818,49 +863,8 @@
 }
 
-/** Default thread for new connections.
- *
- * @param[in] iid   Initial message identifier.
- * @param[in] icall Initial message call structure.
- */
-static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/*
-	 * Accept the connection
-	 *  - Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	ipc_answer_0(iid, EOK);
-	
-	while (true) {
-		ipc_call_t answer;
-		size_t count;
-		
-		/* Clear the answer structure */
-		refresh_answer(&answer, &count);
-		
-		/* Fetch the next message */
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		/* Process the message */
-		int res = il_module_message(callid, &call, &answer,
-		    &count);
-		
-		/*
-		 * End if told to either by the message or the processing
-		 * result.
-		 */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
-			return;
-		
-		/* Answer the message */
-		answer_call(callid, res, &answer, count);
-	}
-}
-
 int main(int argc, char *argv[])
 {
 	/* Start the module */
-	return il_module_start(il_client_connection);
+	return il_module_start(SERVICE_ARP);
 }
 
