Linux c获取IP报文

来源:互联网 发布:ef英孚教育网络课程 编辑:程序博客网 时间:2024/06/05 10:37

#include <stdio.h>

#include <string.h>

#include <sys/socket.h>

#include <sys/ioctl.h>

#include <netinet/ip.h>

#include <netinet/if_ether.h>

#include <net/if.h>

 

int main()

{

/*套接口捕获链路帧*/

int i=0;

int fd;

/*利用类型为SOCK_PACKET的套接口来捕获链路帧*/

fd=socket(AF_INET,SOCK_PACKET,htons(0x0003));//函数返回值的意义?

//AF_INET=ARPA Internet protocols,即TCP/IP协议族 

/*设置网卡的工作方式*/

struct ifreq ifr;// in 'net/if.h'

char *dev="eth0";

strcpy(ifr.ifr_name,dev);   // interface name

i=ioctl(fd,SIOCGIFFLAGS,&ifr);//SIOCGIFFLAGS(0x8913)表示取出工作方式

//返回0:成功    -1:出错

 

if(i<0)

{

close(fd);

perror("can't get flags/n");

//exit(0);

}

ifr.ifr_flags|=IFF_PROMISC;//在标志中加入“混杂“方式

i=ioctl(fd,SIOCSIFFLAGS,&ifr);//获取所有接口信息

if(i<0)

{

perror("can't set promiscuous/n");

//exit(0);

}

/*从套接口读取帧并分析报头*/

  char ep[ETH_FRAME_LEN];

 

  struct ethhdr *eh;

  struct iphdr *ip;

  int fl;

eh = (struct ethhdr *) ep;//eh指向帧头

ip = (struct iphdr *) ( (unsigned long) ep + ETH_HLEN );//ETH_HLEN帧头长

 

  fl = read (fd,(struct etherpacket*) ep,sizeof(ep));//捕获的数据帧长

 

 

printf("数据协议类型代码:%x/n",eh->h_proto);

printf("服务类型: %x/n",ip->tos);

printf("总长度:%x/n",ip->tot_len);

printf("总标识域:%x/n",ip->id);

printf("分片控制和分片偏移量:%x/n",ip->frag_off);

printf("生命周期:%x/n",ip->ttl);

printf("协议:%x/n",ip->protocol);

printf("校验和:%x/n",ip->check);

printf("源IP地址:%x/n",ip->saddr);

printf("目标地址:%x/n",ip->daddr);

 

printf("/n");

}