LoveUnix » 编程开发 & Rational » 关于直接读写网卡
让LU留住您的每

一天 让LU博客留住您的每一天
2005-10-12 21:23 gunman
关于直接读写网卡

我这边有一个发Cap包的程序,有源码。我看了一下。
它的发送是这样实现的:
   struct sockaddr to;
   sprintf(to.sa_data,"eth%d",Eth_No);
   n=sendto(packet_socket,buf,buflen,0,&to,sizeof(to));
其中:Eth_No为网卡号,诸如0,1,2.....
         packet_socket为一个已经生成的套接字
         buf为一个缓冲区指针
         buflen为缓冲区长度
其中省略了很多,我只是对他的实现有一点困惑!
问题1:对地址to,他没有设sa_family!难道有默认的值??
问题2:它把诸如eth0的值赋给sa_data,这样可以吗?

希望了解的帮我解释一下,如果觉得这个实现有问题,希望能给出你的意见。
我只是想实现,读一个Cap格式文件,把它发送出去,cap文件里面的内容肯定是伪造的或是用Sniffer抓下来的。
再问一个问题,如果我想读网卡的数据呢?也就是说截取所有流经网卡的数据!

谢谢了先,呵呵。
期待ing.大家可以给我一个指导或是网址,只是我在网上搜了关于“发包器”的,结果获知很少。

2005-10-13 08:15 gunman
顶一下先。
兄弟们,还有Carol JJ。帮忙看一下呢。

2005-10-13 13:01 无双
问题1:对地址to,他没有设sa_family!难道有默认的值??
问题2:它把诸如eth0的值赋给sa_data,这样可以吗?

....

它创建的socket类型是什么 如果不是AF_INET那不定

2005-10-13 13:23 gunman
我问了一下写这个程序的同事,他说sa_data里面的内容和建立那个套接字的方式有关系。
它的套接字是这样建立的:
    packet_socket=socket(PF_PACKET,SOCK_RAW,hons(0x800));
所以它的sa_data就写进了诸如eth0的内容。
后来,另一个同事改写了一下这个程序。
   packet_socket=socket(AF_INET,SOCK_PACKET,htons(0x3));
sa_data的内容没有改变。
程序依然可用。

2005-10-13 16:24 gunman
无双GG,
我如果想直接读写网卡,要怎么样做??

我设想:1)写网卡,也就是通过网卡向外发数据:
               建立一个适当类型的socket(想问一下,哪个类型适当?)。
               然后把sa_data填入要读取的网卡号。比如:eth0
               用sendto()发数据
            2)读网卡,相当于监听。
               首先,把网卡通过ioctl函数设置为混杂模式,为了获取所有数据。
               建立一个socket,写入网卡号。
               用recvfrom()读数据。

我的想法对吗???

2005-10-13 16:46 无双
可以吧 可以看看libpcap内容

默认使用sock_stream /sock_dgram if_inet创建时 创建的是ip层之上的通信 所以不可以使用那样类型的

2005-10-13 17:02 gunman
我又在论坛里面找了一下,感觉我想做的和“原始套接口”编程有点联系,不知道对不对呢,
我再找找看吧。
有了解的XDJM们,给我个回信,呵呵,我会时常关注这个话题,如果解决了,我也会把方法贴出来。

2005-10-13 20:58 gunman
呵呵,找到了一些东西,应该有用,和大家分享。

看一下 <<UNIX&reg; Network Programming Volume 1, Third Edition: The Sockets Networking API>> By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff 。
这里面的Chapter28--Raw Sockets和Chapter29--Datalink Access讲的比较详细。

谢谢无双GG的帮忙,谢谢大家的关注。

2005-10-14 12:39 无双
祝贺一下 :)

2005-10-17 12:52 gunman
无双GG,我又有一个问题了。
我的包已经可以读了,但是在发包的时候,发送N个包之后,总是出现"no buffer space avaliable"的错误。应该是说网卡的缓冲区满了。
我是这样发的:
      一个Cap包里面可能会有N个packet,我建了一个链表,把这些packet连起来。

      while(1){
             if(指针不为NULL){
                      发送对应的packet;
             }
             把指针再次指向头;
       }

也就是说在发送每个Packet之间是没有时间间隔的。呵呵。只有读指针所花费的时间。
我用setsockopt把socket的缓冲区设大,也不起太多的效果。
有什么好办法吗?还是就只能这样,网卡本身的处理速度根本就不可能快过这种发送速度??
也希望了解的其他XDJM们给支个招。

2005-10-17 20:34 无双
这应该是网卡的buf大小问题 使用setsockopt没用的吧

最好还是自己判断一下然后加上延迟

2005-10-18 07:45 gunman
无双GG,怎么样实时判断网卡的剩余缓冲区或是已用缓冲区的大小呢??

2005-10-18 12:30 无双
可能无法判断吧 这应该是驱动里面提供支持

2005-10-18 12:40 gunman
呵呵,OK,我再自己研究一下!
谢谢无双GG

2005-10-18 12:41 gunman
顺便问一下,你上面说的“判断”,是不是判断sendto,如果不成功,再sleep一会呢?

页: [1]
查看完整版本: 关于直接读写网卡


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.