《基于Raw Socket的嗅探器设计与实现(选座题目及资料)》由会员分享,可在线阅读,更多相关《基于Raw Socket的嗅探器设计与实现(选座题目及资料)(13页珍藏版)》请在金锄头文库上搜索。
1、基于Raw Socket的嗅探器设计与实现功能:基于Raw Socket实现IP 层以上原始数据包的发送和接收。一. 摘要 Raw Socket: 原始套接字,可以用它来发送和接收 IP 层以上的原始数据包, 如 ICMP, TCP, UDP. int sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); Sniffer嗅探器根本原理与实现过程1. 把网卡置于混杂模式; 2. 捕获数据包; 3. 分析数据包. 二. 把网卡置于混杂模式 在正常的情况下,一个网络接口应该只响应两种数据帧:l 与自己硬件地址相匹配的数据帧 l 发向所有机器的播送数据帧
2、如果要网卡接收发向所有机器的播送数据帧,就必须把网卡置于混杂模式。用 Raw Socket 实现代码如下: /设置 IP 头操作选项setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); /把 sockRaw 绑定到本地网卡上bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal);/让 sockRaw 接受所有的数据ioctlsocket(sockRaw, SIO_RCVALL, &dwValue); flag 标志是用来设置 IP 头操作的, 也就是说要亲自
3、处理 IP 头: bool flag = ture; addrLocal 为本地地址: SOCKADDR_IN addrLocal; dwValue 为输入输出参数, 为 1 时执行, 0 时取消: DWORD dwValue = 1; 三. 捕获数据包 #define BUFFER_SIZE 65535 char RecvBufBUFFER_SIZE; /接受任意数据包recv(sockRaw, RecvBuf, BUFFER_SIZE, 0); 四. 分析数据包 用 recv()接收到的数据包中包含IP、TCP 等原始信息。要分析它首先得知道这些结构. 数据包的总体结构: - | ip h
4、eader | tcp header(or x header) | data | - IP header structure: 4 8 16 32 bit |-|-|-|-| | Ver | IHL |Typeofservice| Total length | |-|-|-|-| | Identification | Flags | Fragment offset | |-|-|-|-| | Time to live | Protocol | Header checksum | |-|-|-|-| | Source address | |-|-|-|-| | Destination addre
5、ss | |-|-|-|-| | Option + Padding | |-|-|-|-| | Data | |-|-|-|-| TCP header structure: 16 32 bit |-|-| | Source port | Destination port | |-|-| | Sequence number | |-|-| | Acknowledgement number | |-|-| | Offset | Resrvd |U|A|P|R|S|F| Window | |-|-| | Checksum | Urgent pointer | |-|-| | Option + Pad
6、ding | |-|-| | Data | |-|-| 五. 实现 Sniffer 用 BCB6 写的一个 Simple Sniffer 的代码, 仅供参考. 需要在工程文件里参加WS2_32.LIB这个文件 /*/ /* CPP File: WMain.cpp /* Simple Sniffer by shadowstar /*/ #include #pragma hdrstop #include #include #include #include #include WMain.h /- #pragma package(smart_init) #pragma resource *.dfm
7、TMainForm *MainForm; /- _fastcall TMainForm:TMainForm(TComponent* Owner) : TForm(Owner) WSADATA WSAData; BOOL flag = true; int nTimeout = 1000; char LocalName16; struct hostent *pHost; /检查 Winsock 版本号 if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) throw Exception(WSAStartup error!); /初始化 Raw Socket
8、if (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW) = INVALID_SOCKET) throw Exception(socket setup error!); /设置IP头操作选项 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag) = SOCKET_ERROR) throw Exception(setsockopt IP_HDRINCL error!); /获取本机名 if (gethostname(char*)LocalName, sizeof(L
9、ocalName)-1) = SOCKET_ERROR) throw Exception(gethostname error!); /获取本地 IP 地址 if (pHost = gethostbyname(char*)LocalName) = NULL) throw Exception(gethostbyname error!); addr_in.sin_addr = *(in_addr *)pHost-h_addr_list0; /IP addr_in.sin_family = AF_INET; addr_in.sin_port = htons(57274); /把 sock 绑定到本地地址上 if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in) = SOCKET_ERROR) throw Exception(bind error!); iSortDirection = 1; /- _fa