Beispiel #1
0
/*!
 * Requires:
 *
 *	The "current" pointer in "b" point to an encoded string.
 *
 * Ensures:
 *
 *	The address of the first byte of the string is returned via "c",
 *	and the length is returned via "len".  If NULL, they are not
 *	set.
 *
 *	On return, the current pointer of "b" will point to the character
 *	following the string length, the string, and the trailing NULL.
 *
 */
lwres_result_t
lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len)
{
	lwres_uint16_t datalen;
	char *string;

	REQUIRE(b != NULL);

	/*
	 * Pull off the length (2 bytes)
	 */
	if (!SPACE_REMAINING(b, 2))
		return (LWRES_R_UNEXPECTEDEND);
	datalen = lwres_buffer_getuint16(b);

	/*
	 * Set the pointer to this string to the right place, then
	 * advance the buffer pointer.
	 */
	if (!SPACE_REMAINING(b, datalen))
		return (LWRES_R_UNEXPECTEDEND);
	string = (char *)b->base + b->current;
	lwres_buffer_forward(b, datalen);

	/*
	 * Skip the "must be zero" byte.
	 */
	if (!SPACE_REMAINING(b, 1))
		return (LWRES_R_UNEXPECTEDEND);
	if (0 != lwres_buffer_getuint8(b))
		return (LWRES_R_FAILURE);

	if (len != NULL)
		*len = datalen;
	if (c != NULL)
		*c = string;

	return (LWRES_R_SUCCESS);
}
Beispiel #2
0
/*% Uses context ctx to convert the contents of packet pkt to a lwres_gabnrequest_t structure. */
lwres_result_t
lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp)
{
	int ret;
	char *name;
	lwres_gabnrequest_t *gabn;
	lwres_uint32_t addrtypes;
	lwres_uint32_t flags;
	lwres_uint16_t namelen;

	REQUIRE(ctx != NULL);
	REQUIRE(pkt != NULL);
	REQUIRE(b != NULL);
	REQUIRE(structp != NULL && *structp == NULL);

	if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
		return (LWRES_R_FAILURE);

	if (!SPACE_REMAINING(b, 4 + 4))
		return (LWRES_R_UNEXPECTEDEND);

	flags = lwres_buffer_getuint32(b);
	addrtypes = lwres_buffer_getuint32(b);

	/*
	 * Pull off the name itself
	 */
	ret = lwres_string_parse(b, &name, &namelen);
	if (ret != LWRES_R_SUCCESS)
		return (ret);

	if (LWRES_BUFFER_REMAINING(b) != 0)
		return (LWRES_R_TRAILINGDATA);

	gabn = CTXMALLOC(sizeof(lwres_gabnrequest_t));
	if (gabn == NULL)
		return (LWRES_R_NOMEMORY);

	gabn->flags = flags;
	gabn->addrtypes = addrtypes;
	gabn->name = name;
	gabn->namelen = namelen;

	*structp = gabn;
	return (LWRES_R_SUCCESS);
}
Beispiel #3
0
/*% Uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. */
lwres_result_t
lwres_gnbarequest_parse (lwres_context_t * ctx, lwres_buffer_t * b,
                         lwres_lwpacket_t * pkt, lwres_gnbarequest_t ** structp)
{
    int ret;

    lwres_gnbarequest_t *gnba;

    REQUIRE (ctx != NULL);
    REQUIRE (pkt != NULL);
    REQUIRE (b != NULL);
    REQUIRE (structp != NULL && *structp == NULL);

    if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
        return (LWRES_R_FAILURE);

    if (!SPACE_REMAINING (b, 4))
        return (LWRES_R_UNEXPECTEDEND);

    gnba = CTXMALLOC (sizeof (lwres_gnbarequest_t));
    if (gnba == NULL)
        return (LWRES_R_NOMEMORY);

    gnba->flags = lwres_buffer_getuint32 (b);

    ret = lwres_addr_parse (b, &gnba->addr);
    if (ret != LWRES_R_SUCCESS)
        goto out;

    if (LWRES_BUFFER_REMAINING (b) != 0)
    {
        ret = LWRES_R_TRAILINGDATA;
        goto out;
    }

    *structp = gnba;
    return (LWRES_R_SUCCESS);

  out:
    if (gnba != NULL)
        lwres_gnbarequest_free (ctx, &gnba);

    return (ret);
}
Beispiel #4
0
lwres_result_t
lwres_gnbaresponse_parse (lwres_context_t * ctx, lwres_buffer_t * b,
                          lwres_lwpacket_t * pkt, lwres_gnbaresponse_t ** structp)
{
    int ret;

    unsigned int x;

    lwres_uint32_t flags;

    lwres_uint16_t naliases;

    lwres_gnbaresponse_t *gnba;

    REQUIRE (ctx != NULL);
    REQUIRE (pkt != NULL);
    REQUIRE (b != NULL);
    REQUIRE (structp != NULL && *structp == NULL);

    gnba = NULL;

    if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
        return (LWRES_R_FAILURE);

    /*
     * Pull off flags & naliases
     */
    if (!SPACE_REMAINING (b, 4 + 2))
        return (LWRES_R_UNEXPECTEDEND);
    flags = lwres_buffer_getuint32 (b);
    naliases = lwres_buffer_getuint16 (b);

    gnba = CTXMALLOC (sizeof (lwres_gnbaresponse_t));
    if (gnba == NULL)
        return (LWRES_R_NOMEMORY);
    gnba->base = NULL;
    gnba->aliases = NULL;
    gnba->aliaslen = NULL;

    gnba->flags = flags;
    gnba->naliases = naliases;

    if (naliases > 0)
    {
        gnba->aliases = CTXMALLOC (sizeof (char *) * naliases);
        if (gnba->aliases == NULL)
        {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }

        gnba->aliaslen = CTXMALLOC (sizeof (lwres_uint16_t) * naliases);
        if (gnba->aliaslen == NULL)
        {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }
    }

    /*
     * Now, pull off the real name.
     */
    ret = lwres_string_parse (b, &gnba->realname, &gnba->realnamelen);
    if (ret != LWRES_R_SUCCESS)
        goto out;

    /*
     * Parse off the aliases.
     */
    for (x = 0; x < gnba->naliases; x++)
    {
        ret = lwres_string_parse (b, &gnba->aliases[x], &gnba->aliaslen[x]);
        if (ret != LWRES_R_SUCCESS)
            goto out;
    }

    if (LWRES_BUFFER_REMAINING (b) != 0)
    {
        ret = LWRES_R_TRAILINGDATA;
        goto out;
    }

    *structp = gnba;
    return (LWRES_R_SUCCESS);

  out:
    if (gnba != NULL)
    {
        if (gnba->aliases != NULL)
            CTXFREE (gnba->aliases, sizeof (char *) * naliases);
        if (gnba->aliaslen != NULL)
            CTXFREE (gnba->aliaslen, sizeof (lwres_uint16_t) * naliases);
        CTXFREE (gnba, sizeof (lwres_gnbaresponse_t));
    }

    return (ret);
}
Beispiel #5
0
/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
lwres_result_t
lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
                         lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
{
    lwres_result_t ret;
    unsigned int x;
    lwres_uint32_t flags;
    lwres_uint16_t rdclass, rdtype;
    lwres_uint32_t ttl;
    lwres_uint16_t nrdatas, nsigs;
    lwres_grbnresponse_t *grbn;

    REQUIRE(ctx != NULL);
    REQUIRE(pkt != NULL);
    REQUIRE(b != NULL);
    REQUIRE(structp != NULL && *structp == NULL);

    grbn = NULL;

    if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
        return (LWRES_R_FAILURE);

    /*
     * Pull off the flags, class, type, ttl, nrdatas, and nsigs
     */
    if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
        return (LWRES_R_UNEXPECTEDEND);
    flags = lwres_buffer_getuint32(b);
    rdclass = lwres_buffer_getuint16(b);
    rdtype = lwres_buffer_getuint16(b);
    ttl = lwres_buffer_getuint32(b);
    nrdatas = lwres_buffer_getuint16(b);
    nsigs = lwres_buffer_getuint16(b);

    /*
     * Pull off the name itself
     */

    grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
    if (grbn == NULL)
        return (LWRES_R_NOMEMORY);
    grbn->rdatas = NULL;
    grbn->rdatalen = NULL;
    grbn->sigs = NULL;
    grbn->siglen = NULL;
    grbn->base = NULL;

    grbn->flags = flags;
    grbn->rdclass = rdclass;
    grbn->rdtype = rdtype;
    grbn->ttl = ttl;
    grbn->nrdatas = nrdatas;
    grbn->nsigs = nsigs;

    if (nrdatas > 0) {
        grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
        if (grbn->rdatas == NULL) {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }

        grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
        if (grbn->rdatalen == NULL) {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }
    }

    if (nsigs > 0) {
        grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
        if (grbn->sigs == NULL) {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }

        grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
        if (grbn->siglen == NULL) {
            ret = LWRES_R_NOMEMORY;
            goto out;
        }
    }

    /*
     * Now, pull off the real name.
     */
    ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
    if (ret != LWRES_R_SUCCESS)
        goto out;

    /*
     * Parse off the rdatas.
     */
    for (x = 0; x < grbn->nrdatas; x++) {
        ret = lwres_data_parse(b, &grbn->rdatas[x],
                               &grbn->rdatalen[x]);
        if (ret != LWRES_R_SUCCESS)
            goto out;
    }

    /*
     * Parse off the signatures.
     */
    for (x = 0; x < grbn->nsigs; x++) {
        ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
        if (ret != LWRES_R_SUCCESS)
            goto out;
    }

    if (LWRES_BUFFER_REMAINING(b) != 0) {
        ret = LWRES_R_TRAILINGDATA;
        goto out;
    }

    *structp = grbn;
    return (LWRES_R_SUCCESS);

out:
    if (grbn != NULL) {
        if (grbn->rdatas != NULL)
            CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
        if (grbn->rdatalen != NULL)
            CTXFREE(grbn->rdatalen,
                    sizeof(lwres_uint16_t) * nrdatas);
        if (grbn->sigs != NULL)
            CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
        if (grbn->siglen != NULL)
            CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
        CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
    }

    return (ret);
}
Beispiel #6
0
lwres_result_t
lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
{
	lwres_result_t ret;
	unsigned int x;
	lwres_uint32_t flags;
	lwres_uint16_t naliases;
	lwres_uint16_t naddrs;
	lwres_gabnresponse_t *gabn;
	lwres_addrlist_t addrlist;
	lwres_addr_t *addr;

	REQUIRE(ctx != NULL);
	REQUIRE(pkt != NULL);
	REQUIRE(b != NULL);
	REQUIRE(structp != NULL && *structp == NULL);

	gabn = NULL;

	if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
		return (LWRES_R_FAILURE);

	/*
	 * Pull off the name itself
	 */
	if (!SPACE_REMAINING(b, 4 + 2 + 2))
		return (LWRES_R_UNEXPECTEDEND);
	flags = lwres_buffer_getuint32(b);
	naliases = lwres_buffer_getuint16(b);
	naddrs = lwres_buffer_getuint16(b);

	gabn = CTXMALLOC(sizeof(lwres_gabnresponse_t));
	if (gabn == NULL)
		return (LWRES_R_NOMEMORY);
	gabn->aliases = NULL;
	gabn->aliaslen = NULL;
	LWRES_LIST_INIT(gabn->addrs);
	gabn->base = NULL;

	gabn->flags = flags;
	gabn->naliases = naliases;
	gabn->naddrs = naddrs;

	LWRES_LIST_INIT(addrlist);

	if (naliases > 0) {
		gabn->aliases = CTXMALLOC(sizeof(char *) * naliases);
		if (gabn->aliases == NULL) {
			ret = LWRES_R_NOMEMORY;
			goto out;
		}

		gabn->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
		if (gabn->aliaslen == NULL) {
			ret = LWRES_R_NOMEMORY;
			goto out;
		}
	}

	for (x = 0; x < naddrs; x++) {
		addr = CTXMALLOC(sizeof(lwres_addr_t));
		if (addr == NULL) {
			ret = LWRES_R_NOMEMORY;
			goto out;
		}
		LWRES_LINK_INIT(addr, link);
		LWRES_LIST_APPEND(addrlist, addr, link);
	}

	/*
	 * Now, pull off the real name.
	 */
	ret = lwres_string_parse(b, &gabn->realname, &gabn->realnamelen);
	if (ret != LWRES_R_SUCCESS)
		goto out;

	/*
	 * Parse off the aliases.
	 */
	for (x = 0; x < gabn->naliases; x++) {
		ret = lwres_string_parse(b, &gabn->aliases[x],
					 &gabn->aliaslen[x]);
		if (ret != LWRES_R_SUCCESS)
			goto out;
	}

	/*
	 * Pull off the addresses.  We already strung the linked list
	 * up above.
	 */
	addr = LWRES_LIST_HEAD(addrlist);
	for (x = 0; x < gabn->naddrs; x++) {
		INSIST(addr != NULL);
		ret = lwres_addr_parse(b, addr);
		if (ret != LWRES_R_SUCCESS)
			goto out;
		addr = LWRES_LIST_NEXT(addr, link);
	}

	if (LWRES_BUFFER_REMAINING(b) != 0) {
		ret = LWRES_R_TRAILINGDATA;
		goto out;
	}

	gabn->addrs = addrlist;

	*structp = gabn;
	return (LWRES_R_SUCCESS);

 out:
	if (gabn != NULL) {
		if (gabn->aliases != NULL)
			CTXFREE(gabn->aliases, sizeof(char *) * naliases);
		if (gabn->aliaslen != NULL)
			CTXFREE(gabn->aliaslen,
				sizeof(lwres_uint16_t) * naliases);
		addr = LWRES_LIST_HEAD(addrlist);
		while (addr != NULL) {
			LWRES_LIST_UNLINK(addrlist, addr, link);
			CTXFREE(addr, sizeof(lwres_addr_t));
			addr = LWRES_LIST_HEAD(addrlist);
		}
		CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
	}

	return (ret);
}