2009年11月30日 星期一

Get my IP from network card

這個範例顯示如何取得網卡的IP:
eth0.c


#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
int fd;
char IPbuf[30];
struct ifreq ifr;
struct sockaddr_in *myAddr;

strcpy(ifr.ifr_name, "eth0");
fd = socket(AF_INET, SOCK_STREAM, 0);

if(ioctl(fd, SIOCGIFFLAGS, &ifr)>=0)
{
if (ifr.ifr_flags & IFF_UP)
puts("eth0 is UP");
else
{
puts("eth0 is DOWN");
return 1;
}
}

if(ioctl(fd, SIOCGIFADDR, &ifr)>=0)
{
myAddr = (struct sockaddr_in*)&ifr.ifr_addr;
sprintf(IPbuf,inet_ntoa(myAddr->sin_addr));
printf("IP:%s\n",IPbuf);
}

close(fd);

return 0;
}



執行結果:
[root@ecken01 net]# gcc -Wall eth0.c -o eth0
[root@ecken01 net]# ./eth0
eth0 is UP
IP:192.168.0.51

程式中struct ifreq 定義:

struct ifreq {
char ifr_name[IFNAMSIZ];/* Interface name */
union {
struct sockaddrifr_addr;
struct sockaddrifr_dstaddr;
struct sockaddrifr_broadaddr;
struct sockaddrifr_netmask;
struct sockaddrifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmapifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
};

struct ifconf {
int ifc_len; /* size of buffer */
union {
char * ifc_buf; /* buffer address */
struct ifreq *ifc_req; /* array of structures */
};
};




ioctl的指令:


SIOCGIFNAME:回傳網路卡名稱
SIOCGIFINDEX:取得網路卡索引值
SIOCGIFFLAGS, SIOCSIFFLAGS:取得或設定裝置的Enable旗標

















Device flags
IFF_UP
Interface is running.
IFF_BROADCAST
Valid broadcast address set.
IFF_DEBUG
Internal debugging flag.
IFF_LOOPBACK
Interface is a loopback interface.
IFF_POINTOPOINT
Interface is a point-to-point link.
IFF_RUNNING
Resources allocated.
IFF_NOARP
No arp protocol, L2 destination address not set.
IFF_PROMISC
Interface is in promiscuous mode.
IFF_NOTRAILERS
Avoid use of trailers.
IFF_ALLMULTI
Receive all multicast packets.
IFF_MASTER
Master of a load balancing bundle.
IFF_SLAVE
Slave of a load balancing bundle.
IFF_MULTICAST
Supports multicast
IFF_PORTSEL
Is able to select media type via ifmap.
IFF_AUTOMEDIA
Auto media selection active.
IFF_DYNAMIC
The addresses are lost when the interface goes down.


SIOCGIFMTU, SIOCSIFMTU:傳回或設定最大的傳輸單位MTU
SIOCGIFHWADDR, SIOCSIFHWADDR:取得或設定網路卡的硬體位址
SIOCSIFHWBROADCAST:設定網路卡的廣播位址
SIOCGIFMAP, SIOCSIFMAP:取得或設定網路卡的硬體參數,參數使用ifr_map
struct ifmap {
unsigned long mem_start;
unsigned long mem_end;
unsigned short base_addr;
unsigned char irq;
unsigned char dma;
unsigned char port;
};

SIOCADDMULTI, SIOCDELMULTI:增加或刪除網路卡的位址(link layer using ifr_hwaddr)
SIOCGIFTXQLEN, SIOCSIFTXQLEN:取得或設定傳輸佇列的長度
SIOCSIFNAME:改變網路卡名稱
SIOCGIFADDR:取得網路卡位址
SIOCGIFCONF:傳回網路卡位址列表(IPV4)


參考資料:
netdevice(7) - Linux man page

沒有留言: