[Toybox] [PATCH 1/2] Adding a minimal nslookup frontend to host.c
Moritz C. Weber
mo.c.weber at gmail.com
Tue Jan 3 13:17:08 PST 2023
---
toys/net/host.c | 98 +++++++++++++++++++++++++++++++------------------
1 file changed, 63 insertions(+), 35 deletions(-)
diff --git a/toys/net/host.c b/toys/net/host.c
index 20331678..933f4fb7 100644
--- a/toys/net/host.c
+++ b/toys/net/host.c
@@ -7,6 +7,7 @@
* See https://www.ietf.org/rfc/rfc3596.txt
USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_NSLOOKUP(NEWTOY(nslookup, "<1>2", TOYFLAG_USR|TOYFLAG_BIN))
config HOST
bool "host"
@@ -20,6 +21,14 @@ config HOST
-a All records
-t TYPE Record TYPE (number or ANY A AAAA CNAME MX NS PTR SOA SRV TXT)
-v Verbose
+
+config NSLOOKUP
+ bool "nslookup"
+ default y
+ help
+ usage: nslookup NAME [SERVER]
+
+ Query Internet name servers interactively
*/
#define FOR_host
@@ -70,13 +79,11 @@ static void get_nsname(char **pline, long len)
}
}
-void host_main(void)
+void lookup(int verbose, unsigned *ttl, char* t2, int t2len, int* type, int* rcode)
{
- int verbose = FLAG(a)||FLAG(v), type, abuf_len = 65536, //Largest TCP response
- i, j, sec, rcode, qlen, alen QUIET, pllen = 0, t2len = 2048;
- unsigned count, ttl;
- char *abuf = xmalloc(abuf_len), *name = *toys.optargs, *p, *ss,
- *t2 = toybuf+t2len;
+ int i, j, sec, qlen, alen QUIET, pllen = 0, abuf_len = 65536; //Largest TCP response
+ unsigned count;
+ char *abuf = xmalloc(abuf_len), *name = *toys.optargs, *p, *ss;
struct addrinfo *ai;
// What kind of query are we doing?
@@ -96,26 +103,20 @@ void host_main(void)
} else if (!TT.t) TT.t = "1";
// Prepare query packet of appropriate type
- if (TT.t[0]-'0'<10) type = atoi(TT.t); // TODO
- else if (!strcasecmp(TT.t, "any") || strcmp(TT.t, "*")) type = 255;
+ if (TT.t[0]-'0'<10) *type = atoi(TT.t); // TODO
+ else if (!strcasecmp(TT.t, "any") || strcmp(TT.t, "*")) *type = 255;
else {
for (i = 0; i<ARRAY_LEN(rrt); i++) if (!strcasecmp(TT.t, rrt[i].name)) {
- type = rrt[i].type;
+ *type = rrt[i].type;
break;
}
if (i == ARRAY_LEN(rrt)) error_exit("bad -t: %s", TT.t);
}
- qlen = res_mkquery(0, name, 1, type, 0, 0, 0, t2, 280); //t2len);
+ qlen = res_mkquery(0, name, 1, *type, 0, 0, 0, t2, 280); //t2len);
if (qlen<0) error_exit("bad NAME: %s", name);
- // Grab nameservers
- if (toys.optargs[1]) TT.nsname = toys.optargs+1;
- else do_lines(xopen("/etc/resolv.conf", O_RDONLY), '\n', get_nsname);
- if (!TT.nsname) error_exit("No nameservers");
-
// Send one query packet to each server until we receive response
while (*TT.nsname) {
- if (verbose) printf("Using domain server %s:\n", *TT.nsname);
ai = xgetaddrinfo(*TT.nsname, "53", 0, SOCK_DGRAM, 0, 0);
i = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
xconnect(i, ai->ai_addr, ai->ai_addrlen);
@@ -128,14 +129,14 @@ void host_main(void)
}
// Did it error?
- rcode = abuf[3]&7;
+ *rcode = abuf[3]&7;
if (verbose) {
- printf("rcode = %d, ancount = %d\n", rcode, (int)peek_be(abuf+6, 2));
+ printf("rcode = %d, ancount = %d\n", *rcode, (int)peek_be(abuf+6, 2));
if (!(abuf[2]&4)) puts("The following answer is not authoritative:");
}
- if (rcode) error_exit("Host not found: %s",
+ if (*rcode) error_exit("Host not found: %s",
(char *[]){ "Format error", "Server failure",
- "Non-existant domain", "Not implemented", "Refused", ""}[rcode-1]);
+ "Non-existant domain", "Not implemented", "Refused", ""}[*rcode-1]);
// Print the result
p = abuf + 12;
@@ -148,20 +149,20 @@ void host_main(void)
for (; count--; p += pllen) {
p += xdn_expand(abuf, abuf+alen, p, toybuf, 4096-t2len);
if (alen-(p-abuf)<10) error_exit("tilt");
- type = peek_be(p, 2);
+ *type = peek_be(p, 2);
p += 4;
if (!sec) continue;
- ttl = peek_be(p, 4);
+ *ttl = peek_be(p, 4);
p += 4;
pllen = peek_be(p, 2);
p += 2;
if ((p-abuf)+pllen>alen) error_exit("tilt");
- if (type==1 || type == 28)
- inet_ntop(type==1 ? AF_INET : AF_INET6, p, t2, t2len);
- else if (type==2 || type==5) xdn_expand(abuf, abuf+alen, p, t2, t2len);
- else if (type==16) sprintf(t2, "\"%.*s\"", minof(pllen, t2len), p);
- else if (type==6) {
+ if (*type==1 || *type == 28)
+ inet_ntop(*type==1 ? AF_INET : AF_INET6, p, t2, t2len);
+ else if (*type==2 || *type==5) xdn_expand(abuf, abuf+alen, p, t2, t2len);
+ else if (*type==16) sprintf(t2, "\"%.*s\"", minof(pllen, t2len), p);
+ else if (*type==6) {
ss = p+xdn_expand(abuf, abuf+alen, p, t2, t2len-1);
j = strlen(t2);
t2[j++] = ' ';
@@ -172,25 +173,52 @@ void host_main(void)
"\t\t%u\t;default ttl\n\t\t)", (unsigned)peek_be(ss, 4),
(unsigned)peek_be(ss+4, 4), (unsigned)peek_be(ss+8, 4),
(unsigned)peek_be(ss+12, 4), (unsigned)peek_be(ss+16, 4));
- } else if (type==15) {
+ } else if (*type==15) {
j = peek_be(p, 2);
j = sprintf(t2, verbose ? "%d " : "(pri=%d) by ", j);
xdn_expand(abuf, abuf+alen, p+2, t2+j, t2len-j);
- } else if (type==33) {
+ } else if (*type==33) {
j = sprintf(t2, "%u %u %u ", (int)peek_be(p, 2), (int)peek_be(p+2, 2),
(int)peek_be(p+4, 2));
xdn_expand(abuf, abuf+alen, p+6, t2+j, t2len-j);
} else {
- printf("%s unsupported RR type %u\n", toybuf, type);
+ printf("%s unsupported RR type %u\n", toybuf, *type);
continue;
}
-
- for (i = 0; rrt[i].type != type; i++);
- if (verbose) printf("%s\t%u\tIN %s\t%s\n", toybuf, ttl, rrt[i].name, t2);
- else printf("%s %s %s\n", toybuf, rrt[type].msg, t2);
}
}
-
if (CFG_TOYBOX_FREE) free(abuf);
+}
+
+void host_main(void)
+{
+ int verbose = FLAG(a)||FLAG(v), t2len=2048, type,rcode,i=0;
+ unsigned ttl;
+ char *t2 = toybuf+t2len;
+ // Grab nameservers
+ if (toys.optargs[1]) TT.nsname = toys.optargs+1;
+ else do_lines(xopen("/etc/resolv.conf", O_RDONLY), '\n', get_nsname);
+ if (!TT.nsname) error_exit("No nameservers");
+ if (verbose) printf("Using domain server %s:\n", *TT.nsname);
+ lookup(verbose,&ttl,t2,t2len,&type,&rcode);
+ for (i = 0; rrt[i].type != type; i++);
+ if (verbose) printf("%s\t%u\tIN %s\t%s\n", toybuf, ttl, rrt[i].name, t2);
+ else printf("%s %s %s\n", toybuf, rrt[type].msg, t2);
+ toys.exitval = rcode;
+}
+
+#define FOR_nslookup
+#include "generated/flags.h"
+
+void nslookup_main(void){
+ int t2len=2048, type,rcode;
+ unsigned ttl;
+ char *t2 = toybuf+t2len;
+ if (toys.optargs[1]) TT.nsname = toys.optargs+1;
+ else do_lines(xopen("/etc/resolv.conf", O_RDONLY), '\n', get_nsname);
+ if (!TT.nsname) error_exit("No nameservers");
+ printf("Server:\t %s:\nAddress: %s#53\n\n", *TT.nsname, *TT.nsname);//TODO:Not sure if static port is a good idea here
+ lookup(0,&ttl,t2,t2len,&type,&rcode);
+ printf("Non-authorative answer:\nName: %s\nAddress: %s\n", toybuf, t2);//TODO: Autherative answers
toys.exitval = rcode;
}
--
2.20.1
More information about the Toybox
mailing list