Any one know a way in delphi get a simple list (eg tstrings) of the local ip address.
I have had a look at the other related question, and cant seem to get my head around converting them to delphi.
in indy 9, there is a unit IdStack, with the class TIdStack
fStack := TIdStack.CreateStack;
try
edit.caption := fStack.LocalAddress; //the first address i believe
ComboBox1.Items.Assign(fStack.LocalAddresses); //all the address'
finally
freeandnil(fStack);
end;
works great :)
from Remy Lebeau's Comment
The same exists in Indy 10, but the code is a little different:
TIdStack.IncUsage;
try
GStack.AddLocalAddressesToList(ComboBox1.Items);
Edit.Caption := ComboBox1.Items[0];
finally
TIdStack.DecUsage;
end;
If you are using ICS for socket communication, you can use LocalIPList function, defined in the OverbyteIcsWSocket unit.
Even if you are not using it, you can download the source code and look up the implementation. It uses WinSock internally.
I posted a solution on SO here. This will populate an array of records full of information for every adapter on the system. This includes the IP Address, but also includes MAC address, subnet mask, transferred/recvd packets, description, etc.
Once you've populated the array of records, just enumerate it for the IP Addresses, if that's all you want.
This emulates "ifconfig -a" on Linux:
C:\>ifconfig
0x00000001
"MS TCP Loopback interface"
Link encap: Local loopback
inet addr:127.0.0.1 Mask: 255.0.0.0
MTU: 1520 Speed:10.00 Mbps
Admin status:UP Oper status:OPERATIONAL
RX packets:179805 dropped:0 errors:0 unkown:0
TX packets:179804 dropped:0 errors:0 txqueuelen:0
0x00000002
"Broadcom NetXtreme 57xx Gigabit Controller - Packet Scheduler Miniport"
Link encap: Ethernet HWaddr: XX-XX-XX-XX-XX-XX
inet addr:10.101.101.102 Mask: 255.255.255.0
MTU: 1500 Speed:100.00 Mbps
Admin status:UP Oper status:OPERATIONAL
RX packets:6287896 dropped:0 errors:0 unkown:0
TX packets:5337100 dropped:0 errors:1 txqueuelen:0
Here is the full source of the "ifconfig -a" project. You will also need to grab my helper unit (uAdapterInfo) and include it with this program.
program ifconfig;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
Winsock,
uAdapterInfo in 'uAdapterInfo.pas';
type
TAdapterInfo = array of record
dwIndex: longint;
dwType: longint;
dwMtu: longint;
dwSpeed: extended;
dwPhysAddrLen: longint;
bPhysAddr: string;
dwAdminStatus: longint;
dwOperStatus: longint;
dwLastChange: longint;
dwInOctets: longint;
dwInUcastPkts: longint;
dwInNUcastPkts: longint;
dwInDiscards: longint;
dwInErrors: longint;
dwInUnknownProtos: longint;
dwOutOctets: longint;
dwOutUcastPkts: longint;
dwOutNUcastPkts: longint;
dwOutDiscards: longint;
dwOutErrors: longint;
dwOutQLen: longint;
dwDescrLen: longint;
bDescr: string;
sIpAddress: string;
sIpMask: string;
end;
function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean;
var
pIfTable: ^_IfTable;
pIpTable: ^_IpAddrTable;
ifTableSize, ipTableSize: longint;
tmp: string;
i, j, k, m: integer;
ErrCode: longint;
sAddr, sMask: in_addr;
IPAddresses, IPMasks: TStringList;
sIPAddressLine, sIPMaskLine: string;
bResult: boolean;
begin
bResult := True; //default return value
pIfTable := nil;
pIpTable := nil;
IPAddresses := TStringList.Create;
IPMasks := TStringList.Create;
try
// First: just get the buffer size.
// TableSize returns the size needed.
ifTableSize := 0; // Set to zero so the GetIfTabel function
// won't try to fill the buffer yet,
// but only return the actual size it needs.
GetIfTable(pIfTable, ifTableSize, 1);
if (ifTableSize < SizeOf(MIB_IFROW) + Sizeof(longint)) then
begin
bResult := False;
Result := bResult;
Exit; // less than 1 table entry?!
end;
ipTableSize := 0;
GetIpAddrTable(pIpTable, ipTableSize, 1);
if (ipTableSize < SizeOf(MIB_IPADDRROW) + Sizeof(longint)) then
begin
bResult := False;
Result := bResult;
Exit; // less than 1 table entry?!
end;
// Second:
// allocate memory for the buffer and retrieve the
// entire table.
GetMem(pIfTable, ifTableSize);
ErrCode := GetIfTable(pIfTable, ifTableSize, 1);
if ErrCode <> ERROR_SUCCESS then
begin
bResult := False;
Result := bResult;
Exit; // OK, that did not work.
// Not enough memory i guess.
end;
GetMem(pIpTable, ipTableSize);
ErrCode := GetIpAddrTable(pIpTable, ipTableSize, 1);
if ErrCode <> ERROR_SUCCESS then
begin
bResult := False;
Result := bResult;
Exit;
end;
for k := 1 to pIpTable^.dwNumEntries do
begin
sAddr.S_addr := pIpTable^.table[k].dwAddr;
sMask.S_addr := pIpTable^.table[k].dwMask;
sIPAddressLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) +
'=' + Format('%s', [inet_ntoa(sAddr)]);
sIPMaskLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) +
'=' + Format('%s', [inet_ntoa(sMask)]);
IPAddresses.Add(sIPAddressLine);
IPMasks.Add(sIPMaskLine);
end;
SetLength(AdapterDataFound, pIfTable^.nRows); //initialize the array or records
for i := 1 to pIfTable^.nRows do
try
//if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then
//begin
m := i - 1;
AdapterDataFound[m].dwIndex := 4;//(pIfTable^.ifRow[i].dwIndex);
AdapterDataFound[m].dwType := (pIfTable^.ifRow[i].dwType);
AdapterDataFound[m].dwIndex := (pIfTable^.ifRow[i].dwIndex);
AdapterDataFound[m].sIpAddress :=
IPAddresses.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])];
AdapterDataFound[m].sIpMask :=
IPMasks.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])];
AdapterDataFound[m].dwMtu := (pIfTable^.ifRow[i].dwMtu);
AdapterDataFound[m].dwSpeed := (pIfTable^.ifRow[i].dwSpeed);
AdapterDataFound[m].dwAdminStatus := (pIfTable^.ifRow[i].dwAdminStatus);
AdapterDataFound[m].dwOperStatus := (pIfTable^.ifRow[i].dwOperStatus);
AdapterDataFound[m].dwInUcastPkts := (pIfTable^.ifRow[i].dwInUcastPkts);
AdapterDataFound[m].dwInNUcastPkts := (pIfTable^.ifRow[i].dwInNUcastPkts);
AdapterDataFound[m].dwInDiscards := (pIfTable^.ifRow[i].dwInDiscards);
AdapterDataFound[m].dwInErrors := (pIfTable^.ifRow[i].dwInErrors);
AdapterDataFound[m].dwInUnknownProtos := (pIfTable^.ifRow[i].dwInUnknownProtos);
AdapterDataFound[m].dwOutNUcastPkts := (pIfTable^.ifRow[i].dwOutNUcastPkts);
AdapterDataFound[m].dwOutUcastPkts := (pIfTable^.ifRow[i].dwOutUcastPkts);
AdapterDataFound[m].dwOutDiscards := (pIfTable^.ifRow[i].dwOutDiscards);
AdapterDataFound[m].dwOutErrors := (pIfTable^.ifRow[i].dwOutErrors);
AdapterDataFound[m].dwOutQLen := (pIfTable^.ifRow[i].dwOutQLen);
AdapterDataFound[m].bDescr := (pIfTable^.ifRow[i].bDescr);
tmp := '';
for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen - 1 do
begin
if Length(tmp) > 0 then
tmp := tmp + '-' + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]])
else
tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]);
end;
if Length(tmp) > 0 then
begin
AdapterDataFound[m].bPhysAddr := tmp;
end;
except
bResult := False;
Result := bResult;
Exit;
end;
finally
if Assigned(pIfTable) then
begin
FreeMem(pIfTable, ifTableSize);
end;
FreeAndNil(IPMasks);
FreeAndNil(IPAddresses);
end;
Result := bResult;
end;
var
AdapterData: TAdapterInfo;
i: integer;
begin
try
WriteLn('');
if Get_EthernetAdapterDetail(AdapterData) then
begin
for i := 0 to Length(AdapterData) - 1 do
begin
WriteLn(Format('0x%8.8x', [AdapterData[i].dwIndex]));
WriteLn('"' + AdapterData[i].bDescr + '"');
Write(Format(#9 + 'Link encap: %s ', [Get_if_type(AdapterData[i].dwType)]));
if Length(AdapterData[i].bPhysAddr) > 0 then
Write('HWaddr: ' + AdapterData[i].bPhysAddr);
Write(#13 + #10 + #9 + 'inet addr:' + AdapterData[i].sIpAddress);
WriteLn(' Mask: ' + AdapterData[i].sIpMask);
WriteLn(Format(#9 + 'MTU: %d Speed:%.2f Mbps', [AdapterData[i].dwMtu,
(AdapterData[i].dwSpeed) / 1000 / 1000]));
Write(#9 + 'Admin status:' + Get_if_admin_status(AdapterData[i].dwAdminStatus));
WriteLn(' Oper status:' + Get_if_oper_status(AdapterData[i].dwOperStatus));
WriteLn(#9 + Format('RX packets:%d dropped:%d errors:%d unkown:%d',
[AdapterData[i].dwInUcastPkts + AdapterData[i].dwInNUcastPkts,
AdapterData[i].dwInDiscards, AdapterData[i].dwInErrors,
AdapterData[i].dwInUnknownProtos]));
WriteLn(#9 + Format('TX packets:%d dropped:%d errors:%d txqueuelen:%d',
[AdapterData[i].dwOutUcastPkts + AdapterData[i].dwOutNUcastPkts,
AdapterData[i].dwOutDiscards, AdapterData[i].dwOutErrors,
AdapterData[i].dwOutQLen]));
WriteLn('');
end;
end
else
begin
WriteLn(#13+#10+'*** Error retrieving adapter information');
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
And here is the helper unit you need to include:
unit uAdapterInfo;
interface
uses
Classes,
SysUtils;
const
MAX_INTERFACE_NAME_LEN = $100;
ERROR_SUCCESS = 0;
MAXLEN_IFDESCR = $100;
MAXLEN_PHYSADDR = 8;
MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0;
MIB_IF_OPER_STATUS_UNREACHABLE = 1;
MIB_IF_OPER_STATUS_DISCONNECTED = 2;
MIB_IF_OPER_STATUS_CONNECTING = 3;
MIB_IF_OPER_STATUS_CONNECTED = 4;
MIB_IF_OPER_STATUS_OPERATIONAL = 5;
MIB_IF_TYPE_OTHER = 1;
MIB_IF_TYPE_ETHERNET = 6;
MIB_IF_TYPE_TOKENRING = 9;
MIB_IF_TYPE_FDDI = 15;
MIB_IF_TYPE_PPP = 23;
MIB_IF_TYPE_LOOPBACK = 24;
MIB_IF_TYPE_SLIP = 28;
MIB_IF_ADMIN_STATUS_UP = 1;
MIB_IF_ADMIN_STATUS_DOWN = 2;
MIB_IF_ADMIN_STATUS_TESTING = 3;
_MAX_ROWS_ = 20;
ANY_SIZE = 1;
type
MIB_IFROW = record
wszName: array[0 .. (MAX_INTERFACE_NAME_LEN * 2 - 1)] of ansichar;
dwIndex: longint;
dwType: longint;
dwMtu: longint;
dwSpeed: longint;
dwPhysAddrLen: longint;
bPhysAddr: array[0 .. (MAXLEN_PHYSADDR - 1)] of byte;
dwAdminStatus: longint;
dwOperStatus: longint;
dwLastChange: longint;
dwInOctets: longint;
dwInUcastPkts: longint;
dwInNUcastPkts: longint;
dwInDiscards: longint;
dwInErrors: longint;
dwInUnknownProtos: longint;
dwOutOctets: longint;
dwOutUcastPkts: longint;
dwOutNUcastPkts: longint;
dwOutDiscards: longint;
dwOutErrors: longint;
dwOutQLen: longint;
dwDescrLen: longint;
bDescr: array[0 .. (MAXLEN_IFDESCR - 1)] of ansichar;
end;
type
MIB_IPADDRROW = record
dwAddr: longint;
dwIndex: longint;
dwMask: longint;
dwBCastAddr: longint;
dwReasmSize: longint;
unused1: word;
unused2: word;
end;
type
_IfTable = record
nRows: longint;
ifRow: array[1.._MAX_ROWS_] of MIB_IFROW;
end;
type
_IpAddrTable = record
dwNumEntries: longint;
table: array[1..ANY_SIZE] of MIB_IPADDRROW;
end;
function GetIfTable(pIfTable: Pointer; var pdwSize: longint; bOrder: longint): longint;
stdcall;
function GetIpAddrTable(pIpAddrTable: Pointer; var pdwSize: longint;
bOrder: longint): longint; stdcall;
function Get_if_type(iType: integer): string;
function Get_if_admin_status(iStatus: integer): string;
function Get_if_oper_status(iStatus: integer): string;
implementation
function GetIfTable; stdcall; external 'IPHLPAPI.DLL';
function GetIpAddrTable; stdcall; external 'IPHLPAPI.DLL';
function Get_if_type(iType: integer): string;
var
sResult: string;
begin
sResult := 'UNKNOWN';
case iType of
1: sResult := 'Other';
6: sResult := 'Ethernet';
9: sResult := 'Tokenring';
15: sResult := 'FDDI';
23: sResult := 'PPP';
24: sResult := 'Local loopback';
28: sResult := 'SLIP';
37: sResult := 'ATM';
71: sResult := 'IEEE 802.11';
131: sResult := 'Tunnel';
144: sResult := 'IEEE 1394 (Firewire)';
end;
Result := sResult;
end;
function Get_if_admin_status(iStatus: integer): string;
var
sResult: string;
begin
sResult := 'UNKNOWN';
case iStatus of
1: sResult := 'UP';
2: sResult := 'DOWN';
3: sResult := 'TESTING';
end;
Result := sResult;
end;
function Get_if_oper_status(iStatus: integer): string;
var
sResult: string;
begin
sResult := 'UNKNOWN';
case iStatus of
0: sResult := 'NON_OPERATIONAL';
1: sResult := 'UNREACHABLE';
2: sResult := 'DISCONNECTED';
3: sResult := 'CONNECTING';
4: sResult := 'CONNECTED';
5: sResult := 'OPERATIONAL';
end;
Result := sResult;
end;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With