📄 win32_resolv.c
字号:
if (poll(&sockPollFd, 1, 7000) <= 0) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// OK, check we have got some data
if (sockPollFd.revents != POLLIN) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// read it
if ((count = recv(sockFd,
recvPktBuf,
recvPktSize,
0)) < 0) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// check packet is big enough
header = (HEADER*) (recvPktBuf + 2);
if (count < sizeof(HEADER)) {
// packet too small. try next server
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// incorrect ID => old response. start listening again
if (ntohs(header->id) != ((*expectedId) - 1)) {
continue;
}
// packet truncated. try next server
if (header->tc) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// not a response. try next server
if (!header->qr) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// unknown host. exit lookup
if (header->rcode == RCODE_NAMEERROR) {
close(sockFd);
return RESP_UNKNOWNHOST;
}
// error. try next server
if (header->rcode != RCODE_OK) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// There were no actual records! try next server
if (header->ancount == 0) {
close(sockFd);
return RESP_TRYNEXTSERVER;
}
// If we get here, we are OK. Terminate the loop
break;
}
// need to copy the packet BACK two bytes,
// since it has the size of it prepended
memcpy(recvPktBuf, recvPktBuf+2, count-2);
// OK! return the count
close(sockFd);
return count - 2;
}
/**
* Query domain
*
* @param name Name of service to query for
* @param domain Name of domain service is in
* @param class Class of query
* @param type Type of record to retrieve
* @param dstBuffer Space to put received packet
* @param dstLength Size of received packet buffer
* @return Size of packet received, or < 0 on failure
*/
int res_querydomain(const char *name,
const char *domain,
int class, int type,
u_char *dstBuffer,
int dstLength) {
struct in_addr* dnsServers;
int pktSize;
// find the list of DNS servers on this machine
if (getDnsServers(&dnsServers)) {
return -1;
}
// do the lookup
pktSize =
dnsLookup(name, domain, class, type,
dnsServers, dstBuffer, dstLength);
free(dnsServers);
// Finally return the value
return(pktSize);
}
// -----------------------------------------------------------
// Everything below this line is taken from bind v8.2.3
// See copyright notices above
/*
* Expand compressed domain name 'comp_dn' to full domain name.
* 'msg' is a pointer to the begining of the message,
* 'eomorig' points to the first location after the message,
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
* Return size of compressed name or -1 if there was an error.
*/
int
dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
char *dst, int dstsiz)
{
int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
if (n > 0 && dst[0] == '.')
dst[0] = '\0';
return (n);
}
/*
* ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
* Number of bytes written to buffer, or -1 (with errno set)
* notes:
* The root is returned as "."
* All other domains are returned in non absolute form
*/
int
ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
const u_char *cp;
char *dn, *eom;
u_char c;
u_int n;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) != 0) {
/* Some kind of compression pointer. */
errno = EMSGSIZE;
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
for ((void)NULL; n > 0; n--) {
c = *cp++;
if (special(c)) {
if (dn + 1 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable(c)) {
if (dn + 3 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
/*
* ns_name_uncompress(msg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
* Number of bytes read out of `src', or -1 (with errno set).
* note:
* Root domain returns as "." not "".
*/
int
ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
char *dst, size_t dstsiz)
{
u_char tmp[NS_MAXCDNAME];
int n;
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
/*
* ns_name_unpack(msg, eom, src, dst, dstsiz)
* Unpack a domain name from a message, source may be compressed.
* return:
* -1 if it fails, or consumed octets if it succeeds.
*/
int
ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
u_char *dst, size_t dstsiz)
{
const u_char *srcp, *dstlim;
u_char *dstp;
int n, len, checked;
len = -1;
checked = 0;
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0:
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
checked += n + 1;
*dstp++ = n;
memcpy(dstp, srcp, n);
dstp += n;
srcp += n;
break;
case NS_CMPRSFLGS:
if (srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
if (len < 0)
len = srcp - src + 1;
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom) { /* Out of range. */
errno = EMSGSIZE;
return (-1);
}
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eom - msg) {
errno = EMSGSIZE;
return (-1);
}
break;
default:
errno = EMSGSIZE;
return (-1); /* flag error */
}
}
*dstp = '\0';
if (len < 0)
len = srcp - src;
return (len);
}
/*
* special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted special ("in need of quoting") ?
* return:
* boolean.
*/
static int special(int ch) {
switch (ch) {
case 0x22: /* '"' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
return (1);
default:
return (0);
}
}
/*
* printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
static int printable(int ch) {
return (ch > 0x20 && ch < 0x7f);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -