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");

}

 

發佈了20 篇原創文章 · 獲贊 4 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章