#include #include #include #include #include #include #include #include #define NAME 1 #define ADDR 2 #define CANN 4 #define ALIA 8 #define LABL 16 #define NUMB 32 #define HELP 64 #define RAWE 128 #define RESD 256 #define VERB 512 #define DEFAULT (LABL|0) int main(int ac, char **av) { int options = DEFAULT; int aliasnum = -1; struct hostent *hostent; char *p = av[0]; char *h = 0; int did_reset = 0; int got_options = 0; static char addrbuf[32]; unsigned char a[4]; int ai[4]; int i; char x; more: while (ac > 1) { av++; ac--; if (**av == '-') { while (*(++*av)) { switch (**av) { case 'a': /* addresses only */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ ADDR; break; case 'c': /* canonical entries only */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ CANN; break; case 'C': /* number of aliases only */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ NUMB; break; case 'D': /* debug resolver */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ RESD; break; case 'l': /* only show aliases */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ ALIA; break; case 'n': /* names only */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ NAME; break; case 'q': /* toggle printing field labels */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ LABL; break; case 'r': /* toggle printing raw hostent */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ RAWE; break; case 's': /* specify server(s) */ if (!**av) { if (--ac > 1) { if (**++av == '-') break; } else { break; } } if (sscanf(*av, "%d.%d.%d.%d%c", &ai[0], &ai[1], &ai[2], &ai[3], &x) != 4 || ai[0] < 0 || ai[0] > 255 || ai[1] < 0 || ai[1] > 255 || ai[2] < 0 || ai[2] > 255 || ai[3] < 0 || ai[3] > 255) { hostent = gethostbyname(*av); if (!hostent) break; for (i=0; i<4; i++) ai[i] = hostent->h_addr_list[0][i]; } for (i=0; i<4; i++) a[i] = (unsigned char)(ai[i] & 0xFF); snprintf(addrbuf, 32, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); if (!(did_reset++)) _res.nscount = 0; _res.options |= RES_INIT; _res.nsaddr_list[_res.nscount].sin_family = AF_INET; _res.nsaddr_list[_res.nscount].sin_port = htons(53); *(unsigned long *)&_res.nsaddr_list[_res.nscount++].sin_addr = inet_addr(addrbuf); if (options & VERB) printf("Server: %s -> %08x \n",addrbuf,inet_addr(addrbuf)); goto more; case 'A': /* only show aliases */ if (!got_options) { options = DEFAULT; got_options++; } options = options ^ ALIA; break; case 'v': if (!got_options) { options = DEFAULT; got_options++; } options = options ^ VERB; break; case '?': case 'h': if (!got_options) { options = DEFAULT; got_options++; } options = options ^ HELP; break; default: if (isdigit(**av)) { /* only show specific alias */ aliasnum = strtol(*av,0,0); options = options & ~CANN; } } } } else { h = *av; } } if (options & RESD) _res.options |= RES_DEBUG; if (!h || !*h || (options & HELP)) { fprintf(stderr,"Usage: %s [-{a,n,c,q,A,C,#,sIP}] {name,addr}\n",p); fprintf(stderr," a=addr n=name c=canonical q=nolabels A=aliases C=counts #=entry# s=server\n"); exit(2); } else { p = h; } if (p) { if (isdigit(*p)) { i = 0; do { a[i++] = strtoul(p,NULL,0L); p = strchr(p,'.'); } while (p && isdigit(*++p) && i<4); if (i!=4) { fprintf(stderr,"Unable to parse host address %s\n",av[1]); } hostent = gethostbyaddr(a,4,AF_INET); } else { hostent = gethostbyname(p); } if (!hostent) { perror("gethostbyname(2) failed"); exit(1); } else { int j; unsigned char u; if (options & RAWE) { char **hptr; printf("h_name = %s.\n",hostent->h_name ? hostent->h_name : "(null)"); hptr = hostent->h_aliases; printf("h_aliases = \n"); j = 0; while (*hptr) printf(" %d: %s.\n",j++,*hptr++); printf("addrtype = %d (0x%08x)\n",hostent->h_addrtype,hostent->h_addrtype); printf("addrlen = %d\n",hostent->h_length); hptr = hostent->h_addr_list; while (*hptr) { unsigned char *cptr; fputc(' ',stdout); cptr = (unsigned char *)*hptr; for (j=0; jh_length; j++) printf("%d.",*cptr++); cptr = (unsigned char *)*hptr; printf(" = "); for (j=0; jh_length; j++) printf("%02x.",*cptr++); fputc('\n',stdout); hptr++; } } if (options & NUMB) { int nalias, naddrs; nalias = naddrs = 0; for (i=0; hostent->h_aliases[i]; i++) { nalias++; } for (i=0; hostent->h_addr_list[i]; i++) { naddrs++; } if (!(options & NAME)) { if (options & LABL) { printf("addresses: %d",naddrs); } else { printf("%d",naddrs); } } if (!(options & ADDR)) { if (options & LABL) { if (!(options & NAME)) putchar('\n'); printf("aliases: %d",nalias); } else { if (!(options & NAME)) putchar(' '); printf("%d",nalias); } } putchar('\n'); exit(0); } if (!(options & ADDR) && !(options & ALIA)) { if (!(options & NAME) && !(options & CANN) && (options & LABL)) { printf("h_name: "); } printf("%s",hostent->h_name); if ((options & CANN)) putchar(' '); else putchar('\n'); } if (!(options & ADDR) && !(options & CANN)) { for (i=0; hostent->h_aliases[i]; i++) { if (aliasnum<0 || aliasnum == i) { if (options & LABL) printf("h_aliases[%d]: ",i); printf("%s\n",hostent->h_aliases[i]); } } if ((options & ALIA)) exit(0); } if (!(options & ADDR) && !(options & CANN) && !(options & NAME)) { if (hostent->h_addrtype != AF_INET || hostent->h_length != 4) printf("h_addrrtype: %d\nh_length: %d\n",hostent->h_addrtype,hostent->h_length); } if (!(options & NAME)) { for (i=0; hostent->h_addr_list[i]; i++) { if (aliasnum<0 || aliasnum == i-1) { if (!(options & ADDR) && !(options & CANN) && (options & LABL)) { printf("h_addr_list[%u]: ",i); } u = hostent->h_addr_list[i][0]; printf("%u",u); for (j=1; jh_length; j++) { putchar('.'); u = hostent->h_addr_list[i][j]; printf("%u",u); } putchar('\n'); if ((options & CANN)) break; } } } } } if ((options & NAME) && (options & CANN)) putchar('\n'); exit(0); }