首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言實現 Linux 網卡狀態檢測:精簡版 getifaddrs 實戰

     編輯:關於C語言

前言

在 Linux 系統編程中,檢測網卡(網路介面)的連線狀態是常見需求。傳統做法需打開 Socket、呼叫 ioctl 並解析 ifreq 結構,程式碼繁瑣且易出錯。本文介紹一種更精簡的方法:利用 getifaddrs() 函數一次性獲取所有介面資訊,輕鬆判斷網卡是否啟用、纜線是否連接。

核心原理

getifaddrs() 會填充一個 struct ifaddrs 鏈表,每個節點包含介面名稱、位址族、旗標(flags)等資訊。我們只需遍歷鏈表,找到目標介面並檢查其 ifa_flags 中的 IFF_UP(介面啟用)與 IFF_RUNNING(實體連線)兩個旗標即可。

完整程式碼

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <ifaddrs.h>

int c_ifaddrs_netlink_status(const char *if_name) {
    struct ifaddrs *ifa = NULL, *ifList;
    if (getifaddrs(&ifList) < 0) {
        return -1;
    }
    for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
            if (strcmp(ifa->ifa_name, if_name) == 0) {
                if (!(ifa->ifa_flags & IFF_UP)) {
                    printf("DEVICE_DOWN\r\n");
                    freeifaddrs(ifList);
                    return 1;
                }
                if (!(ifa->ifa_flags & IFF_RUNNING)) {
                    printf("DEVICE_UNPLUGGED\r\n");
                    freeifaddrs(ifList);
                    return 2;
                }
                printf("DEVICE_LINKED\r\n");
                freeifaddrs(ifList);
                return 3;
            }
        }
    }
    fprintf(stderr, "DEVICE_NONE\r\n");
    freeifaddrs(ifList);
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "usage: %s <ethname>\r\n", argv[0]);
        return -1;
    }
    int status = c_ifaddrs_netlink_status(argv[1]);
    fprintf(stderr, "c_ifaddrs_netlink_status if_status = %d\n", status);
    return 0;
}

程式碼解析

  1. 獲取介面列表:getifaddrs(&ifList) 動態分配記憶體,使用完畢必須呼叫 freeifaddrs() 釋放。
  2. 過濾 IPv4 介面:僅處理 sa_family == AF_INET 的節點,避免干擾。
  3. 旗標判斷邏輯:
    • IFF_UP 未置位 → 介面被管理員關閉(DEVICE_DOWN)。
    • IFF_RUNNING 未置位 → 纜線未插或無載波(DEVICE_UNPLUGGED)。
    • 兩者皆置位 → 連線正常(DEVICE_LINKED)。
  4. 未找到介面:輸出 DEVICE_NONE 並回傳 0。

編譯與測試

$ gcc -o net_check net_check.c
$ ./net_check eth0
DEVICE_LINKED
c_ifaddrs_netlink_status if_status = 3

優勢總結

  • 無需手動建立 Socket、呼叫 ioctl,程式碼行數減少 50% 以上。
  • 直接讀取核心維護的旗標,資訊更即時、準確。
  • 可輕鬆擴展:同一鏈表即可獲取 IPv6 位址、MAC 位址、MTU 等資訊。

這個精簡版實現非常適合嵌入式裝置、網路監控工具或系統管理腳本中快速檢測網卡鏈路狀態。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved