diff options
-rw-r--r-- | host.c | 21 | ||||
-rw-r--r-- | host_test.c | 5 | ||||
-rw-r--r-- | main.c | 51 |
3 files changed, 45 insertions, 32 deletions
@@ -21,22 +21,23 @@ struct in_net { POPCNT(32) unsigned int power2[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648 }; /* ah yes, libmath */ /* not needed end */ -struct in_addr host (struct in_net n, int h /* consecutive number of the host in the network */) { +struct in_net host (struct in_net n, unsigned long long int h /* number of host in the network */) { n.addr.s_addr = ntohl(n.addr.s_addr & n.mask.s_addr); n.mask.s_addr = ntohl(n.mask.s_addr); - int c = 1; - int s = 0; - for (int i = 0; i < 32; i++) + unsigned long long int c = 1; + unsigned long int s = 0; + for (unsigned long int i = 0; i < 32; i++) if (1 << i & ~n.mask.s_addr) { if (1 << s++ & h) n.addr.s_addr |= 1 << i; - c = c * 2; - } - if (h >= c) - n.addr.s_addr = 0; + c *= 2; /* if we instead indicated error via addr and */ + } /* returned just addr, it would be impossible to */ + n.mask.s_addr = INADDR_BROADCAST; /* scan 0.0.0.0/0 without immediately detecting */ + if (h >= c) /* this false "error" and address 0.0.0.0 would */ + n.mask.s_addr = 0; /* in fact actually be correct. */ n.addr.s_addr = htonl(n.addr.s_addr); - return n.addr; -} + return n; /* \/= this means host h is outside network */ +} /* returns struct in_net: if .mask is not 255.255.255.255 (INADDR_BROADCAST), .addr is incorrect */ int resolve (const char * d, uint32_t * r) { struct addrinfo hints = { .ai_family = AF_INET, diff --git a/host_test.c b/host_test.c index 0584686..b0d95c5 100644 --- a/host_test.c +++ b/host_test.c @@ -4,6 +4,9 @@ int main (int argc, char ** argv) { fprintf(stderr, "%s network hostnumber\n", argv[0]); return 1; } - printf("%s\n", inet_ntoa(host(str2net(argv[1]), atoi(argv[2])))); + struct in_net h = host(str2net(argv[1]), strtoll(argv[2], NULL, 10)); + char b[16]; + strcpy(b, inet_ntoa(h.addr)); + printf("addr: %s mask %s\n", b, inet_ntoa(h.mask)); return 0; } @@ -28,10 +28,11 @@ #define XSTR(x) #x #define STR(x) XSTR(x) #define HELP "find recursive DNS resolvers on IPv4 networks\n" \ - "%s [-a ip] [-b ip] [-d domain] [-h] [-o file] [-p port] [-t μs] [-w μs] net1 [net2 ...]\n" \ + "%s [-a ip] [-b ip] [-d domain] [-eh] [-o file] [-p port] [-t μs] [-w μs] net1 [net2 ...]\n" \ " -a Specify the IPv4 of the -d domain to be used instead of getaddrinfo(3).\n" \ " -b Bind on a specific interface, defined by IPv4. Default is any interface.\n" \ " -d Specify the domain name to be used in queries that has a single A record.\n" \ + " -e Exclude sent packets from -o PCAP output (they're all the same).\n" \ " -h Show this help and exit.\n" \ " -o Output PCAP to filename. Any existing file is truncated. No IP/UDP checksums.\n" \ " -p Set the source port number to use instead of a dynamically asigned one.\n" \ @@ -234,8 +235,6 @@ struct question { uint16_t class __attribute__((packed)); } __attribute__((packed)); int logudp (int o /* fd */, struct sockaddr_in s, struct sockaddr_in d, char * u, size_t l /* d */) { - if (o == -1) - return -1; struct timespec t; if (clock_gettime(CLOCK_REALTIME, &t) == -1) { perror("clock_gettime(CLOCK_REALTIME, &t)"); @@ -361,11 +360,12 @@ int main (int argc, char ** argv) { int j = -1; /* host in network index */ int t = 1000; int w = 1000000; - struct in_addr h; /* host to scan */ + int e = 0; /* whether to exclude sent packets in PCAP - they're all the same */ + struct in_net h; /* host to scan is .addr, h as struct in_net is returned from host() */ signal(SIGINT, handler); signal(SIGTERM, handler); while (1) { - switch (getopt(argc, argv, ":a:b:d:ho:p:t:w:")) { + switch (getopt(argc, argv, ":a:b:d:eho:p:t:w:")) { case 'a': inet_aton(optarg, &a); break; @@ -375,6 +375,9 @@ int main (int argc, char ** argv) { case 'd': d = optarg; break; + case 'e': + e++; + break; case 'h': printf(HELP, argv[0]); r = 0; @@ -459,7 +462,7 @@ o: .tv_sec = 0 }; while (!finish) { - if (!(h = host(n[i], ++j)).s_addr) { + if ((h = host(n[i], ++j)).mask.s_addr != INADDR_BROADCAST) { if (++i >= l) { fprintf(stderr, "finished sending, waiting for last replies\n"); if (clock_gettime(CLOCK_MONOTONIC, &lp) == -1) { @@ -472,12 +475,12 @@ o: else h = host(n[i], (j = 0)); } - struct sockaddr_in e = { - .sin_family = AF_INET, - .sin_port = htons(53), - .sin_addr = h - }; - struct header h = { + struct sockaddr_in m = { /* see, I don't know much about scopes in C and I'm */ + .sin_family = AF_INET, /* intentionally excercising them for the cost of */ + .sin_port = htons(53), /* code unreadability. in this scope I defined h */ + .sin_addr = h.addr /* as struct header, in parent scope it was in_net, */ + }; /* and I used h as in_net in this scope as well, */ + struct header h = { /* but h as header is declared after that use (; */ .xid = 0x6969, /* oh no, cache poisoning, whatever'll I do */ .flags = htons(QUESTION | QUERY | RD), .qdcount = htons(1), @@ -504,13 +507,13 @@ o: c = (char *) memcpy(c, &y, 2) + 2; c = (char *) memcpy(c, &k, 2) + 2; int ž; - if ((ž = logudp(o, b, e, u, L)) < -1) { - fprintf(stderr, "logudp(o, b, e, u, L) == %d\n", ž); + if (!e && o != -1 && (ž = logudp(o, b, m, u, L)) < -1) { + fprintf(stderr, "logudp(o, b, m, u, L) == %d\n", ž); r = 13; goto r; } - if (sendto(s, u, L, 0, (struct sockaddr *) &e, sizeof(struct sockaddr)) == -1) { - perror("sendto(s, u, L, 0, (struct sockaddr *) &e, sizeof(struct sockaddr))"); + if (sendto(s, u, L, 0, (struct sockaddr *) &m, sizeof(struct sockaddr)) == -1) { + perror("sendto(s, u, L, 0, (struct sockaddr *) &m, sizeof(struct sockaddr))"); r = 14; goto r; } @@ -562,17 +565,23 @@ i: } if (lp.tv_sec) lp = z; /* this loop ends nearly in an instant */ - if ((ž = logudp(o, f, b, u, š)) < -1) { + if (o != -1 && (ž = logudp(o, f, b, u, š)) < -1) { fprintf(stderr, "logudp(o, f, b, u, š) == %d\n", ž); return 3; } - fprintf(stderr, "received response from %s\n", inet_ntoa(f.sin_addr)); + fprintf(stderr, "RESPONSE\t%s", inet_ntoa(f.sin_addr)); ž = 0; struct in_addr i = parse_a(u, 65535, d, strlen(d), ž++); - if (i.s_addr == a.s_addr) /* if we go back to multithread, change to write. */ - printf("WORKING %s\n", inet_ntoa(f.sin_addr)); + while (parse_a(u, 65535, d, strlen(d), ž++).s_addr); + if (i.s_addr == a.s_addr) /* if multithread, change printf to write. */ + printf("\tWORKING"); if (i.s_addr && i.s_addr != a.s_addr) - printf("LYING %s WITH %s\n", inet_ntoa(f.sin_addr), inet_ntoa(i)); + printf("\tLYINGWITH\t%s", inet_ntoa(i)); + if (--ž > 1) + printf("\tMORETHANONE\t%d", ž); + if (!i.s_addr) + printf("\tNOA"); + printf("\n"); } if (z.tv_sec) |