数据包分析

过对数据包的分析,我们可以判断通信双方的操作系统、网络信息流量、经过的路由、数据包的大小,以及数据包的内容等等。对于喜欢网络安全的人来说,掌握这
方面的知识是相当重要的。现在的网络通信中,大部分数据都没有加密,我们可以轻易地从数据包中提取账号、密码之类我们关心的数据.大家在看本文时如有困
难,可先读一读计算机网络及C程序设计还有协议分析方面的书。下面我将分TCP/IP族协议结构、程序部分函数及数据结构说明、案例程序剖析三个部分与大
家共同学习数据包分析程序的设计方法。
一、TCP/IP族协议结构
在说TCP/IP之前,先让我们来认识一下以太网,因为我们现
在接触最多的就是以太网,并且研究数据包又是离不开以太网的帧的。在以太网中,数据是以被称为帧的数据结构本为单位进行交换的。以太网中常用的协议是
CSMA/CD(carrier sense multiple access with collision
detection)即载波监听多点接入/碰撞检测,在这里,我们关注的是帧的格式。常用的以太网帧的格式有两种标准,一种是DIX Ethernet
V2标准,另一种是IEEE的802.3标准。现在最常用的MAC帧是V2格式,这也是我们所要研究的格式,至于802.3帧我们不再讨论。以太网V2帧
的格式如下:
(插入8字节)目的地址(6字节)->源地址(6字节)->类型(2字节)->数据(46-1500)->FCS(4字节)

太网的地址由48位的二进制来表示,也就是我们常说的MAC地址及硬件地址。在MAC帧前还有8字节的前同步码和帧的开始定界符,之后才是地址等报头信
息。接收端和发送端的地址之后是2字节的类型字段,存放帧中传送数据的上层协议类型,RFC1700号文档规定了这些,如下:
ETHER TYPES(十六进制) PROTOCOlS
800 IP
806 ARP
8035 Revese ARP
809B Apple Talk
8137/8138 Novel
814c SNMP
帧的数据部分长度为46-1500字节,当小于46时,会在后面加入一个整数字节的填充字段。FCS(Frame Check Sequence)在以太网常用循环冗佘校检(CRC:cyclic redandancy check)。
IP协议为网络层协议,网络层的数据结构体被称为IP数据报。IP地址及域名这两个概念我们就不说了,下面我们来看一看IP数据报的结构:
成员名 字节数 说明
version 1/2 IP的版本,现在为IPV4
IHL(报送长度) 1/2 最常用为20,取5-15之前的值,最大60字节
Type Of Service 1 优先和可靠性服务要求的数值
Total Lenth 2 IP数据报的全长
Identification 2 识别IP数据报的编号
Flags 3/8 1位为0表示有碎块,2位为0表示是最后的碎块,为1表示接收中。
Fragment Offset 13/8 分片在原分组中的位置
TTL 1 数据报寿命,建议值为32秒
Protocol 1 上层协议
Headerchecksum 2 报头检验码
Source Address 4 发送端IP地址
Destination Address 4 接收端IP地址
Options And Padding 4 选项及填充位
其中协议字段的值对我们分析数据包是很重要的,下面列出来给大家看看:
值 协议 意义
1 ICMP Internet Control Message Protocol
6 TCP              Tranfer Control Protocol
8 EGP Exterior Gateway Protocol
     9 IGP Interior Gateway Protocol
17 UDP User Datagram Protocol
下面这些协议的值在后面的程序中我们可以见到,请大家留心记一下。接着我们介绍地址解析协议(ARP/RARP):
成员名 字节数 说明
Hardware address 2 硬件类型,以太网为1
Protocol address 2 上层协议类型,IP为800
Byte length of each hardware 1     查询物理地址的字节长度,以太网为6
Byte length of each protocol address 1 查询上层协议的字节长度,IPv4时为4
Opcode 2 1为ARP请求,2为响应;3为RARP请求,4为响应
Hardware address of sender of this packet 6 发送端硬件地址
protocol address of sender of this packet 4 发送端IP地址
Hardware address of target of this packet 6 查询对象硬件地址
Protocol address of target of this packet 4 查询对象IP地址
ARP/RARP
协议用来查询IP对应的硬件地址或反过来查询IP地址,这在我们分析数据包时也会见到。下面介绍ICMP协议。我们常用的PING命令就是用的这个协议,
这个协议比较简单,由类型(1字节)、代码(1字节)、检验和(2字节)、还有四个字节的与类型相关的可变部分及数据构成。
数据包在运输层还有两个重要的协议,即TCP/UDP,TCP/UDP中使用端口的概念,以区别计算机上不同的程序。下面我们先来看看TCP数据报的首部构成:
成员名 字节数 说明
Source Port 2 发送端端口号
Destination Port 2 接收端端口号
Sequence NO 4 本报文段所发送的第一个字节的序号
ACk Number 4 期望收到的下一个报文段的序号
DAta Offset 1/2 首部的长度
Reserved 3/4 保留今后用
Contol Bits 3/4 控制位
Window 2 滑动窗口的大小
Checksum 2 检验和
Urgent Pointer 2 紧急指针
Options And Padding 4 可选,真充项
Tcp被使用在跨越路由器进行网络服务的网络应用程序中,如WWW、电子邮件、新闻、FTP等。UDP则是在IP的基础上加入了端口的概念,其结构很简单,只有八个字节首部如下:
源端口(2字节)->目的端口(2字节)->长度(2字节)->检验和(2字节)
二、程序部分函数及数据结构说明
在此部分我们将介绍后面程序中用到的部分函数及数据结构。在程序中我们使用了PCAP程序库,大家可以从
ftp://ftp.ee.lbl.gov/libpcap.tar.z下载。我们主要在Redhat
Linux下测试程序,这里简单介绍一下程序库的安装方法,其它环境请大家自行解决。我的目的是给大家编写数据包分析程序提供思路,至于实用程序的实现这
里不做介绍,第三部分给出的程序也不具实用性,为了演示,程序中实现的功能较多而有些地方又不够详细,编写实用程序时请适当取舍并加入你所需要的功能实现
部分。PCAP程序库的安装方法如下:
1、解压文件
2、进入文件目录执行./configure 及make
3、使用Make命令,设定手册和Include文件(要有Root权限),执行以下命令:
make install -man
make install -incl
4、如出现不存在Include及Include/net目录,则建立此目录并重新执行 make install -incl
5、检查/usr/include/netinet/目录是否存在Protocols.h文件,不存在则拷贝过去。至此程序库安装完毕。
下面介绍程序中出现的部分函数及数据结构:
1、PCAP_t *pd;
此型数据结构称为数据包捕捉描述符。
2、Pcap_Open_Live(argv[1],DEFAUT_SNALEN,1,1000,ebuf)
此函数对Pcap程序库进行初始化并返回指向Pcap_t型数据的指针,其参数列表如下:
        char * 指定网络接口 
int 取得数据的最大字节数 
int 指定网络接口卡,一般用1
int 读出暂停时间
char * 错误消息用缓冲区
3、Pcap_loop(pd,-1,packet_proce,NUll)
     此函数程序的核心,反复执行,利用Pcap取得数据包,返回的是读入数据包的个数,错误时返回-1,其参数列表如下:
Pcap_t * 指定取得数据包的数据包捕捉描述符茶叶www.aichar.com
int 取得数据包的个数,-1为无限
返回指向函数的指针 指定数据包处理的函数
U_char * 指向赋给数据包处理函数字符串的指针
4、struct ether_header * eth
此结构体存储以太网报头信息,其成员如下:
ether_dhost[6] 接收端的MAC地址
ether_shost[6] 发送端的MAC地址
ether_type 上层协议的种类
5、fflush(stdout)
此函数完成的是强制输出,参数Stdout,强制进行标准输出。
6、noths(((struct ether_header *P)->ether_type))
此函数将短整型网络字节顺序转换成主机字节顺序。此类函数还有:
ntohl 长整型 功能同上
htons 短整型 将主机字节顺序转换成网络字节顺序
htons 长整型 同上
7、struct IP *iph
ip型结构体在IPh文件中定义,其成员和第一部分讲到的IP数据报结构对应,如下:
成员名 类型 说明
ip_hl 4位无符号整数 报头长度
ip_v 同上 版本,现为4
ip_tos 8位无符号整数 Type of service
ip_len 16位无符号整数 数据报长度
ip_id 同上 标识 
ip_off 同上 数据块偏移和标志
ip_ttl 8位无符号整数 TTL值
ip_p 同上 上层协议
ip_sum 16位无符号整数 检验和
ip_src in_addr结构体 发送端IP
ip_dst 同上 接收端IP
8、struct ether_arp *arph
ether_arp型结构体成员如下:
成员名 类型 说明
ea_hdr arphdr型结构体 报头中地址以外的部分
arp_sha 8位无符号整数数组 发送端MAC地址
arp_spa 同上 发送端IP地址
arp_tha 同上 目标MAC地址
arp_tpa 同上 目标IP地址
9、struct icmphdr * icmp
icmphdr型结构体中包含共用体根据数据报类型的不同而表现不同性质,这里不再列出,只列能通用的三个成员
成员名 说明
type 类型字段
code 代码
checksum 检验和
三、案例程序剖析
//example.c
//使用方法:example〈网络接口名〉 > 〈输出文件名〉
//例如:example etho > temp.txe
//结束方法:ctrl+c
//程序开始,读入头文件
#include
#include
#include
#include
#include
#include
#include
#include //pcap程序库
#include //DNS检索使用 
#define MAXSTRINGSIZE 256 //字符串长度
#define MAXSIZE 1024 //主机高速缓存中的最大记录条数
#fefine DEFAULT_SNAPLEN 68 /数据包数据的长度
typedef struct重生之大文豪www.dwhao.com
{
    unsigned long int ipaddr; //IP地址
    char hostname[MAXSTRINGSIZE]; //主机名
}dnstable; //高速缓存数据结构
typedef struct 
{
    dnstable table[MAXSIZE];
    int front;
    int rear;
}sequeue; 
sequeue *sq; //定义缓存队列
sq->rear=sq->front=0; //初始化队列
//输出MAC地址函数
void print_hwadd(u_char * hwadd)
{
    for(int i=0,is_name);
    }
    else
        sprintf(portna,"%d",portno);
}
//将IP转化为DNS名
void iptohost(unsigned long int ipad,char* hostn)
{
    struct hostent * shostname;
    int m,n,i;
    m=sq->rear;
    n=sq->front;
    for(i=n%MAXSIZE;i=m%MAXSIZE;i=(++n)%MAXSIZE)
    {
        //检查IP是否第一次出现
        if(sq->table.ipaddr==ipad)
        {
            strcpy(hostn,sq->table.hostname);
            break;
        }
    }
    if(i=m%MAXSIZE)
    {//不存在则从域名服务器查询并把结果放入高速缓存
        if((sq->rear+1)%MAXSIZE=sq->front) //判队满
            sq->front=(sq->front+1)%MAXSIZE; //出队列
        sq->table.ipaddr=ipad;
        shostname=gethostbyaddr((char*)&ipad,sizeof(ipad),AF_INET);
        if(shostname!=NULL)
            strcpy(sq->table.hostname,shostname->h_name);
        else
            strcpy(sq->table.hostname,"");
        sq->rear=(sq->rear+1)%MAXSIZE;
    }
}
void print_hostname(u_char* ipadd)
{
    unsigned long int ipad;
    char hostn[MAXSTRINTSIZE];
    ipad=*((unsigned long int *)ipadd);
    iptohost(ipad,hostn)
        if(strlen(hostn)>0)
            printf("%s",hostn);
        else
            print_ipadd(ipadd);
}
//处理数据包的函数
void packet_proce(u_char* packets,const struct pcap_pkthdr * header,const u_char *pp)
{
    struct ether_header * eth; //以太网帧报头指针
    struct ether_arp * arth; //ARP报头
    struct ip * iph; //IP报头
    struct tcphdr * tcph;
    struct udphdr * udph;
    u_short srcport,dstport; //端口号
    char protocol[MAXSTRINGSIZE]; //协议类型名
    char srcp[MAXSTRINGSIZE],dstp[MAXSTRINGSIZE]; //端口名
    unsigned int ptype; //协议类型变量
    u_char * data; //数据包数据指针
    u_char tcpudpdata[MAXSTRINGSIZE]; //数据包数据
    int i;
    eth=(struct ether_header *)pp;
    ptype=ntohs(((struct ether_header *)pp)->ether_type);
    if((ptype==ETHERTYPE_ARP)||(ptype==ETHERTYPE_RARP))
    {
        arph=(struct ether_arp *)(pp+sizeof(struct ether_header));
        if(ptype==ETHERTYPE_ARP)
            printf("arp ");
        else
            printf("rarp "); //输出协议类型
        print_hwadd((u_char *)&(arph->arp_sha));
        printf("(");
        print_hostname((u_char *)&(arph->arp_spa));
        printf(")->");
        print_hwadd((u_char *)&(arph->arp_tha));
        printf("(");
        print_hostname((u_char *)&(arph->arp_tpa));
        printf(")\tpacketlen:%d",header->len);
    }
    else if(ptype==ETHERTYPE_IP) //IP数据报
    {
        iph=(struct ip *)(pp+sizeof(struct ether_header));
        if(iph->ip_p==1) //ICMP报文
        {
            strcpy(protocol,"icmp");
            srcport=dstport=0;
        }
        else if(iph->ip_p==6) //TCP报文
        {
            strcpy(protocol,"tcp");
            tcph=(struct tcphdr *)(pp+sizeof(struct ether_header)+4*iph->ip_hl);
            srcport=ntohs(tcph->source);
            dstport=ntohs(tcph->dest);
            data=(u_char *)(pp+sizeof(struct ether_header)+4*iph->ip_hl+4*tcph->doff);
            for(i=0;i=header->len-sizeof(struct ether_header)-4*iph->ip_hl-4*tcph->doff);
                break;
                else
                    tcpudpdata=data;
            }
        } //TCP数据处理完毕
        else if(iph->ip_p=17) //UDP报文
        {
            strcpy(protocol,"udp");
            udph=(struct udphdr *)(pp+sizeof(struct ether_header)+4*iph->ip_hl);
            srcport=ntohs(udph->source);
            dstport=ntohs(udph->dest);
            data=(u_char *)(pp+sizeof(struct ether_header)+4*iph->ip_hl+8);
            for(i=0;i=header->len-sizeof(struct ether_header)-4*iph->ip_hl-8);
                break;
                else
                    tcpudpdata=data;
            }
        }
        tcpudpdata='\0';
        getportname(srcport,srcp,protocol);
        getportname(dstport,dstp,protocol);
        printf("ip ");
        print_hwadd(eth->ether_shost);
        printf("(");
        print_hostname((u_char *)&(iph->ip_src));
        printf(")[%s:%s]->",protocol,srcp);
        print_hwadd(eth->ether_dhost);
        printf("(");
        print_hostname((u_char *)&(iph->ip_dst));
        printf(")[%s:%s]",protocol,dstp);
        printf("\tttl:%d packetlen:%d,iph->ttl,header->len);
     printf("\n");
        printf("%s",tcpudpdata);
        printf("==endpacket==");
    }
    printf("\n");
}
//Main函数取数据包并初始化程序环境
int main(int argc,char ** argv)
{
    char ebuf[pcap_ERRBUF_SIZE];
    pcap * pd;
    if(argc\n",argv[0]);
        exit(0);
    }
    //设置PCAP程序库
    if((pd=pcap_open_live(argv[1],DEFAULT_SNAPLEN,1,1000,ebuf))=NULL)
    {
        (void)fprintf(stderr,"%s",ebuf);
        exit(1);
    }
    //循环取数据包
    //改变参数-1为其它值,可确定取数据包的个数,这里为无限个
    if(pcap_loop(pd,-1,packet_proce,NULL)<0)
    {
        (void)fprintf(stderr,"pcap_loop:%s\n",pcap_geterr(pd));
        exit(1);
    }
    pcap_colse(pd);
    exit(0);
}
//程序结束

转载于:https://www.cnblogs.com/haichun/p/3530111.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php-5.2.6安装,php5.2.6安装openssl.o扩展,make时报错?

问题&#xff1a;调试支付宝支付时报错&#xff1a;Fatal error: Call to undefined function openssl_get_privatekey()在网上查了 说是没有安装openssl.so扩展。通过 phpize安装扩展&#xff0c;但是make时报错&#xff1a;/bin/sh /opt/php-5.2.6/ext/openssl/libtool --mod…

highcharts第一篇---简介和使用

Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表&#xff0c;并且免费提供给个人学习、个人网站和非商业用途使用。HighCharts支持的图表类型有曲线图、区域图、柱状图、饼状图、散状点图和综合图表 具体参考&a…

php中数字可以加字符吗,在php中,怎么样把数字转化为字符串

PHP的数据类型转换属于强制转换&#xff0c;允许转换的PHP数据类型有&#xff1a;(int)、(integer)&#xff1a; 转换成整形(float)、(double)、(real)&#xff1a; 转换成浮点型(string)&#xff1a; 转换成字符串(bool)、(boolean)&#xff1a; 转换成布尔类型(array)&#x…

CUBA平台–新的Java企业应用程序框架

所以..你好&#xff0c;世界&#xff01; 我们的英语网站终于可以正常使用了&#xff0c;现在每个人都可以下载该平台&#xff0c;并可以以前所未有的速度更快地创建业务应用程序。 在我们决定与国际Java社区共享足够好之前&#xff0c;我们花了六年的永久发展和偶尔的革命&…

Redis,MemCached,MongoDB 概述

调研项目主要有Redis、 MemCached、 MongoDB&#xff0c;以及Amazon的DynamoDB Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。目前由VMware主持开发工作。 1&#xff09; 数据模型 作为K…

php 正则 回溯,php 正则表达式效率 贪婪、非贪婪与回溯分析

先扫盲一下什么是正则表达式的贪婪&#xff0c;什么是非贪婪&#xff1f;或者说什么是匹配优先量词&#xff0c;什么是忽略优先量词&#xff1f;好吧&#xff0c;我也不知道概念是什么&#xff0c;来举个例子吧。某同学想过滤之间的内容&#xff0c;那是这么写正则以及程序的。…

Abiword页面布局

Abiword页面布局 AP_Win32FrameImpl::_DocumentWndProc 文档窗口过程函数在WM_SIZE消息中设置FV_View对象的整体尺寸&#xff0c;跟窗体的&#xff1a;设备单位 转换成&#xff1a;布局单位。m_iWindowWidth 19695&#xff0c;m_iWindowHeight 8520 设备单位和布局单位的比例是…

php图片编辑失真,PHP处理图片固定大小 不失真 不变形

由于工中使用到此代码 借鉴了各位前辈们代码的基础上修改而来 如果您的项目中有需要此代码 要以尽情的复制和修改 &#xff1b;如果您有更好的代码烦请告知本人 。我将感激不尽下面由上代码//图像处理类class Image {private $file;//图片地址private $width;//图片长度privat…

abiword Namespace List

abiword Namespace List Here is a list of all namespaces with brief descriptions: abicollab 这个命名空间以及下面的abicollab::service均是在线协作相关。abicollab::service 这个命名空间是在线协作相关。AiksaurusImpl 词库相关&#xff0c;命名空间名字翻译&#xff1…

ios php 表单提交图片上传,axios发送post请求提交图片表单步骤详解

这次给大家带来axios发送post请求提交图片表单步骤详解&#xff0c;axios发送post请求提交图片表单的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。DOME接口const userUploadAtt (File,config) > axios.post("接口",File,config)处理数…

solr4.6本地数据提交异常

初次学习solr的时候不能把dist文件夹所有的包都导入工程中&#xff0c;这样会有slf4j异常&#xff0c;这是因为slf4j版本冲突导致的。一个一个jar的导入的话&#xff0c;中间还是有许多异常出在哪个jar包中不清楚&#xff0c;所以我把我遇到的异常整理了一下。 异常一&#xff…

php 文件内容对比,php 比较两个文件是否相同

-### php比较两个文件是否相同小一点的文件直接实用内置函数就可以了function md5_files($filename,$filename1){$file1 md5_file($filename);$file md5_file($filename1);if($file $file1){return "文件相同";}else{return "文件不同";}}md5_file()…

今日心得:给自己写信

1.tomorrow is another day 2.有一种人一认识就觉得温馨 3.这个世界只在乎你是否达到了一定的高度&#xff0c;不在乎你是站在巨人的肩膀还是垃圾上上去的 4.花儿总要在风雨的洗礼下盛开 5.有一种“无能为力”叫宿命 6.幸福是什么&#xff1f;有很多幸福的瞬间&#xff0c;幸福…

Hibernate READ_WRITE CacheConcurrencyStrategy如何工作

介绍 在我以前的文章中&#xff0c;我介绍了NONSTRICT_READ_WRITE二级缓存并发机制。 在本文中&#xff0c;我将使用READ_WRITE策略继续本主题。 直写式缓存 NONSTRICT_READ_WRITE是一种通读缓存策略&#xff0c;可更新最终无效的缓存条目。 尽管这种策略可能很简单&#xff0…

matlab中的控制语句,MATLAB控制语句

目的&#xff1a;研究控制结构(用于, 是否, 切换, 中断, 继续, 输入/输出功能, 读取和存储数据)。If&#xff1a;If评估逻辑表达式并根据表达式的值执行一组语句。If语句的语法if expression 1statement1elseif expression 2statement 2elsestatement 3end例子>> a7a 7&g…

java.logging的重定向?

java.logging的重定向&#xff1f; 接着昨天的工作。 上面说要重定向java.util.logging.Logger的输出&#xff0c; 发现也不是不可能。 package jmx;import java.util.logging.FileHandler; import java.util.logging.Filter; import java.util.logging.Handler; import java.u…

Spring Enable批注–编写自定义的Enable批注

Spring提供了一系列名称以Enable *开头的注释&#xff0c;这些注释本质上使某些Spring管理的功能可以被激活。 这样的注释的一个很好的例子是EnableWebMvc &#xff0c;它引入了在基于Spring的应用程序中支持MVC流所需的所有bean。 另一个很好的例子是EnableAsync注释&#xff…

java hashmap替换key,HashMap 用可变对象作为 key 踩坑

点击上方☝Java编程技术乐园&#xff0c;轻松关注&#xff01;及时获取有趣有料的技术文章做一个积极的人编码、改bug、提升自己我有一个乐园&#xff0c;面向编程&#xff0c;春暖花开&#xff01;作者&#xff1a;Icharlehttps://icharle.com/hashmapkebianobj.html前言在 Ja…

(转)Eclipse平台技术概述

转载&#xff1a;周金根 http://zhoujg.blog.51cto.com/1281471/516833Eclipse&#xff1a;Eclipse平台技术概述2010-10-19 13:35:00标签&#xff1a;Eclipse 休闲 职场原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明…

php post调用api,PHP(CURL)POST数据调用API简单示例

/***一个完整的POST调用API的过程 百度知道*author: bo.xiao*/$url ‘http://zhidao.chanjet.com/restserver/zhidao’;$data array(‘api_key’>’3qQ2Edm62Vd4bAVCwNoxgn0l’,‘method’>’baidu.zhidao.getQuestionList’,‘call_id’>’1308713190’,‘cid’>…