📄 dnsmx.cpp
字号:
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eomorig - msg)
return (-1);
break;
default:
return (-1); /* flag error */
}
}
*dn = '\0';
if (len < 0)
len = cp - comp_dn;
return (len);
}
/*
* Skip over a compressed domain name. Return the size or -1.
*/
dn_skipname(u_char *comp_dn, u_char *eom)
{
register u_char *cp;
register int n;
cp = comp_dn;
while (cp < eom && (n = *cp++)) {
/*
* check for indirection
*/
switch (n & INDIR_MASK) {
case 0: /* normal case, n == len */
cp += n;
continue;
default: /* illegal type */
return (-1);
case INDIR_MASK: /* indirection */
cp++;
}
break;
}
return (cp - comp_dn);
}
char* GetMX( char *pszQuery, char *pszServer, int minlevel )
{
WSADATA stWSAData;
WORD wWSAVersion = 0x0202;
SOCKET hSocket;
SOCKADDR_IN stSockAddr; // socket address structures
int nAddrLen = sizeof( SOCKADDR_IN );
HOSTENT *pHostEnt;
char achBufOut[ BUFSIZE ] = { 0 };
char achBufIn[ BUFSIZE ] = { 0 };
int nQueryLen = 0;
int nRC;
char *p, *np, name[128], *eom;
int count, j, i, n;
nRC = WSAStartup( wWSAVersion, &stWSAData );
if ( nRC )
{
return NULL;
}
memset( &stSockAddr, ASCII_NULL, sizeof( stSockAddr ) );
stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons( 53);
stSockAddr.sin_addr.s_addr = inet_addr( pszServer );
if ( stSockAddr.sin_addr.s_addr == INADDR_NONE )
{
pHostEnt = gethostbyname( pszServer );
if ( pHostEnt )
{
stSockAddr.sin_addr.s_addr = *((u_long *)pHostEnt->h_addr_list[0]);
}
else
{
WSACleanup();
return NULL;
} // end if
} // end if
/*------------------------------------------------------------
* Get a DGRAM socket
*/
hSocket = socket( AF_INET, SOCK_DGRAM, 0 );
if ( hSocket == INVALID_SOCKET )
{
WSACleanup();
return NULL;
} // end if
/*-----------------------------------------------------------
* Format DNS Query
*
* <<8/17/97 hard-coded test case: MX Record>>
*/
pDNShdr = (PDNS_HDR)&( achBufOut[ 0 ] );
pDNShdr->dns_id = htons( 0xDEAD );
pDNShdr->dns_flags = htons( DNS_FLAG_RD ); // do recurse
pDNShdr->dns_q_count = htons( 1 ); // one query
pDNShdr->dns_rr_count = 0; // none in query
pDNShdr->dns_auth_count = 0; // none in query
pDNShdr->dns_add_count = 0; // none in query
nQueryLen = PutQName( pszQuery, &(achBufOut[ DNS_HDR_LEN ] ) );
nQueryLen += DNS_HDR_LEN;
achBufOut[ nQueryLen++ ] = 0;
achBufOut[ nQueryLen++ ] = 0;
/* BQ NOTE: I'm cheating on this one! (should be done cleaner)*/
achBufOut[ nQueryLen ] = DNS_RRTYPE_MX;
achBufOut[ nQueryLen + 1 ] = 0;
achBufOut[ nQueryLen + 2 ] = DNS_RRCLASS_IN;
achBufOut[ nQueryLen + 3 ] = 0;
nQueryLen += 4;
/*-----------------------------------------------------------
* Send DNS Query to server
*/
nRC = sendto( hSocket,
achBufOut,
nQueryLen,
0,
(LPSOCKADDR)&stSockAddr,
sizeof( SOCKADDR_IN ) );
if ( nRC == SOCKET_ERROR )
{
closesocket( hSocket );
WSACleanup();
return NULL;
}
else
{
} // end if
/*------------------------------------------
* Recvfrom()
*/
nRC = recvfrom( hSocket,
achBufIn,
BUFSIZE,
0,
(LPSOCKADDR)&stSockAddr,
&nAddrLen );
if ( nRC == SOCKET_ERROR )
{
int nWSAErr = WSAGetLastError();
if ( nWSAErr != WSAETIMEDOUT )
{
closesocket( hSocket );
WSACleanup();
return NULL;
}
else
{
closesocket( hSocket );
WSACleanup();
return NULL;
}
}
else
{
pDNShdr = (PDNS_HDR)&( achBufIn[ 0 ] );
p = (char *)&pDNShdr[0];
p+=12;
count = (int)*p;
// Parse the Question...
for (i = 0; i< ntohs(pDNShdr->dns_q_count); i++)
{
np = name;
eom = (char *)pDNShdr+nRC;
if ((n = dn_expand((char *)pDNShdr, eom,
p, name, 127)) < 0) {
return NULL;
}
p += n + QFIXEDSZ;
}
//We store the mx's in a 4096 characters list
char *mxstr;
mxstr = (char *) HeapAlloc( GetProcessHeap(),HEAP_ZERO_MEMORY,4096);
sprintf(mxstr,"");
for (i = 0; i< ntohs(pDNShdr->dns_rr_count); i++)
{
// The Question Name appears Again...
if ((n = dn_expand((char *)pDNShdr, eom,
p, name, 127)) < 0) {
return NULL;
}
p+=n;
j = _getshort(p);; //TYPE
p+=2;
//printf("%s\tType:%d", name, j);
j = _getshort(p); //CLASS
p+=2;
// printf("\tClass:%d", j);
j = _getlong(p); //TTL
p+=4;
// printf("\tTTL:%d", j);
j = _getshort(p); //RDLENGTH
p+=2;
// printf("\tRDLENGTH:%d", j);
j = _getshort(p); //N??
p+=2;
// This should be an MX Name...
if ((n = dn_expand((char *)pDNShdr, eom,
p, name, 127)) < 0) {
}
if (i == 0)
{
sprintf(mxstr,"%s %d",name,j);
}
else
{
sprintf(mxstr,"%s\n%s %d",mxstr,name,j);
}
p += n;
}
return mxstr;
} /* end else (recvfrom() succeeded) */
closesocket( hSocket );
WSACleanup();
return NULL;
} /* end main() */
void GetQName( char FAR *pszHostName, char FAR *pQName )
{
int i, j, k;
for ( i = 0; i < BUFSIZE; i++ )
{
j = *pQName;
if ( j == 0 )
break;
for ( k = 1; k <= j; k++ )
{
*pszHostName++ = *( pQName + i + k );
} // end for loop
} // end for loop
*pszHostName++ = ASCII_NULL;
} /* end GetQName() */
void PrintQName( char FAR *pQName )
{
int i, j, k;
for ( i = 0; i < BUFSIZE; i++ )
{
j = *pQName;
if ( j == 0 )
break;
for ( k = 1; k <= j; k++ )
{
//printf( "%c", *( pQName + i + k ) );
} // end for loop
} // end for loop
} /* end PrintQName() */
int PutQName( char FAR *pszHostName, char FAR *pQName )
{
int i;
int j = 0;
int k = 0;
for ( i = 0; *( pszHostName + i ); i++ )
{
char c = *( pszHostName + i ); /* get next character */
if ( c == '.' )
{
/* dot encountered, fill in previous length */
*( pQName + j ) = k;
k = 0; /* reset segment length */
j = i + 1; /* set index to next counter */
}
else
{
*( pQName + i + 1 ) = c; /* assign to QName */
k++; /* inc count of seg chars */
} // end if
} // end for loop
*(pQName + j ) = k; /* count for final segment */
*(pQName + i + 1 ) = 0; /* count for trailing NULL segment is 0 */
#ifdef DEBUG
for ( j = 1; j < 30; j++ )
{
} // end for loop
#endif
return ( i + 1 ); /* return total length of QName */
} /* end PutQName() */
/***********************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -