getifaddrs(3)

الاسم
getifaddrs, freeifaddrs - الحصول على عناوين الواجهات

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <sys/types.h>
#include <ifaddrs.h>

int getifaddrs(struct ifaddrs **ifap);
void freeifaddrs(struct ifaddrs *ifa);

الوصف
تنشئ الدالة getifaddrs() قائمة مترابطة من البنى تصف واجهات الشبكة للنظام المحلي، وتخزن عنوان أول عنصر من القائمة في *ifap. تتكون القائمة من بنى ifaddrs، المُعرَّفة كما يلي:

    struct ifaddrs {
        struct ifaddrs  *ifa_next;    /* العنصر التالي في القائمة */
        char            *ifa_name;    /* اسم الواجهة */
        unsigned int     ifa_flags;   /* الأعلام القادمة من SIOCGIFFLAGS */
        struct sockaddr *ifa_addr;    /* عنوان الواجهة */
        struct sockaddr *ifa_netmask; /* قناع الشبكة (netmask) للواجهة */
        union {
            struct sockaddr *ifu_broadaddr;
                             /* عنوان البث (broadcast) للواجهة */
            struct sockaddr *ifu_dstaddr;
                             /* عنوان الوجهة لنقطة إلى نقطة (point-to-point) */
        } ifa_ifu;
    #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
    #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
        void            *ifa_data;    /* بيانات خاصة بالعنوان */
    };

يحتوي الحقل ifa_next على مؤشر إلى البنية التالية في القائمة، أو NULL إذا كان هذا هو العنصر الأخير في القائمة.

يشير ifa_name إلى اسم الواجهة المنتهي بقيمة خالية.

يحتوي الحقل ifa_flags على أعلام الواجهة، كما تُرجعها عملية SIOCGIFFLAGS ioctl(2) (انظر netdevice(7) للحصول على قائمة بهذه الأعلام).

يشير الحقل ifa_addr إلى بنية تحتوي على عنوان الواجهة. (يجب الرجوع إلى الحقل الفرعي sa_family لتحديد تنسيق بنية العنوان.) قد يحتوي هذا الحقل على مؤشر فارغ.

يشير الحقل ifa_netmask إلى بنية تحتوي على قناع الشبكة المرتبط بـ ifa_addr، إذا كان ذلك مناسبًا لعائلة العنوان. قد يحتوي هذا الحقل على مؤشر فارغ.

اعتمادًا على ما إذا كان البت IFF_BROADCAST أو IFF_POINTOPOINT مضبوطًا في ifa_flags (يمكن ضبط واحد فقط في كل مرة)، إما أن يحتوي ifa_broadaddr على عنوان البث المرتبط بـ ifa_addr (إذا كان مناسبًا لعائلة العنوان) أو يحتوي ifa_dstaddr على عنوان الوجهة للواجهة من نقطة إلى نقطة.

يشير الحقل ifa_data إلى مخزن مؤقت يحتوي على بيانات خاصة بعائلة العنوان؛ قد يكون هذا الحقل NULL إذا لم توجد مثل هذه البيانات لهذه الواجهة.

البيانات التي تُرجعها getifaddrs() مُخصصة ديناميكيًا ويجب تحريرها باستخدام freeifaddrs() عند عدم الحاجة إليها.

قيمة الإرجاع
عند النجاح، تُرجع getifaddrs() صفرًا؛ عند الخطأ، تُرجع -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء
قد تفشل getifaddrs() وتُضبط errno لأي من الأخطاء المُحددة لـ socket(2)، bind(2)، getsockname(2)، recvmsg(2)، sendto(2)، malloc(3)، أو realloc(3).

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
getifaddrs(), freeifaddrs() | سلامة الخيوط | MT-Safe

المعايير
لا شيء.

التاريخ
ظهرت هذه الدالة لأول مرة في BSDi وهي موجودة على أنظمة BSD، ولكن بدلالات مختلفة قليلاً موثقة—تُرجع إدخالاً واحدًا لكل واجهة، وليس لكل عنوان. هذا يعني أن ifa_addr والحقول الأخرى يمكن أن تكون NULL فعليًا إذا لم يكن للواجهة عنوان، ولا يُرجع عنوان مستوى الارتباط إذا كانت الواجهة تحتوي على عنوان IP مُخصص. أيضًا، تختلف طريقة اختيار إما ifa_broadaddr أو ifa_dstaddr على الأنظمة المختلفة.

ظهرت getifaddrs() لأول مرة في glibc 2.3، ولكن قبل glibc 2.3.3، دعم التنفيذ عناوين IPv4 فقط؛ أُضيف دعم IPv6 في glibc 2.3.3. دعم عائلات العناوين غير IPv4 متاح فقط على النوى التي تدعم netlink.

ملاحظات
العناوين التي تُرجع على لينكس ستكون عادةً عناوين IPv4 و IPv6 المُخصصة للواجهة، ولكن أيضًا عنوان AF_PACKET واحد لكل واجهة يحتوي على تفاصيل منخفضة المستوى حول الواجهة وطبقتها المادية. في هذه الحالة، قد يحتوي الحقل ifa_data على مؤشر إلى struct rtnl_link_stats، المُعرَّف في <linux/if_link.h> (في لينكس 2.4 والإصدارات الأقدم، struct net_device_stats، المُعرَّف في <linux/netdevice.h>)، والذي يحتوي على سمات وإحصائيات واجهة متنوعة.

أمثلة
البرنامج أدناه يوضح استخدام getifaddrs() و freeifaddrs() و getnameinfo(3). إليك ما نراه عند تشغيل هذا البرنامج على أحد الأنظمة:

    $ ./a.out;
    lo       AF_PACKET (17)
                    tx_packets =        524; rx_packets =        524
                    tx_bytes   =      38788; rx_bytes   =      38788
    wlp3s0   AF_PACKET (17)
                    tx_packets =     108391; rx_packets =     130245
                    tx_bytes   =   30420659; rx_bytes   =   94230014
    em1      AF_PACKET (17)
                    tx_packets =          0; rx_packets =          0
                    tx_bytes   =          0; rx_bytes   =          0
    lo       AF_INET (2)
                    address: <127.0.0.1>
    wlp3s0   AF_INET (2)
                    address: <192.168.235.137>
    lo       AF_INET6 (10)
                    address: <::1>
    wlp3s0   AF_INET6 (10)
                    address: <fe80::7ee9:d3ff:fef5:1a91%wlp3s0>

  مصدر البرنامج
    #define _GNU_SOURCE     /* To get defns of NI_MAXSERV and NI_MAXHOST */
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <ifaddrs.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <linux/if_link.h>

    int main(int argc, char *argv[])
    {
        struct ifaddrs *ifaddr;
        int family, s;
        char host[NI_MAXHOST];

        if (getifaddrs(&ifaddr) == -1) {
            perror("getifaddrs");
            exit(EXIT_FAILURE);
        }

        /* Walk through linked list, maintaining head pointer so we
           can free list later.  */

        for (struct ifaddrs *ifa = ifaddr; ifa != NULL;
                 ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == NULL)
                continue;

            family = ifa->ifa_addr->sa_family;

            /* Display interface name and family (including symbolic
               form of the latter for the common families).  */

            printf("%-8s %s (%d)\n",
                   ifa->ifa_name,
                   (family == AF_PACKET) ? "AF_PACKET" :
                   (family == AF_INET) ? "AF_INET" :
                   (family == AF_INET6) ? "AF_INET6" : "???",
                   family);

            /* For an AF_INET* interface address, display the address.  */

            if (family == AF_INET || family == AF_INET6) {
                s = getnameinfo(ifa->ifa_addr,
                        (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                              sizeof(struct sockaddr_in6),
                        host, NI_MAXHOST,
                        NULL, 0, NI_NUMERICHOST);
                if (s != 0) {
                    printf("getnameinfo() failed: %s\n", gai_strerror(s));
                    exit(EXIT_FAILURE);
                }

                printf("\t\taddress: <%s>\n", host);

            } else if (family == AF_PACKET && ifa->ifa_data != NULL) {
                struct rtnl_link_stats *stats = ifa->ifa_data;

                printf("\t\ttx_packets = %10u; rx_packets = %10u\n"
                       "\t\ttx_bytes   = %10u; rx_bytes   = %10u\n",
                       stats->tx_packets, stats->rx_packets,
                       stats->tx_bytes, stats->rx_bytes);
            }
        }

        freeifaddrs(ifaddr);
        exit(EXIT_SUCCESS);
    }

انظر أيضًا
bind(2), getsockname(2), socket(2), packet(7), ifconfig(8)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.