- 浏览: 271124 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
AndMacLinuXp:
试了下,不错!
printk内核调试 -
klose:
我引用你的文章,并做了简单的分析:这里贴出url:http:/ ...
linux系统调用fork, vfork, clone -
klose:
你上面提到的问题:free的问题。首先你可能疏忽了,stack ...
linux系统调用fork, vfork, clone -
qwe_rt:
HI ,非常nice的文章,在阅读过程中,我发现我的ubunt ...
linux手动添加开机启动的服务 -
suifeng:
谢谢分享, 受用中.
shell编程分支,循环
网络抓包,必需从数据链路层开始抓取,至于原因之前在原始套接口中提到过。
现在的sniffer大部分都采用了libpcap,详细文档可以在www.tcpdump.org上面找到。
#include <stdio.h>
#include <pcap.h>
#include <stdlib.h>
#include <string>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
#define SIZE_ETHERNET 14 //以太头部长度
using std::string;
using std::cout;
using std::endl;
string info;
static u_int count = 0;
void get_packet(u_char * args, const pcap_pkthdr * header, const u_char * packet){
char from_ip[24], to_ip[24];
const struct sniffer_ethernet * ethernet = (struct sniffer_ethernet *) packet;
//packet记载了包的内容,因为是从数据链路层开始抓取,第一头部当然是以太网(当然不是绝对,但大部分局域网是以太网,如果是其它网络,就用对应的数据结构
//前面我设置的端口是常用的WEB端口80,WEB协议是HTTP,下一层则是TCP,TCP又是构建在IP基础之上,所以这里包的分层解析就很清楚了
const struct ip * ip_header = (struct ip *)(packet + SIZE_ETHERNET);
//越过以太网头部,获取IP头部,struct ip是linux中对IP头部的一个数据结构,如果是windows机器,就请使用对应的数据结构
const struct tcphdr * tcp_header = (struct tcphdr *)(packet + SIZE_ETHERNET + sizeof(struct ip));
//越过以太网和IP头部,获取TCP头部指针,同样道理struct tcphdr是linux下的tcp描述结构,如果是windows机器,换成对应的数据结构
inet_ntop(AF_INET, &ip_header->ip_src, from_ip, sizeof(from_ip));
inet_ntop(AF_INET, &ip_header->ip_dst, to_ip, sizeof(to_ip));
//从ip头部获取目的IP地址和源IP地址
printf("from %s:%d to %s:%d, ip packet len = %d\n", from_ip, ntohs(tcp_header->source), to_ip, ntohs(tcp_header->dest), ip_header->ip_len);
//从TCP头部可以获取目的端口和源端口
printf("tcp syn = %d, ack = %d\n", tcp_header->syn, tcp_header->ack);
char * content = (char *)(packet + SIZE_ETHERNET + sizeof(struct ip) + sizeof(struct tcphdr));
//这里就是TCP包所承载的内容所在,80号端口自然是HTTP内容,这里还包括HTTP头部,但HTTP是应用层协议,linux内核中集成了TCP和UDP协议,并没有关于HTTP描述。不过HTTP比较简单,之后的运行结果可以看到HTTP内容
string content_str(content);
int loc = content_str.find("HTTP", 0);
if(loc != string::npos) { //这个判断后面运行结果会提到
cout << content_str << endl;
}
}
int main(int argc, char ** argv) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t * handle;
struct bpf_program fp;
char filter_exp[] = "port 80"; //设置过滤器,过滤器语法,文档上有说明,这里是监听80号端口的包(本地端口80和目的端口80都会被抓取
char * dev = argv[1];
bpf_u_int32 mask;
bpf_u_int32 net;
struct pcap_pkthdr header;
const u_char *packet;
if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Can't get netmask for device %s\n", dev);
net = 0;
mask = 0;
}
printf("net = %d, mask = %d\n", net, mask);
//dev = pcap_lookupdev(errbuf);
/*if(dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
exit(2);
}*/
/*
pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
snaplen is an integer which defines the maximum number of bytes to be captured by pcap.
promisc, whe nset to true, brings the interface into promiscuous mode
to_ms is the read time out in milliseconds (a value of 0 means no time out)
*/
handle = pcap_open_live(dev, BUFSIZ, 1, 100000, errbuf);
if(!handle) {
fprintf(stderr, "Couldn't open device: %s %s\n", dev, errbuf);
exit(1);
}
if(pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
exit(2);
}
if(pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
exit(2);
}
//packet = pcap_next(handle, &header);
/* Print its length */
//printf("Jacked a packet with length of [%d]\n", header.len);
//pcap_loop(handle, 4, get_packet, NULL);
/*
* pcap_dispatch(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
* p is easy to understand
* cnt told pcap_dispatch how many packets it should sniff before return;
*/
pcap_loop(handle, -1, get_packet, NULL);
pcap_close(handle);
exit(0);
}
结合www.tcpdump.org上的文档,这个程序并不是很难懂。
下面是运行结果,输入./a.out eth0后,打开浏览器(请使用空白页面),输入百度地址后,抓取的包。
difa:/program# ./a.out eth0
from 192.168.1.154:2660 to 119.75.217.56:80, ip packet len = 12288
tcp syn = 1, ack = 0
from 119.75.217.56:80 to 192.168.1.154:2660, ip packet len = 12288
tcp syn = 1, ack = 1
from 192.168.1.154:2660 to 119.75.217.56:80, ip packet len = 10240
tcp syn = 0, ack = 1
from 192.168.1.154:2660 to 119.75.217.56:80, ip packet len = 64514
tcp syn = 0, ack = 1
GET / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: BAIDUID=CDAA16F90ADB78EDFBFC5FEB0D4A620C:FG=1; USERID=c9a484d8b976b5a3e70b5ae36d0f6d; J_MY=1; BDUSS=zNMMnM2cUhSLWFKS2FkTGJqQjdnVEpwODcwTFNQOXZvOFN5QkRMclViV0FPVkpNQUFBQUFBJCQAAAAAAAAAAApBCIorNXYFbWVtb3J5bXlhbm4AAAAAAAAAAAAAAAAAAAAAAAAAAACAy2V7AAAAAAAAAAAAAAAAAU9CAAAAAAAxMC42NS4yNICsKkyArCpMZ; OPENPLATFORM_SP=2b356d656d6f72796d79616e6e7605_1277865106
程序没有退出,结果只是复制粘贴其中一部分,没有全部展出(到后面因为中文乱码显示问题,就没有继续贴出)
./a.out eth0
eth0是网卡,如果想寻找默认的物理设备,pcap中提供了API,可以自己在文档中找到。
net = 108736, mask = 16777215
对应的IP地址和子网掩码,没有换成点分十进制类型。
from 192.168.1.154:2660 to 119.75.217.56:80, ip packet len = 12288
tcp
syn = 1, ack = 0
from 119.75.217.56:80 to 192.168.1.154:2660, ip
packet len = 12288
tcp syn = 1, ack = 1
from 192.168.1.154:2660 to
119.75.217.56:80, ip packet len = 10240
tcp syn = 0, ack = 1
TCP的三路握手,简历链接的过程,从ip头部的SYN和ACK字段可以明显看出。HTTP是构建于TCP之上,所以之前三个包是建立连接所用。
from 192.168.1.154:2660 to 119.75.217.56:80, ip packet len = 64514
tcp
syn = 0, ack = 1
GET / HTTP/1.1
Host: www.baidu.com
User-Agent:
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6)
Gecko/20100625 Firefox/3.6.6
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:
zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset:
GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie:
BAIDUID=CDAA16F90ADB78EDFBFC5FEB0D4A620C:FG=1;
USERID=c9a484d8b976b5a3e70b5ae36d0f6d; J_MY=1;
BDUSS=zNMMnM2cUhSLWFKS2FkTGJqQjdnVEpwODcwTFNQOXZvOFN5QkRMclViV0FPVkpNQUFBQUFBJCQAAAAAAAAAAApBCIorNXYFbWVtb3J5bXlhbm4AAAAAAAAAAAAAAAAAAAAAAAAAAACAy2V7AAAAAAAAAAAAAAAAAU9CAAAAAAAxMC42NS4yNICsKkyArCpMZ;
OPENPLATFORM_SP=2b356d656d6f72796d79616e6e7605_1277865106
这个就很容易理解了,链接建立完毕,浏览器向服务器发送HTTP的请求,内容就是HTTP请求头部。
一个小问题,我的程序是部署在linux虚拟机中,最初的API设置为混杂模式,之后打开的浏览器是WINDOW下面的firefox,所以user-agent属性里面看到的是windows
注:抓包程序一般都是从数据链路层着手,操作系统基本上都提供了对应的系统调用。libpcap并不是操作系统提供,是第三方工具,且它是跨平台的,无论是linux或者windows都可以使用,当然前提是你安装了libpcap。
发表评论
-
hdfs集群搭建
2014-05-11 17:19 1046网上很多hadoop集群搭建的文章,我这里只写下hdfs,不 ... -
网站性能优化
2013-10-25 10:43 0好久没写了,最近一直在做些互联网的一些东西。下面介绍些性能优 ... -
html5学习网站
2011-07-29 14:55 957htm5:http://www.w3school.com.cn ... -
HTTP下载
2011-02-09 15:24 1132HTTP下载的关键是修改Content-Type。 C ... -
28.sniffer程序2
2010-07-01 17:51 1803对前面27中sniffer中的一 ... -
java 和 linux c udp通信的样例
2010-05-28 11:58 2506一个简单的例子 java段(客户端) package ... -
26.原始套接字
2010-05-12 16:45 1838一个小程序: //发送方 #include <sys ... -
25.cookies和session
2010-05-10 15:21 973原文出自:http://blog.csdn ... -
24.SOCKET模拟HTTP请求
2010-05-07 14:11 5367HTTP请求头部样例: GET http://www.bai ... -
23.广播
2010-04-29 16:34 975如果想发送广播到目前为止只能使用AF_INET, SOCK_D ... -
22.非阻塞connect
2010-04-28 11:36 2781connect非阻塞套接口时候,一般使用在以下几种情况: ... -
21.非阻塞I/O
2010-04-27 16:54 2102设置一个I/O成为非阻塞很简单,只需要: int val = ... -
20.辅助数据 和 传输描述字
2010-04-26 15:53 2123打开一个文件或者一个 ... -
19.unix域协议与TCP UDP不同之处
2010-04-22 13:46 2674之前说过一些区别,但基本对我们编程来说没有太多影响,但以下几个 ... -
18.unix域协议
2010-04-21 16:47 2665UNIX域协议并不是一个真正的协议族,它是用在同一台主机上进行 ... -
17.I/O函数recvmsg与sendmsg
2010-04-20 15:58 12494想对于之前的几个IO函 ... -
16.I/O函数
2010-04-20 13:51 1286最早使用的read与write函 ... -
15.服务器守护进程
2010-04-16 17:44 1429前面提到过的服务器都占有控制终端。而有些进程并不需要控制终端。 ... -
14.udp与connect
2010-04-13 16:41 3260UDP在调用sendto发送数据 ... -
13.UDP编程
2010-04-09 17:16 2317虽然UDP不保证传输的可 ...
相关推荐
【简单的Sniffer程序】是一种用于网络数据包捕获的基础工具,它可以帮助我们了解网络通信的细节,对于学习网络安全和网络编程具有重要的实践意义。在网络安全领域,嗅探器(Sniffer)是一种网络分析工具,它可以捕获...
《深入理解Sniffer程序:揭示网络通信的奥秘》 在计算机网络的世界里,Sniffer程序扮演着一个至关重要的角色,它是一种能够捕获网络上数据包的工具,用于监控和分析网络通信。本文将围绕“Sniffer程序”这一主题,...
7. Sniffer.dpr - 主程序文件,包含了程序的启动和主要逻辑。 8. Sniffer.dproj - 项目文件,管理着整个工程,包括源文件、编译选项等。 9. Sniffer.drc - 资源文件,可能包含了程序中的图标、字符串等资源。 10. ...
用mfc编写的的sniffer小程序,可以实现简单ip地址、类型、端口等数据的收集分析,算是网络编程的一个小实验
基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序
【标题】"一个VC++的Sniffer程序"指的是使用Microsoft Visual C++(VC++)编写的网络嗅探器。在计算机网络中,嗅探器是一种工具,它能够捕获网络上的数据包,以便进行网络诊断、性能分析或安全审计。 【描述】中...
实验报告的主题是“sniffer程序分析与设计”,主要涉及了TCP/IP协议的理解、sniffer程序的编写以及winpcap库的使用。以下是基于这些内容详细解释的知识点: 1. **TCP/IP协议**:TCP/IP(Transmission Control ...
在Sniffer_POP3程序中,`Sniffer_POP3Dlg.cpp`和`Sniffer_POP3Dlg.h`文件可能包含了主对话框类的定义和实现,这是用户与程序交互的界面。`Sniffer_POP3.cpp`和`Sniffer_POP3.h`可能包含了程序的主要逻辑,包括数据包...
在这个项目中,我们将会修改一个现有的Sniffer源程序,以便它能显示捕获到的数据包的关键信息,如协议类型、源IP地址、目的IP地址、源端口和目的端口。 首先,我们需要了解网络数据包的基本结构。在TCP/IP协议栈中...
源码分析是指对程序的源代码进行检查和评估,以找出潜在的问题,如性能瓶颈、错误或不规范的编程习惯。这对于软件维护、优化和质量保证至关重要。VC源码sniffer就是这样一个工具,它能够解析C++源代码,并提供有关...
"sniffer程序源码(MFC)" 指的是一款使用Microsoft Foundation Class (MFC) 库开发的网络嗅探器(sniffer)的源代码。MFC是微软为Windows应用程序开发提供的一套C++类库,它基于面向对象的编程思想,简化了Win32 ...
【Winsock 本地抓包Sniffer程序源码】是一个基于Delphi编程语言并利用Winsock API实现的简单网络监听工具。这个程序的核心功能是通过设置网卡为混杂模式,来捕获并分析本地网络中的所有数据包。下面将详细阐述相关...
《VC实现的经典Sniffer程序详解》 Sniffer,也称为网络嗅探器,是一种在网络监控中广泛使用的工具,用于捕获并分析网络上的数据包。本文将深入探讨一个使用Visual C++(VC)开发的经典Sniffer程序,它虽功能简单,...
4. **下载SNIFFER.PORTABLE.V4.7.5SP5安装包:**访问官方网站或其他可信渠道下载最新版本的SNIFFER.PORTABLE.V4.7.5SP5安装程序,并将其保存到本地硬盘上。 5. **检查Java环境:**SNIFFER.PORTABLE.V4.7.5SP5的运行...
标题 "一个简单的sniffer程序" 暗示我们即将探讨的是网络嗅探工具,也称为网络包分析器。网络嗅探器(Sniffer)是一种软件工具,它允许用户捕获和查看通过网络传输的数据包。这些工具对于网络管理员、安全专家和开发...
基于原始套接字编写的Sniffer程序。
以下将详细讲解如何在Linux环境下用C语言编写一个Sniffer程序。 首先,我们需要了解网络数据包在以太网中的传输过程。一个IP数据包会被封装成以太网帧,其中包含了源和目的的MAC地址。当数据包在网络中传输时,它会...
Sniffer源程序是一种网络分析工具,它主要用于监测和分析网络数据包。在IT领域,了解和使用Sniffer类工具是网络管理员、安全专家以及软件开发者的重要技能之一。Sniffer能够捕获并解码网络上的传输数据,这对于故障...