windows-nt/Source/XPSP1/NT/net/snmp/common/dll/ipx.c
2020-09-26 16:20:57 +08:00

198 lines
5 KiB
C

/*++
Copyright (c) 1992-1997 Microsoft Corporation
Module Name:
ipx.c
Abstract:
Contains routines to manipulate ipx addresses.
SnmpSvcAddrToSocket
Environment:
User Mode - Win32
Revision History:
--*/
///////////////////////////////////////////////////////////////////////////////
// //
// Include files //
// //
///////////////////////////////////////////////////////////////////////////////
#include <snmp.h>
#include <snmputil.h>
#include <winsock.h>
#include <wsipx.h>
#define bcopy(slp, dlp, size) (void)memcpy(dlp, slp, size)
BOOL isHex(LPSTR str, int strLen)
{
int ii;
for (ii=0; ii < strLen; ii++)
if (isxdigit(*str))
str++;
else
return FALSE;
return TRUE;
}
unsigned int toHex(unsigned char x)
{
if (x >= '0' && x <= '9')
return x - '0';
else if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
else if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
else
return 0;
}
// convert str to hex number of NumDigits (must be even) into pNum
void atohex(IN LPSTR str, IN int NumDigits, OUT unsigned char *pNum)
{
int i, j;
j=0;
for (i=0; i < (NumDigits>>1) ; i++)
{
pNum[i] = (toHex(str[j]) << 4) + toHex(str[j+1]);
j+=2;
}
}
// return true if addrText is of the form 123456789ABC or
// 000001.123456789abc
// if pNetNum is not null, upon successful return, pNetNum = network number
// if pNodeNum is not null, upon successful return, pNodeNum = node number
BOOL
SNMP_FUNC_TYPE
SnmpSvcAddrIsIpx(
IN LPSTR addrText,
OUT char pNetNum[4],
OUT char pNodeNum[6])
{
int addrTextLen;
addrTextLen = strlen(addrText);
if (addrTextLen == 12 && isHex(addrText, 12))
{
if (pNetNum)
*((UNALIGNED unsigned long *) pNetNum) = 0L;
if (pNodeNum)
atohex(addrText, 12, pNodeNum);
return TRUE;
}
else if (addrTextLen == 21 && addrText[8] == '.' && isHex(addrText, 8) &&
isHex(addrText+9, 12))
{
if (pNetNum)
atohex(addrText, 8, pNetNum);
if (pNodeNum)
atohex(addrText+9, 12, pNodeNum);
return TRUE;
}
else
return FALSE;
}
BOOL
SNMP_FUNC_TYPE
SnmpSvcAddrToSocket(
LPSTR addrText,
struct sockaddr *addrEncoding
)
{
struct hostent * hp;
struct sockaddr_in * pAddr_in = (struct sockaddr_in *)addrEncoding;
struct sockaddr_ipx * pAddr_ipx = (struct sockaddr_ipx *)addrEncoding;
unsigned long addr;
// check for ipx addr
if (SnmpSvcAddrIsIpx(
addrText,
pAddr_ipx->sa_netnum,
pAddr_ipx->sa_nodenum
)) {
// see if ip host name which looks like ipx
if ((hp = gethostbyname(addrText)) == NULL) {
// host really is ipx machine
pAddr_ipx->sa_family = AF_IPX;
pAddr_ipx->sa_socket = htons(DEFAULT_SNMPTRAP_PORT_IPX);
// address transferred above...
} else {
// host is really ip machine
pAddr_in->sin_family = AF_INET;
pAddr_in->sin_port = htons(DEFAULT_SNMPTRAP_PORT_UDP);
pAddr_in->sin_addr.s_addr = *(unsigned long *)hp->h_addr;
}
} else if (strncmp(addrText, "255.255.255.255", 15) == 0) {
// host is a broadcast address
pAddr_in->sin_family = AF_INET;
pAddr_in->sin_port = htons(DEFAULT_SNMPTRAP_PORT_UDP);
pAddr_in->sin_addr.s_addr = 0xffffffff;
} else if ((long)(addr = inet_addr(addrText)) != -1) {
// host is ip machine
struct servent * pServEnt = NULL;
// attempt to get server information
pServEnt = getservbyname("snmptrap","udp");
pAddr_in->sin_family = AF_INET;
pAddr_in->sin_port = (pServEnt != NULL)
? (SHORT)pServEnt->s_port
: htons(DEFAULT_SNMPTRAP_PORT_UDP)
;
pAddr_in->sin_addr.s_addr = addr;
} else if ((hp = gethostbyname(addrText)) != NULL) {
// host is really ip machine
struct servent * pServEnt = NULL;
// attempt to get server information
pServEnt = getservbyname("snmptrap","udp");
pAddr_in->sin_family = AF_INET;
pAddr_in->sin_port = (pServEnt != NULL)
? (SHORT)pServEnt->s_port
: htons(DEFAULT_SNMPTRAP_PORT_UDP)
;
pAddr_in->sin_addr.s_addr = *(unsigned long *)hp->h_addr;
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"SNMP: API: could not convert %s to socket.\n",
addrText
));
// failure
return FALSE;
}
// success
return TRUE;
}