Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 77a69ea2b4d9de163884f75870b8a88e2f717139)
+++ uspace/srv/net/nil/eth/eth.c	(revision cf9cb36f0ca62c70ee2bfb4b1c4cce6ed794d7bb)
@@ -170,5 +170,8 @@
 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
 
-int nil_device_state_msg_local(nic_device_id_t device_id, sysarg_t state)
+static void eth_nic_cb_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
+
+static int eth_device_state(nic_device_id_t device_id, sysarg_t state)
 {
 	int index;
@@ -344,5 +347,12 @@
 	}
 	
-	nic_connect_to_nil(device->sess, SERVICE_ETHERNET, device_id);
+	rc = nic_callback_create(device->sess, device_id,
+	    eth_nic_cb_connection, NULL);
+	if (rc != EOK) {
+		fibril_rwlock_write_unlock(&eth_globals.devices_lock);
+		async_hangup(device->sess);
+		free(device);
+		return EIO;
+	}
 	
 	/* Get hardware address */
@@ -822,6 +832,8 @@
 	
 	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("%s: data_write_accept() failed\n", NAME);
 		return rc;
+	}
 	
 	packet_t *packet = packet_get_1_remote(eth_globals.net_sess, size);
@@ -943,19 +955,40 @@
 		
 		return EOK;
-	case NET_NIL_DEVICE_STATE:
-		nil_device_state_msg_local(IPC_GET_DEVICE(*call), IPC_GET_STATE(*call));
-		async_answer_0(callid, EOK);
-		return EOK;
-	case NET_NIL_RECEIVED:
-		rc = eth_received(IPC_GET_ARG1(*call));
-		async_answer_0(callid, (sysarg_t) rc);
-		return rc;
-	case NET_NIL_ADDR_CHANGED:
-		rc = eth_addr_changed(IPC_GET_DEVICE(*call));
-		async_answer_0(callid, (sysarg_t) rc);
-		return rc;
 	}
 	
 	return ENOTSUP;
+}
+
+static void eth_nic_cb_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	int rc;
+	
+	async_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case NIC_EV_DEVICE_STATE:
+			rc = eth_device_state(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		case NIC_EV_RECEIVED:
+			rc = eth_received(IPC_GET_ARG1(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		case NIC_EV_ADDR_CHANGED:
+			rc = eth_addr_changed(IPC_GET_ARG1(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		default:
+			async_answer_0(callid, ENOTSUP);
+		}
+	}
 }
 
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 77a69ea2b4d9de163884f75870b8a88e2f717139)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision cf9cb36f0ca62c70ee2bfb4b1c4cce6ed794d7bb)
@@ -2,4 +2,5 @@
  * Copyright (c) 2009 Lukas Mejdrech
  * Copyright (c) 2011 Radim Vansa
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -69,5 +70,8 @@
 DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
 
-int nil_device_state_msg_local(nic_device_id_t device_id, sysarg_t state)
+static void nildummy_nic_cb_conn(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
+
+static int nildummy_device_state(nic_device_id_t device_id, sysarg_t state)
 {
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
@@ -78,4 +82,9 @@
 	
 	return EOK;
+}
+
+static int nildummy_addr_changed(nic_device_id_t device_id)
+{
+	return ENOTSUP;
 }
 
@@ -173,8 +182,14 @@
 	}
 	
-	nic_connect_to_nil(device->sess, SERVICE_NILDUMMY, device_id);
+	int rc = nic_callback_create(device->sess, device_id,
+	    nildummy_nic_cb_conn, NULL);
+	if (rc != EOK) {
+		async_hangup(device->sess);
+		
+		return ENOENT;
+	}
 	
 	/* Get hardware address */
-	int rc = nic_get_address(device->sess, &device->addr);
+	rc = nic_get_address(device->sess, &device->addr);
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
@@ -445,18 +460,42 @@
 		*answer_count = 1;
 		return rc;
-	case NET_NIL_DEVICE_STATE:
-		rc = nil_device_state_msg_local(IPC_GET_DEVICE(*call),
-		    IPC_GET_STATE(*call));
-		async_answer_0(callid, (sysarg_t) rc);
-		return rc;
-	
-	case NET_NIL_RECEIVED:
-		rc = nildummy_received(IPC_GET_ARG1(*call));
-		async_answer_0(callid, (sysarg_t) rc);
-		return rc;
 	}
 	
 	return ENOTSUP;
 }
+
+static void nildummy_nic_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	int rc;
+	
+	async_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case NIC_EV_DEVICE_STATE:
+			rc = nildummy_device_state(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		case NIC_EV_RECEIVED:
+			rc = nildummy_received(IPC_GET_ARG1(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		case NIC_EV_ADDR_CHANGED:
+			rc = nildummy_addr_changed(IPC_GET_ARG1(call));
+			async_answer_0(callid, (sysarg_t) rc);
+			break;
+		default:
+			async_answer_0(callid, ENOTSUP);
+		}
+	}
+}
+
 
 int main(int argc, char *argv[])
