+ case LWRES_OPCODE_GETNAMEBYADDR:
+ gnba = (const lwres_gnbarequest_t *)p;
+ ND_TCHECK_4(gnba->flags);
+
+ /* BIND910: not used */
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT(" flags:0x%x",
+ GET_BE_U_4(gnba->flags));
+ }
+
+ s = p + LWRES_GNBAREQUEST_LEN;
+ advance = lwres_printaddr(ndo, s);
+ if (advance < 0)
+ goto invalid;
+ s += advance;
+ break;
+ case LWRES_OPCODE_GETRDATABYNAME:
+ /* XXX no trace, not tested */
+ grbn = (const lwres_grbnrequest_t *)p;
+ ND_TCHECK_2(grbn->namelen);
+
+ /* BIND910: not used */
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT(" flags:0x%x",
+ GET_BE_U_4(grbn->flags));
+ }
+
+ ND_PRINT(" %s", tok2str(ns_type2str, "Type%u",
+ GET_BE_U_2(grbn->rdtype)));
+ if (GET_BE_U_2(grbn->rdclass) != C_IN) {
+ ND_PRINT(" %s", tok2str(ns_class2str, "Class%u",
+ GET_BE_U_2(grbn->rdclass)));
+ }
+
+ s = p + LWRES_GRBNREQUEST_LEN;
+ l = GET_BE_U_2(grbn->namelen);
+ advance = lwres_printname(ndo, l, s);
+ s += advance;
+ break;
+ default:
+ s = p;
+ unsupported++;
+ break;
+ }
+ } else {
+ /*
+ * responses
+ */
+ const lwres_gabnresponse_t *gabn;
+ const lwres_gnbaresponse_t *gnba;
+ const lwres_grbnresponse_t *grbn;
+ uint32_t l, na;
+ uint32_t i;
+
+ gabn = NULL;
+ gnba = NULL;
+ grbn = NULL;
+
+ p = (const u_char *)(np + 1);
+ switch (GET_BE_U_4(np->opcode)) {
+ case LWRES_OPCODE_NOOP:
+ s = p;
+ break;
+ case LWRES_OPCODE_GETADDRSBYNAME:
+ gabn = (const lwres_gabnresponse_t *)p;
+ ND_TCHECK_2(gabn->realnamelen);
+
+ /* BIND910: not used */
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT(" flags:0x%x",
+ GET_BE_U_4(gabn->flags));
+ }
+
+ ND_PRINT(" %u/%u", GET_BE_U_2(gabn->naliases),
+ GET_BE_U_2(gabn->naddrs));
+
+ s = p + LWRES_GABNRESPONSE_LEN;
+ l = GET_BE_U_2(gabn->realnamelen);
+ advance = lwres_printname(ndo, l, s);
+ s += advance;
+
+ /* aliases */
+ na = GET_BE_U_2(gabn->naliases);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printnamelen(ndo, s);
+ s += advance;
+ }
+
+ /* addrs */
+ na = GET_BE_U_2(gabn->naddrs);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printaddr(ndo, s);
+ if (advance < 0)
+ goto invalid;
+ s += advance;
+ }
+ break;
+ case LWRES_OPCODE_GETNAMEBYADDR:
+ gnba = (const lwres_gnbaresponse_t *)p;
+ ND_TCHECK_2(gnba->realnamelen);
+
+ /* BIND910: not used */
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT(" flags:0x%x",
+ GET_BE_U_4(gnba->flags));
+ }
+
+ ND_PRINT(" %u", GET_BE_U_2(gnba->naliases));
+
+ s = p + LWRES_GNBARESPONSE_LEN;
+ l = GET_BE_U_2(gnba->realnamelen);
+ advance = lwres_printname(ndo, l, s);
+ s += advance;
+
+ /* aliases */
+ na = GET_BE_U_2(gnba->naliases);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printnamelen(ndo, s);
+ s += advance;
+ }
+ break;
+ case LWRES_OPCODE_GETRDATABYNAME:
+ /* XXX no trace, not tested */
+ grbn = (const lwres_grbnresponse_t *)p;
+ ND_TCHECK_2(grbn->nsigs);
+
+ /* BIND910: not used */
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT(" flags:0x%x",
+ GET_BE_U_4(grbn->flags));
+ }
+
+ ND_PRINT(" %s", tok2str(ns_type2str, "Type%u",
+ GET_BE_U_2(grbn->rdtype)));
+ if (GET_BE_U_2(grbn->rdclass) != C_IN) {
+ ND_PRINT(" %s", tok2str(ns_class2str, "Class%u",
+ GET_BE_U_2(grbn->rdclass)));
+ }
+ ND_PRINT(" TTL ");
+ unsigned_relts_print(ndo,
+ GET_BE_U_4(grbn->ttl));
+ ND_PRINT(" %u/%u", GET_BE_U_2(grbn->nrdatas),
+ GET_BE_U_2(grbn->nsigs));
+
+ s = p + LWRES_GRBNRESPONSE_LEN;
+ advance = lwres_printnamelen(ndo, s);
+ s += advance;
+
+ /* rdatas */
+ na = GET_BE_U_2(grbn->nrdatas);
+ for (i = 0; i < na; i++) {
+ /* XXX should decode resource data */
+ advance = lwres_printbinlen(ndo, s);
+ s += advance;
+ }
+
+ /* sigs */
+ na = GET_BE_U_2(grbn->nsigs);
+ for (i = 0; i < na; i++) {
+ /* XXX how should we print it? */
+ advance = lwres_printbinlen(ndo, s);
+ s += advance;
+ }
+ break;
+ default:
+ s = p;
+ unsupported++;