设为首页 收藏本站
查看: 1158|回复: 0

[经验分享] linux下网络监听与发送数据包的方法(即libpcap、libnet两种类库的使用方法)

[复制链接]

尚未签到

发表于 2015-3-10 10:00:32 | 显示全部楼层 |阅读模式
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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-45180-1-1.html 上篇帖子: [转帖] Java5/6中的字体自定义设置与美化(Linux/Windows) 下篇帖子: 一个多线程web服务器实例(C,Linux,详细的web服务器原理)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表