2016-04-12 11 views
0

パケットを送信しようとしましたが、send()関数は-1を返しています。SOCK_RAWソケット経由でデータを送信しようとしたときに "宛先アドレスが必要"

int sockfd = socket(AF_INET, SOCK_RAW, 0); 
printf("socket: %d\n", sockfd); 
struct sockaddr_in sock; 
printf("creating packet\n"); 
char packet[27]; 
memcpy(packet + 0, (u_char*) ethernet->ether_dhost, 6); 
memcpy(packet + 6, (u_char*) ethernet->ether_shost, 6); 
memcpy(packet + 12, (u_char*) ethernet + 12, 2); 
memcpy(packet + 14, (u_char *)reqid, 1); 
memcpy(packet + 15, (u_char *)reqid+1, 1); 
memcpy(packet + 16, (u_char *)reqid+2, 4); 
memcpy(packet + 20, (u_char *)reqid+6, 1); 
memcpy(packet + 21, (u_char *)reqid+7, 1); 
memcpy(packet + 22, (u_char *)reqid+8, 4); 
memcpy(packet + 26, (u_char *)reqid+12, 1); 
printf("sending packet\n"); 
if(send(sockfd, packet, sizeof(packet), 0) == -1) 
{ 
    printf("packet not sent\n"); 
    //return; 
} 

パケットはイーサネットパケットと要求IDで構成されています。 パケットは問題なく、すべての値が適切な場所にあることがわかります。 send()関数は失敗します。
"宛先アドレスが必要です"と表示され、sockfdの値は4です。 これは、ところでFreeBSD上にあります。
ありがとう EDIT:私は宛先のIPアドレスを持っていません。私はそのMACアドレスしか持っていません。マンページから

+0

「errno」とは何ですか? 'sockfd'は有効ですか? ISTR 'SOCK_RAW'はルートが必要です –

+0

@LightnessRacesinOrbit宛先アドレスが必要です。 – ipinlnd

+0

@LightnessRacesinOrbitまた、はい** sockfd **が有効です。その値は4で、私はrootユーザーです。 – ipinlnd

答えて

0

これらの答えとその後の読書の後、私は目的のためにFreeBSDでソケットを使用する方法がないと考えました。
今私はこのためにlibpcapを使用しています。 pcap_sendPacket()を使用すると、イーサネットアドレスでパケットを送信できます。
あなたのお役に立てております。

1

:(意図された受信者が知られているように)ソケットが接続状態にあるときにのみ

送信()コールを使用することができます。

私はあなたがsendto、ないsendをしたいと考えています。

+0

しかし、問題は 'sendto'が宛先IPアドレスを必要とすることです。私はそれを持っていません。私はそのMACアドレスしか持っていません。 – ipinlnd

+0

@ipinlnd:どちらもあります。唯一の違いは、 'send'はあなたがここにない接続コンテキストから宛先を取ることです。 APIが独自のIPヘッダーの前にないように、 'IP_HDRINCL'フラグでソケットを作成する必要があるかもしれませんが、port = 0とaddress = NULLを使用できるはずです。どのガイドを使用していますか? –

+0

ああ、またはhttps:// austinmartonごとに宛先MACアドレスを使用できます。wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/ –

1

ローソケットを使用する場合は、イーサネットアドレスを指定しないでください。 Rawソケットを使用すると、ペイロードだけを送信できるIPデータグラムを作成でき、IP_HDRINCLソケットオプションが有効な場合は、ネットワークスタックがIPヘッダーを構成するか、IPヘッダーを指定することもできます。ここでは、イーサネットアドレスを指定することはできません。 Read:http://man7.org/linux/man-pages/man7/raw.7.html

IPアドレスがなく、イーサネットアドレスしか持っていない場合、これは別の方法で解決する必要がある別の問題です。

最初に、パケットソケットhttp://man7.org/linux/man-pages/man7/packet.7.htmlを使用し、もう一方のノードにイーサネットフレームを送信する必要があります。

問題は、他のノードがそのフレームを上位レイヤに渡すことです(デバイスドライバはこれを行います)。そこでは、上位層がIPアドレスを見ない場合、メッセージをドロップします。したがって、RARPメッセージを送信して、他のノードがIPアドレスを渡して応答することを期待することができます。他の可能性はあなた自身のレイヤー2プロトコルを実装することです...