static u_char *mesg_read_sec (G_List *target_list, u_char *section, int count,
			      u_char *mesg, int mesg_len) {
	char *fn = "mesg_read_sec()";
	G_List *rc_list, *gl;
	u_char buf[MAX_PACKET];
	u_char *msg_end, *rp;
	int i;

	if (T.debug > 4)
		syslog (LOG_DEBUG, "%s: start", fn);

	/* initialize */
	rc_list = list_init ();
	if (!rc_list)
		return NULL;

	rp = section;
	msg_end = mesg + mesg_len;
	for (i = 0; i < count; i++) {
		u_char *rname, *rp_ex, *rdp;
		uint16_t r_type, r_class;
		uint16_t rdlen, rdlen_ex;
		uint32_t r_ttl;
		RR_List *rrl;

		/* parse header */
		rname = rp;
		rp = mesg_skip_dname (rp, msg_end);
		if (!rp)
			goto error;

		if (rp + sizeof(uint16_t)*3 + sizeof(uint32_t) > msg_end)
			goto error;

		GETSHORT (r_type, rp);
		GETSHORT (r_class, rp);
		GETLONG (r_ttl, rp);
		GETSHORT (rdlen, rp);

		rdp = rp;
		rp += rdlen;
		if (rp > msg_end)
			goto error;

		/* seek for matching RRset_Couple */
		for (gl = rc_list->next; gl->list_data; gl = gl->next) {
			RRset_Couple *rc;

			rc = (RRset_Couple *) (gl->list_data);
			if ((rc->rrs->key.info->r_type == r_type) &&
			    (rc->rrs->key.info->r_class == r_class) &&
			    !mesg_dname_cmp (mesg, rname, rrset_owner (rc->rrs))) {
				if (T.debug > 4)
					syslog (LOG_DEBUG, "%s: matching record \
found rrs->dname = %s / rname = %s", fn, rrset_owner (rc->rrs), rname);
				break;
			}
		}

		/* if no match, create a new RRset_Couple */
		if (!gl->list_data) {
			RRset_Couple *rc;
			int dname_len;

			if (!dname_decompress (buf, sizeof (buf), rname, mesg,
					       msg_end, &dname_len))
				goto error;

			rc = malloc (sizeof (RRset_Couple));
			if (!rc)
				goto error;

			rc->rrl = rr_list_alloc ();
			rc->rrs = rrset_create (r_type, r_class, dname_len, buf, NULL);

			/* if ok, add it to RRset_Couple list */
			if (!rc->rrl || !rc->rrs || list_add (rc_list, rc)) {
				rrset_couple_free(rc);
				goto error;
			}

			/* point it to the one we just added */
			gl = rc_list->next;
		}

		/* extract resource record */
		if (rdlen) {
			int ret;

			ret = mesg_extract_rr (mesg, msg_end, r_type, r_class,
					       rdp, buf, sizeof (buf));
			if (ret < 0)
				goto error;

			if (!ret) {
				rp_ex = rdp;
				rdlen_ex = rdlen;
			} else {
				rp_ex = buf;
				rdlen_ex = ret;
			}
		} else {
			rp_ex = NULL;
			rdlen_ex = 0;
		}

		/* add the extracted RR to matching RR_List */
		rrl = rr_list_add (((RRset_Couple *) (gl->list_data))->rrl,
				   r_ttl, rdlen_ex, rp_ex);
		if (!rrl)
			goto error;

		((RRset_Couple *) (gl->list_data))->rrl = rrl;
	}

	if (T.debug > 4)
		syslog (LOG_DEBUG, "%s: make each RRset from list.", fn);

	rc_list->list_data = NULL;
	for (gl = rc_list->next; gl->list_data; gl = gl->next) {
		RRset_Couple *rc;
		RRset *rrs;

		/* create complete RRset */
		rc = (RRset_Couple *) (gl->list_data);
		rrs = rrset_create (rc->rrs->key.info->r_type,
				    rc->rrs->key.info->r_class,
				    rc->rrs->key.info->owner_len,
				    rrset_owner (rc->rrs), rc->rrl);
		if (!rrs)
			goto error;

		if (target_list) {
			if (list_add (target_list, rrset_copy (rrs)) < 0) {
				rrset_free (rrs);
				goto error;
			}
		}

		rrset_free (rrs);
	}

	/* free unused resources */
	list_destroy (rc_list, rrset_couple_freev);

	if (T.debug > 4)
		syslog (LOG_DEBUG, "%s: end", fn);

	return rp;  /* byte after of the section we just processed */

error:
	syslog (LOG_INFO, "%s: message extraction failed", fn);
	list_destroy (rc_list, rrset_couple_freev);
	return NULL;
}