mirror of
https://github.com/rofl0r/proxychains-ng
synced 2025-01-21 15:42:58 +08:00
Compare commits
7 Commits
acf2f4725d
...
2ab631918d
Author | SHA1 | Date | |
---|---|---|---|
|
2ab631918d | ||
|
3e791fd797 | ||
|
3a5050bec2 | ||
|
3dfda493d8 | ||
|
ed8f8444ab | ||
|
12e5da1b90 | ||
|
121c582d9c |
@ -20,6 +20,7 @@
|
||||
#include "ip_type.h"
|
||||
#include "mutex.h"
|
||||
#include "hash.h"
|
||||
#include "remotedns.h"
|
||||
|
||||
/* stuff for our internal translation table */
|
||||
|
||||
@ -117,7 +118,7 @@ static ip_type4 ip_from_internal_list(char* name, size_t len) {
|
||||
internal_ips->list[internal_ips->counter] = new_mem;
|
||||
internal_ips->list[internal_ips->counter]->hash = hash;
|
||||
|
||||
new_mem = dumpstring((char*) name, len + 1);
|
||||
new_mem = dumpstring((char*) name, len);
|
||||
|
||||
if(!new_mem) {
|
||||
internal_ips->list[internal_ips->counter] = 0;
|
||||
@ -138,23 +139,12 @@ static ip_type4 ip_from_internal_list(char* name, size_t len) {
|
||||
|
||||
/* stuff for communication with the allocator thread */
|
||||
|
||||
enum at_msgtype {
|
||||
ATM_GETIP,
|
||||
ATM_GETNAME,
|
||||
ATM_EXIT,
|
||||
};
|
||||
|
||||
enum at_direction {
|
||||
ATD_SERVER = 0,
|
||||
ATD_CLIENT,
|
||||
ATD_MAX,
|
||||
};
|
||||
|
||||
struct at_msghdr {
|
||||
enum at_msgtype msgtype;
|
||||
size_t datalen;
|
||||
};
|
||||
|
||||
static pthread_t allocator_thread;
|
||||
int req_pipefd[2];
|
||||
int resp_pipefd[2];
|
||||
@ -198,13 +188,11 @@ again:
|
||||
}
|
||||
}
|
||||
|
||||
static int sendmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
|
||||
static int sendmessage(enum at_direction dir, struct at_msg *msg) {
|
||||
static int* destfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[1], [ATD_CLIENT] = &resp_pipefd[1] };
|
||||
int ret = trywrite(*destfd[dir], hdr, sizeof *hdr);
|
||||
if(ret && hdr->datalen) {
|
||||
assert(hdr->datalen <= MSG_LEN_MAX);
|
||||
ret = trywrite(*destfd[dir], data, hdr->datalen);
|
||||
}
|
||||
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||
int ret = trywrite(*destfd[dir], msg, sizeof (msg->h)+msg->h.datalen);
|
||||
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -225,17 +213,19 @@ again:
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
static int readmsg(int fd, struct at_msg *msg) {
|
||||
int ret = tryread(fd, msg, sizeof(msg->h));
|
||||
if(ret != 1) return ret;
|
||||
return tryread(fd, &msg->m, msg->h.datalen);
|
||||
}
|
||||
|
||||
static int getmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
|
||||
static int getmessage(enum at_direction dir, struct at_msg *msg) {
|
||||
static int* readfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[0], [ATD_CLIENT] = &resp_pipefd[0] };
|
||||
ssize_t ret;
|
||||
if((ret = wait_data(*readfd[dir]))) {
|
||||
if(!tryread(*readfd[dir], hdr, sizeof *hdr))
|
||||
if(!readmsg(*readfd[dir], msg))
|
||||
return 0;
|
||||
assert(hdr->datalen <= MSG_LEN_MAX);
|
||||
if(hdr->datalen) {
|
||||
ret = tryread(*readfd[dir], data, hdr->datalen);
|
||||
}
|
||||
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -243,26 +233,24 @@ static int getmessage(enum at_direction dir, struct at_msghdr *hdr, void* data)
|
||||
static void* threadfunc(void* x) {
|
||||
(void) x;
|
||||
int ret;
|
||||
struct at_msghdr msg;
|
||||
union {
|
||||
char host[MSG_LEN_MAX];
|
||||
ip_type4 ip;
|
||||
} readbuf;
|
||||
while((ret = getmessage(ATD_SERVER, &msg, &readbuf))) {
|
||||
switch(msg.msgtype) {
|
||||
struct at_msg msg;
|
||||
while((ret = getmessage(ATD_SERVER, &msg))) {
|
||||
switch(msg.h.msgtype) {
|
||||
case ATM_GETIP:
|
||||
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
|
||||
* if not, create a new one. */
|
||||
readbuf.ip = ip_from_internal_list(readbuf.host, msg.datalen - 1);
|
||||
msg.datalen = sizeof(ip_type4);
|
||||
msg.m.ip = ip_from_internal_list(msg.m.host, msg.h.datalen);
|
||||
msg.h.datalen = sizeof(ip_type4);
|
||||
break;
|
||||
case ATM_GETNAME: {
|
||||
char *host = string_from_internal_ip(readbuf.ip);
|
||||
char *host = string_from_internal_ip(msg.m.ip);
|
||||
if(host) {
|
||||
size_t l = strlen(host);
|
||||
assert(l < MSG_LEN_MAX);
|
||||
memcpy(readbuf.host, host, l + 1);
|
||||
msg.datalen = l + 1;
|
||||
assert(l+1 < MSG_LEN_MAX);
|
||||
memcpy(msg.m.host, host, l + 1);
|
||||
msg.h.datalen = l + 1;
|
||||
} else {
|
||||
msg.h.datalen = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -271,7 +259,7 @@ static void* threadfunc(void* x) {
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
ret = sendmessage(ATD_CLIENT, &msg, &readbuf);
|
||||
ret = sendmessage(ATD_CLIENT, &msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -282,27 +270,31 @@ ip_type4 at_get_ip_for_host(char* host, size_t len) {
|
||||
ip_type4 readbuf;
|
||||
MUTEX_LOCK(internal_ips_lock);
|
||||
if(len > MSG_LEN_MAX) goto inv;
|
||||
struct at_msghdr msg = {.msgtype = ATM_GETIP, .datalen = len + 1 };
|
||||
if(sendmessage(ATD_SERVER, &msg, host) &&
|
||||
getmessage(ATD_CLIENT, &msg, &readbuf));
|
||||
struct at_msg msg = {.h.msgtype = ATM_GETIP, .h.datalen = len + 1 };
|
||||
memcpy(msg.m.host, host, len+1);
|
||||
if(sendmessage(ATD_SERVER, &msg) &&
|
||||
getmessage(ATD_CLIENT, &msg)) readbuf = msg.m.ip;
|
||||
else {
|
||||
inv:
|
||||
readbuf = ip_type_invalid.addr.v4;
|
||||
}
|
||||
assert(msg.msgtype == ATM_GETIP);
|
||||
assert(msg.h.msgtype == ATM_GETIP);
|
||||
MUTEX_UNLOCK(internal_ips_lock);
|
||||
return readbuf;
|
||||
}
|
||||
|
||||
size_t at_get_host_for_ip(ip_type4 ip, char* readbuf) {
|
||||
struct at_msghdr msg = {.msgtype = ATM_GETNAME, .datalen = sizeof(ip_type4) };
|
||||
struct at_msg msg = {.h.msgtype = ATM_GETNAME, .h.datalen = sizeof(ip_type4), .m.ip = ip };
|
||||
size_t res = 0;
|
||||
MUTEX_LOCK(internal_ips_lock);
|
||||
if(sendmessage(ATD_SERVER, &msg, &ip) && getmessage(ATD_CLIENT, &msg, readbuf)) {
|
||||
if((ptrdiff_t) msg.datalen <= 0) res = 0;
|
||||
else res = msg.datalen - 1;
|
||||
if(sendmessage(ATD_SERVER, &msg) && getmessage(ATD_CLIENT, &msg)) {
|
||||
if((int16_t) msg.h.datalen <= 0) res = 0;
|
||||
else {
|
||||
memcpy(readbuf, msg.m.host, msg.h.datalen);
|
||||
res = msg.h.datalen - 1;
|
||||
}
|
||||
}
|
||||
assert(msg.msgtype == ATM_GETNAME);
|
||||
assert(msg.h.msgtype == ATM_GETNAME);
|
||||
MUTEX_UNLOCK(internal_ips_lock);
|
||||
return res;
|
||||
}
|
||||
|
91
src/core.c
91
src/core.c
@ -43,6 +43,7 @@
|
||||
extern int tcp_read_time_out;
|
||||
extern int tcp_connect_time_out;
|
||||
extern int proxychains_quiet_mode;
|
||||
extern int proxychains_resolver;
|
||||
extern unsigned int proxychains_proxy_offset;
|
||||
extern unsigned int remote_dns_subnet;
|
||||
|
||||
@ -199,7 +200,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
||||
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
||||
// the results returned from gethostbyname et al.)
|
||||
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
|
||||
if(!ip.is_v6 && ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||
if(!ip.is_v6 && proxychains_resolver && ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||
dns_len = at_get_host_for_ip(ip.addr.v4, hostnamebuf);
|
||||
if(!dns_len) goto err;
|
||||
else dns_name = hostnamebuf;
|
||||
@ -524,7 +525,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
|
||||
PFUNC();
|
||||
|
||||
if(!v6 && pto->ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||
if(!v6 && proxychains_resolver && pto->ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||
if(!at_get_host_for_ip(pto->ip.addr.v4, hostname_buf)) goto usenumericip;
|
||||
else hostname = hostname_buf;
|
||||
} else {
|
||||
@ -744,6 +745,86 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char*
|
||||
}
|
||||
|
||||
extern ip_type4 hostsreader_get_numeric_ip_for_name(const char* name);
|
||||
struct hostent* proxy_gethostbyname_old(const char *name)
|
||||
{
|
||||
static struct hostent hostent_space;
|
||||
static in_addr_t resolved_addr;
|
||||
static char* resolved_addr_p;
|
||||
static char addr_name[1024*8];
|
||||
|
||||
int pipe_fd[2];
|
||||
char buff[256];
|
||||
in_addr_t addr;
|
||||
pid_t pid;
|
||||
int status;
|
||||
size_t l;
|
||||
struct hostent* hp;
|
||||
|
||||
hostent_space.h_addr_list = &resolved_addr_p;
|
||||
*hostent_space.h_addr_list = (char*)&resolved_addr;
|
||||
resolved_addr = 0;
|
||||
|
||||
gethostname(buff,sizeof(buff));
|
||||
if(!strcmp(buff,name))
|
||||
goto got_buff;
|
||||
|
||||
memset(buff, 0, sizeof(buff));
|
||||
|
||||
// TODO: this works only once, so cache it ...
|
||||
// later
|
||||
while ((hp=gethostent()))
|
||||
if (!strcmp(hp->h_name,name))
|
||||
return hp;
|
||||
|
||||
if(pipe(pipe_fd))
|
||||
goto err;
|
||||
pid = fork();
|
||||
switch(pid) {
|
||||
|
||||
case 0: // child
|
||||
proxychains_write_log("|DNS-request| %s \n", name);
|
||||
close(pipe_fd[0]);
|
||||
dup2(pipe_fd[1],1);
|
||||
close(pipe_fd[1]);
|
||||
|
||||
// putenv("LD_PRELOAD=");
|
||||
execlp("proxyresolv","proxyresolv",name,NULL);
|
||||
perror("can't exec proxyresolv");
|
||||
exit(2);
|
||||
|
||||
case -1: //error
|
||||
close(pipe_fd[0]);
|
||||
close(pipe_fd[1]);
|
||||
perror("can't fork");
|
||||
goto err;
|
||||
|
||||
default:
|
||||
close(pipe_fd[1]);
|
||||
waitpid(pid, &status, 0);
|
||||
buff[0] = 0;
|
||||
read(pipe_fd[0],&buff,sizeof(buff));
|
||||
close(pipe_fd[0]);
|
||||
got_buff:
|
||||
l = strlen(buff);
|
||||
if(l && buff[l-1] == '\n') buff[l-1] = 0;
|
||||
addr = inet_addr(buff);
|
||||
if (addr == (in_addr_t) (-1))
|
||||
goto err_dns;
|
||||
memcpy(*(hostent_space.h_addr_list),
|
||||
&addr ,sizeof(struct in_addr));
|
||||
hostent_space.h_name = addr_name;
|
||||
hostent_space.h_length = sizeof (in_addr_t);
|
||||
}
|
||||
proxychains_write_log("|DNS-response| %s is %s\n",
|
||||
name, inet_ntoa(*(struct in_addr*)&addr));
|
||||
return &hostent_space;
|
||||
err_dns:
|
||||
proxychains_write_log("|DNS-response|: %s does not exist\n", name);
|
||||
perror("err_dns");
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
|
||||
PFUNC();
|
||||
char buff[256];
|
||||
@ -871,7 +952,11 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
|
||||
free(space);
|
||||
return EAI_NONAME;
|
||||
}
|
||||
hp = proxy_gethostbyname(node, &ghdata);
|
||||
if(proxychains_resolver == 2)
|
||||
hp = proxy_gethostbyname_old(node);
|
||||
else
|
||||
hp = proxy_gethostbyname(node, &ghdata);
|
||||
|
||||
if(hp)
|
||||
memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr,
|
||||
*(hp->h_addr_list), sizeof(in_addr_t));
|
||||
|
@ -121,6 +121,7 @@ struct gethostbyname_data {
|
||||
};
|
||||
|
||||
struct hostent* proxy_gethostbyname(const char *name, struct gethostbyname_data *data);
|
||||
struct hostent* proxy_gethostbyname_old(const char *name);
|
||||
|
||||
int proxy_getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
|
@ -5,7 +5,7 @@
|
||||
# include "debug.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count) {
|
||||
void dump_proxy_chain(proxy_data *pchain, unsigned int count) {
|
||||
char ip_buf[INET6_ADDRSTRLEN];
|
||||
for (; count; pchain++, count--) {
|
||||
if(!inet_ntop(pchain->ip.is_v6?AF_INET6:AF_INET,pchain->ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
||||
|
12
src/debug.h
12
src/debug.h
@ -1,15 +1,13 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# define PSTDERR(fmt, args...) do { dprintf(2,fmt, ## args); } while(0)
|
||||
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
|
||||
# define DEBUGDECL(args...) args
|
||||
|
||||
# include "core.h"
|
||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
|
||||
|
||||
# define DUMP_PROXY_CHAIN(A, B) dump_proxy_chain(A, B)
|
||||
#else
|
||||
# define PDEBUG(fmt, args...) do {} while (0)
|
||||
# define DEBUGDECL(args...)
|
||||
@ -18,5 +16,9 @@ void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
|
||||
|
||||
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
|
||||
|
||||
#include "core.h"
|
||||
void dump_proxy_chain(proxy_data *pchain, unsigned int count);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -116,19 +116,24 @@ static void setup_hooks(void) {
|
||||
SETUP_SYM(freeaddrinfo);
|
||||
SETUP_SYM(gethostbyaddr);
|
||||
SETUP_SYM(getnameinfo);
|
||||
SETUP_SYM(close);
|
||||
#ifdef IS_SOLARIS
|
||||
SETUP_SYM(__xnet_connect);
|
||||
#endif
|
||||
SETUP_SYM(close);
|
||||
}
|
||||
|
||||
static int close_fds[16];
|
||||
static int close_fds_cnt = 0;
|
||||
|
||||
static void rdns_init(void) {
|
||||
static int init_done = 0;
|
||||
if(!init_done) at_init();
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
static void do_init(void) {
|
||||
srand(time(NULL));
|
||||
core_initialize();
|
||||
at_init();
|
||||
|
||||
/* read the config file */
|
||||
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
||||
@ -139,8 +144,9 @@ static void do_init(void) {
|
||||
setup_hooks();
|
||||
|
||||
while(close_fds_cnt) true_close(close_fds[--close_fds_cnt]);
|
||||
|
||||
init_l = 1;
|
||||
|
||||
if(proxychains_resolver == 1) rdns_init();
|
||||
}
|
||||
|
||||
static void init_lib_wrapper(const char* caller) {
|
||||
@ -278,6 +284,8 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
||||
if(proxychains_got_chain_data)
|
||||
return;
|
||||
|
||||
PFUNC();
|
||||
|
||||
//Some defaults
|
||||
tcp_read_time_out = 4 * 1000;
|
||||
tcp_connect_time_out = 10 * 1000;
|
||||
@ -320,8 +328,9 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
||||
pd[count].port = htons((unsigned short) port_n);
|
||||
ip_type* host_ip = &pd[count].ip;
|
||||
if(1 != inet_pton(host_ip->is_v6 ? AF_INET6 : AF_INET, host, host_ip->addr.v6)) {
|
||||
if(*ct == STRICT_TYPE && proxychains_resolver && count > 0) {
|
||||
if(*ct == STRICT_TYPE && proxychains_resolver == 1 && count > 0) {
|
||||
/* we can allow dns hostnames for all but the first proxy in the list if chaintype is strict, as remote lookup can be done */
|
||||
rdns_init();
|
||||
ip_type4 internal_ip = at_get_ip_for_host(host, strlen(host));
|
||||
pd[count].ip.is_v6 = 0;
|
||||
host_ip->addr.v4 = internal_ip;
|
||||
@ -422,6 +431,8 @@ inv_host:
|
||||
proxychains_max_chain = (len ? len : 1);
|
||||
} else if(strstr(buff, "quiet_mode")) {
|
||||
proxychains_quiet_mode = 1;
|
||||
} else if(strstr(buff, "proxy_dns_old")) {
|
||||
proxychains_resolver = 2;
|
||||
} else if(strstr(buff, "proxy_dns")) {
|
||||
proxychains_resolver = 1;
|
||||
} else if(strstr(buff, "dnat")) {
|
||||
@ -486,7 +497,7 @@ inv_host:
|
||||
}
|
||||
*proxy_count = count;
|
||||
proxychains_got_chain_data = 1;
|
||||
PDEBUG("proxy_dns: %s\n", proxychains_resolver ? "ON" : "OFF");
|
||||
PDEBUG("proxy_dns: %s\n", proxychains_resolver ? (proxychains_resolver == 2 ? "OLD" : "ON") : "OFF");
|
||||
}
|
||||
|
||||
/******* HOOK FUNCTIONS *******/
|
||||
@ -498,6 +509,8 @@ int close(int fd) {
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
if(proxychains_resolver != 1) return true_close(fd);
|
||||
|
||||
/* prevent rude programs (like ssh) from closing our pipes */
|
||||
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
|
||||
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
|
||||
@ -611,8 +624,10 @@ struct hostent *gethostbyname(const char *name) {
|
||||
INIT();
|
||||
PDEBUG("gethostbyname: %s\n", name);
|
||||
|
||||
if(proxychains_resolver)
|
||||
if(proxychains_resolver == 1)
|
||||
return proxy_gethostbyname(name, &ghbndata);
|
||||
else if(proxychains_resolver == 2)
|
||||
return proxy_gethostbyname_old(name);
|
||||
else
|
||||
return true_gethostbyname(name);
|
||||
|
||||
|
@ -49,7 +49,15 @@ strict_chain
|
||||
#quiet_mode
|
||||
|
||||
# Proxy DNS requests - no leak for DNS data
|
||||
proxy_dns
|
||||
# this uses the proxychains4 style method to do remote dns
|
||||
proxy_dns
|
||||
|
||||
# use the old proxyresolv script to proxy DNS requests
|
||||
# in proxychains 3.1 style. requires proxyresolv in $PATH
|
||||
# plus a dynamically linked `dig` binary.
|
||||
# this is a lot slower than `proxy_dns`, doesn't support .onion URLs,
|
||||
# but might be more compatible with complex software like webbrowsers.
|
||||
#proxy_dns_old
|
||||
|
||||
# set the class A subnet number to use for the internal remote DNS mapping
|
||||
# we use the reserved 224.x.x.x range by default,
|
||||
|
@ -1,10 +1,8 @@
|
||||
#!/bin/sh
|
||||
# This is a legacy script that uses "dig" to do DNS lookups via TCP.
|
||||
# it is not actively maintained since proxychains no longer depends
|
||||
# on it. i leave it here as a bonus.
|
||||
# This is a legacy script that uses "dig" or "drill" to do DNS lookups via TCP.
|
||||
|
||||
# DNS server used to resolve names
|
||||
DNS_SERVER=8.8.8.8
|
||||
test -z "$DNS_SERVER" && DNS_SERVER=8.8.8.8
|
||||
|
||||
|
||||
if [ $# = 0 ] ; then
|
||||
@ -14,5 +12,12 @@ if [ $# = 0 ] ; then
|
||||
fi
|
||||
|
||||
|
||||
export LD_PRELOAD=libproxychains4.so
|
||||
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
||||
test -z $LD_PRELOAD && export LD_PRELOAD=libproxychains4.so
|
||||
|
||||
if type dig 1>/dev/null 2>&1 ; then
|
||||
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
||||
elif type drill 1>/dev/null 2>&1 ; then
|
||||
drill -t4 $1 @$DNS_SERVER | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
||||
else
|
||||
echo "error: neither dig nor drill found" >&2
|
||||
fi
|
||||
|
29
src/remotedns.h
Normal file
29
src/remotedns.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef REMOTEDNS_H
|
||||
#define REMOTEDNS_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "ip_type.h"
|
||||
|
||||
enum at_msgtype {
|
||||
ATM_GETIP = 0,
|
||||
ATM_GETNAME,
|
||||
ATM_FAIL,
|
||||
ATM_EXIT,
|
||||
};
|
||||
|
||||
struct at_msghdr {
|
||||
unsigned char msgtype; /* at_msgtype */
|
||||
char reserved;
|
||||
unsigned short datalen;
|
||||
};
|
||||
|
||||
struct at_msg {
|
||||
struct at_msghdr h;
|
||||
union {
|
||||
char host[260];
|
||||
ip_type4 ip;
|
||||
} m;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user