首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

各种帧头及嗅探器通常步骤

2012-07-03 
各种帧头及嗅探器一般步骤我在这里写的第一篇文章。许多人推荐这个网站,说很多高手在这里写博客,激扬文字。

各种帧头及嗅探器一般步骤
我在这里写的第一篇文章。
许多人推荐这个网站,说很多高手在这里写博客,激扬文字。我还不是高手,但总有一天会是的。

以下是嗅探器的一般步骤和各种头结构:

建立直接从链路层读取数据的套接字:fd_1 = socket(PF_PACKET, SOCK_RAW, htons(0x0003));



设置网卡混杂模式:

struct ifreq ifr;

int i;

strcpy(ifr.ifr_name, adapt);

i = ioctl(fd_1, SIOCGIFFLAGS, &ifr);

if (i < 0){

perror("Can't get adapter flags");

return 0;

}

ifr.ifr_flags |= IFF_PROMISC;

i = ioctl(fd_1, SIOCSIFFLAGS, &ifr);

if (i < 0){

perror("Promiscuous mode set error");

return 0;

}



各种包头部长度宏定义:

#define ETH_H 14

#define PPP_H 8

#define IP_H 20

#define IP_MAX_H 60

#define IP6_H 40

#define ARP_H 24

#define TCP_H 20

#define UDP_H 8

#define ICMP_H 4



自定义数据类型:

#define _u8 unsigned char

#define _u16 unsigned short

#define _u32 unsigned int

后来我发现,好像直接用char数组存储接收到的包就可以。



各种包头:

/* Dest MAC(6), Source MAC(6), Type(2), data(46-1500), CRC(4) */

typedef struct enode{

unsigned char dest_mac[6];

unsigned char src_mac[6];

unsigned short proto;

}ethhd;

/* PPPoE 0x8864; 5byte head, protocol: LCP(0xC021), NCP(0x8021), IP(0x0021) */

/* version(4bit), type(4bit), code(1), session-ID(2), length(2), protocol(2) */

typedef struct ppp_node{

_u8 ver:4,// 标志

    type:4;// 地址

_u8 code;// 代码

_u8 id[2];// 会话

_u8 len;// 长度, 此处和所谓ID本人不能确定

_u16 proto;// 协议

_u8 unknown;// 本人怀疑是检验和

}ppp_hd;

/*ipv4 0x0800; 20 byte head, the last 4 byte is options*/

/*ip_hl(4bit), ip_v(4bit), ip_tos(1), ip_len(2), ip_id(2), ip_off(2), ip_ttl(1), ip_p(1), ip_sum(2), ip_src(4), ip_dst(4), options(4) */

typedef struct ipv4_node{

#if defined(LITTLE_ENDIAN)

_u8 ihl:4,// 4位IP头部长度,以4字节为单位

    ver:4;// 4bit version number

#elif defined(BIG_ENDIAN)

unsigned char ver:4,

          ihl:4;

/* 纯属练习,因为我已经定义。而且动态修改的。

* Purely practice, because I have defined it. And the program will confirm it every time it runs

*/         

#else

#error "Sorry, please check head.h and add "#include <types.h>""

#endif

_u8 tos;  // 服务类型,各种优先级

_u16 len;// IP部分总长度,包括IP头部和IP的数据部分

_u16 id;// 标识,大的数据包分片后有同一标识,所以能重装

_u16 frag_off;// 片偏移,以8字节为单位,

_u8 ttl;// 生存时间

_u8 proto;// 协议类型

_u16 check;// 头部校验和

_u32 saddr;// 源IP地址

_u32 daddr;// 目的IP地址

_u32 option;// 选项字段

}ip_hd;

/*ipv6 0x86DD; 40 byte head*/

/*source ip start in 8 byte, dest ip start in 24 byte, all is 40 byte */

typedef struct ipv6_node{

#if defined(LITTLE_ENDIAN)

_u32 ver:4,

    type:8,

    stream:20;

#elif defined(BIG_ENDIAN)

_u32 stream:20,// 流标签, 标志同属一个业务的包

     type:8,// 类别,类似ipv4的服务类型

     ver:4;     // 版本,6

#else

#error "Sorry, please check head.h and add "#include <types.h>""  

#endif

_u16 len;// 负载长度, 即不包括ipv6头部的包长度  

_u8 head;// ipv6协议内协议的头部,从ipv6头部算起

_u8 ttl;// 跳限

_u8 saddr[16];// 源IP

_u8 daddr[16];// 目的IP

}ip6_hd;

/*arp 0x0806; 24 byte head*/

/*ar_hrd(2), ar_pro(2), ar_hln(1), ar_pln(1), ar_op(2), ar_sha(6), ar_ip(2), ar_dha(6), ar_dip(2) */

typedef struct anode{

_u16 hd;// 硬件类型

_u16 proto;// 协议类型

_u8 hln;// 硬件地址长度

_u8 pln;// 协议地址长度

_u16 op;// 操作码

unsigned char src_mac[ETH_ALEN];// 发送方MAC地址

unsigned char sip[4];// 发送方IP地址

unsigned char dest_mac[ETH_ALEN];// 接收方MAC地址

unsigned char dip[4];// 目的IP地址

}arp_hd;

/* tcp 6; 20 byte head*/

/* source port(2), destination port(2), serial number(4), confirmation number(4), head lenth(4bit),

* retention(6bit), urgentpointer: urg(1bit), acknowledge: ack(1bit), psh(1bit), restart touch: rst(1bit),

* synchronous number: syn(1bit), finally: fin(1bit), windows(2), CRC(2), emergency pointer(2), options(4)

*/

typedef struct tnode{

_u16 sport;// 源端口

_u16 dport;// 目的端口

_u32 seq;// 序列号

_u32 ack_seq;// 确认序列号

#if defined(LITTLE_ENDIAN)

_u16 ret: 4,// 保留

     hln: 4,// 头部长度

     fin: 1,// 关闭连接标志

     syn: 1,// 请求连接标志

     rst: 1,// 重置连接标志

     psh: 1,// 接收方尽快递交给应用层

     ack: 1,// 确认序号标志

     urg: 1,// 紧急指针标志

     ece: 1,// 拥塞标志位

     cwr: 1;// 拥塞标志位

#elif defined(BIG_ENDIAN)

_u16 ret: 4,// 保留

     cwr: 1,// 拥塞标志位

     ece: 1,// 拥塞标志位

     urg: 1,// 紧急指针标志

     ack: 1,// 确认序号标志

     psh: 1,// 接收方尽快递交数据给应用层

     rst: 1,// 重置连接标志

     syn: 1,// 请求连接标志

     fin: 1;// 关闭连接标志

#else

#error "Sorry, please check head.h and add "#include <types.h>""

#endif

_u16 window;// 滑动窗口大小

_u16 check;// 校验和

_u16 urg_ptr;// 紧急字段标志

}tcphd;

/* UDP 17; 8 byte head*/

/* source port(2), dest port(2), UDP len(2), CRC(2) */

typedef struct unode{

_u16 sport;// 源端口

_u16 dport;// 目的端口

_u16 uln;// UDP包长度 = UDP头部 + 数据

_u16 check;// 校验和

}udphd;

/* ICMP 2;  basic 4 byte */    

/* type(1), code(1), check sum(2) */

typedef struct inode{

_u8 type;// 消息类型

_u8 code;// 消息类型的子码

_u16 check;// 校验和

union{

struct {// type = 3, 4, 11, 5

_u32 unused;// 多数情况下未使用, 设为全0;type = 5时为目标路由器IP

_u8 buf[IP_MAX_H + 8];// 收到的IP数据包首部及数据前八个字节

}usual;

struct{// type = 12, code = 0

_u8 point;

_u8 other[3];

_u8 buf[IP_MAX_H + 8];

}para;

struct{// type = 0 || 8, code = 0, echo message or echo reply message

_u16 id;// Identifier,识别码

_u16 seq;// Sequence Number, 序列号

_u8 data[IP_MAX_H + 8];

}echo;

struct {// type = 13 || 14, code = 0

_u16 id;

_u16 seq;

_u32 ot;// Originate Timestamp

_u32 rt;// Receive Timestamp 

_u32 tt;// Transmit Timestamp 

}time;

struct{// type = 10, 15,16, code = 0,

_u16 id;

_u16 seq;

}info;

struct{// type = 9, code = 0

_u8 an;// address number

_u8 aln;// address lenght

_u16 ttl;//

_u8 route[ETH_FRAME_LEN - ETH_H - IP_H];// routing address, refefence, ……

}rout;

}un;

}icmphd;

typedef struct gnode{

_u8 type;// 类型

/* 0x11          Membership Query

* 0x22          Version 3 Membership Report

* 0x12          Version 1 Membership Report

* 0x16          Version 2 Membership Report

* 0x17          Version 2 Leave Group

*/

_u8 mrc;// max responding time

_u16 check;// 校验和, IGMP校验和,16位 校验和是从IGMP类型开始的IGMP报文中16位二进制反码和的16位二进制反码值。

union{

struct{// 0x11

_u32 add;// general query: set to 0; other: IP multicast address

#if defined(LITTLE_ENDIAN)

_u8 resv:4,// Reserved, set to zero on transmission, and ignored on reception.

    s:1,// 1阻止路由器定时更新组成员信息

    qrv:3;//

#elif defined(BIG_ENDIAN)

_u8 qrv:3,

   s:1,

    resv:4;

#else

#error "Sorry, please check head.h and add "#include <types.h>""

#endif

_u16 ns;// number of sources

_u32 ga;// Group Address 组地址, 最多可以有336组。

}query;

struct{// 0x22, report, reserved

_u16 resv;// 0, 否则和ns一起组成组播地址, 而下面的ga也是地址

_u16 ns;// number of sources

_u32 ga;// Group Record, 组成员记录,有几种不同方式,本人暂时不想再细分了

}report;

}un;       

}igmphd;



其中关于PPPoE、IGMP的,有些地方没弄清楚,但总算可以辨别了。希望了解或者有资料的读者在下面的网址留下它们的结构:http://q-tian.iteye.com

发现RFC文档是个好东西,有个IETF的网站有很多专业规范的资料,不过是英文的。那个IGMP我就是参考了其中一份IGMPv3文档。


记得看到电视剧《网球王子》里某个人总是喜欢说:你还差得远呢!是的,现在离高手还差得远,然而,正因如此,前途不可限量,哈哈!!

源代码,,由于本人写的比较粗糙,故而,还是不上传了。

谢谢你看到这里。坚持的人会有奖品的!
现在我把linux系统定义的相关头文件整理了以下,打包成sniffer.tar.gz,以上的头部定义和其它一些有用的东西都在里面。希望能对你有帮助!
友情提示:不要直接用这些头文件。可以从中截取你要的放到程序里。

热点排行