【VS开发】raw socket 的例子
raw socket 的例子
一. 摘要?
? Raw Socket: 原始套接字?
? 可以用它來發送和接收 IP 層以上的原始數據包, 如 ICMP, TCP, UDP...
??? int sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
? 這樣我們就創建了一個 Raw Socket
? Sniffer: 嗅探器?
? 關于嗅探器的原理我想大多數人可能都知道?
? 1. 把網卡置于混雜模式;?
? 2. 捕獲數據包;?
? 3. 分析數據包.
? 但具體的實現知道的人恐怕就不是那么多了. 好, 現在讓我們用 Raw Socket 的做一個自已的 Sniffer.
二. 把網卡置于混雜模式?
? 在正常的情況下,一個網絡接口應該只響應兩種數據幀:?
? 一種是與自己硬件地址相匹配的數據幀?
? 一種是發向所有機器的廣播數據幀?
? 如果要網卡接收所有通過它的數據, 而不管是不是發給它的, 那么必須把網卡置于混雜模式. 也就是說讓它的思維混亂, 不按正常的方式工作. 用 Raw Socket 實現代碼如下:
??? setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); //設置 IP 頭操作選項?
??? bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal); //把 sockRaw 綁定到本地網卡上?
??? ioctlsocket(sockRaw, SIO_RCVALL, &dwValue);?????? //讓 sockRaw 接受所有的數據
? flag 標志是用來設置 IP 頭操作的, 也就是說要親自處理 IP 頭: bool flag = ture;?
? addrLocal 為本地地址: SOCKADDR_IN addrLocal;?
? dwValue 為輸入輸出參數, 為 1 時執行, 0 時取消: DWORD dwValue = 1;?
? 沒想到這么簡單吧?
三. 捕獲數據包?
? 你的 sockRaw 現在已經在工作了, 可以在局域網內其它的電腦上用 Sniffer 檢測工具檢測一下, 看你的網卡是否處于混雜模式(比如 DigitalBrain 的 ARPKiller).?
? 不能讓他白白的浪費資源啊, 抓包!
??? recv(sockRaw, RecvBuf, BUFFER_SIZE, 0); //接受任意數據包
? #define BUFFER_SIZE 65535?
? char RecvBuf[BUFFER_SIZE];?
? 越來越發現 Sniffer 原來如此的簡單了, 這么一個函數就已經完成抓取數據包的任務了.
四. 分析數據包?
? 這回抓來的包和平常用 Socket 接受的包可就不是一回事兒了, 里面包含 IP, TCP 等原始信息. 要分析它首先得知道這些結構.?
? 數據包的總體結構:?
? ----------------------------------------------?
? | ip header | tcp header(or x header) | data |?
? ----------------------------------------------
? IP header structure:?
?????? 4??? 8??? 16??????????????????? 32 bit?
? |--------|--------|----------------|--------------------------------|?
? | Ver? | IHL? |Type of service |???? Total length???? |?
? |--------|--------|----------------|--------------------------------|?
? | Identification |?? Flags?? |???? Fragment offset??? |?
? |--------|--------|----------------|--------------------------------|?
? | Time to live? |? Protocol? |???? Header checksum??? |?
? |--------|--------|----------------|--------------------------------|?
? |???????????? Source address????????????? |?
? |--------|--------|----------------|--------------------------------|?
? |??????????? Destination address???????????? |?
? |--------|--------|----------------|--------------------------------|?
? |??????????? 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 + Padding??????????? |?
? |--------------------------------|--------------------------------|?
? |?????????????? Data??????????????? |?
? |--------------------------------|--------------------------------|
五. 實現 Sniffer?
? OK!?
? 現在都清楚了, 還等什么.?
? 下面是我用 BCB6 寫的一個 Simple Sniffer 的代碼, 僅供參考.?
? (需要在工程文件里加入WS2_32.LIB這個文件)?
//?
//?
#include <vcl.h>?
#pragma hdrstop
#include <winsock2.h>?
#include <ws2tcpip.h>?
#include <mstcpip.h>?
#include <netmon.h>?
#include "WMain.h"?
//---------------------------------------------------------------------------?
#pragma package(smart_init)?
#pragma resource "*.dfm"?
TMainForm *MainForm;?
//---------------------------------------------------------------------------?
__fastcall TMainForm::TMainForm(TComponent* Owner)?
? : TForm(Owner)?
{?
WSADATA WSAData;?
? BOOL? flag? = true;?
? int?? nTimeout = 1000;?
? char? LocalName[16];?
? struct hostent *pHost;
? //檢查 Winsock 版本號?
? if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)?
??? throw Exception("WSAStartup error!");
? //初始化 Raw Socket?
? 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(LocalName)-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_list[0]; //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;?
}?
//---------------------------------------------------------------------------?
__fastcall TMainForm::~TMainForm()?
{?
? WSACleanup();?
}?
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnCtrlClick(TObject *Sender)?
{?
? TListItem *Item;?
? DWORD dwValue;?
? int nIndex = 0;
? if (btnCtrl->Caption == "&Start")?
? {?
??? dwValue = 1;?
??? //設置 SOCK_RAW 為SIO_RCVALL,以便接收所有的IP包?
??? if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0)?
????? throw Exception("ioctlsocket SIO_RCVALL error!");?
??? bStop = false;?
??? btnCtrl->Caption = "&Stop";?
??? lsvPacket->Items->Clear();?
? }?
? else?
? {?
??? dwValue = 0;?
??? bStop = true;?
??? btnCtrl->Caption = "&Start";?
??? //設置SOCK_RAW為SIO_RCVALL,停止接收?
??? if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0)?
????? throw Exception("WSAIoctl SIO_RCVALL error!");?
? }
? while (!bStop)?
? {?
??? if (recv(sock, RecvBuf, BUFFER_SIZE, 0) > 0)?
??? {?
????? nIndex++;?
????? ip = *(IP*)RecvBuf;?
????? tcp = *(TCP*)(RecvBuf + (ip.HdrLen & IP_HDRLEN_MASK));
????? Item = lsvPacket->Items->Add();?
????? Item->Caption = nIndex;?
????? Item->SubItems->Add(GetProtocolTxt(ip.Protocol));?
????? Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.SrcAddr));?
????? Item->SubItems->Add(inet_ntoa(*(in_addr*)&ip.DstAddr));?
????? Item->SubItems->Add(tcp.SrcPort);?
????? Item->SubItems->Add(tcp.DstPort);?
????? Item->SubItems->Add(ntohs(ip.TotalLen));?
??? }?
??? Application->ProcessMessages();?
? }???
}?
//---------------------------------------------------------------------------
AnsiString __fastcall TMainForm::GetProtocolTxt(int Protocol)?
{?
? switch (Protocol)?
? {?
??? case IPPROTO_ICMP :????? //1????????
????? return PROTOCOL_STRING_ICMP_TXT;?
??? case IPPROTO_TCP :????? //6????????
????? return PROTOCOL_STRING_TCP_TXT;?
??? case IPPROTO_UDP :????? //17???????
????? return PROTOCOL_STRING_UDP_TXT;?
??? default :?
????? return PROTOCOL_STRING_UNKNOWN_TXT;?
? }?
}?
//---------------------------------------------------------------------------
//?
//?
//---------------------------------------------------------------------------
#ifndef WMainH?
#define WMainH?
//---------------------------------------------------------------------------?
#define BUFFER_SIZE 65535
#include <Classes.hpp>?
#include <Controls.hpp>?
#include <StdCtrls.hpp>?
#include <Forms.hpp>?
#include <ComCtrls.hpp>?
#include <ExtCtrls.hpp>?
#include <winsock2.h>?
#include "netmon.h"
//---------------------------------------------------------------------------?
class TMainForm : public TForm?
{?
__published: // IDE-managed Components?
? TPanel *Panel1;?
? TButton *btnCtrl;?
? TListView *lsvPacket;?
? TLabel *Label1;?
? void __fastcall btnCtrlClick(TObject *Sender);?
? void __fastcall lsvPacketColumnClick(TObject *Sender,?
???? TListColumn *Column);?
? void __fastcall lsvPacketCompare(TObject *Sender, TListItem *Item1,?
???? TListItem *Item2, int Data, int &Compare);?
? void __fastcall Label1Click(TObject *Sender);?
private: // User declarations?
? AnsiString __fastcall GetProtocolTxt(int Protocol);?
public: // User declarations?
? SOCKET?? sock;?
? SOCKADDR_IN addr_in;?
? IP???? ip;?
? TCP???? tcp;?
? PSUHDR?? psdHeader;?
? char??? RecvBuf[BUFFER_SIZE];?
? bool??? bStop;
? int iSortDirection;?
? int iColumnToSort;?
? __fastcall TMainForm(TComponent* Owner);?
? __fastcall ~TMainForm();?
};?
//---------------------------------------------------------------------------?
extern PACKAGE TMainForm *MainForm;?
//---------------------------------------------------------------------------?
#endif
? 偷了個懶, IP, TCP 頭及一些宏定義用了 netmon.h 的頭, 這個文件在 BCB6 的 include 目錄下可以找得到, 其中與本程序相關內容如下:
//?
//?
//?
// IP Packet Structure?
//?
typedef struct _IP?
{?
? union?
? {?
??? BYTE? Version;?
??? BYTE? HdrLen;?
? };?
? BYTE ServiceType;?
? WORD TotalLen;?
? WORD ID;?
? union?
? {?
??? WORD? Flags;?
??? WORD? FragOff;?
? };?
? BYTE TimeToLive;?
? BYTE Protocol;?
? WORD HdrChksum;?
? DWORD? SrcAddr;?
? DWORD? DstAddr;?
? BYTE Options[0];?
} IP;
typedef IP * LPIP;?
typedef IP UNALIGNED * ULPIP;
//?
// TCP Packet Structure?
//?
typedef struct _TCP?
? {?
? WORD SrcPort;?
? WORD DstPort;?
? DWORD SeqNum;?
? DWORD AckNum;?
? BYTE DataOff;?
? BYTE Flags;?
? WORD Window;?
? WORD Chksum;?
? WORD UrgPtr;?
? } TCP;
typedef TCP *LPTCP;?
typedef TCP UNALIGNED * ULPTCP;
// upper protocols?
#define PROTOCOL_STRING_ICMP_TXT??? "ICMP"?
#define PROTOCOL_STRING_TCP_TXT??? "TCP"?
#define PROTOCOL_STRING_UDP_TXT??? "UDP"?
#define PROTOCOL_STRING_SPX_TXT??? "SPX"?
#define PROTOCOL_STRING_NCP_TXT??? "NCP"
#define PROTOCOL_STRING_UNKNOW_TXT?? "UNKNOW"
? 這個文件也有人聲稱沒有.?
//?
//?
// Copyright (c) Microsoft Corporation. All rights reserved.?
#if _MSC_VER > 1000?
#pragma once?
#endif
struct tcp_keepalive {?
? u_long onoff;?
? u_long keepalivetime;?
? u_long keepaliveinterval;?
};
// New WSAIoctl Options
#define SIO_RCVALL????? _WSAIOW(IOC_VENDOR,1)?
#define SIO_RCVALL_MCAST?? _WSAIOW(IOC_VENDOR,2)?
#define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)?
#define SIO_KEEPALIVE_VALS? _WSAIOW(IOC_VENDOR,4)?
#define SIO_ABSORB_RTRALERT? _WSAIOW(IOC_VENDOR,5)?
#define SIO_UCAST_IF???? _WSAIOW(IOC_VENDOR,6)?
#define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)?
#define SIO_INDEX_BIND??? _WSAIOW(IOC_VENDOR,8)?
#define SIO_INDEX_MCASTIF?? _WSAIOW(IOC_VENDOR,9)?
#define SIO_INDEX_ADD_MCAST? _WSAIOW(IOC_VENDOR,10)?
#define SIO_INDEX_DEL_MCAST? _WSAIOW(IOC_VENDOR,11)
// Values for use with SIO_RCVALL* options?
#define RCVALL_OFF?????? 0?
#define RCVALL_ON?????? 1?
#define RCVALL_SOCKETLEVELONLY 2
? 現在我們自已的 Sniffer 就做好了, Run, Start......哇, 這么多數據包, 都是從這一臺機器上發出的, 它在干什么? 原來 Adminstrator 密碼為空, 中了尼姆達病毒!
六. 小結?
? 優點: 實現簡單, 不需要做驅動程序就可實現抓包.?
? 缺點: 數據包頭不含幀信息, 不能接收到與 IP 同層的其它數據包, 如 ARP, RARP...?
? 這里提供的程序僅僅是一個 Sniffer 的例子, 沒有對數據包進行進一步的分析. 寫此文的目的在于熟悉Raw Socket 編程方法, 了解 TCP/IP 協議結構原理以及各協議之間的關系.
posted @ 2009-05-07 22:16 WindFly 閱讀(354) 評論(0)?編輯
基于套接字發送偽造IP包
這 里介紹Windows Sockets的一些關于原始套接字(Raw Socket)的編程。同Winsock1相比,最明顯的就是支持了Raw Socket套接字類型,通過原始套接字,我們可以更加自如地控制Windows下的多種協議,而且能夠對網絡底層的傳輸機制進行控制。?
1、創建一個原始套接字,并設置IP頭選項。?
SOCKET sock;?
sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);?
或者:?
s = WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);?
這 里,我們設置了SOCK_RAW標志,表示我們聲明的是一個原始套接字類型。創建原始套接字后,IP頭就會包含在接收的數據中,如果我們設定 IP_HDRINCL 選項,那么,就需要自己來構造IP頭。注意,如果設置IP_HDRINCL 選項,那么必須具有 administrator權限,要不就必須修改注冊表:?
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameter\?
修改鍵:DisableRawSecurity(類型為DWORD),把值修改為 1。如果沒有,就添加。?
BOOL blnFlag=TRUE;?
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag);?
對于原始套接字在接收數據報的時候,要注意這么幾點:?
1、如果接收的數據報中協議類型和定義的原始套接字匹配,那么,接收的所有數據就拷貝到套接字中。?
2、如果綁定了本地地址,那么只有接收數據IP頭中對應的遠端地址匹配,接收的數據就拷貝到套接字中。?
3、如果定義的是外部地址,比如使用connect(),那么,只有接收數據IP頭中對應的源地址匹配,接收的數據就拷貝到套接字中。?
2、構造IP頭和TCP頭?
這里,提供IP頭和TCP頭的結構:?
// Standard TCP flags?
#define URG 0x20?
#define ACK 0x10?
#define PSH 0x08?
#define RST 0x04?
#define SYN 0x02?
#define FIN 0x01?
typedef struct _iphdr //定義IP首部?
{?
unsigned char h_lenver; //4位首部長度+4位IP版本號?
unsigned char tos; //8位服務類型TOS?
unsigned short total_len; //16位總長度(字節)?
unsigned short ident; //16位標識?
unsigned short frag_and_flags; //3位標志位?
unsigned char ttl; //8位生存時間 TTL?
unsigned char proto; //8位協議 (TCP, UDP 或其他)?
unsigned short checksum; //16位IP首部校驗和?
unsigned int sourceIP; //32位源IP地址?
unsigned int destIP; //32位目的IP地址?
}IP_HEADER;?
typedef struct psd_hdr //定義TCP偽首部?
{?
unsigned long saddr; //源地址?
unsigned long daddr; //目的地址?
char mbz;?
char ptcl; //協議類型?
unsigned short tcpl; //TCP長度?
}PSD_HEADER;?
typedef struct _tcphdr //定義TCP首部?
{?
USHORT th_sport; //16位源端口?
USHORT th_dport; //16位目的端口?
unsigned int th_seq; //32位序列號?
unsigned int th_ack; //32位確認號?
unsigned char th_lenres; //4位首部長度/6位保留字?
unsigned char th_flag; //6位標志位?
USHORT th_win; //16位窗口大小?
USHORT th_sum; //16位校驗和?
USHORT th_urp; //16位緊急數據偏移量?
}TCP_HEADER;?
TCP偽首部并不是真正存在的,只是用于計算檢驗和。校驗和函數:?
USHORT checksum(USHORT *buffer, int size)?
{?
unsigned long cksum=0;?
while (size > 1)?
{?
cksum += *buffer++;?
size -= sizeof(USHORT);?
}?
if (size)?
{?
cksum += *(UCHAR*)buffer;?
}?
cksum = (cksum >> 16) + (cksum & 0xffff);?
cksum += (cksum >>16);?
return (USHORT)(~cksum);?
}?
當需要自己填充IP頭部和TCP頭部的時候,就同時需要自己計算他們的檢驗和。?
3、發送原始套接字數據報?
填充這些頭部稍微麻煩點,發送就相對簡單多了。只需要使用sendto()就OK。?
sendto(sock, (char*)&tcpHeader, sizeof(tcpHeader), 0, (sockaddr*)&addr_in,sizeof(addr_in));?
下面是一個示例程序,可以作為SYN掃描的一部分。?
#include <stdio.h>?
#include <winsock2.h>?
#include <ws2tcpip.h>?
#define SOURCE_PORT 7234?
#define MAX_RECEIVEBYTE 255?
typedef struct ip_hdr //定義IP首部?
{?
unsigned char h_verlen; //4位首部長度,4位IP版本號?
unsigned char tos; //8位服務類型TOS?
unsigned short total_len; //16位總長度(字節)?
unsigned short ident; //16位標識?
unsigned short frag_and_flags; //3位標志位?
unsigned char ttl; //8位生存時間 TTL?
unsigned char proto; //8位協議 (TCP, UDP 或其他)?
unsigned short checksum; //16位IP首部校驗和?
unsigned int sourceIP; //32位源IP地址?
unsigned int destIP; //32位目的IP地址?
}IPHEADER;?
typedef struct tsd_hdr //定義TCP偽首部?
{?
unsigned long saddr; //源地址?
unsigned long daddr; //目的地址?
char mbz;?
char ptcl; //協議類型?
unsigned short tcpl; //TCP長度?
}PSDHEADER;?
typedef struct tcp_hdr //定義TCP首部?
{?
USHORT th_sport; //16位源端口?
USHORT th_dport; //16位目的端口?
unsigned int th_seq; //32位序列號?
unsigned int th_ack; //32位確認號?
unsigned char th_lenres; //4位首部長度/6位保留字?
unsigned char th_flag; //6位標志位?
USHORT th_win; //16位窗口大小?
USHORT th_sum; //16位校驗和?
USHORT th_urp; //16位緊急數據偏移量?
}TCPHEADER;?
//CheckSum:計算校驗和的子函數?
USHORT checksum(USHORT *buffer, int size)?
{?
unsigned long cksum=0;?
while(size >1)?
{?
cksum+=*buffer++;?
size -=sizeof(USHORT);?
}?
if(size )?
{?
cksum += *(UCHAR*)buffer;?
}?
cksum = (cksum >> 16) + (cksum & 0xffff);?
cksum += (cksum >>16);?
return (USHORT)(~cksum);?
}?
void useage()?
{?
printf("******************************************\n");?
printf("TCPPing\n");?
printf("\t Written by Refdom\n");?
printf("\t Email: refdom@263.net\n");?
printf("Useage: TCPPing.exe Target_ip Target_port \n");?
printf("*******************************************\n");?
}?
int main(int argc, char* argv[])?
{?
WSADATA WSAData;?
SOCKET sock;?
SOCKADDR_IN addr_in;?
IPHEADER ipHeader;?
TCPHEADER tcpHeader;?
PSDHEADER psdHeader;?
char szSendBuf[60]={0};?
BOOL flag;?
int rect,nTimeOver;?
useage();?
if (argc!= 3)?
{ return false; }?
if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)?
{?
printf("WSAStartup Error!\n");?
return false;?
}?
if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)?
{?
printf("Socket Setup Error!\n");?
return false;?
}?
flag=true;?
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)?
{?
printf("setsockopt IP_HDRINCL error!\n");?
return false;?
}?
nTimeOver=1000;?
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)?
{?
printf("setsockopt SO_SNDTIMEO error!\n");?
return false;?
}?
addr_in.sin_family=AF_INET;?
addr_in.sin_port=htons(atoi(argv[2]));?
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);?
//?
//?
//填充IP首部?
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));?
// ipHeader.tos=0;?
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));?
ipHeader.ident=1;?
ipHeader.frag_and_flags=0;?
ipHeader.ttl=128;?
ipHeader.proto=IPPROTO_TCP;?
ipHeader.checksum=0;?
ipHeader.sourceIP=inet_addr("本地地址");?
ipHeader.destIP=inet_addr(argv[1]);?
//填充TCP首部?
tcpHeader.th_dport=htons(atoi(argv[2]));?
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口號?
tcpHeader.th_seq=htonl(0x12345678);?
tcpHeader.th_ack=0;?
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);?
tcpHeader.th_flag=2; //修改這里來實現不同的標志位探測,2是SYN,1是FIN,16是ACK探測 等等?
tcpHeader.th_win=htons(512);?
tcpHeader.th_urp=0;?
tcpHeader.th_sum=0;?
psdHeader.saddr=ipHeader.sourceIP;?
psdHeader.daddr=ipHeader.destIP;?
psdHeader.mbz=0;?
psdHeader.ptcl=IPPROTO_TCP;?
psdHeader.tcpl=htons(sizeof(tcpHeader));?
//計算校驗和?
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));?
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));?
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));?
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));?
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));?
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);?
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));?
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));?
rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),?
0, (struct sockaddr*)&addr_in, sizeof(addr_in));?
if (rect==SOCKET_ERROR)?
{?
printf("send error!:%d\n",WSAGetLastError());?
return false;?
}?
else?
printf("send ok!\n");?
closesocket(sock);?
WSACleanup();?
return 0;?
}?
4、接收數據?
和 發送原始套接字數據相比,接收就比較麻煩了。因為在WIN我們不能用recv()來接收raw socket上的數據,這是因為,所有的IP包都是先遞交給系統核心,然后再傳輸到用戶程序,當發送一個raws socket包的時候(比如syn),核心并不知道,也沒有這個數據被發送或者連接建立的記錄,因此,當遠端主機回應的時候,系統核心就把這些包都全部丟 掉,從而到不了應用程序上。所以,就不能簡單地使用接收函數來接收這些數據報。?
要達到接收數據的目的,就必須采用嗅探,接收所有通過的數據包,然后進行篩選,留下符合我們需要的。可以再定義一個原始套接字,用來完成接收數據的任務,需要設置SIO_RCVALL,表示接收所有的數據。?
SOCKET sniffersock;?
sniffsock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);?
DWORD lpvBuffer = 1;?
DWORD lpcbBytesReturned = 0 ;?
WSAIoctl(sniffersock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL);?
創建一個用于接收數據的原始套接字,我們可以用接收函數來接收數據包了。然后在使用一個過濾函數達到篩選的目的,接收我們需要的數據包。
轉載于:https://www.cnblogs.com/huty/p/8518346.html
總結
以上是生活随笔為你收集整理的【VS开发】raw socket 的例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【HEVC学习与研究】46、HEVC参考
- 下一篇: Web漏洞扫描器—AWVS