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

Linux 網卡狀態檢測:C 語言結合 Shell 命令實現 (ifconfig + popen)

     編輯:關於C語言

需求背景

在嵌入式 Linux 環境下,需檢測指定網卡是否存在、是否 UP、是否連接 (LINKED)。要求環境具備 grep 和 awk。

狀態定義

返回值含義
0網卡不存在 (NO FOUND)
1網卡存在但 DOWN
2網卡 UP 但未連接 (UNPLUGGED)
3網卡 UP 且已連接 (LINKED)
-1檢測異常

核心實現

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int get_if_status(char *if_name) {
    char buffer[BUFSIZ], cmd[100];
    FILE *read_fp;
    int chars_read, ret = 0;

    // 1. 檢查網卡是否存在 (ifconfig -a)
    memset(buffer, 0, BUFSIZ); memset(cmd, 0, 100);
    sprintf(cmd, "ifconfig -a | grep %s", if_name);
    read_fp = popen(cmd, "r");
    if (read_fp) {
        chars_read = fread(buffer, 1, BUFSIZ-1, read_fp);
        pclose(read_fp);
        if (chars_read > 0) ret = 1;
        else { fprintf(stderr, "%s: NO FOUND\r\n", if_name); return 0; }
    }

    // 2. 檢查網卡是否 UP (ifconfig 不帶 -a)
    if (ret == 1) {
        memset(buffer, 0, BUFSIZ); memset(cmd, 0, 100);
        sprintf(cmd, "ifconfig | grep %s", if_name);
        read_fp = popen(cmd, "r");
        if (read_fp) {
            chars_read = fread(buffer, 1, BUFSIZ-1, read_fp);
            pclose(read_fp);
            if (chars_read > 0) ret = 2;
            else { fprintf(stderr, "%s: DOWN\r\n", if_name); return 1; }
        }
    }

    // 3. 檢查 LINKED 狀態 (RUNNING 標誌)
    if (ret == 2) {
        memset(buffer, 0, BUFSIZ); memset(cmd, 0, 100);
        sprintf(cmd, "ifconfig %s | grep RUNNING | awk '{print $3}'", if_name);
        read_fp = popen(cmd, "r");
        if (read_fp) {
            chars_read = fread(buffer, 1, BUFSIZ-1, read_fp);
            pclose(read_fp);
            if (chars_read > 0) { fprintf(stderr, "%s: LINKED\r\n", if_name); return 3; }
            else { fprintf(stderr, "%s: UNPLUGGED\r\n", if_name); return 2; }
        }
    }
    return -1;
}

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

交叉編譯與測試

# 編譯 (MIPS 嵌入式示例)
mips-linux-gnu-gcc -mips32 -EL -mhard-float -Wall -o netlink netlink.c

# 測試輸出
./netlink eth100  # eth100: NO FOUND, if_status = 0
ifconfig eth0 down
./netlink eth0    # eth0: DOWN, if_status = 1
ifconfig eth0 up
./netlink eth0    # eth0: UNPLUGGED, if_status = 2 (網線未插)
# 插上網線後
./netlink eth0    # eth0: LINKED, if_status = 3

優化建議

  • 解析 /sys/class/net/<iface>/operstate 或 carrier 文件,避免啟動 Shell 進程,效率更高
  • 使用 ioctl(SIOCGIFFLAGS) 獲取 IFF_UP/IFF_RUNNING 標誌,純用戶態 C 實現
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved