Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1992-1997 Microsoft Corporation
  3. Module Name:
  4. ipx.c
  5. Abstract:
  6. Contains routines to manipulate ipx addresses.
  7. SnmpSvcAddrToSocket
  8. Environment:
  9. User Mode - Win32
  10. Revision History:
  11. --*/
  12. ///////////////////////////////////////////////////////////////////////////////
  13. // //
  14. // Include files //
  15. // //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. #include <snmp.h>
  18. #include <snmputil.h>
  19. #include <winsock.h>
  20. #include <wsipx.h>
  21. BOOL isHex(LPSTR str, int strLen)
  22. {
  23. int ii;
  24. for (ii=0; ii < strLen; ii++)
  25. if (isxdigit(*str))
  26. str++;
  27. else
  28. return FALSE;
  29. return TRUE;
  30. }
  31. unsigned int toHex(unsigned char x)
  32. {
  33. if (x >= '0' && x <= '9')
  34. return x - '0';
  35. else if (x >= 'A' && x <= 'F')
  36. return x - 'A' + 10;
  37. else if (x >= 'a' && x <= 'f')
  38. return x - 'a' + 10;
  39. else
  40. return 0;
  41. }
  42. // convert str to hex number of NumDigits (must be even) into pNum
  43. void atohex(IN LPSTR str, IN int NumDigits, OUT unsigned char *pNum)
  44. {
  45. int i, j;
  46. j=0;
  47. for (i=0; i < (NumDigits>>1) ; i++)
  48. {
  49. pNum[i] = (toHex(str[j]) << 4) + toHex(str[j+1]);
  50. j+=2;
  51. }
  52. }
  53. // return true if addrText is of the form 123456789ABC or
  54. // 000001.123456789abc
  55. // if pNetNum is not null, upon successful return, pNetNum = network number
  56. // if pNodeNum is not null, upon successful return, pNodeNum = node number
  57. BOOL
  58. SNMP_FUNC_TYPE
  59. SnmpSvcAddrIsIpx(
  60. IN LPSTR addrText,
  61. OUT char pNetNum[4],
  62. OUT char pNodeNum[6])
  63. {
  64. int addrTextLen;
  65. addrTextLen = strlen(addrText);
  66. if (addrTextLen == 12 && isHex(addrText, 12))
  67. {
  68. if (pNetNum)
  69. *((UNALIGNED unsigned long *) pNetNum) = 0L;
  70. if (pNodeNum)
  71. atohex(addrText, 12, pNodeNum);
  72. return TRUE;
  73. }
  74. else if (addrTextLen == 21 && addrText[8] == '.' && isHex(addrText, 8) &&
  75. isHex(addrText+9, 12))
  76. {
  77. if (pNetNum)
  78. atohex(addrText, 8, pNetNum);
  79. if (pNodeNum)
  80. atohex(addrText+9, 12, pNodeNum);
  81. return TRUE;
  82. }
  83. else
  84. return FALSE;
  85. }
  86. BOOL
  87. SNMP_FUNC_TYPE
  88. SnmpSvcAddrToSocket(
  89. LPSTR addrText,
  90. struct sockaddr *addrEncoding
  91. )
  92. {
  93. struct hostent * hp;
  94. struct sockaddr_in * pAddr_in = (struct sockaddr_in *)addrEncoding;
  95. struct sockaddr_ipx * pAddr_ipx = (struct sockaddr_ipx *)addrEncoding;
  96. unsigned long addr;
  97. // check for ipx addr
  98. if (SnmpSvcAddrIsIpx(
  99. addrText,
  100. pAddr_ipx->sa_netnum,
  101. pAddr_ipx->sa_nodenum
  102. )) {
  103. // see if ip host name which looks like ipx
  104. if ((hp = gethostbyname(addrText)) == NULL) {
  105. // host really is ipx machine
  106. pAddr_ipx->sa_family = AF_IPX;
  107. pAddr_ipx->sa_socket = htons(DEFAULT_SNMPTRAP_PORT_IPX);
  108. // address transferred above...
  109. } else {
  110. // host is really ip machine
  111. struct servent * pServEnt = NULL;
  112. // save value returned by gethostbyname before calling getservbyname
  113. pAddr_in->sin_family = AF_INET;
  114. pAddr_in->sin_addr.s_addr = *(unsigned long *)hp->h_addr;
  115. // attempt to get server information
  116. pServEnt = getservbyname("snmptrap","udp");
  117. pAddr_in->sin_port = (pServEnt != NULL)
  118. ? (SHORT)pServEnt->s_port
  119. : htons(DEFAULT_SNMPTRAP_PORT_UDP)
  120. ;
  121. }
  122. } else if (strncmp(addrText, "255.255.255.255", 15) == 0) {
  123. // host is a broadcast address
  124. struct servent * pServEnt = NULL;
  125. // attempt to get server information
  126. pServEnt = getservbyname("snmptrap","udp");
  127. pAddr_in->sin_family = AF_INET;
  128. pAddr_in->sin_port = (pServEnt != NULL)
  129. ? (SHORT)pServEnt->s_port
  130. : htons(DEFAULT_SNMPTRAP_PORT_UDP)
  131. ;
  132. pAddr_in->sin_addr.s_addr = 0xffffffff;
  133. } else if ((long)(addr = inet_addr(addrText)) != -1) {
  134. // host is ip machine
  135. struct servent * pServEnt = NULL;
  136. // attempt to get server information
  137. pServEnt = getservbyname("snmptrap","udp");
  138. pAddr_in->sin_family = AF_INET;
  139. pAddr_in->sin_port = (pServEnt != NULL)
  140. ? (SHORT)pServEnt->s_port
  141. : htons(DEFAULT_SNMPTRAP_PORT_UDP)
  142. ;
  143. pAddr_in->sin_addr.s_addr = addr;
  144. } else if ((hp = gethostbyname(addrText)) != NULL) {
  145. // host is really ip machine
  146. struct servent * pServEnt = NULL;
  147. // BUG 507426
  148. // save value returned by gethostbyname before calling getservbyname
  149. pAddr_in->sin_family = AF_INET;
  150. pAddr_in->sin_addr.s_addr = *(unsigned long *)hp->h_addr;
  151. // attempt to get server information
  152. pServEnt = getservbyname("snmptrap","udp");
  153. pAddr_in->sin_port = (pServEnt != NULL)
  154. ? (SHORT)pServEnt->s_port
  155. : htons(DEFAULT_SNMPTRAP_PORT_UDP)
  156. ;
  157. } else {
  158. SNMPDBG((
  159. SNMP_LOG_ERROR,
  160. "SNMP: API: could not convert %s to socket.\n",
  161. addrText
  162. ));
  163. // failure
  164. return FALSE;
  165. }
  166. // success
  167. return TRUE;
  168. }