+ for(cai = ai; cai != NULL; cai = cai->ai_next) {
+ if((s = socket(cai->ai_family, SOCK_RAW, IPPROTO_ICMP)) < 0) {
+ perror("could not create raw socket");
+ exit(1);
+ }
+
+ id = random() % 65536;
+ memset(&req, 0, sizeof(req));
+ req.type = ICMP_NAMEREQ;
+ req.id = htons(id);
+ cksum(&req, sizeof(req));
+
+ ret = sendto(s, &req, sizeof(req), 0, cai->ai_addr, cai->ai_addrlen);
+ if(ret < 0) {
+ perror("sendto");
+ exit(1);
+ } else if(ret != sizeof(req)) {
+ fprintf(stderr, "socket would not send entire packet\n");
+ exit(1);
+ }
+
+ 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);
+ }
+ ret = poll(&pfd, 1, timeout - elapsed);
+ if(ret < 0) {
+ perror("idnlookup: reading data");
+ exit(1);
+ }
+
+ if(pfd.revents & POLLIN) {
+ namelen = sizeof(name);
+ ret = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&name, &namelen);
+ if(ret < 0) {
+ perror("idnlookup: receiving data");
+ exit(1);
+ }
+
+ if(name.ss_family != cai->ai_addr->sa_family)
+ continue;
+ 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;
+ } 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;
+ } 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;
+ if(rep.type != ICMP_NAMEREP)
+ continue;
+ if((ntohs(rep.id) != id) || (ntohs(rep.seq != 0)))
+ continue;
+
+ break;
+ }
+ }
+
+ printdn(stdout, buf + sizeof(iphdr) + sizeof(rep), ret - sizeof(iphdr) - sizeof(rep));
+
+ close(s);