1

ここからsimpletunに似たプログラムを作っています。

  1. アプリケーションは、UDPブロードキャストをTapインターフェイスに送信します。

  2. タップインターフェイス(simpletunと同様)でリッスンしているプログラムは、パケットを受信し、ブロードキャストとして再度エコーします。

  3. Wiresharkで両方のパケットを確認できますが、アプリケーションはそれを受信しません。カーネルがそれらをドロップしているようです。

  4. 同様のパケットが別のマシンから送信された場合。それはうまくいきます。

tun / tapコード:-

char datagram[4096];
struct pseudo_header
{
        u_int32_t source_address;
        u_int32_t dest_address;
        u_int8_t placeholder;
        u_int8_t protocol;
        u_int16_t udp_length;
};
struct pseudo_header psh;
char *pseudogram;

 nread = cread(tap_fd, buffer, BUFSIZE);

    memcpy(&source_port,(char *)(buffer+14+20),2);  

    memset (datagram, 0, 4096);

    memcpy(datagram,buffer,14); //copy eth-header
    datagram[6] = 0xXX;//change mac address
    datagram[7] = 0xXX;
    datagram[8] = 0xXX;
    //IP header
    struct iphdr *iph = (struct iphdr *) (datagram +14);
    //TCP header
    struct udphdr *udph = (struct udphdr *) (datagram + 14 + sizeof (struct iphdr));

    data = datagram + sizeof(struct iphdr) + sizeof(struct udphdr) +14;     
    strcpy(data,"Any string");
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = sizeof (struct iphdr) + sizeof (struct udphdr) + strlen(data);
    iph->id = htonl (54321);        //Id of this packet
    iph->frag_off = 0;
    iph->ttl = 255;

    iph->protocol = IPPROTO_UDP;
    iph->check = 0;         //Set to 0 before calculating checksum

    strcpy(source_ip , "192.168.0.99");
    iph->saddr = inet_addr ( source_ip );   //Spoof the source ip address
    strcpy(destination_ip , "255.255.255.255");
    iph->daddr = inet_addr (destination_ip);


     udph->source = htons(5933);
    //udph->dest = htons(source_port);
    udph->dest = (source_port);
    udph->len = htons(sizeof(struct udphdr) + strlen(data));


    //Now the UDP checksum
    psh.source_address = inet_addr( source_ip );
    psh.dest_address = inet_addr(destination_ip);
    psh.placeholder = 0;
    psh.protocol = IPPROTO_UDP;
    psh.udp_length = htons(sizeof(struct udphdr) + strlen(data) );

    int psize = sizeof(struct pseudo_header) + sizeof(struct udphdr) + strlen(data);
    pseudogram = malloc(psize);

    memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
    memcpy(pseudogram + sizeof(struct pseudo_header) , udph , sizeof(struct udphdr) + strlen(data));
    memcpy(pseudogram + sizeof(struct pseudo_header) + sizeof(struct udphdr), data , strlen(data));

    udph->check = 0;
    udph->check = csum( (unsigned short*) pseudogram , psize);
    //Ip checksum
    iph->check = csum ((unsigned short *) datagram, iph->tot_len);

    //writeback
    cwrite(tap_fd,datagram,iph->tot_len +14);

上記のコードは、rawソケットの読み取りと書き込みを使用して別のマシンから実行すると、うまく機能します。(ethヘッダーなし)。

アプリケーションコードの受信:-

int broadcast =1;

if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
      err("socket");

setsockopt(sockfd,SOL_SOCKET,SO_BINDTODEVICE,"tun0",5);

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
memset(&my_addr.sin_addr.s_addr,255,sizeof(my_addr.sin_addr.s_addr));

ret = setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast));
    if(ret<0)
      printf("setsockopt bindto failed");

    if (sendto(sockfd,buf,500,0, (struct sockaddr*)&my_addr,slen_len) == -1)
        err("send()");

    recvfrom(sockfd, buf, 500, 0, (struct sockaddr*)&cli_addr, &slen);
4

3 に答える 3

1

ホストファイアウォールルールを確認しましたか?

于 2013-03-15T09:16:24.020 に答える
1

ipヘッダーのtot_lenに適切なチェックサムと適切なバイト順序を使用して解決しました

iph->tot_len = (htons)sizeof (struct iphdr) + sizeof (struct udphdr) + strlen(data);

iph->id = htons (54321); //Id of this packet

iph->check = htons(csum ((unsigned short *) datagram,sizeof(struct ip_hdr))); **ここで、csumはチェックサムを計算するための一般的な関数です。

カーネルのネットワークスタックがiph->tot_lenとipチェックサムを再計算していたため、別のマシンパケットから受信されました。したがって、パケットは適切に形成されました。

tot_lenパケットのチェックサムとバイトオーダーを修正した後、私のtunインターフェイスでアプリケーションが受信しました。

于 2013-03-19T05:56:50.030 に答える
0

暗い推測で撮影:

しかし、IP宛先をブロードキャストIP(255.255.255.255)と見なすときに、宛先MACアドレスをブロードキャスト(FF:FF:FF:FF:FF:FF)に設定して、TUN / TAPコードを変更してみることができますか?

于 2013-03-15T09:56:15.337 に答える