/*% 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); }
void ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { lwres_gnbarequest_t *req; isc_result_t result; isc_sockaddr_t sa; ns_lwdclientmgr_t *cm; REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); INSIST(client->byaddr == NULL); cm = client->clientmgr; req = NULL; result = lwres_gnbarequest_parse(cm->lwctx, b, &client->pkt, &req); if (result != LWRES_R_SUCCESS) goto out; client->options = 0; if (req->addr.family == LWRES_ADDRTYPE_V4) { client->na.family = AF_INET; if (req->addr.length != 4) goto out; memcpy(&client->na.type.in, req->addr.address, 4); } else if (req->addr.family == LWRES_ADDRTYPE_V6) { client->na.family = AF_INET6; if (req->addr.length != 16) goto out; memcpy(&client->na.type.in6, req->addr.address, 16); } else { goto out; } isc_sockaddr_fromnetaddr(&sa, &client->na, 53); ns_lwdclient_log(50, "client %p looking for addrtype %08x", client, req->addr.family); /* * We no longer need to keep this around. */ lwres_gnbarequest_free(cm->lwctx, &req); /* * Initialize the real name and alias arrays in the reply we're * going to build up. */ init_gnba(client); client->options = 0; /* * Start the find. */ start_byaddr(client); return; /* * We're screwed. Return an error packet to our caller. */ out: if (req != NULL) lwres_gnbarequest_free(cm->lwctx, &req); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); }