X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=idnlookup.c;h=e97f62fd51360fca9a19e3955825605833bae081;hb=732b835938a7a80fe3c5ef71b84fa2ce0090bd01;hp=be4809bc934a443aa53a3e17c37b88dcbd6d2de6;hpb=e172b003e179ce9b70459eadbef8a73a4f218e0e;p=icmp-dn.git diff --git a/idnlookup.c b/idnlookup.c index be4809b..e97f62f 100644 --- a/idnlookup.c +++ b/idnlookup.c @@ -1,5 +1,6 @@ /* * idnlookup - ICMP Domain Name lookup utility for Linux + * Should be installed SUID root, even though I don't know if it's secure yet. :-) * Copyright (C) 2005 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +64,7 @@ unsigned char buf[65536]; /* DN decompression not yet implemented, since I don't know where to * begin counting the offset from -- the beginning of the ICMP * payload, or from the beginning of the DN data buffer? */ -void printdn(FILE *f, unsigned char *dnbuf, size_t size) +void printdn(FILE *f, unsigned char *dnbuf, size_t size, int onlyfirst) { unsigned char *p; @@ -80,6 +82,8 @@ void printdn(FILE *f, unsigned char *dnbuf, size_t size) } p++; fprintf(f, "\n"); + if(onlyfirst) + break; } } @@ -120,7 +124,7 @@ void cksum(void *hdr, size_t len) void usage(void) { - fprintf(stderr, "usage: idnlookup [-h] [-t timeout] host\n"); + fprintf(stderr, "usage: idnlookup [-hTa] [-t timeout] host\n"); } int main(int argc, char **argv) @@ -132,20 +136,25 @@ int main(int argc, char **argv) struct reqhdr req; struct rephdr rep; struct iphdr iphdr; + size_t hdrlen; struct addrinfo *ai, *cai, aihint; struct pollfd pfd; struct timeval tvb, tvc; struct sockaddr_storage name; - int timeout, dispttl; - int elapsed; + int timeout, dispttl, onlyfirst; + int elapsed, timedout, found; timeout = 3000; dispttl = 0; - while((c = getopt(argc, argv, "hTt:")) != -1) { + onlyfirst = 1; + while((c = getopt(argc, argv, "haTt:")) != -1) { switch(c) { case 't': timeout = atoi(optarg); break; + case 'a': + onlyfirst = 0; + break; case 'T': dispttl = 1; break; @@ -164,7 +173,6 @@ int main(int argc, char **argv) } memset(&aihint, 0, sizeof(aihint)); - aihint.ai_family = PF_INET; /* Only IPv4 for now. */ aihint.ai_socktype = SOCK_RAW; aihint.ai_protocol = IPPROTO_ICMP; ret = getaddrinfo(argv[optind], NULL, &aihint, &ai); @@ -190,15 +198,17 @@ int main(int argc, char **argv) exit(1); } + timedout = 0; + found = 0; gettimeofday(&tvb, NULL); while(1) { pfd.fd = s; pfd.events = POLLIN; gettimeofday(&tvc, NULL); elapsed = ((tvc.tv_sec - tvb.tv_sec) * 1000) + ((tvc.tv_usec - tvb.tv_usec) / 1000); - if(elapsed > timeout) { - fprintf(stderr, "idnlookup: timeout\n"); - exit(1); + if(elapsed >= timeout) { + timedout = 1; + break; } ret = poll(&pfd, 1, timeout - elapsed); if(ret < 0) { @@ -219,34 +229,53 @@ int main(int argc, char **argv) if(name.ss_family == AF_INET) { if(memcmp(&(((struct sockaddr_in *)&name)->sin_addr), &(((struct sockaddr_in *)cai->ai_addr)->sin_addr), sizeof(struct in_addr))) continue; + if(ret < sizeof(iphdr) + sizeof(rep)) + continue; + hdrlen = sizeof(iphdr); + memcpy(&iphdr, buf, sizeof(iphdr)); + if(iphdr.protocol != IPPROTO_ICMP) + continue; } else if(name.ss_family == AF_INET6) { if(memcmp(&(((struct sockaddr_in6 *)&name)->sin6_addr), &(((struct sockaddr_in6 *)cai->ai_addr)->sin6_addr), sizeof(struct in6_addr))) continue; + if(ret < sizeof(rep)) + continue; + hdrlen = 0; } else { continue; } - if(ret < sizeof(iphdr) + sizeof(rep)) - continue; - memcpy(&iphdr, buf, sizeof(iphdr)); - memcpy(&rep, buf + sizeof(iphdr), sizeof(rep)); - if(iphdr.protocol != IPPROTO_ICMP) - continue; + memcpy(&rep, buf + hdrlen, sizeof(rep)); if(rep.type != ICMP_NAMEREP) continue; if((ntohs(rep.id) != id) || (ntohs(rep.seq != 0))) continue; + found = 1; break; } } - if(dispttl) - printf("%i\n", ntohl(rep.ttl)); - printdn(stdout, buf + sizeof(iphdr) + sizeof(rep), ret - sizeof(iphdr) - sizeof(rep)); - close(s); + + if(found) { + if(dispttl) + printf("%i\n", ntohl(rep.ttl)); + printdn(stdout, buf + hdrlen + sizeof(rep), ret - hdrlen - sizeof(rep), onlyfirst); + break; + } + } + + if(timedout) { + fprintf(stderr, "idnlookup: timeout\n"); + exit(1); } return(0); } + +/* + * Local Variables: + * compile-command: "gcc -Wall -g -o idnlookup idnlookup.c" + * End: + */