利用libpcap分析网络上的数据包(入门级)

本文可任意转载,但请保留作者及出处
作者:rainfish
出处:http://blog.csdn.net/bat603/
经过几天的突击,终于明白了怎样在局域网内抓包,这可是我多年来的梦想。首先说说我的学习过程,一开始从网上搜索了关于sniffer大量资料,大致学会了,可是仔细分析结果发现,都是本机上的数据包,而不是整个局域网的。于是又查资料,在 linuxsir上有高人指点,说,现在局域网内都是交换机联接,而不是以前的Hub所以,如果要抓整个局域网的数据包,必须用libpcap,于是又查了许多关于Libpcap的资料,经过一天的努力,总算稍微有点眉目了。总结手里的资料,它们都在讲怎样用libpcap抓包,而没有讲怎样去分析包,所以在下就写了一个小小的例子,去分析数据包里的具体信息,如果有不正确的地方,敬请指正。
关于libpcap的使用方法,请参考我收集的的资料
http://blog.csdn.net/bat603/archive/2006/09/04/1175729.aspx
http://blog.csdn.net/bat603/archive/2006/09/04/1176251.aspx
下边这个比较深奥
http://blog.csdn.net/bat603/archive/2006/09/04/1175271.aspx

源代码及解释
/**************************************************************
********************rainfish**********************************
***************http://blog.csdn.net/bat603/**********************
**********本文可任意转载,但请保留作者及出处*****************/

//该程序使用方法:./exe_your_file  numpacket
#include <stdio.h>
#include <pcap.h>
/* if this gives you an error try pcap/pcap.h 里面有相应的数据结构一般在/usr/include/中*/
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>//注意使用的ip、tcp数据结构,至于它们和 <netinet/ip.h | tcp.h>的区别,我也弄不清楚。

/*回调函数,int pcap_loop(pcap_t *p, int cnt,
          pcap_handler callback, u_char *user)调用的
这里需要说明的是,关于参数 pkthdr、packet的说明,好多资料都没有进行解释,在这里我只能尝试的去解释
当执行pcap_loop,会自动调用回调函数,pcap_t *p是调用者传递的,参看下面例子,而pkthdr(libpcap 自定义数据包头部),packet(捕获的书据包)就会相应得到,而不用用户操作。下面的例子也能证明这一点。我实在不敢确定,因为没有找到相应的文档
*/
void my_callback(u_char *userless, const struct pcap_pkthdr *pkthdr, 
                    const u_char *packet)
{
    struct in_addr addr;
    struct iphdr *ipptr;
    struct tcphdr *tcpptr;//太次片,,ip,tcp数据结构
    char *data;
        
    pcap_t *descr = (pcap_t*)userless;//捕获网络数据包的数据包捕获描述字
    //const u_char *packet;
    struct pcap_pkthdr hdr = *pkthdr;//(libpcap 自定义数据包头部),
    struct ether_header *eptr;//以太网字头
    u_char *ptr;
    int i;
 
    if (packet == NULL)//packet里面有内容,可以证明上面的猜想,
    {
        printf ("Didn‘t grab packet!/n");
        exit (1);
    }
    printf ("/n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/n");
    printf ("Grabbed packet of length %d/n", hdr.len);
    printf ("Received at : %s/n", ctime((const time_t*)&hdr.ts.tv_sec));
    printf ("Ethernet address length is %d/n", ETHER_HDR_LEN);
    
    eptr = (struct ether_header*)packet;//得到以太网字头
    
    if (ntohs(eptr->ether_type) == ETHERTYPE_IP)
    {
        printf ("Ethernet type hex:%x dec:%d is an IP packet/n",
                    ntohs(eptr->ether_type), ntohs(eptr->ether_type));
    }
    else 
    {
        if (ntohs(eptr->ether_type) == ETHERTYPE_ARP)
        {
            printf ("Ethernet type hex:%x dec:%d is an ARP packet/n",
                        ntohs(eptr->ether_type), ntohs(eptr->ether_type));
        }
        else
        {
            printf ("Ethernet type %x not IP/n", ntohs(eptr->ether_type));
            exit (1);
        }
    }
        
    ptr = eptr->ether_dhost;
    i = ETHER_ADDR_LEN;
    printf ("i=%d/n", i);
    printf ("Destination Address: ");
    do
    {
        printf ("%s%x", (i == ETHER_ADDR_LEN)?"":":", *ptr++);
    }while(--i>0);
    printf ("/n");
    //printf ("%x/n",ptr);
    
    ptr = eptr->ether_shost;
    i = ETHER_ADDR_LEN;
    printf ("Source Address: ");
    do
    {
        printf ("%s%x", (i == ETHER_ADDR_LEN)?"":":", *ptr++);
    }while(--i>0);
    printf ("/n");
    printf ("Now decoding the IP packet./n");
    ipptr = (struct iphdr*)    (packet+sizeof(struct ether_header));//得到ip包头
    
    printf ("the IP packets total_length is :%d/n", ipptr->tot_len);
    printf ("the IP protocol is %d/n", ipptr->protocol);
    addr.s_addr = ipptr->daddr;
    printf ("Destination IP: %s/n", inet_ntoa(addr));    
    addr.s_addr = ipptr->saddr;
    printf ("Source IP: %s/n", inet_ntoa(addr));
    
    printf ("Now decoding the TCP packet./n");
    tcpptr = (struct iphdr*)(packet+sizeof(struct ether_header)
                                    +sizeof(struct iphdr));//得到tcp包头
    printf ("Destination port : %d/n", tcpptr->dest);
    printf ("Source port : %d/n", tcpptr->source);
    printf ("the seq of packet is %d/n", tcpptr->seq);
//以上关于ip、tcp的结构信息请查询/usr/include/linux/ip.h | tcp.h
    
    data = (char*)(packet+sizeof(struct ether_header)+sizeof(struct iphdr)
                                    +sizeof(struct tcphdr));//得到数据包里内容,不过一般为乱码。
    
    printf ("the content of packets is /n%s/n",data);
}
int main(int argc, char **argv)
{
    int i;
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *descr;
    const u_char *packet;
    struct pcap_pkthdr hdr;
    struct ether_header *eptr;
    
    if (argc != 2)
    {
        fprintf (stdout, "Usage: %s numpackets/n", argv[0]);
        return 0;
    }
    
    dev = pcap_lookupdev (errbuf);
    if (dev == NULL)
    {
        printf ("%s/n", errbuf);
        exit (1);
    }
    
    descr = pcap_open_live (dev, BUFSIZ, 1, -1, errbuf);
    //第三个参数,1为混杂模式;0为非混杂模式
    //BUFSIZ同PCAP_ERRBUF_SIZE一样,均为库文件已经定义好的,不推荐使用
    if (descr == NULL)
    {
        printf ("pcap_open_live(): %s/n", errbuf);
        exit (1);
    }
    pcap_loop (descr, atoi(argv[1]), my_callback, NULL);//调用回调函数
    
 
        
    printf("Hello world/n");
    return (0);
}
关于过滤机制,以后再写

时间: 2024-10-11 04:49:23

利用libpcap分析网络上的数据包(入门级)的相关文章

Linux内核--网络栈实现分析(七)--数据包的传递过程(下)

本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地址http://blog.csdn.net/column/details/linux-kernel-net.html 作者:闫明 注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析.”(下)“表示分析是从上向下分析. 在博文Linux内核--网络栈

转 Android智能手机上捕获数据包

如何在Android智能手机上捕获数据包? 本文由CSDN-蚍蜉撼青松[主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 当前Android系统越来越流行,无论是对于安卓应用的开发人员,还是对于网络安全的研究人员,都有可能需要掌握捕获Android应用通信数据包的方法.根据技术手段不同,常用的抓包方法分两类,一类是通过Android智能移动终端所接入的上层网络设备或线路获取数据流,另一类则是直接在Android移动终端上监听数据流.本文主要探讨第二类方法

利用fiddler抓取Android app数据包

前言 做Android开发的朋友经常需要做网络数据的获取和提交表单数据等操作,然而对于调试程序而言,很难知道我们的数据到底是以怎样的形式发送的,是否发送成功,如果发送失败有是什么原因引起的.fiddler工具为我们提供了很方便的抓包操作,可以轻松抓取浏览器的发出的数据,不管是手机APP,还是web浏览器,都是可以的. 什么是fiddler 百度百科上是这样说的:Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的"进出&quo

网络概述:数据包、数据帧

1.数据包 "包"(Packet)是TCP/IP协议通信传输中的数据单位,一般也称"数据包".有人说,局域网中传输的不是"帧"(Frame)吗?没错,但是TCP/IP协议是工作在OSI模型第三层(网络层).第四层(传输层)上的,而帧是工作在第二层(数据链路层).上一层的内容由下一层的内容来传输,所以在局域网中,"包"是包含在"帧"里的. 数据包主要由"目的IP地址"."源IP地

ios学习(从网络上获取数据)

从网络上获取数据: 1.从网络上获取数据,采用如下这种方式会带来主线成阻塞现象,主线成主要是负责的是ui的交互(用户输入指令或数据,系统给一个反馈) 会进一步让ui停止交互 1)首先给我们将要下载的图片设置好位置 UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"地址"]]]; UIImageView *imageView = [[UIImageVie

Snail—iOS网络学习之得到网络上的数据

在开发项目工程中,尤其是手机APP,一般都是先把界面给搭建出来,然后再从网上down数据 来填充 那么网上的数据是怎么得来的呢,网络上的数据无非就常用的两种JSON和XML 现在 大部分都是在用JSON 网络上传输数据都是以二进制形式进行传输的 ,只要我们得到网上的二进制数据 如果它是JSON的二进制形式 那么我们就可以用JSON进行解析 如果是XML,那么我们可以用XML解析 关键是怎么得到网上的二进制数据呢 设计一个常用的工具类 很简单 给我一个接口(URL),那我就可以用这个类得到二进制文

(转)mac 下使用wireshark监听网络上的数据

mac 下使用wireshark监听网络上的数据 分三个步骤: 1.wireshark安装 wireshark运行需要mac上安装X11,mac 10.8的系统上默认是没有X11的.先去http://xquartz.macosforge.org/landing/下载最新的 xquartz安装,安装好就有X11了. wireshark的下载,网上有很多下载源.官网试了几次,没打开的成.可以考虑去华军之类的网站上下载. 2.打开网卡,允许wireshark访问 安装好xquartz和wireshar

Linux内核--网络栈实现分析(二)--数据包的传递过程(上)

本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7492423 更多请看专栏,地址http://blog.csdn.net/column/details/linux-kernel-net.html 作者:闫明 注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析.”(下)“表示分析是从上向下分析. 上一篇博文中我们从宏观上分析了L

Linux 网络编程——IP 数据包格式详解

IP 数据报首部 TCP/IP 协议定义了一个在因特网上传输的包,称为 IP 数据报 (IP Datagram).这是一个与硬件无关的虚拟包,由首部和数据两部分组成. 首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的.在首部的固定部分的后面是一些可选字段,其长度是可变的.首都中的源地址和目的地址都是 IP 协议地址. IP 数据报首部的固定部分中的各字段: 1)版本:占4位,指IP协议的版本. 通信双方使用的 IP 协议版本必须一致.日前广泛使用的 IP 协议版本号为 4