summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host.c21
-rw-r--r--host_test.c5
-rw-r--r--main.c51
3 files changed, 45 insertions, 32 deletions
diff --git a/host.c b/host.c
index b6e68dd..2087761 100644
--- a/host.c
+++ b/host.c
@@ -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;
}
diff --git a/main.c b/main.c
index 41b18dc..c96bc8e 100644
--- a/main.c
+++ b/main.c
@@ -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)