问题
I am writing a program on a Linux system using Lazarus IDE. The program is supposed to connect to the Internet or Intranet. So, I want to display to the user list of all the available network connections that they can use to connect to the Internet or Intranet like wifi, if there are two active network cards on the system, then this program should display their available connections.
At the moment, I don't know where to start or what tool(s) to use.
Any hints, clues or advice will be greatly appreciated.
回答1:
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.
回答2:
The following code does work on my Linux system. It outputs all the available connection point through which you can connect to the Internet or intranet. I modified the code to print out its name and ip address.
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
// you may need to include other headers
int main()
{
struct ifaddrs* interfaces = NULL;
struct ifaddrs* temp_addr = NULL;
int success;
char *name;
char *address;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0)
{
// Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr != NULL)
{
if (temp_addr->ifa_addr->sa_family == AF_INET) // internetwork only
{
name = temp_addr->ifa_name;
address = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr);
printf("%s %s\n",name,address);
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
}
来源:https://stackoverflow.com/questions/19932189/lazarus-how-to-list-all-the-available-network-connection-on-a-system