利用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);
}
关于过滤机制,以后再写
利用libpcap分析网络上的数据包(入门级)的更多相关文章
- 利用wireshark抓取远程linux上的数据包
原文发表在我的博客主页,转载请注明出处. 前言 因为出差,前后准备总结了一周多,所以博客有所搁置.出差真是累人的活计,不过确实可以学习到很多东西,跟着老板学习做人,学习交流的技巧.入正题~ wires ...
- Linux内核--网络栈实现分析(七)--数据包的传递过程(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地 ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程--转
转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...
- Snail—iOS网络学习之得到网络上的数据
在开发项目project中,尤其是手机APP,一般都是先把界面给搭建出来.然后再从网上down数据 来填充 那么网上的数据是怎么得来的呢,网络上的数据无非就经常使用的两种JSON和XML 如今 大部分 ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程(上)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7492423 更多请看专栏,地址 ...
- IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习
相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...
- 使用异步任务加载网络上json数据并加载到ListView中
Android中使用网络访问来加载网上的内容,并将其解析出来加载到控件中,是一种很常见的操作.但是Android的UI线程(也就是主线程)中是不允许进行耗时操作的,因为耗时操作会阻塞主线程,影响用户体 ...
- 网络编程-pcap数据包格式
Libpcap的官方网站是http://www.tcpdump.org/,该项目和Tcpdump项目是同一个团队维护.Libpcap是一个平台独立的 数据包捕获开发包,制定了数据包离线存储的事实标准. ...
- 利用Fiddler抓取手机APP数据包
Fiddler是一个调试代理,下载地址http://www.telerik.com/download/fiddler 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接 ...
随机推荐
- LoadRunner如何在脚本运行时修改log设置选项
LoadRunner如何在脚本运行时修改log设置选项?答案是使用lr_set_debug_message函数: lr_set_debug_message Sets the message level ...
- sencha touch结合webservice读取jsonp数据详解
sencha touch读取jsonp数据主要依靠Ext.data.JsonP组件,在mvc的store文件中定义代码如下: Ext.define('eparkapp.store.ParksNearb ...
- 基于React实现的【绿色版电子书阅读器】,支持离线下载
代码地址如下:http://www.demodashi.com/demo/12052.html MyReader 绿色版电子书阅读器 在线地址:http://myreader.linxins.com ...
- mac之homebrew安装
通过homebrew可以管理众多开源软件的安装和卸载.使用homebrew可以非常容易的安装 os x中没有包含的unix工具包和语言包,比如wget;node;lua;rabbitmq;nginx等 ...
- Python内存管理:垃圾回收
http://blog.csdn.net/pipisorry/article/details/39647931 Python GC主要使用引用计数(reference counting)来跟踪和回收垃 ...
- 用JWT技术为SpringBoot的API增加授权保护(转),需要自己实现userdetailservice接口
转自:https://blog.csdn.net/haiyan_qi/article/details/77373900 概述 示例 https://github.com/qihaiyan/jwt-bo ...
- python 学习方法
依据本人的学习经验,我总结了下面十点和大家分享: 1)学好python的第一步.就是立即到www.python.org站点上下载一个python版本号.我建议刚開始学习的人,不要下载具有IDE功能的集 ...
- nginx源码学习_数据结构(ngx_str_t)
nginx中关于字符串的数据结构位于src/core/ngx_string.c和src/core/ngx_string.h中 先来看一下数据结构: typedef struct { size_t le ...
- Java并发编程(三)概念介绍
在构建稳健的并发程序时,必须正确使用线程和锁.但是这终归只是一些机制.要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问. 对 ...
- linux用户密码生成
linux账户保存在/etc/passwd,密码保存在/etc/shadow. 通过man 5 passwd,man 5 shadow可查看文件中各字段含义. encrypted password ...