Index: uspace/lib/nettl/include/nettl/amap.h
===================================================================
--- uspace/lib/nettl/include/nettl/amap.h	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
+++ uspace/lib/nettl/include/nettl/amap.h	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -96,5 +96,5 @@
     inet_ep2_t *);
 extern void amap_remove(amap_t *, inet_ep2_t *);
-extern int amap_find(amap_t *, inet_ep2_t *, void **);
+extern int amap_find_match(amap_t *, inet_ep2_t *, void **);
 
 #endif
Index: uspace/lib/nettl/include/nettl/portrng.h
===================================================================
--- uspace/lib/nettl/include/nettl/portrng.h	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
+++ uspace/lib/nettl/include/nettl/portrng.h	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -46,4 +46,6 @@
 	/** Port number */
 	uint16_t pn;
+	/** User argument */
+	void *arg;
 } portrng_port_t;
 
@@ -60,4 +62,5 @@
 extern int portrng_alloc(portrng_t *, uint16_t, void *,
     portrng_flags_t, uint16_t *);
+extern int portrng_find_port(portrng_t *, uint16_t, void **);
 extern void portrng_free_port(portrng_t *, uint16_t);
 extern bool portrng_empty(portrng_t *);
Index: uspace/lib/nettl/src/amap.c
===================================================================
--- uspace/lib/nettl/src/amap.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
+++ uspace/lib/nettl/src/amap.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -510,8 +510,70 @@
 }
 
-int amap_find(amap_t *map, inet_ep2_t *epp, void **rarg)
-{
-	log_msg(LOG_DEFAULT, LVL_NOTE, "amap_find()");
-	return EOK;
+/** Find association matching an endpoint pair.
+ *
+ * Used to find which association to deliver a datagram to.
+ *
+ * @param map	Association map
+ * @param epp	Endpoint pair
+ * @param rarg	Place to store user argument for the matching association.
+ *
+ * @return	EOK on success, ENOENT if not found.
+ */
+int amap_find_match(amap_t *map, inet_ep2_t *epp, void **rarg)
+{
+	int rc;
+	amap_repla_t *repla;
+	amap_laddr_t *laddr;
+	amap_llink_t *llink;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "amap_find_match(llink=%zu)",
+	    epp->local_link);
+
+	/* Remode endpoint, local address */
+	rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
+	if (rc == EOK) {
+		rc = portrng_find_port(repla->portrng, epp->local.port,
+		    rarg);
+		if (rc == EOK) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "Matched repla / "
+			    "port %" PRIu16, epp->local.port);
+			return EOK;
+		}
+	}
+
+	/* Local address */
+	rc = amap_laddr_find(map, &epp->local.addr, &laddr);
+	if (rc == EOK) {
+		rc = portrng_find_port(laddr->portrng, epp->local.port,
+		    rarg);
+		if (rc == EOK) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "Matched laddr / "
+			    "port %" PRIu16, epp->local.port);
+			return EOK;
+		}
+	}
+
+	/* Local link */
+	rc = amap_llink_find(map, epp->local_link, &llink);
+	if (epp->local_link != 0 && rc == EOK) {
+		rc = portrng_find_port(llink->portrng, epp->local.port,
+		    rarg);
+		if (rc == EOK) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "Matched llink / "
+			    "port %" PRIu16, epp->local.port);
+			return EOK;
+		}
+	}
+
+	/* Unspecified */
+	rc = portrng_find_port(map->unspec, epp->local.port, rarg);
+	if (rc == EOK) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Matched unspec / port %" PRIu16,
+		    epp->local.port);
+		return EOK;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "No match.");
+	return ENOENT;
 }
 
Index: uspace/lib/nettl/src/portrng.c
===================================================================
--- uspace/lib/nettl/src/portrng.c	(revision ab6326bcc8e9a50d34db6b657d59aaddc9baca6c)
+++ uspace/lib/nettl/src/portrng.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -118,4 +118,5 @@
 
 	p->pn = pnum;
+	p->arg = arg;
 	list_append(&p->lprng, &pr->used);
 	*apnum = pnum;
@@ -123,4 +124,16 @@
 	    pnum);
 	return EOK;
+}
+
+int portrng_find_port(portrng_t *pr, uint16_t pnum, void **rarg)
+{
+	list_foreach(pr->used, lprng, portrng_port_t, port) {
+		if (port->pn == pnum) {
+			*rarg = port->arg;
+			return EOK;
+		}
+	}
+
+	return ENOENT;
 }
 
