⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnsmx.cpp

📁 邮件终端发送程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			continue;
		default:	/* illegal type */
			return (-1);
		case INDIR_MASK:	/* indirection */
			cp++;
		}
		break;
	}
	return (cp - comp_dn);
}

//
// 设置阻塞模式
//
BOOL SetBlockingMode ( SOCKET hSocket, BOOL bNonblockingEnable )
{
	if ( hSocket == INVALID_SOCKET || hSocket == 0 )
	{
		return FALSE;
	}
	
	long cmd = FIONBIO;
	long zero = 0;
	u_long* argp = NULL;
	if ( bNonblockingEnable )
		argp = (u_long*)&cmd;
	else
		argp = (u_long*)&zero;
	int err = ioctlsocket ( hSocket, cmd, argp );
	if ( err != 0 )
	{
		return FALSE;
	}
	
	return TRUE;
}


BOOL GetMX (
			char *pszQuery,
			char *pszServer,
			OUT t_Ary_MXHostInfos &Ary_MXHostInfos
			)
{
	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;
	
	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 = *((ULONG *)pHostEnt->h_addr_list[0]);
		}
		else
		{
			return FALSE;
		} // end if
	} // end if
	
	
	  /*------------------------------------------------------------
	  *  Get a DGRAM socket
	*/
	
	hSocket = socket( AF_INET, SOCK_DGRAM, 0 );
	
	if ( hSocket == INVALID_SOCKET )
	{
		return FALSE;
	} // end if

	  /*-----------------------------------------------------------
	  * Format DNS Query
	*/
	
	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;	
	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 );
		return FALSE;
	}
	else
	{
		
	}
	
//	VERIFY ( SetBlockingMode ( hSocket, TRUE ) );

	// 用 select 模型实现连接超时
	struct timeval timeout;
	fd_set r;
	FD_ZERO(&r);
	FD_SET(hSocket, &r);
	timeout.tv_sec = 5; //连接超时秒
	timeout.tv_usec =0;
	int ret = select(0, &r, 0, 0, &timeout);
	if ( ret == SOCKET_ERROR )
	{
		::closesocket(hSocket);
		hSocket = SOCKET_ERROR;
		return FALSE;
	}

	// 得到可读的数据长度
	long cmd = FIONREAD;
	u_long argp = 0;
	BOOL err = ioctlsocket ( hSocket, cmd, (u_long*)&argp );
	if ( err || argp < 1 )
	{
		::closesocket(hSocket);
		hSocket = SOCKET_ERROR;
		return FALSE;
	}

	nRC = recvfrom( hSocket,
		achBufIn,
		BUFSIZE,
		0,
		(LPSOCKADDR)&stSockAddr,
		&nAddrLen );
	
	if ( nRC == SOCKET_ERROR )
	{
		int nWSAErr = WSAGetLastError();
		
		if ( nWSAErr != WSAETIMEDOUT )
		{
			
			closesocket( hSocket );
			return FALSE;
		}
		else
		{
			
			closesocket( hSocket );
			return FALSE;
		}
	}
	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 FALSE;
				
			}
			p += n + QFIXEDSZ;
		}		
		
		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 FALSE;
			}
			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 )
			{
				return FALSE;
			}

			t_MXHostInfo tMXHostInfo = {0};
			strncpy ( (char*)tMXHostInfo.szMXHost, name, sizeof(tMXHostInfo.szMXHost)/sizeof(tMXHostInfo.szMXHost[0]) );
			tMXHostInfo.N = j;
			Ary_MXHostInfos.Add ( tMXHostInfo );
			TRACE ( _T("%s\t%d\r\n"), name, j );
			p += n;
		}
		return TRUE;
		
		
	}
	
	
	closesocket( hSocket );
	return FALSE;
}


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 */
	
	return ( i + 1 );        /* return total length of QName */
}

//
// 尝试所有的DNS来查询邮局服务器地址
//
BOOL GetMX (
			char *pszQuery,							// 要查询的域名
			OUT t_Ary_MXHostInfos &Ary_MXHostInfos	// 输出 Mail Exchange 主机名
			)
{
	CNetAdapterInfo m_NetAdapterInfo;
	m_NetAdapterInfo.Refresh ();
	int nNetAdapterCount = m_NetAdapterInfo.GetNetCardCount();
	for ( int i=0; i<nNetAdapterCount; i++ )
	{
		COneNetAdapterInfo *pOneNetAdapterInfo = m_NetAdapterInfo.Get_OneNetAdapterInfo ( i );
		if ( pOneNetAdapterInfo )
		{
			int nDNSCount = pOneNetAdapterInfo->Get_DNSCount ();
			for ( int j=0; j<nDNSCount; j++ )
			{
				CString csDNS = pOneNetAdapterInfo->Get_DNSAddr ( j );
				if ( GetMX ( pszQuery, csDNS.GetBuffer(0), Ary_MXHostInfos ) )
				{
					return TRUE;
				}
			}
		}
	}

	return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -