📄 adig.c
字号:
ares_destroy(channel); return 0;}static void callback(void *arg, int status, unsigned char *abuf, int alen){ char *name = (char *) arg, *errmem; int id, qr, opcode, aa, tc, rd, ra, rcode, i; unsigned int qdcount, ancount, nscount, arcount; const unsigned char *aptr; /* Display the query name if given. */ if (name) printf("Answer for query %s:\n", name); /* Display an error message if there was an error, but only stop if * we actually didn't get an answer buffer. */ if (status != ARES_SUCCESS) { printf("%s\n", ares_strerror(status));//, &errmem)); ares_free_errmem(errmem); if (!abuf) return; } /* Won't happen, but check anyway, for safety. */ if (alen < HFIXEDSZ) return; /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); /* query identification number */ qr = DNS_HEADER_QR(abuf); /* query response */ opcode = DNS_HEADER_OPCODE(abuf); /* opcode */ aa = DNS_HEADER_AA(abuf); /* authoritative answer */ tc = DNS_HEADER_TC(abuf); /* truncation */ rd = DNS_HEADER_RD(abuf); /* recursion desired */ ra = DNS_HEADER_RA(abuf); /* recursion available */ rcode = DNS_HEADER_RCODE(abuf); /* response code */ qdcount = DNS_HEADER_QDCOUNT(abuf); /* question count */ ancount = DNS_HEADER_ANCOUNT(abuf); /* answer record count */ nscount = DNS_HEADER_NSCOUNT(abuf); /* name server record count */ arcount = DNS_HEADER_ARCOUNT(abuf); /* additional record count */ /* Display the answer header. */ printf("id: %d\n", id); printf("flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); printf("opcode: %s\n", opcodes[opcode]); printf("rcode: %s\n", rcodes[rcode]); /* Display the questions. */ printf("Questions:\n"); aptr = abuf + HFIXEDSZ; for (i = 0; i < (int)qdcount; i++) { aptr = display_question(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the answers. */ printf("Answers:\n"); for (i = 0; i < (int)ancount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the NS records. */ printf("NS records:\n"); for (i = 0; i < (int)nscount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the additional records. */ printf("Additional records:\n"); for (i = 0; i < (int)arcount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; }}static const unsigned char *display_question(const unsigned char *aptr, const unsigned char *abuf, int alen){ char *name; int type, dnsclass, status, len; /* Parse the question name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; aptr += len; /* Make sure there's enough data after the name for the fixed part * of the question. */ if (aptr + QFIXEDSZ > abuf + alen) { free(name); return NULL; } /* Parse the question type and class. */ type = DNS_QUESTION_TYPE(aptr); dnsclass = DNS_QUESTION_CLASS(aptr); aptr += QFIXEDSZ; /* Display the question, in a format sort of similar to how we will * display RRs. */ printf("\t%-15s.\t", name); if (dnsclass != C_IN) printf("\t%s", class_name(dnsclass)); printf("\t%s\n", type_name(type)); free(name); return aptr;}static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen){ const unsigned char *p; char *name; int type, dnsclass, ttl, dlen, status, len; struct in_addr addr; /* Parse the RR name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; aptr += len; /* Make sure there is enough data after the RR name for the fixed * part of the RR. */ if (aptr + RRFIXEDSZ > abuf + alen) { free(name); return NULL; } /* Parse the fixed part of the RR, and advance to the RR data * field. */ type = DNS_RR_TYPE(aptr); dnsclass = DNS_RR_CLASS(aptr); ttl = DNS_RR_TTL(aptr); dlen = DNS_RR_LEN(aptr); aptr += RRFIXEDSZ; if (aptr + dlen > abuf + alen) { free(name); return NULL; } /* Display the RR name, class, and type. */ printf("\t%-15s.\t%d", name, ttl); if (dnsclass != C_IN) printf("\t%s", class_name(dnsclass)); printf("\t%s", type_name(type)); free(name); /* Display the RR data. Don't touch aptr. */ switch (type) { case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_NS: case T_PTR: /* For these types, the RR data is just a domain name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); break; case T_HINFO: /* The RR data is two length-counted character strings. */ p = aptr; len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf("\t%.*s", len, p + 1); p += len + 1; len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf("\t%.*s", len, p + 1); break; case T_MINFO: /* The RR data is two domain names. */ p = aptr; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); p += len; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); break; case T_MX: /* The RR data is two bytes giving a preference ordering, and * then a domain name. */ if (dlen < 2) return NULL; printf("\t%d", (aptr[0] << 8) | aptr[1]); status = ares_expand_name(aptr + 2, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); break; case T_SOA: /* The RR data is two domain names and then five four-byte * numbers giving the serial number and some timeouts. */ p = aptr; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.\n", name); free(name); p += len; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t\t\t\t\t\t%s.\n", name); free(name); p += len; if (p + 20 > aptr + dlen) return NULL; printf("\t\t\t\t\t\t( %d %d %d %d %d )", (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7], (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11], (p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15], (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]); break; case T_TXT: /* The RR data is one or more length-counted character * strings. */ p = aptr; while (p < aptr + dlen) { len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf("\t%.*s", len, p + 1); p += len + 1; } break; case T_A: /* The RR data is a four-byte Internet address. */ if (dlen != 4) return NULL; memcpy(&addr, aptr, sizeof(struct in_addr)); printf("\t%s", inet_ntoa(addr)); break; case T_WKS: /* Not implemented yet */ break; case T_SRV: /* The RR data is three two-byte numbers representing the * priority, weight, and port, followed by a domain name. */ printf("\t%d", DNS__16BIT(aptr)); printf(" %d", DNS__16BIT(aptr + 2)); printf(" %d", DNS__16BIT(aptr + 4)); status = ares_expand_name(aptr + 6, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); break; case T_NAPTR: /* The RR data is two two-byte numbers representing the * order and preference, followed by three character strings * representing flags, services, a regex, and a domain name. */ printf("\t%d", DNS__16BIT(aptr)); printf(" %d", DNS__16BIT(aptr + 2)); p = aptr + 4; len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf(" %.*s", len, p + 1); p += len + 1; len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf(" %.*s", len, p + 1); p += len + 1; len = *p; if (p + len + 1 > aptr + dlen) return NULL; printf(" %.*s", len, p + 1); p += len + 1; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; printf("\t%s.", name); free(name); break; default: printf("\t[Unknown RR; cannot parse]"); } printf("\n"); return aptr + dlen;}static const char *type_name(int type){ int i; for (i = 0; i < ntypes; i++) { if (types[i].value == type) return types[i].name; } return "(unknown)";}static const char *class_name(int dnsclass){ int i; for (i = 0; i < nclasses; i++) { if (classes[i].value == dnsclass) return classes[i].name; } return "(unknown)";}static void usage(void){ fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] " "[-t type] [-p port] name ...\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -