適用於已知網卡名稱 (如 eth0) 獲取 IPv4 位址。
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 建立 UDP socket
struct ifreq ifr;
strcpy(ifr.ifr_name, "eth0"); // 目標網卡名
if (ioctl(sockfd, SIOCGIFADDR, &ifr) == 0) {
struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
printf("IP: %s\n", inet_ntoa(sin->sin_addr));
} else {
perror("ioctl");
}
close(sockfd);
return 0;
}
獲取系統所有網卡介面資訊,再逐一提取 IP。
struct ifconf ifc;
char buf[512];
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
ioctl(sockfd, SIOCGIFCONF, &ifc); // 獲取所有介面
struct ifreq *ifr = (struct ifreq*)buf;
int count = ifc.ifc_len / sizeof(struct ifreq);
for (int i = 0; i < count; i++, ifr++) {
if (ifr->ifr_addr.sa_family == AF_INET) { // 僅 IPv4
printf("Interface: %s, IP: %s\n",
ifr->ifr_name,
inet_ntoa(((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr));
}
}
ifr_name 存介面名,ifr_ifru 聯合體存 IP、廣播、子網掩碼、MAC、MTU 等。ifc_len 緩衝區長度,ifc_buf 指向 ifreq 陣列緩衝區。Linux 用 ioctl,Windows 需用 WSAIoctl 或 IP Helper API (GetAdaptersAddresses)。
socket() 參數同義:AF_INET (IPv4)、SOCK_DGRAM (UDP)、protocol=0 (自動選協定)。
ifc.ifc_len 需足夠大 (如 1024/4096),否則截斷。CAP_NET_ADMIN。sa_family == AF_INET6 時轉型為 sockaddr_in6。inet_ntoa 非執行緒安全,多執行緒請用 inet_ntop。ioctl 配合 SIOCGIFADDR/SIOCGIFCONF 是 Linux 獲取網卡 IP 的標準底層方式。理解 ifreq/ifconf 聯合體結構,掌握單網卡查詢與全介面遍歷兩種模式,即可靈活應對各類網路工具開發需求。