Subversion Repositories userdetect2

Rev

Rev 70 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 daniel-mar 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.