Source code of Windows XP (NT5)
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.

119 lines
2.7 KiB

  1. #include "dpsp.h"
  2. #undef DPF_MODNAME
  3. #define DPF_MODNAME "GetHostAddr"
  4. #define DUMMYPORTNAME "1" // value unused but must be non-zero
  5. void
  6. AddAddress(IPV6_INFO_INTERFACE *IF, IPV6_INFO_ADDRESS *ADE, void *Context)
  7. {
  8. int i;
  9. LPSOCKADDR_IN6 ps;
  10. SOCKET_ADDRESS_LIST *pList = (SOCKET_ADDRESS_LIST *)Context;
  11. ULONG ulSize = sizeof(SOCKADDR_IN6);
  12. // Skip it if it's not a unicast address
  13. if (IN6_IS_ADDR_MULTICAST(&ADE->This.Address))
  14. {
  15. return;
  16. }
  17. ps = MemAlloc(ulSize);
  18. if (ps == NULL)
  19. {
  20. // Memory allocation failed
  21. DEBUGPRINTADDR(0,"Could not add address : \n",ps);
  22. return;
  23. }
  24. i = pList->iAddressCount++;
  25. ZeroMemory(ps, ulSize);
  26. ps->sin6_family = AF_INET6;
  27. ps->sin6_addr = ADE->This.Address;
  28. ps->sin6_scope_id = IF->ZoneIndices[ADE->Scope];
  29. pList->Address[i].iSockaddrLength = ulSize;
  30. pList->Address[i].lpSockaddr = (LPSOCKADDR)ps;
  31. DEBUGPRINTADDR(0,"Added address : \n",ps);
  32. }
  33. void
  34. AddInterfaceAddresses(IPV6_INFO_INTERFACE *IF, void *Context1, void *Context2, void *Context3)
  35. {
  36. // Skip the loopback interface
  37. if (IF->This.Index == 1)
  38. {
  39. return;
  40. }
  41. DPF(0,"Processing interface %d",IF->This.Index);
  42. ForEachAddress(IF, AddAddress, Context1);
  43. }
  44. void
  45. CountAddress(IPV6_INFO_INTERFACE *IF, IPV6_INFO_ADDRESS *ADE, void *Context)
  46. {
  47. ULONG *pulNumAddresses = (ULONG *)Context;
  48. // Skip it if it's not a unicast address
  49. if (IN6_IS_ADDR_MULTICAST(&ADE->This.Address))
  50. {
  51. return;
  52. }
  53. (*pulNumAddresses)++;
  54. }
  55. void
  56. CountInterfaceAddresses(IPV6_INFO_INTERFACE *IF, void *Context1, void *Context2, void *Context3)
  57. {
  58. // Skip the loopback interface
  59. if (IF->This.Index == 1)
  60. {
  61. return;
  62. }
  63. ForEachAddress(IF, CountAddress, Context1);
  64. }
  65. // Helper function to retrieve host IP Address(es).
  66. // Caller must call FreeHostAddr on list returned
  67. SOCKET_ADDRESS_LIST *GetHostAddr(void)
  68. {
  69. UINT err;
  70. ULONG ulNumAddresses = 0;
  71. SOCKET_ADDRESS_LIST *pList;
  72. ForEachInterface(CountInterfaceAddresses, &ulNumAddresses, NULL, NULL);
  73. if (ulNumAddresses == 0)
  74. {
  75. DPF(0,"could not get addresses for local machine\n");
  76. return NULL;
  77. }
  78. pList = MemAlloc( FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[ulNumAddresses] ));
  79. if (pList == NULL)
  80. {
  81. DPF(0,"could not get addresses for local machine - err = %d\n", GetLastError());
  82. return NULL;
  83. }
  84. pList->iAddressCount = 0;
  85. ForEachInterface(AddInterfaceAddresses, pList, NULL, NULL);
  86. return pList;
  87. } // GetHostAddr
  88. void
  89. FreeHostAddr(SOCKET_ADDRESS_LIST *pList)
  90. {
  91. int i;
  92. for (i=0; i<pList->iAddressCount; i++)
  93. {
  94. MemFree(pList->Address[i].lpSockaddr);
  95. }
  96. MemFree(pList);
  97. }