+/*
+ * return matching entry.
+ * no matching entry found and if there is anonymous entry, return it.
+ * else return NULL.
+ * XXX by each data type, should be changed to compare the buffer.
+ */
+struct sainfo *
+getsainfo_by_dst_id(dst, peer)
+ const vchar_t *dst, *peer;
+{
+ struct sainfo *s = NULL;
+ struct sainfo *anonymous = NULL;
+
+ plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - dst id:\n");
+ if (dst != NULL)
+ plogdump(LLV_DEBUG2, dst->v, dst->l);
+ else
+ return NULL;
+
+ LIST_FOREACH(s, &sitree, chain) {
+ if (s->to_delete || s->to_remove) {
+ continue;
+ }
+ if (s->idsrc != NULL) {
+ plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id - src & dst:\n");
+ plogdump(LLV_DEBUG2, s->idsrc->v, s->idsrc->l);
+ plogdump(LLV_DEBUG2, s->iddst->v, s->iddst->l);
+ } else {
+ plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id = anonymous\n");
+ }
+ if (s->id_i != NULL) {
+ plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id_i:\n");
+ plogdump(LLV_DEBUG2, s->id_i->v, s->id_i->l);
+ if (peer == NULL)
+ continue;
+ if (memcmp(peer->v, s->id_i->v, s->id_i->l) != 0)
+ continue;
+ }
+ if (s->idsrc == NULL) {
+ anonymous = s;
+ continue;
+ }
+
+ if (memcmp(dst->v, s->iddst->v, s->iddst->l) == 0)
+ return s;
+ }
+
+ if (anonymous) {
+ plog(LLV_DEBUG, LOCATION, NULL,
+ "anonymous sainfo selected.\n");
+ }
+
+ return anonymous;
+}
+