LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1353|回复: 6

关于sniffer的,在网上找到一个很经典的例子,但是只能接受本机的,数据包,为什么?已经设置

[复制链接]
发表于 2006-9-1 20:27:31 | 显示全部楼层 |阅读模式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#define FTP 22
#define INTERFACE "eth0" /* 网卡 */
int set_promisc(char *interface,int sock) /* 杂乱模式 */
{
struct ifreq ifr;
strncpy(ifr.ifr_name, interface,strlen(interface)+1);
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
printf("Could not retrive flags for the interface\n");
exit(0);
}
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) {
printf("Could not set the PROMISC flag.\n");
exit(0);
}
printf("Setting interface ::: %s ::: to promisc\n", interface);
}
main()
{
struct iphdr *ip;
struct tcphdr *tcp;
struct sockaddr_in addr;
char buffer[1024];
char *data;
int sock,byte_size,addrlen;
addrlen = sizeof(addr);
if(( sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1) { /* 使用SOCK_RAW */
printf("socket failt \n");
exit(0);
}
set_promisc(INTERFACE,sock);
ip = (struct iphdr *)buffer; /* 格式化buffer */
tcp = (struct tcphdr *)(buffer+sizeof(struct iphdr)); /* 格式化去掉iphdr后的buffer */
while(1)
{
byte_size = recvfrom(sock,(char *)&buffer,sizeof(buffer),0,(struct sockaddr *)&addr,&addrlen);
if((ntohs(tcp->dest)) == FTP) /* sniffer FTP 密码 */
{
data = &buffer[sizeof(struct iphdr) + sizeof(struct tcphdr)]; /* data 等于去掉iphdr和tcphdr后的buffer内容 */
printf("data: %s",data);
}
}
}

请达人指点。
发表于 2006-9-3 10:19:36 | 显示全部楼层
这个代码只有recvfrom,没有sendto(或send)啊,当然不能了。。。。。。
回复 支持 反对

使用道具 举报

发表于 2006-9-3 19:27:23 | 显示全部楼层
你的网络环境是什么样的呢?
通常sniffer只能用于共享介质的以太网,而现在大多数局域网都使用的交换机,交换网内sniffer是不起作用的。
顺便说一下,原始套接字通常是不推荐使用的。一般是使用libpcap库。
回复 支持 反对

使用道具 举报

发表于 2006-9-12 16:38:16 | 显示全部楼层
对,libpcap还是很方便的
回复 支持 反对

使用道具 举报

发表于 2006-9-20 13:56:58 | 显示全部楼层
Post by 与雨相随
这个代码只有recvfrom,没有sendto(或send)啊,当然不能了。。。。。。


我倒.....SNIFFER当然是只收不发的....

我N年前就看了这例子,这几天为了测试一个通信软件,又翻出来.....
的确是只能接受其他机器发送过来的包....连自己回送的都截不到.....我看了其他的SNIFFER的例子,似乎用的是read来接收....
目前我是在windows下用一个小软件来截....期待有人对这程序修正后,我可以做一个适合自己的sniffer
回复 支持 反对

使用道具 举报

发表于 2006-9-22 13:21:46 | 显示全部楼层
查了点资料,有这么一说
        /*
         * Current Linux kernels use the protocol family PF_PACKET to
         * allow direct access to all packets on the network while
         * older kernels had a special socket type SOCK_PACKET to
         * implement this feature.
         * While this old implementation is kind of obsolete we need
         * to be compatible with older kernels for a while so we are
         * trying both methods with the newer method preferred.
         */
事实上这是Libpcap里面的注释.....他里面有两种打开监听的方法
难道说我们高版本的RH已经不支持以前的这种打开方法了?
回复 支持 反对

使用道具 举报

发表于 2006-9-27 13:21:53 | 显示全部楼层
终于搞出来了...查了N个网站,几乎国内所有的sniffer都是这例子....看来国人治学还有待提高啊.....
最大的问题在这里
socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) ;
这么设置本来就是有缺陷的.....我看了libpcap的源代码,找到他的原理,才弄明白
socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)));
是这么设置地......
这篇广为流传的文章有些误人子弟啊.....让别人以为只要是RAW_SOCKET就是网络上最基本的东西了....其实最基本的是从eather packet开始的(当然下面还有更基础的东西,但我们不需要那些东西了)....
不过这么一来就需要懂一些协议方面的知识才可以编下去了....因为你截获了很多非TCP/IP的包...你需要过滤掉不要的东西.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表