Lazarus: How to List All the Available Network Connection on a System

Lazarus: How to list all the available network connection on a system?

You can use ifconfig to list all available network interfaces and their status.

Edit: For doing it programmatically you have to use function ioctl with SIOCGIFCONF.

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>

int main()
{
int sockfd, len, lastlen;
char *ptr, *buf;
struct ifconf ifc;
struct ifreq *ifr;
char ifname[IFNAMSIZ + 1];
char str[INET6_ADDRSTRLEN];

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

lastlen = 0;
len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
for ( ; ; )
{
buf = malloc(len);
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
{
if (errno != EINVAL || lastlen != 0)
exit(-1);
}
else
{
if (ifc.ifc_len == lastlen)
break; /* success, len has not changed */
lastlen = ifc.ifc_len;
}

len += 10 * sizeof(struct ifreq); /* increment */
free(buf);
}

printf("LEN: %d\n", ifc.ifc_len);

for (ptr = buf; ptr < buf + ifc.ifc_len; )
{
ifr = (struct ifreq *) ptr;

ptr += sizeof(struct ifreq); /* for next one in buffer */

memcpy(ifname, ifr->ifr_name, IFNAMSIZ);

printf("Interface name: %s\n", ifname);

const char *res;

switch (ifr->ifr_addr.sa_family)
{
case AF_INET6:
res = inet_ntop(ifr->ifr_addr.sa_family, &(((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr), str, INET6_ADDRSTRLEN);
break;
case AF_INET:
res = inet_ntop(ifr->ifr_addr.sa_family, &(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr), str, INET_ADDRSTRLEN);
break;
default:
printf("OTHER\n");
str[0] = 0;
res = 0;
}

if (res != 0)
{
printf("IP Address: %s\n", str);
}
else
{
printf("ERROR\n");
}
}

return 0;
}

ioctl SIOCGIFCONF will return, if success, a struct ifconf which has a pointer to an array of struct ifreq.
These structs are defined in net/if.h

Using this code, from ifc.ifc_req you can get all interfaces, please look at the declaration of struct ifreq in order to determine the length and type of each array element. I think from here you can continue alone, if not please let me know.

bind/connect to network interface card using FreePascal or other language(s)?

I just compiled it and executed it, it seems to work. You just need to change the IP addresses and ports and add more error checking.

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>

#define MY_PORT 8564
#define THEIR_PORT 8090

int main()
{
int sockfd;
struct sockaddr_in myaddr;
struct sockaddr_in theiraddr;
int res;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&myaddr, 0, sizeof(struct sockaddr_in));

myaddr.sin_family = AF_INET;
myaddr.sin_port = htons((unsigned short)MY_PORT);
//myaddr.sin_addr = INADDR_ANY; //for any interface

res = inet_pton(AF_INET, "127.0.0.1", &myaddr.sin_addr);

if (1 == res)
{
res = bind(sockfd, (const struct sockaddr *)&myaddr, sizeof(struct sockaddr_in));

if (0 == res)
{
printf("PASO-1\n");
theiraddr.sin_family = AF_INET;
theiraddr.sin_port = htons((unsigned short)THEIR_PORT);
inet_pton(AF_INET, "10.0.2.78", &theiraddr.sin_addr);
printf("PASO-2\n");
connect(sockfd, (const struct sockaddr *)&theiraddr, sizeof(struct sockaddr_in));
}
}

return 0;
}

Get all IPs in the same network as my computer

This is a VB solution, but I'm pretty sure you'll be able to make the changes you need to make this work!

There's probably a better way, but this was a first cut.

Imports System.Net.NetworkInformation
Imports System.Directory Services

Class NetworkInfo

Function GetComputers() as list(Of String)

dim List as new list(of String)

Dim DomainEntry as new DirectoryEntry("WinNT://" + DomainInfo.GetDomain.Trim())
DomainEntry.Children.SchemaFilter.Add("computer")

For Each Machine as DirectoryEntry in DomainEntry.Children
List.Add(Machine.Name)
Next

return List

End Function

End Class

There are all sorts of useful tools knocking about in the System.Net.NetworkInformation namespace to let you capture things like the IP address, etc.

delphi check internet connection

Add in your uses the unit "WinNet". With the function "InternetGetConnectedState" return a value for internet state and type. See below:

function YourFunctionName : boolean;
var
origin : cardinal;
begin
result := InternetGetConnectedState(@origin,0);

//connections origins by origin value
//NO INTERNET CONNECTION = 0;
//INTERNET_CONNECTION_MODEM = 1;
//INTERNET_CONNECTION_LAN = 2;
//INTERNET_CONNECTION_PROXY = 4;
//INTERNET_CONNECTION_MODEM_BUSY = 8;
end;

update i newer Delphi versions add "wininet" as uses class.

How to get a list with all computers from the local network?

See the documentation for WNetEnumResource, 'lpcCount' ('Entries' parameter in your code') on return receives the number of items enumerated. You're terminating the enumeration if it is greater than 0, but this is expected. You're requesting one item to be enumerated and the function does that and sets it to 1. Just remove that condition from loop termination:

..
until (Res <> NO_ERROR) or (Limit > 100);
..

You may also want to review the code, f.i. you don't need StrPas.

Get information about the installed network adapters

Jan Schulz's code works fine when properly converted to unicode-friendly Delphi.

I've done some corrections:

  • As TOndrej has pointed, char must be converted to AnsiChar when needed. In this case, this only occurs in the Padding field of the SockAddr_Gen record, which was not only screwing the record, but also causing SizeOf(Interface_Info), and subsequently NoOfInterfaces, to return a wrong result. Since it's not really a character, it is better to define it as a byte.

  • Dropped PChars used to hold results of inet_ntoa calls, and assigning TNetworkInterface string fields directly.

  • Strings in TNetworkInterface are fine, because they are not passed to any api calls. Also, ComputerName is passed to GetComputerName api, which expects a PWideChar/PChar.


Unit USock;

Interface

Uses Windows, Winsock;

{ Unit to identify the network interfaces
This code requires at least Win98/ME/2K, 95 OSR 2 or NT service pack #3
as WinSock 2 is used (WS2_32.DLL) }

// Constants found in manual on non-officially documented M$ Winsock functions
Const SIO_GET_INTERFACE_LIST = $4004747F;
IFF_UP = $00000001;
IFF_BROADCAST = $00000002;
IFF_LOOPBACK = $00000004;
IFF_POINTTOPOINT = $00000008;
IFF_MULTICAST = $00000010;

Type SockAddr_Gen = Packed Record
AddressIn : SockAddr_In;
Padding : Packed Array [0..7] of Byte;
end;

Interface_Info = Record
iiFlags : u_Long;
iiAddress : SockAddr_Gen;
iiBroadcastAddress : SockAddr_Gen;
iiNetmask : SockAddr_Gen;
end;

tNetworkInterface = Record
ComputerName : String;
AddrIP : String;
SubnetMask : String;
AddrNet : String;
AddrLimitedBroadcast : String;
AddrDirectedBroadcast : String;
IsInterfaceUp : Boolean;
BroadcastSupport : Boolean;
IsLoopback : Boolean;
end;

tNetworkInterfaceList = Array of tNetworkInterface;

Function WSAIoctl (aSocket : TSocket;
aCommand : DWord;
lpInBuffer : Pointer;
dwInBufferLen : DWord;
lpOutBuffer : Pointer;
dwOutBufferLen : DWord;
lpdwOutBytesReturned : LPDWord;
lpOverLapped : Pointer;
lpOverLappedRoutine : Pointer) : Integer; stdcall; external 'WS2_32.DLL';

Function GetNetworkInterfaces (Var aNetworkInterfaceList : tNetworkInterfaceList): Boolean;

implementation

Function GetNetworkInterfaces (Var aNetworkInterfaceList : tNetworkInterfaceList): Boolean;
// Returns a complete list the of available network interfaces on a system (IPv4)
// Copyright by Dr. Jan Schulz, 23-26th March 2007
// This version can be used for free and non-profit projects. In any other case get in contact
// Written with information retrieved from MSDN
// www.code10.net
Var aSocket : TSocket;
aWSADataRecord : WSAData;
NoOfInterfaces : Integer;
NoOfBytesReturned : u_Long;
InterfaceFlags : u_Long;
NameLength : DWord;
pAddrIP : SockAddr_In;
pAddrSubnetMask : SockAddr_In;
pAddrBroadcast : Sockaddr_In;
DirBroadcastDummy : In_Addr;
NetAddrDummy : In_Addr;
Buffer : Array [0..30] of Interface_Info;
i : Integer;
Begin
Result := False;
SetLength (aNetworkInterfaceList, 0);

// Startup of old the WinSock
// WSAStartup ($0101, aWSADataRecord);

// Startup of WinSock2
WSAStartup(MAKEWORD(2, 0), aWSADataRecord);

// Open a socket
aSocket := Socket (AF_INET, SOCK_STREAM, 0);

// If impossible to open a socket, not worthy to go any further
If (aSocket = INVALID_SOCKET) THen Exit;

Try
If WSAIoCtl (aSocket, SIO_GET_INTERFACE_LIST, NIL, 0,
@Buffer, 1024, @NoOfBytesReturned, NIL, NIL) <> SOCKET_ERROR THen
Begin
NoOfInterfaces := NoOfBytesReturned Div SizeOf (Interface_Info);
SetLength (aNetworkInterfaceList, NoOfInterfaces);

// For each of the identified interfaces get:
For i := 0 to NoOfInterfaces - 1 do
Begin

With aNetworkInterfaceList[i] do
Begin

// Get the name of the machine
NameLength := MAX_COMPUTERNAME_LENGTH + 1;
SetLength (ComputerName, NameLength) ;
If Not GetComputerName (PChar (Computername), NameLength) THen ComputerName := '';

// Get the IP address
pAddrIP := Buffer[i].iiAddress.AddressIn;
AddrIP := string(inet_ntoa (pAddrIP.Sin_Addr));

// Get the subnet mask
pAddrSubnetMask := Buffer[i].iiNetMask.AddressIn;
SubnetMask := string(inet_ntoa (pAddrSubnetMask.Sin_Addr));

// Get the limited broadcast address
pAddrBroadcast := Buffer[i].iiBroadCastAddress.AddressIn;
AddrLimitedBroadcast := string(inet_ntoa (pAddrBroadcast.Sin_Addr));

// Calculate the net and the directed broadcast address
NetAddrDummy.S_addr := Buffer[i].iiAddress.AddressIn.Sin_Addr.S_Addr;
NetAddrDummy.S_addr := NetAddrDummy.S_addr And Buffer[i].iiNetMask.AddressIn.Sin_Addr.S_Addr;
DirBroadcastDummy.S_addr := NetAddrDummy.S_addr Or Not Buffer[i].iiNetMask.AddressIn.Sin_Addr.S_Addr;

AddrNet := string(inet_ntoa ((NetAddrDummy)));
AddrDirectedBroadcast := string(inet_ntoa ((DirBroadcastDummy)));

// From the evaluation of the Flags we receive more information
InterfaceFlags := Buffer[i].iiFlags;

// Is the network interface up or down ?
If (InterfaceFlags And IFF_UP) = IFF_UP THen IsInterfaceUp := True
Else IsInterfaceUp := False;

// Does the network interface support limited broadcasts ?
If (InterfaceFlags And IFF_BROADCAST) = IFF_BROADCAST THen BroadcastSupport := True
Else BroadcastSupport := False;

// Is the network interface a loopback interface ?
If (InterfaceFlags And IFF_LOOPBACK) = IFF_LOOPBACK THen IsLoopback := True
Else IsLoopback := False;
end;
end;
end;
Except
//Result := False;
end;

// Cleanup the mess
CloseSocket (aSocket);
WSACleanUp;
Result := True;
end;

end.


Related Topics



Leave a reply



Submit