mirror of
https://github.com/yarrick/iodine.git
synced 2025-04-11 04:50:55 +00:00
add support for more query types: A6 AAAA DNAME PTR
This commit is contained in:
parent
dbe9a10fc1
commit
2e6a5876d6
6 changed files with 63 additions and 14 deletions
|
@ -50,9 +50,13 @@ typedef struct {
|
||||||
#define T_A 1
|
#define T_A 1
|
||||||
#define T_CNAME 5
|
#define T_CNAME 5
|
||||||
#define T_NULL 10
|
#define T_NULL 10
|
||||||
|
#define T_PTR 12
|
||||||
#define T_MX 15
|
#define T_MX 15
|
||||||
#define T_TXT 16
|
#define T_TXT 16
|
||||||
|
#define T_AAAA 28
|
||||||
#define T_SRV 33
|
#define T_SRV 33
|
||||||
|
#define T_A6 38
|
||||||
|
#define T_DNAME 39
|
||||||
|
|
||||||
#endif /* !C_IN */
|
#endif /* !C_IN */
|
||||||
|
|
||||||
|
|
33
src/client.c
33
src/client.c
|
@ -78,6 +78,14 @@ client_set_qtype(char *qtype)
|
||||||
this.do_qtype = T_SRV;
|
this.do_qtype = T_SRV;
|
||||||
else if (!strcasecmp(qtype, "TXT"))
|
else if (!strcasecmp(qtype, "TXT"))
|
||||||
this.do_qtype = T_TXT;
|
this.do_qtype = T_TXT;
|
||||||
|
else if (!strcasecmp(qtype, "PTR"))
|
||||||
|
this.do_qtype = T_PTR;
|
||||||
|
else if (!strcasecmp(qtype, "AAAA"))
|
||||||
|
this.do_qtype = T_AAAA;
|
||||||
|
else if (!strcasecmp(qtype, "A6"))
|
||||||
|
this.do_qtype = T_A6;
|
||||||
|
else if (!strcasecmp(qtype, "DNAME"))
|
||||||
|
this.do_qtype = T_DNAME;
|
||||||
return (this.do_qtype == T_UNSET);
|
return (this.do_qtype == T_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +101,10 @@ client_get_qtype()
|
||||||
else if (this.do_qtype == T_MX) c = "MX";
|
else if (this.do_qtype == T_MX) c = "MX";
|
||||||
else if (this.do_qtype == T_SRV) c = "SRV";
|
else if (this.do_qtype == T_SRV) c = "SRV";
|
||||||
else if (this.do_qtype == T_TXT) c = "TXT";
|
else if (this.do_qtype == T_TXT) c = "TXT";
|
||||||
|
else if (this.do_qtype == T_PTR) c = "PTR";
|
||||||
|
else if (this.do_qtype == T_AAAA) c = "AAAA";
|
||||||
|
else if (this.do_qtype == T_A6) c = "A6";
|
||||||
|
else if (this.do_qtype == T_DNAME) c = "DNAME";
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -724,7 +736,8 @@ read_dns_withq(uint8_t *buf, size_t buflen, struct query *q)
|
||||||
if (rv <= 0)
|
if (rv <= 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (q->type == T_CNAME || q->type == T_TXT)
|
if (q->type == T_CNAME || q->type == T_TXT ||
|
||||||
|
q->type == T_PTR || q->type == T_A6 || q->type == T_DNAME)
|
||||||
/* CNAME can also be returned from an A question */
|
/* CNAME can also be returned from an A question */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -2113,13 +2126,17 @@ static int
|
||||||
handshake_qtype_numcvt(int num)
|
handshake_qtype_numcvt(int num)
|
||||||
{
|
{
|
||||||
switch (num) {
|
switch (num) {
|
||||||
case 0: return T_NULL;
|
case 0: return T_NULL;
|
||||||
case 1: return T_PRIVATE;
|
case 1: return T_PRIVATE;
|
||||||
case 2: return T_TXT;
|
case 2: return T_TXT;
|
||||||
case 3: return T_SRV;
|
case 3: return T_SRV;
|
||||||
case 4: return T_MX;
|
case 4: return T_MX;
|
||||||
case 5: return T_CNAME;
|
case 5: return T_DNAME;
|
||||||
case 6: return T_A;
|
case 6: return T_PTR;
|
||||||
|
case 7: return T_CNAME;
|
||||||
|
case 8: return T_A6;
|
||||||
|
case 9: return T_AAAA;
|
||||||
|
case 10: return T_A;
|
||||||
}
|
}
|
||||||
return T_UNSET;
|
return T_UNSET;
|
||||||
}
|
}
|
||||||
|
|
22
src/dns.c
22
src/dns.c
|
@ -90,7 +90,9 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
|
||||||
|
|
||||||
/* Answer section */
|
/* Answer section */
|
||||||
|
|
||||||
if (q->type == T_CNAME || q->type == T_A) {
|
if (q->type == T_CNAME || q->type == T_A ||
|
||||||
|
q->type == T_PTR || q->type == T_AAAA ||
|
||||||
|
q->type == T_A6 || q->type == T_DNAME) {
|
||||||
/* data is expected to be like "Hblabla.host.name.com\0" */
|
/* data is expected to be like "Hblabla.host.name.com\0" */
|
||||||
|
|
||||||
char *startp;
|
char *startp;
|
||||||
|
@ -98,7 +100,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
|
||||||
|
|
||||||
CHECKLEN(10);
|
CHECKLEN(10);
|
||||||
putshort(&p, name);
|
putshort(&p, name);
|
||||||
if (q->type == T_A)
|
if (q->type == T_A || q->type == T_AAAA)
|
||||||
/* answer CNAME to A question */
|
/* answer CNAME to A question */
|
||||||
putshort(&p, T_CNAME);
|
putshort(&p, T_CNAME);
|
||||||
else
|
else
|
||||||
|
@ -108,6 +110,10 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
|
||||||
|
|
||||||
startp = p;
|
startp = p;
|
||||||
p += 2; /* skip 2 bytes length */
|
p += 2; /* skip 2 bytes length */
|
||||||
|
if (q->type == T_A6) {
|
||||||
|
CHECKLEN(1);
|
||||||
|
putbyte(&p, 128);
|
||||||
|
}
|
||||||
putname(&p, buflen - (p - buf), data);
|
putname(&p, buflen - (p - buf), data);
|
||||||
CHECKLEN(0);
|
CHECKLEN(0);
|
||||||
namelen = p - startp;
|
namelen = p - startp;
|
||||||
|
@ -483,7 +489,9 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
|
||||||
rv = 0;
|
rv = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((type == T_A || type == T_CNAME) && buf) {
|
else if ((type == T_A || type == T_CNAME ||
|
||||||
|
type == T_PTR || type == T_AAAA ||
|
||||||
|
type == T_A6 || type == T_DNAME) && buf) {
|
||||||
/* Assume that first answer is what we wanted */
|
/* Assume that first answer is what we wanted */
|
||||||
readname(packet, packetlen, &data, name, sizeof(name));
|
readname(packet, packetlen, &data, name, sizeof(name));
|
||||||
CHECKLEN(10);
|
CHECKLEN(10);
|
||||||
|
@ -492,6 +500,14 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
|
||||||
readlong(packet, &data, &ttl);
|
readlong(packet, &data, &ttl);
|
||||||
readshort(packet, &data, &rlen);
|
readshort(packet, &data, &rlen);
|
||||||
|
|
||||||
|
if (type == T_A6) {
|
||||||
|
unsigned char prefix;
|
||||||
|
CHECKLEN(1);
|
||||||
|
readdata(packet, &data, (char *) &prefix, 1);
|
||||||
|
if (prefix != 128) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
memset(name, 0, sizeof(name));
|
memset(name, 0, sizeof(name));
|
||||||
readname(packet, packetlen, &data, name, sizeof(name) - 1);
|
readname(packet, packetlen, &data, name, sizeof(name) - 1);
|
||||||
name[sizeof(name)-1] = '\0';
|
name[sizeof(name)-1] = '\0';
|
||||||
|
|
|
@ -246,7 +246,8 @@ help()
|
||||||
fprintf(stderr, "iodine IP over DNS tunneling client\n");
|
fprintf(stderr, "iodine IP over DNS tunneling client\n");
|
||||||
print_usage();
|
print_usage();
|
||||||
fprintf(stderr, "\nOptions to try if connection doesn't work:\n");
|
fprintf(stderr, "\nOptions to try if connection doesn't work:\n");
|
||||||
fprintf(stderr, " -T use DNS type: NULL, PRIVATE, TXT, SRV, MX, CNAME, A (default: autodetect)\n");
|
fprintf(stderr, " -T use DNS type: NULL, PRIVATE, TXT, SRV, MX,\n");
|
||||||
|
fprintf(stderr, " DNAME, PTR, CNAME, A6, AAAA, A (default: autodetect)\n");
|
||||||
fprintf(stderr, " -O use specific downstream encoding for queries: Base32, Base64, Base64u,\n");
|
fprintf(stderr, " -O use specific downstream encoding for queries: Base32, Base64, Base64u,\n");
|
||||||
fprintf(stderr, " Base128, or (only for TXT:) Raw (default: autodetect)\n");
|
fprintf(stderr, " Base128, or (only for TXT:) Raw (default: autodetect)\n");
|
||||||
fprintf(stderr, " -I target interval between sending and receiving requests (default: 4 secs)\n");
|
fprintf(stderr, " -I target interval between sending and receiving requests (default: 4 secs)\n");
|
||||||
|
|
11
src/server.c
11
src/server.c
|
@ -738,6 +738,10 @@ tunnel_dns(int dns_fd)
|
||||||
case T_MX:
|
case T_MX:
|
||||||
case T_SRV:
|
case T_SRV:
|
||||||
case T_TXT:
|
case T_TXT:
|
||||||
|
case T_PTR:
|
||||||
|
case T_AAAA:
|
||||||
|
case T_A6:
|
||||||
|
case T_DNAME:
|
||||||
/* encoding is "transparent" here */
|
/* encoding is "transparent" here */
|
||||||
handle_null_request(dns_fd, &q, domain_len);
|
handle_null_request(dns_fd, &q, domain_len);
|
||||||
break;
|
break;
|
||||||
|
@ -1142,7 +1146,8 @@ write_dns(int fd, struct query *q, char *data, size_t datalen, char downenc)
|
||||||
char buf[64*1024];
|
char buf[64*1024];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (q->type == T_CNAME || q->type == T_A) {
|
if (q->type == T_CNAME || q->type == T_A ||
|
||||||
|
q->type == T_PTR || q->type == T_AAAA || q->type == T_A6 || q->type == T_DNAME) {
|
||||||
char cnamebuf[1024]; /* max 255 */
|
char cnamebuf[1024]; /* max 255 */
|
||||||
|
|
||||||
write_dns_nameenc((uint8_t *)cnamebuf, sizeof(cnamebuf), (uint8_t *)data, datalen, downenc);
|
write_dns_nameenc((uint8_t *)cnamebuf, sizeof(cnamebuf), (uint8_t *)data, datalen, downenc);
|
||||||
|
@ -1319,7 +1324,9 @@ handle_dns_downstream_codec_check(int dns_fd, struct query *q, uint8_t *domain,
|
||||||
case 'V':
|
case 'V':
|
||||||
if (q->type == T_TXT ||
|
if (q->type == T_TXT ||
|
||||||
q->type == T_SRV || q->type == T_MX ||
|
q->type == T_SRV || q->type == T_MX ||
|
||||||
q->type == T_CNAME || q->type == T_A) {
|
q->type == T_CNAME || q->type == T_A ||
|
||||||
|
q->type == T_PTR || q->type == T_AAAA ||
|
||||||
|
q->type == T_A6 || q->type == T_DNAME) {
|
||||||
write_dns(dns_fd, q, datap, datalen, codec);
|
write_dns(dns_fd, q, datap, datalen, codec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,10 @@ typedef unsigned int in_addr_t;
|
||||||
#define T_MX DNS_TYPE_MX
|
#define T_MX DNS_TYPE_MX
|
||||||
#define T_TXT DNS_TYPE_TXT
|
#define T_TXT DNS_TYPE_TXT
|
||||||
#define T_SRV DNS_TYPE_SRV
|
#define T_SRV DNS_TYPE_SRV
|
||||||
|
#define T_PTR DNS_TYPE_PTR
|
||||||
|
#define T_AAAA DNS_TYPE_AAAA
|
||||||
|
#define T_A6 DNS_TYPE_A6
|
||||||
|
#define T_DNAME DNS_TYPE_DNAME
|
||||||
|
|
||||||
#define C_IN 1
|
#define C_IN 1
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue