2008年1月4日 星期五

取得網路裝置(NETDEVICE)的系統訊息

Standard
之前提到正在開發的 Network Status Daemon ,其監控 netdevice 的部份已經完成,從 System Tray 上可以看到現在的網路傳送接收狀態、是否有插上網路線、IP位置等等。其中除了讀取/proc/net/dev 來取得封包流量,還有許多針對 netdevice 的 ioctl() 實作。

這是一個檢查網路裝置是否已經被 ifconfig bring up 的例子:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

void main(void)
{
struct ifreq ifr;
int sockfd;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&ifr, sizeof(ifr));
strcpy(ifr.ifr_name, "eth0");

ioctl(sockfd, SIOCGIFFLAGS, &ifr);
/*
ifr_flags 的各項旗標和說明:
IFF_UP 裝置正在運作
IFF_BROADCAST 有效的廣播位址
IFF_DEBUG Debug 標誌
IFF_LOOPBACK 這是 Loopback 裝置
IFF_POINTOPOINT 這是點到點的網路裝置介面
IFF_RUNNING 資源已分配
IFF_NOARP 無arp協議,沒有設置第二層目的地址
IFF_PROMISC 介面為雜湊(promiscuous)模式
IFF_NOTRAILERS 避免使用 trailer
IFF_ALLMULTI 接收所有群組廣播(multicast)封包資料
IFF_MASTER 主負載平衡群(bundle)
IFF_SLAVE 從負載平衡群(bundle)
IFF_MULTICAST 支持群組廣播(multicast)
IFF_PORTSEL 可以通過 ifmap 選擇 media 類型
IFF_AUTOMEDIA 自動選擇 media
IFF_DYNAMIC 裝置介面關閉時丟棄地址
*/
if (ifr.ifr_flags & IFF_UP) {
printf("eth0 is up!");
}
close(sockfd);
}


結構 struct ifreq 的定義如下:
struct ifreq
{
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
}


ioctl() 可以操作的標誌如下:
SIOCGIFNAME
SIOCGIFINDEX
SIOCGIFFLAGS, SIOCSIFFLAGS
SIOCGIFMETRIC, SIOCSIFMETRIC
SIOCGIFMTU, SIOCSIFMTU
SIOCGIFHWADDR, SIOCSIFHWADDR
SIOCSIFHWBROADCAST
SIOCGIFMAP, SIOCSIFMAP
SIOCADDMULTI, SIOCDELMULTI
SIOCGIFTXQLEN, SIOCSIFTXQLEN
SIOCSIFNAME
SIOCGIFCONF


詳細說明可參考 Manpage of NETDEVICE 或是從這取得相關說明:
http://www.linuxinfor.com/english/man7/netdevice.html