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

泪湿孤枕 提交于 2019-12-01 09:37:32

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.

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