#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <string.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <signal.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/if_ether.h>
#include <net/ethernet.h>
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 )
die("ioctl num1",2);
ifr.ifr_flags |= IFF_PROMISC; //reset flag
if(ioctl(sock,SIOCSIFFLAGS,&ifr) == -1 )
die("ioctl num2",3);
}
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,*ptemp;
char ss[32],dd[32];
//创建套接口为接收数据链路层的所有帧
if((sock = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) == -1)
die("socket",1);
do_promisc("eth0",sock);
system("ifconfig");
for(;;) {
len = sizeof(addr);
r = recvfrom(sock,(char *)buf,sizeof(buf),0,(struct sockaddr *)&addr,&len);
printf("get the packet or not %s /n",buf);
buf[r] = 0;
ptemp = buf;
peth = (struct ether_header *)ptemp;
ptemp += sizeof(struct ether_header);
pip = (struct ip *)ptemp;
//移动指针到TCP,UDP头部
ptemp += sizeof(struct ip);
char *content;
switch(pip->protocol){、
case IPPROTO_TCP:
ptcp = (struct tcphdr *)ptemp;
printf("tcp pkt:from[%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));
//要判断具体的是什么应用需要对端口进行判断,如HTTP:80,FTP:23
ptemp += sizeof(struct tcphdr);
content = (char *)ptemp;
printf("tcp content is %s/n",content);
break;
case IPPROTO_UDP:
pudp = (struct udphdr *)ptemp;
// printf("udp pkt: len:%d payload len:%d from %s:%d to %s:%d/n",
// r,
/// ntohs(pudp->len),
// inet_ntoa(*(struct in_addr*)&(pip->saddr)),
// ntohs(pudp->source),
// inet_ntoa(*(struct in_addr*)&(pip->daddr)),
// ntohs(pudp->dest));
printf("get udp pkt");
break;
case IPPROTO_ICMP:
printf("icmp pkt:%s/n",inet_ntoa(*(struct in_addr*)&(pip->saddr)));
break;
case IPPROTO_IGMP:
printf("igmp pkt:/n");
break;
default:
printf("unkown pkt,protocol:%d/n",pip->protocol);
break;
}
perror("dump");
}
}