📄 gethost.c
字号:
if (addr == INADDR_BROADCAST || /* 255.255.255.255 */
(~ntohl(addr) & ~sin_mask) == 0) /* directed broadcast */
{
ret.h_address = addr;
ret.h_name = "broadcast";
return FillHostEnt (&ret);
}
for (h = host0; h; h = h->h_next)
if (h->h_address == addr)
{
/* if cached entry expired, do a new reverse lookup
*/
if (h->h_timeout && time(NULL) >= h->h_timeout)
break;
return FillHostEnt (h);
}
rc = resolve_ip (addr, name); /* do a reverse ip lookup */
/* interrupted or timedout
*/
if (!rc && (_resolve_exit || _resolve_timeout))
return (NULL);
if (rc) /* successfully resolved */
{
AddHostEnt (h, name, addr, TRUE);
ret.h_address = addr;
ret.h_name = name;
ret.h_aliases = h ? h->h_aliases : NULL;
return FillHostEnt (&ret);
}
/* Add the IP to the list even if reverse lookup failed and not
* interrupted by _resolve_hook(). Thus the next call to gethostbyxx()
* will return immediately.
*/
AddHostEnt (h, "*unknown*", addr, FALSE);
return (NULL);
}
/*------------------------------------------------------------------*/
void sethostent (int stayopen)
{
hostClose = (stayopen == 0);
if (!netdb_init() || !hostFname)
return;
if (!hostFile)
hostFile = fopen (hostFname, "rt");
else rewind (hostFile);
}
/*------------------------------------------------------------------*/
static __inline void free_aliases (const struct _hostent *h)
{
if (h->h_aliases)
{
int i;
for (i = 0; i < MAX_HOST_ALIASES; i++)
if (h->h_aliases[i])
free (h->h_aliases[i]);
free (h->h_aliases);
}
}
/*------------------------------------------------------------------*/
void endhostent (void)
{
struct _hostent *h, *next = NULL;
if (!netdb_init() || !hostFile)
return;
free (hostFname);
fclose (hostFile);
hostFname = NULL;
hostFile = NULL;
for (h = host0; h; h = next)
{
free_aliases (h);
next = h->h_next;
free (h->h_name);
free (h);
}
host0 = NULL;
hostClose = 1;
}
#endif /* USE_BSD_FUNC */
/*------------------------------------------------------------------*/
u_long gethostid (void)
{
if (!netdb_init())
return (INADDR_NONE);
return htonl (my_ip_addr);
}
u_long sethostid (DWORD ip)
{
return (my_ip_addr = ntohl(ip));
}
/*
* Fill in the reverse lookup question packet
*/
static __inline void qinit (question_t *q, DWORD ip)
{
char *c;
BYTE i;
q->h.ident = set_timeout (0); /* Random ID */
q->h.flags = intel16 (DRD); /* recursion desired */
q->h.qdcount = intel16 (1);
q->h.ancount = 0;
q->h.nscount = 0;
q->h.arcount = 0;
c = q->x;
ip = ntohl (ip);
for (i = 0; i < 4; ++i)
{
BYTE x = (BYTE) ip;
ip >>= 8;
*c = (x < 10) ? 1 : (x < 100) ? 2 : 3;
itoa (x,c+1,10);
c += *c + 1;
}
strcpy (c, "\7in-addr\4arpa");
c += 14;
*(short*) c = intel16 (DTYPEPTR);
c += sizeof(short);
*(short*) c = intel16 (DIN);
}
/*
* getresult() - read answer and extract host name
* return 0 on error, 1 on success
*/
static __inline int getresult (sock_type *s, char *name)
{
answer_t a;
struct rrpart *rr;
char *c;
int len = sock_fastread (s, (BYTE*)&a, sizeof(a));
if (len < sizeof(struct dhead) ||
a.h.qdcount != intel16(1) ||
a.h.ancount == 0)
return (0);
/* Skip question */
c = a.x;
while (*c)
++c;
c += 5;
/* Skip name */
while (*c)
{
if ((*c & 0xC0) == 0xC0)
{
c += 2;
break;
}
else
++c;
}
rr = (struct rrpart*) c;
if (rr->rtype != intel16(DTYPEPTR))
return (0);
c = (char*) &rr->rdata;
while (*c)
{
if ((*c & 0xC0) == 0xC0)
c = a.x + (*(int*)c & 0x3FFF);
strncpy (name,c+1,*c);
name += *c;
c += *c + 1;
if (*c)
*name++ = '.';
}
*name = 0;
return (1);
}
/*
* reverse_lookup() - Translate an IP into a host name.
* Returns 1 on success, 0 on error or timeout
*/
static DWORD resolve_timeout = 0UL;
static int reverse_lookup (question_t *q, char *name, DWORD nameserver)
{
int sec, ret;
int ready = 0;
int quit = 0;
udp_Socket dom_sock;
sock_type *s = (sock_type*)&dom_sock;
if (!nameserver || /* no nameserver, give up */
dns_timeout == 0)
return (0);
if (!udp_open(&s->udp, 997, nameserver, 53, NULL))
return (0);
for (sec = 2; sec < dns_timeout-1 && !quit && !_resolve_exit; sec *= 2)
{
sock_write (s, (BYTE*)q, sizeof(*q));
ip_timer_init (&s->udp, sec);
do
{
kbhit();
tcp_tick (s);
if (watcbroke || (_resolve_hook && (*_resolve_hook)() == 0))
{
_resolve_exit = 1;
quit = 1;
ready = 0;
break;
}
if (sock_dataready(s))
{
quit = 1;
ready = 1;
}
if (ip_timer_expired(&s->udp) || chk_timeout(resolve_timeout))
{
ready = 0;
resolve_timeout = 1;
break; /* retry */
}
}
while (!quit);
}
if (ready)
ret = getresult (s, name);
else ret = 0;
sock_close (s);
return (ret);
}
/*
* Do a reverse lookup on `my_ip_addr'. If successfull, replace
* `hostname' and `def_domain' with returned result.
*/
int reverse_lookup_myip (void)
{
char myname [MAX_HOSTLEN];
if (!resolve_ip(htonl(my_ip_addr),myname))
return (0);
if (debug_on >= 1)
{
outs (_LANG("My FQDN: "));
outsnl (myname);
}
if (sethostname(myname,sizeof(myname)) < 0)
return (0);
return (1);
}
/*------------------------------------------------------------------*/
int resolve_ip (DWORD ip, char *result)
{
question_t q;
int i;
WORD oldhndlcbrk;
if (dns_timeout == 0)
dns_timeout = (UINT)sock_delay << 2;
resolve_timeout = set_timeout (1000 * dns_timeout);
oldhndlcbrk = wathndlcbrk;
wathndlcbrk = 1; /* enable special interrupt mode */
watcbroke = 0;
*result = 0;
_resolve_exit = _resolve_timeout = 0;
qinit (&q, ip);
for (i = 0; i < last_nameserver; ++i)
if (reverse_lookup(&q,result,def_nameservers[i]))
break;
watcbroke = 0; /* always clean up */
wathndlcbrk = oldhndlcbrk;
return (*result != 0);
}
/*------------------------------------------------------------------*/
#ifdef TEST_PROG
#include <conio.h>
#include <unistd.h>
#include "pcdbug.h"
#include "sock_ini.h"
/*
* Print list of hosts unsorted.
*/
static void print_hosts (void)
{
struct _hostent *h;
for (h = host0; h; h = h->h_next)
{
int i;
printf ("h->h_address = %-17.17s h->h_name = %s; ",
inet_ntoa(*(struct in_addr*)&h->h_address), h->h_name);
for (i = 0; h->h_aliases && h->h_aliases[i]; i++)
{
if (i == 0)
printf ("Aliases: ");
printf ("%s,", h->h_aliases[i]);
}
puts ("");
}
}
void Sleep (int time)
{
while (time)
{
if (kbhit() && getch() == 27)
{
fputc ('\n', stderr);
return;
}
fprintf (stderr, "%4d\b\b\b\b", time--);
sleep (1);
}
}
int main (void)
{
struct hostent *h;
int wait_time;
char *host_name = "test-address";
dbug_init();
sock_init();
print_hosts();
wait_time = netdbCacheLife + 1;
AddHostEnt (NULL, host_name, inet_aton("11.22.33.44",NULL), TRUE);
h = gethostbyname (host_name);
if (!h)
{
fprintf (stderr, "gethostbyname() failed!. h_errno = %d\n", h_errno);
return (1);
}
fprintf (stderr, "Waiting for cache-entry to timeout..");
Sleep (wait_time);
fprintf (stderr, "gethostbyname() should do a DNS lookup now.\n");
h = gethostbyname (host_name);
if (h)
{
fprintf (stderr, "entry didn't timeout!.\n");
return (1);
}
#if defined(USE_FORTIFY)
Fortify_ListAllMemory();
Fortify_OutputStatistics();
#endif
return (0);
}
#endif /* TEST_PROG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -