中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
获取本机ip和网卡mac等信息的代码
作者:未知 时间:2005-09-13 19:22 出处:ChinaUnix.net 责编:chinaitpower
              摘要:获取本机ip和网卡mac等信息的代码

我以前贴过,好像被删了。老有人问。我就再贴了

支持多网卡。很久以前写的,参照几本资料,忘了是哪些。
[code:1:034fc26618]
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>

#define MAXINTERFACES   16

main (argc, argv)
register int argc;
register char *argv[];
{
   register int fd, intrface, retn = 0;
   struct ifreq buf[MAXINTERFACES];
   struct arpreq arp;
   struct ifconf ifc;

   if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0) {
      ifc.ifc_len = sizeof buf;
      ifc.ifc_buf = (caddr_t) buf;
      if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {
         intrface = ifc.ifc_len / sizeof (struct ifreq);
         printf("interface num is intrface=%d\n\n\n",intrface);
         while (intrface-- > 0)
          {
            printf ("net device %s\n", buf[intrface].ifr_name);

/*Jugde whether the net card status is promisc  */
            if (!(ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]))) {
               if (buf[intrface].ifr_flags & IFF_PROMISC) {
                  puts ("the interface is PROMISC");
                  retn++;
               }
            } else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
            }

/*Jugde whether the net card status is up       */
            if (buf[intrface].ifr_flags & IFF_UP) {
                puts("the interface status is UP");
               }
            else {
                puts("the interface status is DOWN");
            }

/*Get IP of the net card */
            if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface])))
                {
                 puts ("IP address is:");
                 puts(inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));
                 puts("");
                   //puts (buf[intrface].ifr_addr.sa_data);
                }
            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
/* this section can't get Hardware Address,I don't know whether the reason is module driver
//          ((struct sockaddr_in*)&arp.arp_pa)->sin_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr;
            arp.arp_pa.sa_family = AF_INET;
            arp.arp_ha.sa_family = AF_INET;
            ((struct sockaddr_in*)&arp.arp_pa)->sin_addr.s_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr.s_addr;
            if (!(ioctl (fd, SIOCGARP, (char *) &arp)))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)arp.arp_ha.sa_data[0],
                                (unsigned char)arp.arp_ha.sa_data[1],
                                (unsigned char)arp.arp_ha.sa_data[2],
                                (unsigned char)arp.arp_ha.sa_data[3],
                                (unsigned char)arp.arp_ha.sa_data[4],
                                (unsigned char)arp.arp_ha.sa_data[5]);

                 puts("");
                 puts("");
                }

*/

/*Get HW ADDRESS of the net card */
            if (!(ioctl (fd, SIOCGIFHWADDR, (char *) &buf[intrface])))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[0],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[1],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[2],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[3],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[4],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[5]);

                 puts("");
                 puts("");
                }

            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
        }
      } else
         perror ("cpm: ioctl");

   } else
      perror ("cpm: socket");

    close (fd);
    return retn;
}
[/code:1:034fc26618]

 gadfly 回复于:2003-06-06 18:18:23
另外有人问我solaris怎么有问题,我查阅了一下,确实如此。

ioctl用的不是一个选项,稍微改了一下,编译的时候,方法如下:
gcc getip.c -DSOLARIS -lsocket -lnsl
[code:1:fa24714df5]
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>

#ifdef SOLARIS
#include <sys/sockio.h>
#endif

#define MAXINTERFACES   16

main (argc, argv)
register int argc;
register char *argv[];
{
   register int fd, intrface, retn = 0;
   struct ifreq buf[MAXINTERFACES];
   struct arpreq arp;
   struct ifconf ifc;

   if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0) {
      ifc.ifc_len = sizeof buf;
      ifc.ifc_buf = (caddr_t) buf;
      if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {
         intrface = ifc.ifc_len / sizeof (struct ifreq);
         printf("interface num is intrface=%d\n\n\n",intrface);
         while (intrface-- > 0)
          {
            printf ("net device %s\n", buf[intrface].ifr_name);

/*Jugde whether the net card status is promisc  */
            if (!(ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]))) {
               if (buf[intrface].ifr_flags & IFF_PROMISC) {
                  puts ("the interface is PROMISC");
                  retn++;
               }
            } else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
            }

/*Jugde whether the net card status is up       */
            if (buf[intrface].ifr_flags & IFF_UP) {
                puts("the interface status is UP");
               }
            else {
                puts("the interface status is DOWN");
            }

/*Get IP of the net card */
            if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface])))
                {
                 puts ("IP address is:");
                 puts(inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));
                 puts("");
                   //puts (buf[intrface].ifr_addr.sa_data);
                }
            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
/* this section can't get Hardware Address,I don't know whether the reason is module driver
//          ((struct sockaddr_in*)&arp.arp_pa)->sin_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr;
            arp.arp_pa.sa_family = AF_INET;
            arp.arp_ha.sa_family = AF_INET;
            ((struct sockaddr_in*)&arp.arp_pa)->sin_addr.s_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr.s_addr;
            if (!(ioctl (fd, SIOCGARP, (char *) &arp)))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)arp.arp_ha.sa_data[0],
                                (unsigned char)arp.arp_ha.sa_data[1],
                                (unsigned char)arp.arp_ha.sa_data[2],
                                (unsigned char)arp.arp_ha.sa_data[3],
                                (unsigned char)arp.arp_ha.sa_data[4],
                                (unsigned char)arp.arp_ha.sa_data[5]);

                 puts("");
                 puts("");
                }

*/

/*Get HW ADDRESS of the net card */
#ifdef SOLARIS
            if (!(ioctl (fd,  SIOCGENADDR, (char *) &buf[intrface])))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)buf[intrface].ifr_enaddr[0],
                                (unsigned char)buf[intrface].ifr_enaddr[1],
                                (unsigned char)buf[intrface].ifr_enaddr[2],
                                (unsigned char)buf[intrface].ifr_enaddr[3],
                                (unsigned char)buf[intrface].ifr_enaddr[4],
                                (unsigned char)buf[intrface].ifr_enaddr[5]);

                 puts("");
                 puts("");
                }
#else
            if (!(ioctl (fd, SIOCGIFHWADDR, (char *) &buf[intrface])))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[0],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[1],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[2],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[3],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[4],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[5]);

                 puts("");
                 puts("");
                }
#endif

            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
        }
      } else
         perror ("cpm: ioctl");

   } else
      perror ("cpm: socket");

    close (fd);
    return retn;
}
[/code:1:fa24714df5]

 gadfly 回复于:2003-06-06 18:28:40
但是用以上的方法,会报错类似
[quote:800085c1f7]
cpm: ioctl device hme0: No such file or directory
[/quote:800085c1f7]
的错。我又查了一下,有资料说,solaris上对SIOCGENADDR ioctl 没有实现。

我就仔细看了看代码,试试以前被我注释的,发现被注释的可以在solaris用,但是不能在linux下用。 :D:D:D

所以最终版本是下面这个
solaris上编译方式是:
gcc getip.c -DSOLARIS -lsocket -lnsl 

linux直接用
gcc getip.c

[code:1:800085c1f7]
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>

#ifdef SOLARIS
#include <sys/sockio.h>
#endif

#define MAXINTERFACES   16

main (argc, argv)
register int argc;
register char *argv[];
{
   register int fd, intrface, retn = 0;
   struct ifreq buf[MAXINTERFACES];
   struct arpreq arp;
   struct ifconf ifc;

   if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0) {
      ifc.ifc_len = sizeof buf;
      ifc.ifc_buf = (caddr_t) buf;
      if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {
         intrface = ifc.ifc_len / sizeof (struct ifreq);
         printf("interface num is intrface=%d\n\n\n",intrface);
         while (intrface-- > 0)
          {
            printf ("net device %s\n", buf[intrface].ifr_name);

/*Jugde whether the net card status is promisc  */
            if (!(ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]))) {
               if (buf[intrface].ifr_flags & IFF_PROMISC) {
                  puts ("the interface is PROMISC");
                  retn++;
               }
            } else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
            }

/*Jugde whether the net card status is up       */
            if (buf[intrface].ifr_flags & IFF_UP) {
                puts("the interface status is UP");
               }
            else {
                puts("the interface status is DOWN");
            }

/*Get IP of the net card */
            if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface])))
                {
                 puts ("IP address is:");
                 puts(inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));
                 puts("");
                   //puts (buf[intrface].ifr_addr.sa_data);
                }
            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
/* this section can't get Hardware Address,I don't know whether the reason is module driver*/
//          ((struct sockaddr_in*)&arp.arp_pa)->sin_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr;
#ifdef SOLARIS
            arp.arp_pa.sa_family = AF_INET;
            arp.arp_ha.sa_family = AF_INET;
            ((struct sockaddr_in*)&arp.arp_pa)->sin_addr.s_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr.s_addr;
            if (!(ioctl (fd, SIOCGARP, (char *) &arp)))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)arp.arp_ha.sa_data[0],
                                (unsigned char)arp.arp_ha.sa_data[1],
                                (unsigned char)arp.arp_ha.sa_data[2],
                                (unsigned char)arp.arp_ha.sa_data[3],
                                (unsigned char)arp.arp_ha.sa_data[4],
                                (unsigned char)arp.arp_ha.sa_data[5]);

                 puts("");
                 puts("");
                }


#else
#if 0
/*Get HW ADDRESS of the net card */
            if (!(ioctl (fd,  SIOCGENADDR, (char *) &buf[intrface])))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)buf[intrface].ifr_enaddr[0],
                                (unsigned char)buf[intrface].ifr_enaddr[1],
                                (unsigned char)buf[intrface].ifr_enaddr[2],
                                (unsigned char)buf[intrface].ifr_enaddr[3],
                                (unsigned char)buf[intrface].ifr_enaddr[4],
                                (unsigned char)buf[intrface].ifr_enaddr[5]);

                 puts("");
                 puts("");
                }
#endif
            if (!(ioctl (fd, SIOCGIFHWADDR, (char *) &buf[intrface])))
                {
                 puts ("HW address is:");

                 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[0],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[1],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[2],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[3],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[4],
                                (unsigned char)buf[intrface].ifr_hwaddr.sa_data[5]);

                 puts("");
                 puts("");
                }
#endif

            else {
               char str[256];

               sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);
               perror (str);
           }
        }
      } else
         perror ("cpm: ioctl");

   } else
      perror ("cpm: socket");

    close (fd);
    return retn;
}
[/code:1:800085c1f7]

 gadfly 回复于:2003-06-06 18:33:02
我看到另外一个网上资料,solaris下说可以用直接访问dlpi api的方式可以取到mac地址。我贴过来了,各位试试看。
http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&oe=UTF-8&frame=right&th=4e11f68182497875&seekm=tardp79vv9o9d3%40corp.supernews.com#link2
[code:1:90f29de857]
/*
 * mac_addr_dlpi.c
 *
 * Return the MAC (ie, ethernet hardware) address by using the dlpi api.
 *
 * compile with: gcc -c -D "OS" mac_addr_dlpi.c
 * with "OS" is one of AIX, SunOS, HPUX
 */

/**********************************************************************/
/* this section defines a list of the dlpi capable devices
 * this depends on the operating system
 */

#undef DLPI_DEV

#ifdef HPUX
static char *dlpi_dev[] = {"/dev/dlpi", ""};
#define DLPI_DEV
#endif

#ifdef AIX
static char *dlpi_dev[] = {"/dev/dlpi/et", "/dev/dlpi/en",
"/dev/dlpi/tr", "/dev/dlpi/fddi", ""};
#define DLPI_DEV
/* AIX: remember to set up /etc/pse.conf or /etc/dlpi.conf */
#endif

#ifdef SunOS
static char *dlpi_dev[] = {"/dev/hme", "/dev/ie", "/dev/le", ""};
#define DLPI_DEV
#endif

#ifndef DLPI_DEV
static char *dlpi_dev[] = {"/dev/dlpi", ""};
/* unknown OS - hope that this will work ??? */
#define DLPI_DEV
#endif

/**********************************************************************/
/*
 * implementation
 */

#define INSAP 22
#define OUTSAP 24

#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <sys/stropts.h>
#include <sys/poll.h>
#include <sys/dlpi.h>

#define bcopy(source, destination, length) memcpy(destination, source, length)

#define AREA_SZ 5000 /*&=&* buffer length in bytes *&=&*/
static u_long ctl_area[AREA_SZ];
static u_long dat_area[AREA_SZ];
static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area};
static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area};
#define GOT_CTRL 1
#define GOT_DATA 2
#define GOT_BOTH 3
#define GOT_INTR 4
#define GOT_ERR 128

/*&=&* get a message from a stream; return type of message *&=&*/
static int get_msg(int fd)
{
    int flags = 0;
    int res, ret;
    ctl_area[0] = 0;
    dat_area[0] = 0;
    ret = 0;
    res = getmsg(fd, &ctl, &dat, &flags);
    if(res < 0) {
        if(errno == EINTR) {
            return(GOT_INTR);
        } else {
            return(GOT_ERR);
        }
    }
    if(ctl.len > 0) {
        ret |= GOT_CTRL;
    }
    if(dat.len > 0) {
        ret |= GOT_DATA;
    } return(ret);
}

/*&=&* verify that dl_primitive in ctl_area = prim *&=&*/
static int check_ctrl(int prim)
{
    dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area;
    if(err_ack->dl_primitive != prim) {
        return GOT_ERR;
    } return 0;
}

/*&=&* put a control message on a stream *&=&*/
static int put_ctrl(int fd, int len, int pri)
{
    ctl.len = len;
    if(putmsg(fd, &ctl, 0, pri) < 0) {
        return GOT_ERR;
    } return  0;
}

/*&=&* put a control + data message on a stream *&=&*/
static int put_both(int fd, int clen, int dlen, int pri)
{
    ctl.len = clen;
    dat.len = dlen;
    if(putmsg(fd, &ctl, &dat, pri) < 0) {
        return GOT_ERR;
    } return  0;
}

/*&=&* open file descriptor and attach *&=&*/
static int dl_open(const char *dev, int ppa, int *fd)
{
    dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area;
    if((*fd = open(dev, O_RDWR)) == -1) {
        return GOT_ERR;
    }
    attach_req->dl_primitive = DL_ATTACH_REQ;
    attach_req->dl_ppa = ppa;
    put_ctrl(*fd, sizeof(dl_attach_req_t), 0);
    get_msg(*fd);
    return check_ctrl(DL_OK_ACK);
}

/*&=&* send DL_BIND_REQ *&=&*/
static int dl_bind(int fd, int sap, u_char *addr)
{
    dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area;
    dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area;
    bind_req->dl_primitive = DL_BIND_REQ;
    bind_req->dl_sap = sap;
    bind_req->dl_max_conind = 1;
    bind_req->dl_service_mode = DL_CLDLS;
    bind_req->dl_conn_mgmt = 0;
    bind_req->dl_xidtest_flg = 0;
    put_ctrl(fd, sizeof(dl_bind_req_t), 0);
    get_msg(fd);
    if (GOT_ERR == check_ctrl(DL_BIND_ACK)) {
        return GOT_ERR;
    }
    bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr,
        bind_ack->dl_addr_length);
    return 0;
}

/**********************************************************************/
/*
 * interface:
 * function mac_addr_dlpi - get the mac address of the "first" interface
 *
 * parameter: addr: an array of six bytes, has to be allocated by the
caller
 *
 * return: 0 if OK, -1 if the address could not be determined
 *
 */

long mac_addr_dlpi ( u_char  *addr)
{
    int fd;
    int ppa;
    u_char mac_addr[25];
    int i;

    char **dev;

    for (dev = dlpi_dev; **dev != '\0'; ++dev) {
        for (ppa=0; ppa<10; ++ppa) {
            if (GOT_ERR != dl_open(*dev, ppa, &fd)) {
                if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) {
                    bcopy( mac_addr, addr, 6);
                    return 0;
                }
            }
            close(fd);
        }
    } return -1;
}


/**********************************************************************/
/*
 * Main (only for testing)
 */
#ifdef MAIN
int main( int argc, char **argv)
{
    long stat;
    int i;
    u_char addr[6];

    stat = mac_addr_dlpi( addr);
    if (0 == stat) {
        printf( "MAC address = ");
        for (i=0; i<6; ++i) {
            printf("%2.2x", addr[i]);
        }
        printf( "\n");
    }
    else {
        fprintf( stderr, "can't get MAC address\n");
        exit( 1);
    } return 0;
}
#endif
[/code:1:90f29de857]

晕,不是我置的顶吧?误操作?

 无双 回复于:2003-06-07 14:48:40
很实用
加精华

 jackyzhou 回复于:2003-06-09 17:56:49
为什么不用shell 呢?
ifconfig -a
set - -
 Ip=$..............
MAC=$..........
这样不就很简单了吗?

 蓝色键盘 回复于:2003-06-09 17:58:40
有些人要用程序实现。

感谢gadfly的热情和努力吧。

 jerrypan 回复于:2003-06-10 10:16:25
收藏先。。。。

多谢

 angel518 回复于:2003-06-10 11:23:13
save

 pillow 回复于:2003-06-11 10:29:44
谢谢……

 shangxd 回复于:2003-06-26 13:55:49
可是怎么才能获得子网掩码呢?

 shangxd 回复于:2003-06-26 16:05:24
我知道了,要知道子网掩码使用下面的ioctl
ioctl (rec, SIOCGIFNETMASK, &if_data)

 breadso 回复于:2003-07-05 12:08:39
对于您的乐于助人首先表示感谢!

看了大作中提到的两种查询mac,ip地址等信息的例子代码,现在有以下问题还不太明白,希望不吝赐教:

1。程序中有如下的定义:#define MAXINTERFACES   16 
用在这个地方:     
struct ifreq buf[MAXINTERFACES];
经过试验,如果实际的网卡(或接口)数字大于,16的话,那么ioctl会失败!
不知道,定义16 是为什么?
顺便想问问,Solrias,HP,linux,所能支持的最大的网卡个数是多少?

 shangxd 回复于:2003-07-05 21:17:55
16应该是自己定义的吧,一般接口数不大会超过这个数目。
要知道LINUX最多支持多少个网卡的话可能要看内核的代码了。

 gadfly 回复于:2003-07-05 21:20:20
我在solaris和linux上把MAXINTERFACES改成255都没有问题呀?

你什么环境?怎么改的?另外用perror打印出错误信息看看

 breadso 回复于:2003-07-05 21:24:26
如果是作者自己定义的,那么这个程序会ioctl执行失败的可能!

我很想知道的是在,HP,SunOS,中,最多可以设多少个网卡?
每个网卡可以设多少个IP地址。

 gadfly 回复于:2003-07-05 21:31:37
没看到我前面的回复?

 breadso 回复于:2003-07-05 21:42:46
对不起,刚看到:)

现在这个问题我觉得十分的棘手!!

1。你把MAXINTERFACES设的足够大,当然不会有问题,
现在问题时,如果你的机器有17个以上的地址,那么在设MAXINTERFACES=16, 就会出问题:

在HP,SUN,上面,ioctl 都会返回-1,也就是出错。
所以,我想知道一个足够大的极限值呀?
或者有什么方法可以获得??

还有一个问题:对于获取ip地址,是否,一定要检查网卡的状态,是否为UP呢?

 gadfly 回复于:2003-07-05 22:03:47
是这样子的,我刚看了ifconfig的处理方式,它是用试探的方法,也就是说它的buf是动态的。如果发现这个buf都满了,就再扩展buf的大小。上面的代码你可以自己改成动态分配的,或者通过参数输入。

取ip不需要判断状态,我这只是个示例,其实interface还有其它的一些属性。另外如果interface是down的话,这个代码的网卡信息是取不到的,
你自己可以试试看。

 breadso 回复于:2003-07-05 22:13:58
我现在就是不知道,怎么去探测呀?(HP,Sun)

是根据ioctl的错误返回值吗?
在HP,Sun,中,如果分配的内存不足,那么errno = 22,是说参数出错,
但是这个信息好像不足以说明是否是因为,内存分配的不足,

**不知道您认为该如何去判断,继续探测的条件??

对了,Sun 2.6之前每个网卡最多支持256个地址,以后嘛,就可任意多了。
但是HP是什么情况呢?

还想问一下:调用 ioclt  用:SIOCGIFFLAGS,这个参数是干嘛用的?,(linux支持)

 gadfly 回复于:2003-07-05 22:26:42
在linux中,是ioctl去取,如果发现返回的len是等于buf的len,就继续加大这个buf的len。

如果sun和hp是这种情况,你也完全可以根据这个errno,循环的增大到一定数量,可以设个最大的上限。

呵呵,由于我这没有这么多的interface,所以说这种情况,我也没法试。
这个是取网卡的一些状态属性的,状态信息很多,如:是否是混杂模式,
是否up, 是否接受广播包,是否支持多播等等。我上面的例子,只取了最常用的几种信息。这些在solaris上也支持的呀。

 breadso 回复于:2003-07-05 22:34:47
SUN,HP:
情况与linux有区别,
errno时说有不正确的参数,

也就是说如果,你内存分配足够,但是其他的参数出错,也是不行的。

项测试的话很容易,你把你设置的maxifnum设小点,自己在加几个地址,就可以了。

 yanyf 回复于:2003-07-10 15:36:57
为什么在FREEBSD4.5上编译第一段代码,遇到如下错误(在LINUX可以):
nic.c:57: warning: passing arg 1 of `puts' makes pointer from integer without a cast
nic.c:91: `SIOCGIFHWADDR' undeclared (first use in this function)
nic.c:91: (Each undeclared identifier is reported only once
nic.c:91: for each function it appears in.)
nic.c:96: structure has no member named `ifr_hwaddr'
nic.c:97: structure has no member named `ifr_hwaddr'
nic.c:98: structure has no member named `ifr_hwaddr'
nic.c:99: structure has no member named `ifr_hwaddr'
nic.c:100: structure has no member named `ifr_hwaddr'
nic.c:101: structure has no member named `ifr_hwaddr'

主要是在执行ioctl获取硬件地址时,不认识SIOCGIFHWADDR,是不是有头文件没包含?

 gadfly 回复于:2003-07-11 13:49:35
估计freebsd不支持这个ioctl的选项。

试试solaris上的代码吧

 allenli007 回复于:2003-09-19 14:51:31
好文
支持

 云飞月 回复于:2005-08-06 23:22:10
好东西

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有