Linux c获取IP报文(转)
#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");
}
作者:issta hu
出处:http://www.cnblogs.com/hcu5555/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。