这个基于libnet的程序,实现一个构造ARP包并发送的功能
同样一个程序,我的电脑上(WINDOWS XP系统)运行没问题,正常构造数据包正常发送
但是在我同学的电脑(也是XP 系统)就出问题了,问题出在libnet_init这个函数上,出错信息是libnet_select_device():no network interface found有人知道怎么回事么?先谢谢啦
原程序如下:
  #if   (HAVE_CONFIG_H)   
  #include   "../include/config.h"   
  #endif   
  #include   "../sample/libnet_test.h"   
  #ifdef   __WIN32__   
  #include   "../include/win32/getopt.h"   
  #endif   
  #include   <conio.h>  
#pragma comment(lib, "libnet.lib")
int   
  main(int   argc,   char   *argv[])   
  {   
          int   c;    
          libnet_t   *l;   
          libnet_ptag_t   t;   
          char   *payload;   
          u_short   payload_s;   
          u_long   src_ip,   dst_ip; /*源IP的地址和目的IP地址*/   
          u_short   src_prt,   dst_prt; /*源端口号和目的端口号*/   
          char   errbuf[LIBNET_ERRBUF_SIZE];   
  char   szSrc[255],szDes[255];   
    
  int   i=0;   
    
          printf("libnet   1.1   packet   shaping:   TCP   +   options[link]\n");   
 
          l   =   libnet_init(   
                          LIBNET_LINK,                                                         /*Libnet类型   */   
                          NULL,                                                                       /*   网络设置接口   */   
                          errbuf);                                                                 /*   错误信息   */   
    
          if   (l   ==   NULL)   
          {   
                  fprintf(stderr,   "libnet_init()   failed:   %s",   errbuf); 
  system("pause");
                  exit(EXIT_FAILURE);     
          }   
    
          src_ip     =   0;   
          dst_ip     =   0;   
          src_prt   =   0;   
          dst_prt   =   0;   
          payload   =   NULL; /*负载*/   
          payload_s   =   0; /*负载大小*/   
    strcpy(szSrc,"127.0.0.1");   
  strcpy(szDes,"www.fighterforum.com");   
  src_ip=libnet_name2addr4(l,szSrc,LIBNET_RESOLVE);   
  dst_ip=libnet_name2addr4(l,szDes,LIBNET_RESOLVE);   
  payload="33333333";   
          payload_s   =   strlen(payload);   
  dst_prt=80;   
  src_prt=99;     
    
  /*构造TCP选项*/   
          t   =   libnet_build_tcp_options(   
                  (unsigned char *)"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000",                   20,   
                  l,   
                  0);   
          if   (t   ==   -1)   
          {   
                  fprintf(stderr,   "Can't   build   TCP   options:   %s\n",   libnet_geterror(l));   
                  goto   bad;   
          }   
  /*构造TCP协议*/   
          t   =   libnet_build_tcp(   
                  src_prt,                                                                         /*   源端口号   */   
dst_prt,                                                                         /*   目的端口号   */   
0x01010101,                                                                   /*   序列号   */   
0x02020202,                                                                   /*   确认序列号   */   
                  TH_SYN,                                                                           /*   控制标记   */   
                  32767,                                                                             /*   窗口大小   */   
  0,                                                                                     /*   校验和s   */   
   10,                                                                                   /*   紧急指针   */   
                  LIBNET_TCP_H   +   20   +   payload_s,                             /*   数据包大小   */   
          (unsigned char *)payload,                                                                         /*   负载   */   
                  payload_s,                                                                     /*   负载大小   */   
                  l,                                                                                     /*   libnet   句柄   */   
                  0);                                                                                   /*   libnet   协议ID   */   
          if   (t   ==   -1)   
          {   
                  fprintf(stderr,   "Can't   build   TCP   header:   %s\n",   libnet_geterror(l));   
                  goto   bad;   
          }   
  /*构造IPV4协议块*/   
          t   =   libnet_build_ipv4(   
                  LIBNET_IPV4_H   +   LIBNET_TCP_H   +   20   +   payload_s,/*   长度   */   
              0,                                                                                     /*   服务质量   */   
                  242,                                                                                 /*   标识   */   
                  0,                                                                                     /*   偏移   */   
                  64,                                                                                   /*   生存时间   */   
                  IPPROTO_TCP,       /*   上层协议类型   */  0,                                                                                     /*   校验和   */   
                  src_ip,                                                                           /*   源IP地址   */   
dst_ip,                                                                           /*   目的IP地址   */   
NULL,                                                                               /*   负载   */   
0,                                                                                     /*   负载大小   */   l,                                                                                     /*   libnet   句柄   */   
0);    /*   libnet   协议ID   */           if   (t   ==   -1)   
          {   
                  fprintf(stderr,   "Can't   build   IP   header:   %s\n",   libnet_geterror(l));   
                  goto   bad;   
          }   
   /*构造以太网协议块*/   
          t   =   libnet_build_ethernet(enet_dst,enet_src,                                                                                         ETHERTYPE_IP,                                                               /*   上层协议类型*/NULL,                                                                               /*   负载   */0, /*   负载大小   */   
l,                                                                                     /*   libnet   句柄   */   
                  0);                                                                                   /*   libnet   协议ID   */   
          if   (t   ==   -1)   
          {   
                  fprintf(stderr,   "Can't   build   ethernet   header:   %s\n",   libnet_geterror(l));   
                  goto   bad;   
          }   
    
  /*打印IP信息*/   
  printf("源地址IP:%d,目的IP   adress:%d\n",src_ip,dst_ip);   
    printf("解码后的源地址IP:%s,目的IP   adress:%s\n",libnet_addr2name4(src_ip,1),libnet_addr2name4(dst_ip,1));             c   =   libnet_write(l); /*发送数据包*/   
          if   (c   ==   -1)   
          {   
                  fprintf(stderr,   "Write   error:   %s\n",   libnet_geterror(l));   
                  goto   bad;   
  }   
  else   
  {   
                fprintf(stderr,   "Wrote   %d   byte   TCP   packet;   check   the   wire.\n",   c);   
  }   
          libnet_destroy(l); /*销毁Libnet*/   
    
  getch();   
          return   (EXIT_SUCCESS);   
  bad:   
          libnet_destroy(l);   
  printf("出错了你知道不?妈妈的~\n");   
    
  getch();   
          return   (EXIT_FAILURE);   
  }   
    
  void   
  usage(char   *name)   
  {   
          fprintf(stderr,   
                  "usage:   %s   -s   source_ip.source_port   -d   destination_ip.destination_port"   
                  "   [-p   payload]\n",   
                  name);   
  }   
    
  #if   defined(__WIN32__)   
  #include   <../include/win32/getopt.h>   
  #include   <winsock2.h>   
  #include   <ws2tcpip.h>   
  #endif     /*   __WIN32__   */    

解决方案 »

  1.   

    google一下libnet_init,需要winpcap的支持Libnet在Visual Studio 05下编译
    http://www.cublog.cn/u/12592/showart_192885.html
      

  2.   

    另外有一个差不多的,
    http://topic.csdn.net/t/20060131/14/4537640.html
      

  3.   

    我之前在VC 6.0下编译了winpcap,生成了wpcap.dll文件
    后分别在VS 2005下和VC 6.0(需要较新的sdk支持,我用的是windows server 2003的sdk)下编译了libnet,生成libnet.dll文件另外运行这个程序(我是说运行,不是编译),还需要packet.dll和wanpacket.dll这两个动态链接库以上4个dll文件都要放在system32目录下在同学机子上试时,我是把我机子里system32文件夹下的wpcap.dll,libnet.dll,packet.dll和wanpacket.dll都一起放在他们计算机的system32目录下。
    但是我的机子运行没有问题,可以初始化成功,他们就出现了我说的那个错误
      

  4.   

    现在问题暂时解决,是这样的:通过单步跟踪,发现libnet_init()这个函数会调用到libnet_ifaddrlist()这个函数,这个函数在libnet 1.1.2的源码如下:int
    libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, int8_t *dev,
    register int8_t *errbuf)
    {
        int nipaddr = 0;    int i = 0;    static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
        pcap_if_t *alldevs;
        pcap_if_t *d;
        int8_t err[PCAP_ERRBUF_SIZE];    /* Retrieve the interfaces list */
        if (pcap_findalldevs(&alldevs, err) == -1)
        {
            snprintf(errbuf, LIBNET_ERRBUF_SIZE, 
                    "%s(): error in pcap_findalldevs: %s\n", __func__, err);
            return (-1);
        }    /* Scan the list printing every entry */
    for (d = alldevs; d; d = d->next)
        {
    if((!d->addresses) || (d->addresses->addr->sa_family != AF_INET))
                continue;
            if(d->flags & PCAP_IF_LOOPBACK)
                continue;
        
    /* XXX - strdup */
            ifaddrlist[i].device = strdup(d->name);
            ifaddrlist[i].addr = (u_int32_t)
                    strdup(iptos(((struct sockaddr_in *)
                    d->addresses->addr)->sin_addr.s_addr));
            ++i;
            ++nipaddr;
        }    *ipaddrp = ifaddrlist;
        return (nipaddr);
    }
    #endif /* __WIN32__ */注意代码中的红色部分,只有是网络地址协议类型AF_INET的网卡才能被libnet初始化。
    我的电脑的网卡,是这种类型的网卡;而我同学电脑的网卡,是AF_INET6这种类型的WinSock2.h对以上两个类型是这么定义的:
    #define AF_INET         2               /* internetwork: UDP, TCP, etc. */
    #define AF_INET6        23              /* Internetwork Version 6 */我的电脑是dell的,所以装的网卡类型跟同学的不一样???现在暂时的解决办法是:
    把红色那句改为 if((!d->addresses) ||(! (d->addresses->addr->sa_family == AF_INET || (AF_INET6 == d->addresses->addr->sa_family )
                continue;现在同学电脑可以发包了,不过这样动了libnet的代码总觉得不大好
      

  5.   

    我也遇到同样的问题,两台电脑中在比较早的电脑运行不了,程序无法自动找到网卡接口。
    这种情况下,不能在libnet_init()时参数device就不能设置成NULL了,需要自己去先找到device。
    在程序中加入以下一段代码试试……
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int inum;
    int i=0;
    pcap_t *adhandle;
    char errbuf[PCAP_ERRBUF_SIZE];

        /* Retrieve the device list */
        if (pcap_findalldevs(&alldevs, errbuf) == -1)
        {
            fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
            exit(1);
        }
        
        /* Print the list */
        for(d=alldevs; d; d=d->next)
        {
            printf("%d. %s", ++i, d->name);
            if (d->description)
                printf(" (%s)\n", d->description);
            else
                printf(" (No description available)\n");
        }    if(i==0)
        {
            printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
            return -1;
        }
        
        printf("Enter the interface number (1-%d):",i);
        scanf("%d", &inum);
    cin.get();
        
        if(inum < 1 || inum > i)
        {
            printf("\nInterface number out of range.\n");
            /* Free the device list */
            pcap_freealldevs(alldevs);
    cout << "press ENTER to Exit";
    cin.get();
            return -1;
        }    /* Jump to the selected adapter */
        for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); char *device = NULL;//设备名字,此时为NULL device=d->name;
    l=libnet_init(LIBNET_LINK,device,error_inf);
    这样就可以自己找到网卡接口了,注意选择网卡接口的时候选择当前上网的所用的网络接口。