用raw socket截获所有端口socket数据包!有这方面经验帮我看看吧,多谢了

mtsw 2004-11-09 05:29:09
我的源程序如下:
compile通过,但是收不到数据包,一直停在recv调用处。OS:solaris.多谢了。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/filio.h>
#include <arpa/inet.h>
#include <time.h>

typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct _TCP{
WORD SrcPort;
WORD DstPort;
DWORD SeqNum;
DWORD AckNum;
BYTE DataOff;
BYTE Flags;
WORD Window;
WORD Chksum;
WORD UrgPtr;
} TCP;
TCP tcp;
typedef TCP *LPTCP;
typedef TCP *ULPTCP;
//typedef TCP UNALIGNED *ULPTCP;

typedef struct _IP {
union {
BYTE Version;
BYTE HdrLen;
};
BYTE ServiceType;
WORD TotalLen;
WORD ID;
union{
WORD Flags;
WORD FragOff;
};
BYTE TimeToLive;
BYTE Protocol;
WORD HdrChksum;
DWORD SrcAddr;
DWORD DstAddr;
BYTE Options;
} IP;
typedef IP *LPIP;
typedef IP *ULPIP;
IP ip;
//typedef IP UNALIGNED *ULPIP;
#define BUFFER_SIZE 200 ;
int sock ;
struct sockaddr_in addr_in;
char LocalName[100];
struct hostent *pHost;
char RecvBuf[10000];
bool flag;

main(){
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

flag = true;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
gethostname((char*)LocalName,100);
pHost = gethostbyname((char*)LocalName);

addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);

bind(sock, (struct sockaddr*)&addr_in, sizeof(addr_in));

DWORD dwValue = 1;
//ioctlsocket(sock, SIO_RCVALL, &dwValue);
//ioctl(sock, FIOGETOWN, &dwValue);
ioctl(sock, SIOCGLIFINDEX, &dwValue);

printf("Hostname:%s.\nStarting Receive Socket Data.\n",LocalName);
memset(RecvBuf,sizeof(RecvBuf),0);
while (true)
{
int ret = recv(sock, RecvBuf, 1024,0);
if (ret > 0)
{
ip = *((IP*)RecvBuf);
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
printf("protocol:%s\n",ip.Protocol);
printf("srcIP:%s\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
printf("dstIP:%s\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
printf("srcport:%d\n",tcp.SrcPort);
printf("dstport:%d\n",tcp.DstPort);
printf("totalLen:%d\n",ntohs(ip.TotalLen));
}
}

close(sock);
}

...全文
692 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
gaoxianfeng 2005-04-13
  • 打赏
  • 举报
回复
难道你不知道iptables 有编程接口?
cbenny 2005-04-12
  • 打赏
  • 举报
回复
libpcap好像只是抓到一份COPY啊。。。。。。如果不是做包过滤libpcap很好用。。。。。。。不知道用socket抓raw packet能不能做包过滤啊 。。。。。。。
mtsw 2004-11-23
  • 打赏
  • 举报
回复
道理我明白,但是就是不行。不知道是那里不对。
andycl 2004-11-22
  • 打赏
  • 举报
回复
网络适配器混合模式!

至于ip和tcp结构一般头文件有定义的,
关于详细的自己找了
直接recvfrom就ok了其他都取消掉吧
socket函数调用是对的,都行的
mtsw 2004-11-22
  • 打赏
  • 举报
回复
我把bind去掉了,加了一个 Set_Promisc("eri0", sock );还是不行:

int Set_Promisc(char *interface, int sock ) {
struct ifreq ifr;
strncpy(ifr.ifr_name, interface,strlen(interface)+1);
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
perror("Could not retrive flags for the interface");
exit(0);
}
printf("The interface is ::: %s\n", interface);
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) {
perror("Could not set the PROMISC flag:");
exit(0);
}
printf("Setting interface ::: %s ::: to promisc", interface);
return(0);
}


main(){
//sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
flag = true;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
/*
gethostname((char*)LocalName,100);
pHost = gethostbyname((char*)LocalName);

addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);

bind(sock, (struct sockaddr*)&addr_in, sizeof(addr_in));
*/
DWORD dwValue = 1;
//ioctlsocket(sock, SIO_RCVALL, &dwValue);
//ioctl(sock, FIOGETOWN, &dwValue);
//ioctl(sock, SIOCGLIFINDEX, &dwValue);
Set_Promisc("eri0", sock );

// printf("Hostname:%s.\nAddr_List:%s.Starting Receive Socket Data.\n",LocalName,pHost->h_addr_list[0]);
memset(RecvBuf,sizeof(RecvBuf),0);
while (true)
{
// int ret = recv(sock, RecvBuf, 1024,0);
printf("Starting to recevie data...\n");
int ret = recvfrom(sock,RecvBuf,1200,0,NULL,NULL);
printf("Have receving Data:%s\n",RecvBuf);
if (ret > 0)
{
ip = *((IP*)RecvBuf);
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
printf("protocol:%s\n",ip.Protocol);
printf("srcIP:%s\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
printf("dstIP:%s\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
printf("srcport:%d\n",tcp.SrcPort);
printf("dstport:%d\n",tcp.DstPort);
printf("totalLen:%d\n",ntohs(ip.TotalLen));
}
}

close(sock);
}


tengulre 2004-11-12
  • 打赏
  • 举报
回复
UP
steel_de_lee 2004-11-12
  • 打赏
  • 举报
回复
建议使用libpcap,开源的,可以抓到以太帧,当然也可以抓到Raw,比你使用socket强
eternal_baggio 2004-11-10
  • 打赏
  • 举报
回复
还发现你的错误,
为什么要bind()呢?
你绑定了一个固定端口怎么监听所有端口的数据包!去掉bind
你查一下有关PF_PACKET协议簇的概念
刚才应该这样写socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)),
至于在solaris中有没有这样的协议簇请查实,原理是直接利用网络驱动程序发送和接收。

在socket到recvfrom之间语句全去掉,试试看。
明天接着讨论,下班了!
kingzai 2004-11-10
  • 打赏
  • 举报
回复
http://search.csdn.net/Expert/topic/2590/2590795.xml?temp=.9473841
kingzai 2004-11-10
  • 打赏
  • 举报
回复
http://search.csdn.net/Expert/topic/2590/2590795.xml?temp=.9473841
mtsw 2004-11-10
  • 打赏
  • 举报
回复
我现在用的是Solaris,我把把recv改称了recvfrom但是还是不行阿!
改 sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
中的IPPROTO_RAW为IPPROTO_IP.试了也不行。


eternal_baggio 2004-11-10
  • 打赏
  • 举报
回复
兄弟,原始套接字的写法是这样的
...
#include<linux/in.h>
#include<linux/if_ether.h>
socket(PF_INET, SOCK_RAW, htons(ETH_P_IP))

......

while(1)
{
......
recvfrom(sock,buffer,size,0,NULL,NULL);
......
}
自己调试一下试试,如果有问题再讨论
kingzai 2004-11-09
  • 打赏
  • 举报
回复
raw socket 不是这样写地:
这是windows下的raw socket 编写方法,
改成C下的也一样。
http://www.donews.net/darkness/archive/2004/08/17/70347.aspx
eternal_baggio 2004-11-09
  • 打赏
  • 举报
回复
大哥,原始套接字也只能到网络层,IP协议是面向无连接的,你知道recv是怎么用的吗,用recvfrom试试,建议你最好先看看ping的实现,ICMP在ip包中,看看原始套接字是怎么用的。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧