mirror of
git://git.psyced.org/git/psyclpc
synced 2024-08-15 03:20:16 +00:00
193 lines
4.9 KiB
C
193 lines
4.9 KiB
C
/*---------------------------------------------------------------------------
|
|
* XErq - Address Lookup
|
|
* (C) Copyright 1995 by Brian Gerst.
|
|
*---------------------------------------------------------------------------
|
|
* Here are the function to lookup up internet addresses and names.
|
|
* If the first lookup attempt doesn't succeed, a retry is attempted
|
|
* five seconds later.
|
|
*
|
|
* TODO: The functions block the ERQ.
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "defs.h"
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
erq_rlookup(char *mesg, int msglen)
|
|
|
|
/* ERQ_RLOOKUP: look up a hostname by an address.
|
|
*/
|
|
|
|
{
|
|
struct hostent *hp;
|
|
int len;
|
|
char addr[4];
|
|
|
|
if (msglen != 13)
|
|
{
|
|
const char status=ERQ_E_ARGLENGTH;
|
|
reply1(get_handle(mesg), &status, 1);
|
|
return;
|
|
}
|
|
|
|
memcpy(addr, mesg+9, 4);
|
|
|
|
XPRINTF((stderr, "%s rlookup %02x.%02x.%02x.%02x\n"
|
|
, time_stamp(), addr[0], addr[1], addr[2], addr[3]));
|
|
|
|
hp = gethostbyaddr(addr, 4, AF_INET);
|
|
if (!hp && mesg[8] == ERQ_RLOOKUP)
|
|
{
|
|
mesg[8]++; /* No second retry */
|
|
XPRINTF((stderr, "%s Retry in 5 seconds.\n", time_stamp()));
|
|
add_retry(erq_rlookup, mesg, 13, 5);
|
|
return;
|
|
}
|
|
|
|
if (hp)
|
|
{
|
|
XPRINTF((stderr, "%s rlookup found '%s'\n", time_stamp(), hp->h_name));
|
|
len = strlen(hp->h_name)+1;
|
|
}
|
|
else
|
|
{
|
|
XPRINTF((stderr, "%s rlookup failed.\n", time_stamp()));
|
|
len = 0;
|
|
}
|
|
|
|
if (hp)
|
|
replyn(get_handle(mesg), 0, 2,
|
|
mesg+9, 4,
|
|
hp->h_name, len);
|
|
else
|
|
reply1(get_handle(mesg), mesg+9, 4);
|
|
} /* erq_rlookup() */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
erq_lookup(char *mesg, int len)
|
|
|
|
/* ERQ_LOOKUP: look up an address by a hostname.
|
|
*/
|
|
|
|
{
|
|
struct hostent *hp;
|
|
char * msg;
|
|
|
|
msg = mesg;
|
|
if (mesg[len-1] != 0)
|
|
{
|
|
/* Create a local copy of the message in which the string
|
|
* has a proper termination.
|
|
*/
|
|
msg = malloc(len+1);
|
|
if (!msg)
|
|
{
|
|
XPRINTF((stderr, "%s Out of memory.\n", time_stamp()));
|
|
die();
|
|
}
|
|
memcpy(msg, mesg, len);
|
|
msg[len] = 0;
|
|
len++;
|
|
}
|
|
|
|
XPRINTF((stderr, "%s lookup '%s'\n", time_stamp(), msg+9));
|
|
hp = gethostbyname(msg+9);
|
|
if (!hp && msg[8] == ERQ_LOOKUP && h_errno == TRY_AGAIN)
|
|
{
|
|
XPRINTF((stderr, "%s Retry in 5 seconds.\n", time_stamp()));
|
|
mesg[8]++; /* No second retry */
|
|
add_retry(erq_lookup, msg, len, 5);
|
|
if (msg != mesg)
|
|
free(msg);
|
|
return;
|
|
}
|
|
|
|
{
|
|
char r_ok[] = { ERQ_OK };
|
|
char r_notfound[] = { ERQ_E_NOTFOUND };
|
|
char r_noaddr[] = { 0, 0, 0, 0 };
|
|
|
|
if (hp)
|
|
XPRINTF((stderr, "%s lookup found %02x.%02x.%02x.%02x\n"
|
|
, time_stamp(), hp->h_addr[0], hp->h_addr[1]
|
|
, hp->h_addr[2], hp->h_addr[3]));
|
|
else
|
|
XPRINTF((stderr, "%s lookup failed.\n", time_stamp()));
|
|
replyn(get_handle(mesg), 0, 3,
|
|
hp ? r_ok : r_notfound, 1,
|
|
hp ? (char *) hp->h_addr : r_noaddr, 4,
|
|
msg+9, len-9);
|
|
}
|
|
|
|
if (msg != mesg)
|
|
free(msg);
|
|
} /* erq_lookup() */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
#ifdef USE_IPV6
|
|
|
|
void
|
|
erq_rlookupv6(char *mesg, int msglen)
|
|
|
|
/* ERQ_RLOOKUPV6: look up an IPv6 address by a hostname.
|
|
*/
|
|
|
|
{
|
|
int i;
|
|
char *mbuff, *buf;
|
|
size_t buflen;
|
|
struct addrinfo req, *ai, *ai2;
|
|
static char *msg_invalid = "invalid-format";
|
|
static char *msg_nomem = "out-of-memory";
|
|
|
|
buflen = msglen -9 +1;
|
|
buf = malloc(msglen -9 +1);
|
|
if (!buf)
|
|
{
|
|
reply1(get_handle(mesg), msg_nomem, strlen(msg_nomem)+1);
|
|
return;
|
|
}
|
|
|
|
memcpy(buf, mesg+9, msglen-9);
|
|
buf[buflen-1] = '\0';
|
|
|
|
memset(&req, 0, sizeof(struct addrinfo));
|
|
req.ai_family = AF_INET6;
|
|
req.ai_flags = AI_CANONNAME;
|
|
i = getaddrinfo(buf, NULL, &req, &ai);
|
|
if (!i)
|
|
for (ai2 = ai
|
|
; ai2 && (ai2->ai_family != AF_INET)
|
|
&& (ai2->ai_family != AF_INET6)
|
|
; ai2 = ai2->ai_next) NOOP;
|
|
|
|
if (!i && ai2 && ai2->ai_canonname)
|
|
{
|
|
mbuff = malloc(strlen(ai2->ai_canonname)+1+buflen);
|
|
if (!mbuff)
|
|
{
|
|
free(buf);
|
|
reply1(get_handle(mesg), msg_nomem, strlen(msg_nomem)+1);
|
|
return;
|
|
}
|
|
strcpy(mbuff, buf);
|
|
strcat(mbuff, " ");
|
|
strcat(mbuff, ai2->ai_canonname);
|
|
reply1(get_handle(mesg), mbuff, strlen(mbuff)+1);
|
|
free(mbuff);
|
|
}
|
|
else
|
|
reply1(get_handle(mesg), msg_invalid, strlen(msg_invalid)+1);
|
|
|
|
if (!i)
|
|
freeaddrinfo(ai);
|
|
|
|
free(buf);
|
|
} /* erq_rlookupv6() */
|
|
|
|
#endif /* USE_IPV6 */
|
|
|
|
/***************************************************************************/
|
|
|