Subversion Repositories delphiutils

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. unit NetworkUtils;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, SysUtils, Classes;
  7.  
  8. function GetLocalIPAddressList(outsl: TStrings): DWORD;
  9. function GetLocalMACAddressList(outSL: TStrings): DWORD;
  10. function GetDHCPIPAddressList(outsl: TStrings): DWORD;
  11. function GetGatewayIPAddressList(outsl: TStrings): DWORD;
  12. function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD;
  13. function FormatMAC(s: string): string;
  14.  
  15. implementation
  16.  
  17. uses
  18.   iphlp, WinSock;
  19.  
  20. // TODO: Replace GetAdaptersInfo()? A comment at MSDN states that there might be problems with IPv6
  21. //           "GetAdaptersInfo returns ERROR_NO_DATA if there are only IPv6 interfaces
  22. //            configured on system. In that case GetAdapterAddresses has to be used!"
  23.  
  24. function GetLocalIPAddressList(outsl: TStrings): DWORD;
  25. var
  26.   pAdapterInfo: PIP_ADAPTER_INFO;
  27.   addr: string;
  28.   addrStr: IP_ADDR_STRING;
  29.   BufLen: Cardinal;
  30. begin
  31.   BufLen := SizeOf(IP_ADAPTER_INFO);
  32.   GetAdaptersInfo(nil, @BufLen);
  33.   pAdapterInfo := AllocMem(BufLen);
  34.   try
  35.     Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
  36.     if not Result = ERROR_SUCCESS then Exit;
  37.     while pAdapterInfo <> nil do
  38.     begin
  39.       addrStr := pAdapterInfo^.IpAddressList;
  40.       repeat
  41.         addr := addrStr.IpAddress.S;
  42.         if (addr <> '') and (outsl.IndexOf(addr) = -1) then
  43.           outsl.Add(addr);
  44.         if addrStr.Next = nil then break;
  45.         AddrStr := addrStr.Next^;
  46.       until false;
  47.       pAdapterInfo := pAdapterInfo^.next;
  48.     end;
  49.   finally
  50.     Freemem(pAdapterInfo);
  51.   end;
  52. end;
  53.  
  54. function GetDHCPIPAddressList(outsl: TStrings): DWORD;
  55. var
  56.   pAdapterInfo: PIP_ADAPTER_INFO;
  57.   addr: string;
  58.   addrStr: IP_ADDR_STRING;
  59.   BufLen: Cardinal;
  60. begin
  61.   BufLen := SizeOf(IP_ADAPTER_INFO);
  62.   GetAdaptersInfo(nil, @BufLen);
  63.   pAdapterInfo := AllocMem(BufLen);
  64.   try
  65.     Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
  66.     if not Result = ERROR_SUCCESS then Exit;
  67.     while pAdapterInfo <> nil do
  68.     begin
  69.       addrStr := pAdapterInfo^.DhcpServer;
  70.       repeat
  71.         addr := addrStr.IpAddress.S;
  72.         if (addr <> '') and (outsl.IndexOf(addr) = -1) then
  73.           outsl.Add(addr);
  74.         if addrStr.Next = nil then break;
  75.         AddrStr := addrStr.Next^;
  76.       until false;
  77.       pAdapterInfo := pAdapterInfo^.next;
  78.     end;
  79.   finally
  80.     Freemem(pAdapterInfo);
  81.   end;
  82. end;
  83.  
  84. function GetGatewayIPAddressList(outsl: TStrings): DWORD;
  85. var
  86.   pAdapterInfo: PIP_ADAPTER_INFO;
  87.   addr: string;
  88.   addrStr: IP_ADDR_STRING;
  89.   BufLen: Cardinal;
  90. begin
  91.   BufLen := SizeOf(IP_ADAPTER_INFO);
  92.   GetAdaptersInfo(nil, @BufLen);
  93.   pAdapterInfo := AllocMem(BufLen);
  94.   try
  95.     Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
  96.     if not Result = ERROR_SUCCESS then Exit;
  97.     while pAdapterInfo <> nil do
  98.     begin
  99.       addrStr := pAdapterInfo^.GatewayList;
  100.       repeat
  101.         addr := addrStr.IpAddress.S;
  102.         if (addr <> '') and (outsl.IndexOf(addr) = -1) then
  103.           outsl.Add(addr);
  104.         if addrStr.Next = nil then break;
  105.         AddrStr := addrStr.Next^;
  106.       until false;
  107.       pAdapterInfo := pAdapterInfo^.next;
  108.     end;
  109.   finally
  110.     Freemem(pAdapterInfo);
  111.   end;
  112. end;
  113.  
  114. function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD;
  115. // http://stackoverflow.com/questions/4550672/delphi-get-mac-of-router
  116. var
  117.   MacAddr    : Array[0..5] of Byte;
  118.   DestIP     : ULONG;
  119.   PhyAddrLen : ULONG;
  120.   WSAData    : TWSAData;
  121.   j: integer;
  122. begin
  123.   outAddress := '';
  124.   WSAStartup($0101, WSAData);
  125.   try
  126.     ZeroMemory(@MacAddr, SizeOf(MacAddr));
  127.     DestIP     := inet_addr(PAnsiChar(IPAddress));
  128.     PhyAddrLen := SizeOf(MacAddr); // TODO: more ?
  129.     Result     := SendArp(DestIP, 0, @MacAddr, @PhyAddrLen);
  130.     if Result = S_OK then
  131.     begin
  132.       outAddress := '';
  133.       for j := 0 to PhyAddrLen-1 do
  134.       begin
  135.         outAddress := outAddress + format('%.2x', [MacAddr[j]]);
  136.       end;
  137.       outAddress := FormatMAC(outAddress);
  138.     end;
  139.   finally
  140.     WSACleanup;
  141.   end;
  142. end;
  143.  
  144. function GetLocalMACAddressList(outSL: TStrings): DWORD;
  145. const
  146.   _MAX_ROWS_ = 100;
  147. type
  148.   _IfTable = Record
  149.     nRows: LongInt;
  150.     ifRow: Array[1.._MAX_ROWS_] of MIB_IFROW;
  151.   end;
  152. var
  153.   pIfTable: ^_IfTable;
  154.   TableSize: LongInt;
  155.   tmp: String;
  156.   i, j: Integer;
  157. begin
  158.   pIfTable := nil;
  159.   try
  160.     // First: just get the buffer size.
  161.     // TableSize returns the size needed.
  162.     TableSize := 0; // Set to zero so the GetIfTabel function
  163.     // won't try to fill the buffer yet,
  164.     // but only return the actual size it needs.
  165.     GetIfTable(pIfTable, TableSize, 1);
  166.     if (TableSize < SizeOf(MIB_IFROW)+SizeOf(LongInt)) then
  167.     begin
  168.       Result := ERROR_NO_DATA;
  169.       Exit; // less than 1 table entry?!
  170.     end;
  171.  
  172.     // Second:
  173.     // allocate memory for the buffer and retrieve the
  174.     // entire table.
  175.     GetMem(pIfTable, TableSize);
  176.     Result := GetIfTable(pIfTable, TableSize, 1);
  177.     if Result <> NO_ERROR then Exit;
  178.  
  179.     // Read the ETHERNET addresses.
  180.     for i := 1 to pIfTable^.nRows do
  181.     begin
  182.       //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then
  183.       begin
  184.         tmp := '';
  185.         for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do
  186.         begin
  187.           tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]);
  188.         end;
  189.         tmp := FormatMAC(tmp);
  190.         if (tmp <> '') and (outSL.IndexOf(tmp) = -1) then
  191.           outSL.Add(tmp);
  192.       end;
  193.     end;
  194.   finally
  195.     if Assigned(pIfTable) then FreeMem(pIfTable, TableSize);
  196.   end;
  197. end;
  198.  
  199. function FormatMAC(s: string): string;
  200. var
  201.   m: integer;
  202. begin
  203.   result := '';
  204.   m := 1;
  205.   s := UpperCase(s);
  206.   repeat
  207.     if m > 1 then result := result + '-';
  208.     result := result + Copy(s, m, 2);
  209.     inc(m, 2);
  210.   until m > Length(s);
  211. end;
  212.  
  213. end.
  214.