mirror of https://github.com/M66B/NetGuard.git
Native get name by IP PoC
This commit is contained in:
parent
291c309a70
commit
1d2a6baaa1
|
@ -74,6 +74,8 @@ public class Util {
|
|||
|
||||
private static native String jni_getprop(String name);
|
||||
|
||||
private static native String jni_resolve(String ip);
|
||||
|
||||
static {
|
||||
System.loadLibrary("netguard");
|
||||
}
|
||||
|
@ -370,12 +372,15 @@ public class Util {
|
|||
new AsyncTask<String, Object, String>() {
|
||||
@Override
|
||||
protected String doInBackground(String... args) {
|
||||
return jni_resolve(args[0]);
|
||||
/*
|
||||
try {
|
||||
// This requires internet permission
|
||||
return InetAddress.getByName(args[0]).getHostName();
|
||||
} catch (UnknownHostException ignored) {
|
||||
return args[0];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -793,6 +793,8 @@ int get_qname(const uint8_t *data, const size_t datalen, uint16_t off, char *qna
|
|||
return (c ? off : ptr);
|
||||
}
|
||||
|
||||
static struct dns_entry *dns_entry = NULL;
|
||||
|
||||
void parse_dns_response(const struct arguments *args, const uint8_t *data, const size_t datalen) {
|
||||
if (datalen < sizeof(struct dns_header) + 1) {
|
||||
log_android(ANDROID_LOG_WARN, "DNS response length %d", datalen);
|
||||
|
@ -804,12 +806,16 @@ void parse_dns_response(const struct arguments *args, const uint8_t *data, const
|
|||
const struct dns_header *dns = (struct dns_header *) data;
|
||||
int qcount = ntohs(dns->q_count);
|
||||
int acount = ntohs(dns->ans_count);
|
||||
if (dns->qr == 1 && dns->opcode == 0 && qcount > 0) {
|
||||
if (dns->qr == 1 && dns->opcode == 0 && qcount > 0 && acount > 0) {
|
||||
log_android(ANDROID_LOG_WARN, "DNS response qcount %d acount %d", qcount, acount);
|
||||
|
||||
// http://tools.ietf.org/html/rfc1035
|
||||
char qname[DNS_QNAME_MAX + 1];
|
||||
|
||||
struct dns_entry *entry = malloc(sizeof(struct dns_entry));
|
||||
entry->acount = 0;
|
||||
entry->answer = NULL;
|
||||
|
||||
char qname[DNS_QNAME_MAX + 1];
|
||||
uint16_t off = sizeof(struct dns_header);
|
||||
for (int q = 0; q < qcount; q++) {
|
||||
off = get_qname(data, datalen, off, qname);
|
||||
|
@ -820,6 +826,11 @@ void parse_dns_response(const struct arguments *args, const uint8_t *data, const
|
|||
"DNS question %d qtype %d qclass %d qname %s",
|
||||
q, qtype, qclass, qname);
|
||||
off += 4;
|
||||
|
||||
// TODO multiple qnames?
|
||||
if (q == 0)
|
||||
entry->qname = malloc(strlen(qname) + 1);
|
||||
strcpy(entry->qname, qname);
|
||||
}
|
||||
else {
|
||||
log_android(ANDROID_LOG_ERROR,
|
||||
|
@ -839,23 +850,35 @@ void parse_dns_response(const struct arguments *args, const uint8_t *data, const
|
|||
off += 10;
|
||||
|
||||
if (off + rdlength <= datalen) {
|
||||
char addr[INET6_ADDRSTRLEN + 1];
|
||||
if (qclass == DNS_QCLASS_IN && qtype == DNS_QTYPE_A) {
|
||||
inet_ntop(AF_INET, data + off, addr, sizeof(addr));
|
||||
if (qclass == DNS_QCLASS_IN &&
|
||||
(qtype == DNS_QTYPE_A ||
|
||||
qtype == DNS_QTYPE_AAAA ||
|
||||
qtype == DNS_QTYPE_CNAME)) {
|
||||
|
||||
char rd[INET6_ADDRSTRLEN + 1];
|
||||
if (qtype == DNS_QTYPE_A)
|
||||
inet_ntop(AF_INET, data + off, rd, sizeof(rd));
|
||||
else if (qclass == DNS_QCLASS_IN && qtype == DNS_QTYPE_AAAA)
|
||||
inet_ntop(AF_INET6, data + off, rd, sizeof(rd));
|
||||
else if (qclass == DNS_QCLASS_IN && qtype == DNS_QTYPE_CNAME) {
|
||||
if (get_qname(data, datalen, off, rd) < 0)
|
||||
log_android(ANDROID_LOG_WARN, "DNS cname error");
|
||||
}
|
||||
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"DNS answer %d qname %s qtype %d ttl %d addr %s",
|
||||
a, qname, qtype, ttl, addr);
|
||||
} else if (qclass == DNS_QCLASS_IN && qtype == DNS_QTYPE_AAAA) {
|
||||
inet_ntop(AF_INET6, data + off, addr, sizeof(addr));
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"DNS answer %d qname %s qtype %d ttl %d addr %s",
|
||||
a, qname, qtype, ttl, addr);
|
||||
} else if (qclass == DNS_QCLASS_IN && qtype == DNS_QTYPE_CNAME) {
|
||||
char cname[DNS_QNAME_MAX + 1];
|
||||
get_qname(data, datalen, off, cname);
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"DNS answer %d qname %s qtype %d ttl %d cname %s",
|
||||
a, qname, qtype, ttl, cname);
|
||||
"DNS answer %d qname %s qtype %d ttl %d data %s",
|
||||
a, qname, qtype, ttl, rd);
|
||||
|
||||
entry->answer = realloc(entry->answer,
|
||||
sizeof(struct dns_answer *) * (entry->acount + 1));
|
||||
entry->answer[entry->acount] = malloc(sizeof(struct dns_answer));
|
||||
entry->answer[entry->acount]->time = time(NULL);
|
||||
entry->answer[entry->acount]->ttl = ttl;
|
||||
entry->answer[entry->acount]->qtype = qtype;
|
||||
entry->answer[entry->acount]->rd = malloc(strlen(rd) + 1);
|
||||
strcpy(entry->answer[entry->acount]->rd, rd);
|
||||
entry->acount++;
|
||||
|
||||
} else
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"DNS answer %d qname %s qclass %d qtype %d ttl %d length %d",
|
||||
|
@ -878,6 +901,14 @@ void parse_dns_response(const struct arguments *args, const uint8_t *data, const
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->acount > 0) {
|
||||
// TODO cleanup old entries
|
||||
entry->next = dns_entry;
|
||||
dns_entry = entry;
|
||||
}
|
||||
else
|
||||
free(entry);
|
||||
}
|
||||
else
|
||||
log_android(ANDROID_LOG_INFO,
|
||||
|
@ -885,6 +916,36 @@ void parse_dns_response(const struct arguments *args, const uint8_t *data, const
|
|||
dns->qr, dns->opcode, qcount, acount);
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_eu_faircode_netguard_Util_jni_1resolve(JNIEnv *env, jclass type, jstring ip_) {
|
||||
const char *ip = (*env)->GetStringUTFChars(env, ip_, 0);
|
||||
|
||||
if (pthread_mutex_lock(&lock))
|
||||
log_android(ANDROID_LOG_ERROR, "pthread_mutex_lock failed");
|
||||
|
||||
char *result = NULL;
|
||||
struct dns_entry *entry = dns_entry;
|
||||
while (entry != NULL) {
|
||||
for (int a = 0; a < entry->acount; a++)
|
||||
// TODO check ttl
|
||||
if (entry->answer[a]->qtype == DNS_QTYPE_CNAME) {
|
||||
// TODO cname recursion
|
||||
}
|
||||
else if (!strcmp(entry->answer[a]->rd, ip)) {
|
||||
result = entry->qname;
|
||||
break;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&lock))
|
||||
log_android(ANDROID_LOG_ERROR, "pthread_mutex_unlock failed");
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, ip_, ip);
|
||||
|
||||
return (result == NULL ? NULL : (*env)->NewStringUTF(env, result));
|
||||
}
|
||||
|
||||
void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
|
||||
struct tcp_session *cur = tcp_session;
|
||||
while (cur != NULL) {
|
||||
|
|
|
@ -169,6 +169,21 @@ typedef struct dns_rr {
|
|||
__be16 rdlength;
|
||||
} __packed;
|
||||
|
||||
typedef struct dns_answer {
|
||||
int time;
|
||||
int ttl;
|
||||
char *qname;
|
||||
int qtype;
|
||||
char *rd;
|
||||
};
|
||||
|
||||
typedef struct dns_entry {
|
||||
char *qname;
|
||||
int acount;
|
||||
struct dns_answer **answer;
|
||||
struct dns_entry *next;
|
||||
};
|
||||
|
||||
// DHCP
|
||||
|
||||
#define DHCP_OPTION_MAGIC_NUMBER (0x63825363)
|
||||
|
|
Loading…
Reference in New Issue