2017-11-27 9 views
-1

シミュレーション環境でネットワークデバイスをメディアアクセスコントローラとして組み込むために未処理のイーサネットフレームを送受信しようとしています。 したがって、パケットの受信は非ブロックステートメントを介して機能することが重要です。未処理のソケットでイーサネットフレームの長さを取得する(ノンブロッキング)

生のイーサネットフレームの送信はうまく動作しますが、受信パスについて私に混乱を招くことが1つあります。 1つのフレームが終了し、もう1つのフレームがどこで開始されるかを知る方法を教えてください。非ブロッキングとしてそれを設定する

device.socket = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); 

flags = fcntl(s,F_GETFL,0); 
assert(flags != -1); 
fcntl(s, F_SETFL, flags | O_NONBLOCK); 

、その後からデータを取得するために、周期的にrecv()関数を呼び出して、私は基本的に何

は、生のソケットを開くことですソケット:

length = recv(s, buffer, ETH_FRAME_LEN_MY, 0); 

私が知る限り、recv()関数はバイト数を返しますが、それは現在受信バッファで利用可能なので、私は別のフレームが開始するかどうか、あるいは私がまだ "古い"パケットを読んでいるかどうかわかりません。

実際には、イーサネットフレームの長さがヘッダーに含まれていないため、私自身でこれを行うことはできません。

ありがとうございます!

+0

はhttps://en.wikipedia.org/wiki/Ethernet_frameを参照してください。 –

+0

私はイーサネットプロトコルがどのように動作しているのか知っていますが、どうすればこの問題を解決できますか? ヘッダーの唯一の情報は、フレームの長さを含むことができるタイプですが、必要はありません! –

+0

'EtherType'フィールドにはペイロードの長さを持つ2つのオクテットがあります。これで、合計フレームサイズを決定できます。 –

答えて

0

誰もが同じ問題に遭遇した場合は、ここでの可能なソリューションです:

あなたはキャプチャデバイスなどのデバイスを開きます(WindowsのWinPcapの中で)のlibpcapライブラリを使用することができます。

char errbuf[PCAP_ERRBUF_SIZE];  /* error buffer */ 
Pcap_t *handle;      /* packet capture handle */ 

/* open capture device*/ 
/* max possible length, not in promiscous mode, no timeout!*/ 
handle = pcap_open_live(dev, 65536, 0, 0, errbuf); 
if (handle == NULL) { 
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); 
} 

/* set capture device to non blocking*/ 
if(pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)){ 
    fprintf("Could not set pcap interface in non blocking mode: %s \n", errbuf); 
} 

今することができますあなたは、データが処理されているコールバック関数を提供する必要が

int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user); 

:巡回コールpcap_dispatch機能は、パケット(複数可)を受信します。 詳細については、https://www.freebsd.org/cgi/man.cgi?query=pcap_dispatch&apropos=0&sektion=3&manpath=FreeBSD+11-current&format=htmlを参照してください。

あなたは、注入機能を使用することにより、生のイーサネットフレームを送信することができます

pcap_inject(pcap,frame,sizeof(frame)); 
関連する問題