我正在使用Lazarus IDE在Linux系统上编写程序。该程序应该连接到Internet或Intranet。因此,我想向用户列表显示他们可用于连接到Internet或Intranet的所有可用网络连接,如果系统上有两个活动网卡,则此程序应显示其可用连接。
目前,我不知道从哪里开始或使用什么工具。
任何提示,线索或建议都将不胜感激。
答案 0 :(得分:1)
您可以使用ifconfig列出所有可用的网络接口及其状态。
编辑:为了以编程方式执行,您必须使用带有SIOCGIFCONF的函数ioctl。
#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将返回一个struct ifconf,它有一个指向struct ifreq数组的指针。 这些结构在net / if.h
中定义使用此代码,从ifc.ifc_req可以获得所有接口,请查看struct ifreq的声明,以确定每个数组元素的长度和类型。我想从这里你可以继续独自,如果不是,请告诉我。
答案 1 :(得分:1)
以下代码适用于我的Linux系统。它输出所有可用的连接点,您可以通过它连接到Internet或Intranet。我修改了代码以打印出它的名称和IP地址。
#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);
}