2016-09-13 5 views
1

IPヘッダーの1つのフィールドを除いて、完全に正常に機能するRaw IPパケットを送信します。Cソケットプログラミング:IPヘッダーのIDを0に設定しますか?

私はそれを次のように試してみました0にIP IDを設定する必要が

:私は、作成

 if ((sockd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) { 
     perror("Failed to create socket"); 
     exit(1); 
    } 
int hdrincl = 1; 
if (setsockopt(sockd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl)) == -1) { 
    perror("Failed to set IP_HDRINCL"); 
    exit(1); 
} 

:私はその後、IP_HDRINCLオプションセットでRAW_SOCKETを作成

struct iphdr ip; 

ip.version = 4;        // Ipv4 
ip.frag_off = 0;        // IP Fragmentation 
ip.tos  = 0;        // Type of Service - We don't need this 
ip.ttl = 64;         // Maxmimum value 
ip.protocol = IPPROTO_UDP;     // DHCP uses UDP 
ip.check = 0;         // The checksum needs to be 0 before being calculated 

// We don't yet have an IP Address 
if((ip.saddr = inet_addr("0.0.0.0")) == -1) { 
    perror("Failed to convert IP address"); 
    exit(1); 
} 

ip.daddr = inet_addr("255.255.255.255");  // we have to do a broadcast 
ip.id = 0;         // 
ip.ihl = 5;         // Header length - 5 means no additional options are being sent in the IP header 
ip.tot_len = sizeof(struct packet);   // The total length of the Packet 

を私のIPヘッダー、UDPヘッダー、およびペイロードを含んでいて、それを送信します。

ただし、ネットワークスタックはIPヘッダーのIDを変更し続けます。 IPヘッダーを含める必要がありますが、フラグメンテーションを無効にしたり、IP IDを0に設定する必要があります。これをどのように達成できますか?

編集:私はLinux上でのLinux

+0

あなたはLinuxまたはWindowsを使用していますか?あなたが窓の上にいる場合、ソケットはそれを行う方法ではありません。代わりにlibpcapを試してください。 –

+1

manページ 'man 7 raw'をチェックすると、' id'が '0'のときに自動的に記入されるので、なぜid 0を使うことができないのか分かりますが、 id 0を実際に使用するソリューションです。 – Jite

答えて

3

日午前、あなたはSOCK_RAWSOCK_DGRAMソケットの代わりAF_INETAF_PACKETを使用してsockaddr_llを埋めることができます。

そのような何か:

socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)) 

しかし、あまりにもWindowsとのあなたのプログラムを動作させるために、あなたはlibpcapを使用する必要があります。

宛先の物理アドレスは自分で解決する必要があります(Linuxの場合はrtnetlinkインターフェイスを使用してみてください)。

packet(7)rtnetlink(7)をさらに参照してください。あなたのプロジェクトがオープンソースの場合は、my old projectを使ってこれらのことを行うことができます(詳細は私に連絡してください)。

関連する問題