198 lines
5 KiB
C
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;
|
|
}
|