linux基礎プログラミングリンク層socket winPcap誇張セグメントsocket通信誇張プラットフォーム移植から抜け出す


linux環境ではリンク層(MAC)から直接データフレームを送受信するには、libpcapとlibnetの2つのダイナミックライブラリを介して送受信の作業をそれぞれ完了することができる.広く使用されているが、プラットフォーム間移植を要求するソフトウェアで使用するのは難しい.
これは、より直接的に、他のライブラリをインストールすることなく、MAC層からデータフレームを送受信する方法であり、すなわち、リンク層のソケットを定義することによって達成される.
次のコードも私が作ったプロジェクトのコード(ネットワークの組み込み機器にアクセスすることを誇張して)、敏感な部分を取り除いて、みんなと共有します!
しかし、他の人の労働成果を尊重し、転載して出典を明記しなければなりません.ありがとうございます.
#include          
#include           
#include 
#include 
#include  
#include 		
#include       
#include       
#include        
#include          
#include 
#include 


/*   socket    */
#define RAW_PROTOCOL 0x0909
#define ETH_NAME "eth0"

#define __DEBUG
#ifdef __DEBUG
#define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)
#else
#define DBG(fmt,args...)
#endif
#define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)

static int raw_fd;
static int if_index;
static int isSearchQuit = 0;
unsigned char my_mac[6];	/*          */

/*        */
int GetPacket(unsigned char *buf, int *len)
{
	int length = 0;

	length = recvfrom( raw_fd, buf, 2000, 0, NULL, NULL );
	if ( length < 0 )	{
		ERR("failed to receive buf!");
		return -1;
	}else	{
		*len = length;
		return 0;
	}
}

/*        */
int SendPacket(unsigned char *buf, int len)
{
	struct sockaddr_ll link;
	link.sll_ifindex = if_index;

	memcpy( link.sll_addr, buf, link.sll_halen );

	if ( sendto( raw_fd, buf, len, 0, (struct sockaddr *)&link, sizeof(link) ) < 0 )	{
		ERR( "failed to send to RAW socket!\r
" ); return -1; } return 0; } void ShowData(unsigned char *d1,int len) { int i; for(i=0;i

実行結果、ネットワークから完全なパケットを受信:
[root@localhost src]# ./RawSocket
ff ff ff ff ff ff 1c 6f 65 dc fa fb 09 09 00 00 00 00 06 04 01 00 00 00 00 00 00 00 c0 a8 01 dc ff ff ff ff ff ff c0 a8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00