当前位置: 技术问答>linux和unix
网络数据收发监测
来源: 互联网 发布时间:2015-12-26
本文导语: 分析linux网络部分代码,了解网络数据包发送接收过程。通过修改内核相关部分代码,或添加相关函数代码实现数据包发送过程的监测。 大家有什么好的意见想法,谢谢! | 一个抓包程序,希望...
分析linux网络部分代码,了解网络数据包发送接收过程。通过修改内核相关部分代码,或添加相关函数代码实现数据包发送过程的监测。
大家有什么好的意见想法,谢谢!
大家有什么好的意见想法,谢谢!
|
一个抓包程序,希望对你有用
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char * why, int n)
{
perror(why);
exit(n);
}
int do_promisc(char * nif, int sock)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, nif, strlen(nif)+ 1);
if ((ioctl(sock, SIOCGIFFLAGS,&ifr)== - 1)) //获得flag
{
die("ioctl", 2);
}
ifr.ifr_flags |= IFF_PROMISC; //重置flag标志
if (ioctl(sock, SIOCSIFFLAGS,&ifr)== - 1) //改变模式
{
die("ioctl", 3);
}
}
//修改网卡成PROMISC(混杂)模式
char buf[40960];
main()
{
struct sockaddr_in addr;
struct ether_header * peth;
struct iphdr * pip;
struct tcphdr * ptcp;
struct udphdr * pudp;
char mac[16];
int i, sock, r, len;
char * data;
char * ptemp;
char ss[32], dd[32];
printf("11111n");
if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))== - 1) //建立socket
//man socket可以看到上面几个宏的意思
{
die("socket", 1);
}
printf("ifconfign");
do_promisc("sn0", sock); //eth0为网卡名称
system("ifconfig");
for (;;)
{
len = sizeof(addr);
r = recvfrom(sock,(char *)buf, sizeof(buf), 0,(struct sockaddr *)&addr,&len);
//调试的时候可以增加一个输出r的语句判断是否抓到包
buf[r]= 0;
ptemp = buf;
peth =(struct ether_header *)ptemp;
ptemp += sizeof(struct ether_header); //指针后移eth头的长度
pip =(struct ip *)ptemp;//pip指向ip层的包头
ptemp += sizeof(struct ip); //指针后移ip头的长度
switch (pip->protocol) //根据不同协议判断指针类型
{
case IPPROTO_TCP:
ptcp =(struct tcphdr *)ptemp; //ptcp指向tcp头部
printf("TCP pkt :FORM:[%s]:[%d]n", inet_ntoa(*(struct in_addr *)&(pip->saddr)),
ntohs(ptcp->source));
printf("TCP pkt :TO:[%s]:[%d]n", inet_ntoa(*(struct in_addr *)&(pip->daddr)),
ntohs(ptcp->dest));
break;
case IPPROTO_UDP:
pudp =(struct udphdr *)ptemp; //ptcp指向udp头部
printf("UDP pkt:n len:%d payload len:%d from %s:%d to %s:%dn",
r,
ntohs(pudp->len),
inet_ntoa(*(struct in_addr *)&(pip->saddr)),
ntohs(pudp->source),
inet_ntoa(*(struct in_addr *)&(pip->daddr)),
ntohs(pudp->dest)
);
break;
case IPPROTO_ICMP:
printf("ICMP pkt:%sn", inet_ntoa(*(struct in_addr *)&(pip->saddr)));
break;
case IPPROTO_IGMP:
printf("IGMP pkt:n");
break;
default:
printf("Unkown pkt, protocl:%dn", pip->protocol);
break;
} //end switch
perror("dump");
}
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void die(char * why, int n)
{
perror(why);
exit(n);
}
int do_promisc(char * nif, int sock)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, nif, strlen(nif)+ 1);
if ((ioctl(sock, SIOCGIFFLAGS,&ifr)== - 1)) //获得flag
{
die("ioctl", 2);
}
ifr.ifr_flags |= IFF_PROMISC; //重置flag标志
if (ioctl(sock, SIOCSIFFLAGS,&ifr)== - 1) //改变模式
{
die("ioctl", 3);
}
}
//修改网卡成PROMISC(混杂)模式
char buf[40960];
main()
{
struct sockaddr_in addr;
struct ether_header * peth;
struct iphdr * pip;
struct tcphdr * ptcp;
struct udphdr * pudp;
char mac[16];
int i, sock, r, len;
char * data;
char * ptemp;
char ss[32], dd[32];
printf("11111n");
if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))== - 1) //建立socket
//man socket可以看到上面几个宏的意思
{
die("socket", 1);
}
printf("ifconfign");
do_promisc("sn0", sock); //eth0为网卡名称
system("ifconfig");
for (;;)
{
len = sizeof(addr);
r = recvfrom(sock,(char *)buf, sizeof(buf), 0,(struct sockaddr *)&addr,&len);
//调试的时候可以增加一个输出r的语句判断是否抓到包
buf[r]= 0;
ptemp = buf;
peth =(struct ether_header *)ptemp;
ptemp += sizeof(struct ether_header); //指针后移eth头的长度
pip =(struct ip *)ptemp;//pip指向ip层的包头
ptemp += sizeof(struct ip); //指针后移ip头的长度
switch (pip->protocol) //根据不同协议判断指针类型
{
case IPPROTO_TCP:
ptcp =(struct tcphdr *)ptemp; //ptcp指向tcp头部
printf("TCP pkt :FORM:[%s]:[%d]n", inet_ntoa(*(struct in_addr *)&(pip->saddr)),
ntohs(ptcp->source));
printf("TCP pkt :TO:[%s]:[%d]n", inet_ntoa(*(struct in_addr *)&(pip->daddr)),
ntohs(ptcp->dest));
break;
case IPPROTO_UDP:
pudp =(struct udphdr *)ptemp; //ptcp指向udp头部
printf("UDP pkt:n len:%d payload len:%d from %s:%d to %s:%dn",
r,
ntohs(pudp->len),
inet_ntoa(*(struct in_addr *)&(pip->saddr)),
ntohs(pudp->source),
inet_ntoa(*(struct in_addr *)&(pip->daddr)),
ntohs(pudp->dest)
);
break;
case IPPROTO_ICMP:
printf("ICMP pkt:%sn", inet_ntoa(*(struct in_addr *)&(pip->saddr)));
break;
case IPPROTO_IGMP:
printf("IGMP pkt:n");
break;
default:
printf("Unkown pkt, protocl:%dn", pip->protocol);
break;
} //end switch
perror("dump");
}
}
|
http://www-128.ibm.com/developerworks/cn/linux/l-ntflt/index.html
先看看这篇文章,再理下思路,看看自己需要什么
先看看这篇文章,再理下思路,看看自己需要什么
|
在linux下内核中可以使用netfilter,应用层可以使用libpcap库函数
在windows下可以使用winpcap库函数
在windows下可以使用winpcap库函数
|
用Netfilter实现最简单也最通用
|
libpcap
|
libpcap包比较合适你的需求。
|
mark
|
mark
|
Maybe pcap is your best choice