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

主宰稳场 提交于 2020-01-11 06:44:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!