linux 监听数据包,linux下网络监听与发送数据包的方法(即libpcap、libnet两种类库的使用方法)...

linux下可以用libpcap函数库实现监听数据包,使用libnet 函数库发送数据包

安装:

在命令行下apt-get install 就可以了

libpcap的使用:

/*author hjj

date 2011-1-21

function:capture packet with the ruler and output the packet information

modify 2011-1-23

function:get dns packet*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ETHER_ADDR_LEN 6

/*以太网头*/

struct sniff_ethernet

{

u_char ether_dhost[ETHER_ADDR_LEN];

u_char ether_shost[ETHER_ADDR_LEN];

u_short ether_type;

};

/*IP头*/

struct sniff_ip

{

u_char ip_vhl;

u_char ip_tos;

u_short ip_len;

u_short ip_id;

u_short ip_off;

#define IP_RF 0x8000

#define IP_DF 0x4000

#define IP_MF 0x2000

#define IP_OFFMASK 0x1fff

u_char ip_ttl;

u_char ip_p;

u_short ip_sum;

struct in_addr ip_src,ip_dst;

};

/*TCP头*/

typedef u_int tcp_seq;

struct sniff_tcp

{

u_short th_sport;

u_short th_dport;

tcp_seq th_seq;

tcp_seq th_ack;

u_char th_offx2;

u_char th_flags;

u_short th_win;

u_short th_sum;

u_short th_urp;

};

/*UDP报头*/

struct sniff_udp

{

u_short udp_sport;

u_short udp_dport;

u_short udp_len;

u_short udp_sum;

};

/*DNS报头*/

struct sniff_dns

{

u_short dns_id;

u_short dns_flag;

u_short dns_ques;

u_short dns_ans;

u_short dns_auth;

u_short dns_add;

u_int8_t *dsn_data;

};

//数据包到达回调函数void packetcall(u_char *user,const struct pcap_pkthdr *pcap_head,const u_char *packet);

char *ipstr(struct in_addr s_addr);

char* getpackettype(u_short packet_type);

char* toString(u_long s);

//由u_char[6]获取网卡地址字符串char *getMac(u_char *host);

int main(int argc,char **argv)

{

char *dev,errbuf[PCAP_ERRBUF_SIZE];

pcap_t *handler;

struct bpf_program fp;

char filter_exp[50]="ip and dst 172.20.92.118";

if(argc==3)

{

sprintf(filter_exp,"dst %s and dst port %s",argv[1],argv[2]);

}

if(argc==5)

{

sprintf(filter_exp,"dst %s and dst port %s or src %s and src port %s",argv[1],argv[2],argv[3],argv[4]);

}

bpf_u_int32 mask;

bpf_u_int32 net;

struct pcap_pkthdr header;

const u_char *packet;

dev=pcap_lookupdev(errbuf);

if(dev==NULL)

{

fprintf(stderr,"could not find default device:%s\n",errbuf);

return 2;

}

printf("device:%s\n",dev);

if(pcap_lookupnet(dev,&net,&mask,errbuf)==-1)

{

fprintf(stderr,"counld not get netmask for device %s;%s\n",dev,errbuf);

net=0;

mask=0;

}

handler=pcap_open_live(dev,BUFSIZ,1,10000,errbuf);

if(handler==NULL)

{

fprintf(stderr,"could not open device %s;%s",dev,errbuf);

return 2;

}

if(pcap_compile(handler,&fp,filter_exp,0,net)==-1)

{

fprintf(stderr,"counld not parse filter %s;%s\n",filter_exp,pcap_geterr(handler));

return 2;

}

if(pcap_setfilter(handler,&fp)==-1)

{

fprintf(stderr,"counld not install filter %s;%s\n",filter_exp,pcap_geterr(handler));

return 2;

}

//捕获数据包 int packetnums=20;

packet=pcap_loop(handler,packetnums,packetcall,NULL);

pcap_close(handler);

return 0;

}

//数据包到达回调函数void packetcall(u_char *user,const struct pcap_pkthdr *pcap_head,const u_char *packet)

{

static int count=1;//数据包计数 struct sniff_ethernet *ethernet;//以太网包头

struct sniff_ip *ip;//ip包头

struct sniff_udp *udp;//udp包头

struct sniff_dns *dns;//dns报头

const u_char *payload;//数据包负载的数据

int pay_size;//数据包负载的数据大小

ethernet=(struct sniff_ethernet*)(packet);

ip=(struct sniff_ip*)(packet + sizeof(struct sniff_ethernet));

udp=(struct sniff_udp*)(packet + sizeof(struct sniff_ethernet)+sizeof(struct sniff_ip));

dns=(struct sniff_dns*)(packet + sizeof(struct sniff_ethernet) + sizeof(struct sniff_ip) + sizeof(struct sniff_udp));

payload=(u_char *)(packet+sizeof(struct sniff_ethernet)+sizeof(struct sniff_ip)+sizeof(struct sniff_udp)+sizeof(struct sniff_dns));

pay_size=ntohs(udp->udp_len)-sizeof(struct sniff_udp)-sizeof(struct sniff_dns);

printf("-------------数据包:%d\n",count);

printf("数据包类型:%s\n",getpackettype(ethernet->ether_type));

printf("源地址:%X:%X:%X:%X:%X:%X\n",

(ethernet->ether_shost)[0],

(ethernet->ether_shost)[1],

(ethernet->ether_shost)[2],

(ethernet->ether_shost)[3],

(ethernet->ether_shost)[4],

(ethernet->ether_shost)[5]);

printf("目的地址:%X:%X:%X:%X:%X:%X\n",

(ethernet->ether_dhost)[0],

(ethernet->ether_dhost)[1],

(ethernet->ether_dhost)[2],

(ethernet->ether_dhost)[3],

(ethernet->ether_dhost)[4],

(ethernet->ether_dhost)[5]);

printf("From:%s\n",inet_ntoa(ip->ip_src));

printf("To:%s\n",inet_ntoa(ip->ip_dst));

printf("源端口:%d\n",ntohs(udp->udp_sport));

printf("目的端口:%d\n",ntohs(udp->udp_dport));

printf("DNS查询问题数%d\n",ntohs(dns->dns_ques));

if(pay_size>0)

{

printf("Payload data size %d\n",pay_size);

const u_char *ch=payload;

int i,j;

for(i=0;idns_ques);i++)

{

//获取各查询名 printf("第%d个查询名\n",i);

int k=1;//标志符号; while(1)

{

if(*ch==0)

break;

u_int8_t identify_size=*ch;

printf("\t第%d个标志符号\n",k);

ch++;

for(j=0;j

{

if(isprint(*ch))

{

printf("%c",*ch);

}else

{

printf(".");

}

}

k++;

}

}

}

count++;

}

libnet的使用

/*author hjj

date 2011-1-20

function: send an arp packet to all machine on local net*/

#include

#include

#define MAC_ADDR_LEN 6

#define IP_ADDR_LEN 4

#define LIBNET_DNS_H 0xc

int main(int argc,char **argv)

{

libnet_t *net_t=NULL;

char *dev="eth0";

char err_buf[LIBNET_ERRBUF_SIZE];

libnet_ptag_t p_tag;

unsigned char src_mac[MAC_ADDR_LEN]={0x00,0x00,0xf1,0xe8,0x0e,0xc8};//发送者网卡地址

unsigned char dst_mac[MAC_ADDR_LEN]={0xff,0xff,0xff,0xff,0xff,0xff};//接收者网卡地址 char *src_ip_str="172.20.92.117";

if(argc==2)

{

if(strcmp(argv[1],"-h")==0||strcmp(argv[1],"--help")==0)

{

printf("%s","help message");

}else

{

src_ip_str=argv[1];

}

}

unsigned long src_ip,dst_ip=0;

src_ip=libnet_name2addr4(net_t,src_ip_str,LIBNET_RESOLVE);//将字符串类型的ip转换为顺序网络字节流 net_t=libnet_init(LIBNET_LINK_ADV,dev,err_buf);//初始化发送包结构 if(net_t==NULL)

{

printf("libnet_init error\n");

exit(0)

}

p_tag=libnet_build_arp(

ARPHRD_ETHER,//hardware type ethernet ETHERTYPE_IP,//protocol type MAC_ADDR_LEN,//mac length IP_ADDR_LEN,//protocol length ARPOP_REPLY,//op type (u_int8_t*)src_mac,//source mac addr这里的作用是更新目的地的arp表 (u_int8_t*)&src_ip,//source ip addr (u_int8_t*)dst_mac,//source mac addr (u_int8_t*)&dst_ip,//dest ip addr NULL,//payload 0,//payload length net_t,//libnet context 0//0 stands to build a new one );

if(-1 == p_tag)

{

printf("libnet_build_arp error");

exit(0);

}

//以太网头部 p_tag=libnet_build_ethernet(//create ethernet header (u_int8_t*)dst_mac,//dest mac addr (u_int8_t*)src_mac,//source mac addr ETHERTYPE_ARP,//protocol type NULL,//payload 0,//payload length net_t,//libnet context 0//0 to build a new one );

if(-1 == p_tag)

{

printf("libnet_build_ethernet error!\n");

exit(1);

}

int res;

if(-1==(res=libnet_write(net_t)))

{

printf("libnet_write error!\n");

exit(1);

}

libnet_destroy(net_t);

return 0;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值