網路編程原始通訊端SOCKET_RAW

來源:互聯網
上載者:User

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.