2017-01-31 8 views
0

クライアントのソケットコードで、UDPデータグラムの受信パケットのIPレイヤヘッダーを取得する必要があります。Windows 10のRaw UDPソケットがネットワークの問題を引き起こします

int optval=1; 
WSADATA wsaData; 
if (WSAStartup(MAKEWORD(2,2),&wsaData) == SOCKET_ERROR) { 

    int err = WSAGetLastError(); 
    my_err("WSAStartup error %d\n",err); 
    return 0; 
} 

if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == INVALID_SOCKET) { 

     perror("socket()"); 
     return 0; 
} 

if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof optval) != 0) { 

    perror("setsockopt(IPPROTO_IP,IP_HDRINCL)"); 
    return 0; 
} 

Anは、私が使用して最初にデータを送信します:

は、だから私は、システムコールの下に使用してRAWにソケットを変更することを決めたコードの上

//content is a structure containing data and its length 
uint16_t all_length = content->len; 

size_t IP_HL = sizeof (IPHEADER); 

//get_interface_ip returns interface ip address 
uint32_t src_addr = get_interface_ip(); 

IPHEADER *iph = NULL; 
size_t all_length = IP_HL + sizeof (UDPHEADER) + total_len; 
UDPHEADER *udph = NULL; 
BUFFER buf; 
make_buf(&buf, 0); 

iph = (IPHEADER *) BPTR(&buf); 

iph->ip_hl = 5; 
iph->ip_v = 4; 
iph->ip_tos = 0; 
iph->ip_len = all_length; 
//get_uniq_id creates ip id field 
iph->ip_id = htonl (get_uniq_id()); //Id of this packet 
iph->ip_off = 64; //DONT fragment 
iph->ip_ttl = 255; 
iph->ip_p = IPPROTO_UDP; 
iph->ip_sum = 0;  //Set to 0 before calculating checksum 
iph->ip_src = src_addr; 
iph->ip_dst = remote.sin_addr.s_addr; 

iph->ip_sum = csum((uint16_t *)iph, iph->ip_len); 

udph = (UDPHEADER *) (iph + 1); 
memcpy((udph + 1), (char *)content->data, total_len); 

//get_src_port gets a fixed source port number randomly created in program start time 
udph->uh_sport = get_src_port(); 
udph->uh_dport = get_server_port(); 

udph->uh_len = htons(sizeof (UDPHEADER) + total_len); 
udph->uh_check = 0; //leave checksum 0 now, filled later by pseudo header 

{ 
    PSESUDO_HEADER psh; 
    int psize = 0; 
    char *pseudogram = NULL; 

    psh.source_address = src_addr; 
    psh.dest_address = remote.sin_addr.s_addr; 
    psh.placeholder = 0; 
    psh.protocol = IPPROTO_UDP; 
    psh.udp_length = udph->uh_len; 

    psize = sizeof(PSESUDO_HEADER) + sizeof(UDPHEADER) + total_len; 
    pseudogram = (char *)malloc(psize); 

    memcpy(pseudogram , (char*) &psh , sizeof (PSESUDO_HEADER)); 
    memcpy(pseudogram + sizeof(PSESUDO_HEADER) , udph , sizeof(UDPHEADER) + total_len); 

    udph->uh_check = csum((uint16_t *)pseudogram, psize); 
} 

es->wsabuf.len = all_length; 
es->wsabuf.buf = buf.data; 

if(WSASendTo(sock, &wsabuf, 1, NULL, 0, (SOCKADDR *)&remote, sizeof(remote), &io_ovl, NULL) == SOCKET_ERROR) { 

    int err = WSAGetLastError(); 
    if (err != WSA_IO_PENDING) 
     return 0; 
} 

、その後、IPヘッダ、UDPヘッダを作成IPとUDPのチェックサムを計算します。私はLinuxのコードに同じロジックを使用し、かなりうまく動作します。

私はプログラムを実行し、最初のデータを送信すると、何かが起こります!このプログラムは私の古いADSLモデムをクラッシュさせます!

私が考えることができるのは、それが生成するパケットフォーマットだけです。

私は古いモデムをクラッシュさせるような不良なIPまたはUDPヘッダーを生成する必要があると考えました。

私はWiresharkを開始し、パケットを2回キャプチャしました。最初にRAWソケットなしで同じコード(通常送信)と2回目のRAWソケットをキャプチャしました。

次に、結果を比較しました。驚いたことに、私は違いを見つけることができませんでした!

Wiresharkのは、RAWソケットなしでキャプチャを送る:

Frame 1: 105 bytes on wire (840 bits), 105 bytes captured (840 bits) on interface 0 
    Interface id: 0 (\Device\NPF_{UUID}) 
    Encapsulation type: Ethernet (1) 
    Arrival Time: Jan 30, 2017 21:53:46.500050000 Iran Standard Time 
    [Time shift for this packet: 0.000000000 seconds] 
    Epoch Time: 1485800626.500050000 seconds 
    [Time delta from previous captured frame: 0.000000000 seconds] 
    [Time delta from previous displayed frame: 0.000000000 seconds] 
    [Time since reference or first frame: 0.000000000 seconds] 
    Frame Number: 1 
    Frame Length: 105 bytes (840 bits) 
    Capture Length: 105 bytes (840 bits) 
    [Frame is marked: False] 
    [Frame is ignored: False] 
    [Protocols in frame: eth:ethertype:ip:udp:data] 
    [Coloring Rule Name: UDP] 
    [Coloring Rule String: udp] 
Ethernet II, Src: IntelCor_MAC:ADDR (SRC:MAC:ADDR), Dst: AlphaNet_MAC:ADDR (DST:MAC:ADDR) 
    Destination: AlphaNet_MAC:ADDR (DST:MAC:ADDR) 
    Source: IntelCor_MAC:ADDR (SRC:MAC:ADDR) 
    Type: IPv4 (0x0800) 
Internet Protocol Version 4, Src: 192.168.1.4, Dst: server_ip 
    0100 .... = Version: 4 
    .... 0101 = Header Length: 20 bytes (5) 
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 
    Total Length: 91 
    Identification: 0x6a10 (27152) 
    Flags: 0x02 (Don't Fragment) 
    Fragment offset: 0 
    Time to live: 128 
    Protocol: UDP (17) 
    Header checksum: 0x70a6 [correct] 
    [Header checksum status: Good] 
    [Calculated Checksum: 0x70a6] 
    Source: 192.168.1.4 
    Destination: server_ip 
    [Source GeoIP: Unknown] 
    [Destination GeoIP: Unknown] 
User Datagram Protocol, Src Port: 60594, Dst Port: 7554 
    Source Port: 60594 
    Destination Port: 7554 
    Length: 71 
    Checksum: 0x755e [correct] 
    [Checksum Status: Good] 
    [Stream index: 0] 
Data (63 bytes) 
    Data: 002523a38308884051a46d6c5135778f0a32db3027df1576... 
    [Length: 63] 

そして、RAWソケットを持つ:

Frame 2: 105 bytes on wire (840 bits), 105 bytes captured (840 bits) on interface 0 
    Interface id: 0 (\Device\NPF_{UUID}) 
    Encapsulation type: Ethernet (1) 
    Arrival Time: Jan 30, 2017 21:39:38.086166000 Iran Standard Time 
    [Time shift for this packet: 0.000000000 seconds] 
    Epoch Time: 1485799778.086166000 seconds 
    [Time delta from previous captured frame: 17.305889000 seconds] 
    [Time delta from previous displayed frame: 17.305889000 seconds] 
    [Time since reference or first frame: 17.305889000 seconds] 
    Frame Number: 2 
    Frame Length: 105 bytes (840 bits) 
    Capture Length: 105 bytes (840 bits) 
    [Frame is marked: False] 
    [Frame is ignored: False] 
    [Protocols in frame: eth:ethertype:ip:udp:data] 
    [Coloring Rule Name: UDP] 
    [Coloring Rule String: udp] 
Ethernet II, Src: IntelCor_MAC:ADDR (SRC:MAC:ADDR), Dst: AlphaNet_MAC:ADDR (DST:MAC:ADDR) 
    Destination: AlphaNet_MAC:ADDR (DST:MAC:ADDR) 
    Source: IntelCor_MAC:ADDR (SRC:MAC:ADDR) 
    Type: IPv4 (0x0800) 
Internet Protocol Version 4, Src: 192.168.1.4, Dst: server_ip 
    0100 .... = Version: 4 
    .... 0101 = Header Length: 20 bytes (5) 
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) 
    Total Length: 91 
    Identification: 0x58ef (22767) 
    Flags: 0x02 (Don't Fragment) 
    Fragment offset: 0 
    Time to live: 255 
    Protocol: UDP (17) 
    Header checksum: 0x02c7 [correct] 
    [Header checksum status: Good] 
    [Calculated Checksum: 0x02c7] 
    Source: 192.168.1.4 
    Destination: server_ip 
    [Source GeoIP: Unknown] 
    [Destination GeoIP: Unknown] 
User Datagram Protocol, Src Port: 16383, Dst Port: 7554 
    Source Port: 16383 
    Destination Port: 7554 
    Length: 71 
    Checksum: 0x2faf [correct] 
    [Checksum Status: Good] 
    [Stream index: 0] 
Data (63 bytes) 
    Data: 00250d80dd1b561e4d81c22c2914f49f1bb492f78d6a3ee8... 
    [Length: 63] 

任意のアイデア?

+0

「私の古いADSLモデムクラッシュ "、XD。非常に安全です。 "私はIP層ヘッダーを取得する必要があります"、なぜ私に教えてくれますか、私は興味があります。 – Stargateur

+0

受信パケットにDFフラグが設定されているかどうかを確認したい(これは長い話ですが、受信パケットのDFフラグを取得する方法はわかりません) – madz

+0

中国では何が起こるか見てみよう) – madz

答えて

1

申し訳ありませんが、これは私の間違いでした。このコードは、たくさんのファイルを含む古いコードです。最近私はいくつかの自由な時間を得て、いくつかのTODOタスクを行うことに決めました。

私はRAWにソケットを変更したので、書き込み回数は(DATA_LENGTH + udp_header + ip_header)増加したが、次の内容の他に、いくつかの場所(別のファイル)内のコードの別の平和がありました:

if(number_of_written != data_length) { 

    repeat_socket_process(); 
} 

このコードでは、私は実際に自分のルータのDOS(サービス拒否攻撃)でした!

数分の1秒で生成されたパケットが多すぎます。だから、生のソケットやパケットヘッダーとは関係ありませんでした。

私が行うために必要なすべてはとにかくフォローアップのために君たちに感謝し、似たような状況の場合、そのコードの他の場所を追跡するためにこのヘルプ他人を願っています

if (number_of_written != data_length + udp_header + ip_header) 

をチェックすることです

関連する問題