SOCKET_STREAM 流式通訊端
SOCKET_DGRAM
SOCKET_RAW 原始通訊端
IPPROTO_IP IP協議
IPPROTO_ICMP INTERNET控制訊息協議,配合原始通訊端可以實現ping的功能
IPPROTO_IGMP INTERNET 網關服務合約,在多播中用到
在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三種通訊端類型。SOCK_STREAM也就是通常所說的TCP,而SOCK_DGRAM則是通常所說的UDP,而SOCK_RAW則是用於提供一些較低級的控制的;第3個參數依賴於第2個參數,用於指定通訊端所用的特定協議,設為0表示使用預設的協議。
希望各位參與,進來的順便UP一下.
RAW SOCKET能夠對較低層次的協議直接存取,網路監聽技術很大程度上依賴於它。該文介紹了利用RAW SOCKET捕獲網路底層資料包的步驟和方法,並開發了一個程式模型來進一步探討了利用RAW SOCKET捕獲資料包的方法。
【關鍵詞】 RAW SOCKET;捕獲;資料包
1 引言
隨著資訊技術的快速發展,網路已成為資訊交換的主要手段,一些網路新業務在不斷地興起,如電子商務、移動支付等,這些都對網路安全提出了較高的要求。與此同時,駭客對網路的攻擊從未停止,網路的安全問題變得日趨嚴峻。
很多網路攻擊都是從監聽開始的,網路監聽最重要一步就是捕獲區域網路中的資料幀,因此,研究資料擷取技術對於保障網路安全有著重要的意義。
2 RAW SOCKET簡介
同一台主機不同進程可以用進程號來唯一標識,但是在網路環境下進程號並不能唯一標識該進程。TCP/IP主要引入了網路地址、連接埠和串連等概念來解決網路間進程標識問題。通訊端(Socket)是一個指向傳輸提供者的控制代碼,TCP/IP協議支援3種類型的通訊端,分別是流式通訊端、資料報式通訊端和原始通訊端。
流式通訊端(SOCKET_STREAM)提供了連線導向、雙向可靠的資料流傳輸服務。資料報式通訊端(SOCKET_ DGRAM)提供了無串連服務,不提供無錯保證。原始通訊端(SOCKET_RAW)允許對較低層次的協議直接存取,比如IP、 ICMP協議,它常用於檢驗新的協議實現,或者訪問現有服務中配置的新裝置,因為RAW SOCKET可以自如地控制Windows下的多種協議,能夠對網路底層的傳輸機制進行控制,所以可以應用原始通訊端來操縱網路層和傳輸層應用。比如,我們可以通過RAW SOCKET來接收發向原生ICMP、IGMP協議包,或者接收TCP/IP棧不能夠處理的IP包,也可以用來發送一些自定包頭或自定協議的IP包。網路監聽技術很大程度上依賴於SOCKET_RAW。
3 RAW SOCKET編程
要使用原始通訊端,必須經過建立原始通訊端、設定通訊端選項和建立並填充相應協議頭這三個步驟,然後用send、WSASend函數將組裝好的資料發送出去。接收的過程也很相似,只是需要用recv或WSARecv函數接收資料。下面介紹使用RAW SOCKET編程的幾個步驟。
3.1 建立原始通訊端
我們可以用socket或WSASocket函數來建立原始通訊端,因為原始通訊端能直接控制底層協議,因此只有屬於“管理員”組的成員,才有權建立原始通訊端。下面是用socket函數建立原始通訊端的代碼。
SOCKET sock;
Sock=socket (AF_INET, SOCK_RAW, IPPROTO_UDP);
上述建立原始通訊端的代碼使用的是UDP協議,如果要使用其它的協議,比如ICMP、IGMP、IP等協議,只需要把相應的參數改為IPPROTO_ICM、IPPROTO_ IGMP、IPPROTO_IP就可以了。另外,IPPROTO_UDP、IPPROTO_IP、IPPROTO_RAW這幾個協議標誌要求使用通訊端選項IP_HDRINCL,而目前只有Windows 2000和Windows XP提供了對IP_HDRINCL的支援,這意味著在Windows 2000以下平台建立原始通訊端時是不能使用IP、UDP、TCP協議的。
3.2 設定通訊端選項
建立了原始通訊端後,就要設定通訊端選項,這要通過setsocketopt函數來實現,setsocketopt函數的聲明如下:
int setsocketopt (
SOCKET s,
int level,
int optname,
const char FAR *optval,
int optlen
);
在該聲明中,參數s是標識套介面的描述字,要注意的是選項對這個通訊端必須是有效。參數Level表明選項定義的層次,對TCP/IP協議族而言,支援SOL_SOCKET、IPPROTO_IP和IPPROTO_CP層次。參數Optname是需要設定的選項名,這些選項名是在Winsock標頭檔內定義的常數值。參數optval是一個指標,它指向存放選項值的緩衝區。參數optlen指示optval緩衝區的長度
3.3 建立並填充相應協議頭
這一步就是建立IP和TCP協議頭的資料結構,根據相關協議的定義進行編寫即可,下面是一個TCP協議頭的資料結構。
struct TCP
{
unsigned short tcp_sport;
unsigned short tcp_dport;
unsigned int tcp_seq;
unsigned int tcp_ack;
unsigned char tcp_lenres;
unsigned char tcp_flag;
unsigned short tcp_win;
unsigned short tcp_sum;
unsigned short tcp_urp;
};
4 一個利用RAW SOCKET捕獲網路資料包的程式模型
下面介紹一個利用RAW SOCKET捕獲網路資料包的程式模型。這個程式模型示範了如何使用RAW SOCKET捕獲區域網路中的資料包,它完成了網路底層資料的接收,能顯示源地址、目標地址、源連接埠、目標連接埠和接收的位元組數等資訊。這個程式模型也說明了網路監聽的基本原理,給捕獲區域網路中的資料包提供了一種方法,即先把網卡設定為混雜模式,然後利用RAW SOCKET接收IP層的資料。
程式在Visual C++.net 2003中調試並編譯通過,運行環境為乙太網路, 程式碼可同時在Linux與windows環境下編譯和運行,當然在編譯時間需要不同的標頭檔以及需要對代碼作相應的改動。本程式模型在Windows下能直接運行,如果在Linux下運行,則需要先用手工把網卡設定為混雜模式,在root許可權下用如下命令設定:ifconfig eth0 promisc。
在Unix/Linux下程式要包含以下這幾個進行調用系統和網路函數的標頭檔:
#include〈stdio.h〉
#include〈sys/socket.h〉
#include〈netinet/in.h〉
#include〈arpa/inet.h〉
#include"headers.h"
為了方便基於Berkeley套介面的已有來源程式的移植,Windows Sockets支援許多Berkeley標頭檔。這些Berkeley標頭檔被包含在WINSOCK2.H中,所以一個Windows Sockets應用程式只需包含WINSOCK2.H標頭檔就足夠了,這也是目前推薦使用的一種方法。在Windows平台下程式改用以下這幾個標頭檔:
#include "stdafx.h"
#include<stdio.h>
#include<Winsock2.h>
#include"headers.h"
headers.h是自己編寫的標頭檔,它的作用是定義IP和TCP包的頭結構。在程式中首先定義幾個變數和結構,然後調用函數socket()建立socket串連,主要代碼如下:
int _tmain(int argc, _TCHAR* argv[])
{
int sock,bytes_recieved,fromlen;
char buffer[65535];
struct sockaddr_in from;
struct ip *ip;
struct tcp *tcp;
sock=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
……
return 0;
}
程式的第二步用一個while(1)語句來建立一個死迴圈,用來不停地接收網路資訊。首先用函數sizeof()取出一個socket結構的長度,這個參數是recvfrom()函數所必須的。從建立的socket串連中接收資料是通過函數recvfrom()是來實現的,因為recvfrom()函數需要一個sockaddr資料類型,所以用了一個強制類型轉換,代碼如下:fromlen=sizeof(from);
bytes_recieved=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&from,&fromlen);
接下來用一條語句把接收到的資料轉化為我們預先定義的結構,以便於查看,代碼為:
ip=(struct ip *)buffer
還要用一條語句來指向TCP頭,因為接收的資料中,IP頭的大小是固定的4位元組,所以用IP長度乘以4就能指向TCP頭部分,代碼為:
tcp=(struct tcp *)(buffer+(4*ip->ip_length))
最後就可以用列印語句把接收的位元組數、資料的源地址、目標地址、源連接埠、目標連接埠、IP頭長度和協議的類型輸出來。
轉自:http://www.cnblogs.com/hnrainll/archive/2011/09/20/2182423.html