2017-10-23 2 views
1

私は1つのインタフェース(VxBridge)からパケットを転送したい場所にプログラムを持っています。&別のインタフェース(ens3: - 生のソケットをリストしています)Cプログラムの複数のインターフェイスをリストしています

私のプログラムはens3 <から3つのインターフェイス

1. VxBridge --> Listing on port 1702 
2. ens3 --> listen raw interface 
3. tap interface --> tun tap interface 

パケットに耳を傾けますが - > VxBridge

問題: - 私はens3にWiresharkのリストを実行しているのであれば、プログラムが正常に動作します。 wiresharkがstopの場合、プログラムはens3のパケットをlistenしません。以下はプログラムのコードスニペットです。 また、I/Oイベントが発生するのを待つselect()関数に多少は関係していると思います。

私はここで本当に間違っていることを知っています。リダイレクトの助けがあれば感謝します。以下 プログラムである: - インターフェイス上でプロミスキャスモードを有効にする

main(int argc, char **argv) 
{ 
    struct sockaddr_in addr; 
    struct sockaddr_ll daddr; 
    fd_set  rfds; 
    fd_set   hfds; 
    int  cc,ccd; 
    struct sockaddr_in from; 
    size_t  fromlen; 
    int  fdmax; 
    int  i; 
    char* newframe=NULL; 
    int fdcounter =0; 
    char   *vb = NULL; 
    int vxSocketfdSet,hwSocketfdSet,tapSocketfdSet; 
    vxSocketfdSet= hwSocketfdSet=tapSocketfdSet=0; 

     // Open sockets for L2 device 
     if (send_to_hw){ 
     if ((destsock_fd = socket(PF_PACKET , SOCK_RAW , IPPROTO_RAW)) < 0){ 
      perror("destsocket creation failed exit"); 
       exit(1); 
      } 

      global_fd[fdcounter]=destsock_fd; 
      fdcounter++; 
     } 

      memset(&daddr, 0, sizeof(struct sockaddr_ll)); 
      daddr.sll_family = AF_PACKET; 
      daddr.sll_protocol = htons(ETH_P_ALL); 
      daddr.sll_ifindex = if_nametoindex("ens3"); 
      if (bind(destsock_fd, (struct sockaddr*) &daddr, sizeof(daddr)) < 0) { 
        printf(" ens3 bind failed\n"); 
        close(destsock_fd); 
      } 

      struct ifreq ifr; 
      memset(&ifr, 0, sizeof(ifr)); 
      snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "ens3"); 
      if (setsockopt(destsock_fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0)  { 
         printf("setsockopt to ens3 failed"); 
      } 

    /* Open a socket for receiving frames from the Bridge, and forwarding to other l2fwd instances of remote host. */ 
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 
     perror("socket"); 
     exit(1); 
    } 
     global_fd[fdcounter]=sock_fd; 

    if (vb != NULL) 
    { 
     /* create a TAP interface and attach to virtual bridge */ 
     if ((tap_fd = tap_alloc_via_tun_helper(argv[tap_ip_arg], vb)) < 0)  { 
      exit(1); 
     } 
      global_fd[fdcounter]=tap_fd; 
       fdcounter++; 

    } 


    memset(&addr, '\0', sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    addr.sin_port = htons(DE); 

    if (bind(sock_fd, (void *) &addr, sizeof(addr)) < 0) { 
     perror("bind"); 
     exit(1); 
    } 

    write(1, "> ", 2); 


    if (pcap) 
     tv_wait = &pcap_flush_delay; 

    for (;;) { 
     FD_ZERO(&rfds); 
     fdmax = 0; 

       for (i =0;i<=fdcounter;i++){ 
        FD_SET(global_fd[i], &rfds); 
        if (global_fd[i] > fdmax) 
         fdmax = global_fd[i]; 
       } 
     if (select(fdmax + 1, &rfds, 0, 0, tv_wait) < 0) { 
      perror("select"); 
      continue; 
     } 

        for (i = 0;i <= fdcounter; i++) 
        { 
        if (FD_ISSET(global_fd[i], &rfds)) { 
         printf ("\nfdset value is %d &&& %d\n",i,global_fd[i]);    
         if (i==0) 
         { 
         printf("hw set "); 
         hwSocketfdSet = 1; 
         destsock_fd=global_fd[i]; 
         } 
         else if (i==1){ 
         printf ("vx Set x"); 
         vxSocketfdSet = 1; 
         sock_fd=global_fd[i]; 
         } 
         else if (i ==2){ 
         tapSocketfdSet = 1; 
          tap_fd=global_fd[i]; 
         } 
        break; 
        } 
       } 


       if (vxSocketfdSet){ 
      fromlen = sizeof(from); 
      cc = recvfrom(sock_fd, buf, sizeof(buf), 0, (void *) &from, &fromlen); 

      if (cc < 0) { 
       perror("recvfrom"); 
       continue; 
      } 

         printf("\nvx frame buf\n"); 
         tempFrom = &from;      
      forward(buf, cc, &from,0); 
     } 
     if (tapSocketfdSet){ 
         printf("tap frame received"); 
      /* Ethernet frame received from local XC. */ 
      if ((cc = read(tap_fd, buf, sizeof(buf))) < 0) { 
       perror("read"); 
       continue; 
      } 
      forward(buf, cc, NULL,0); 
     } 

     if (hwSocketfdSet){     
       printf ("Packet received on ens3 header buffer\n"); 

      if ((ccd = read(destsock_fd, hbuf, sizeof(hbuf))) < 0) { 
           printf ("error reading"); 
       perror("read"); 
       continue; 
      } 
         if (headerbuff != NULL && tempFrom != NULL) 
         { 
         printf("headerbuff =%u\n",headerbuff); 
         printf("headerbuff+ACTUAL_PAYLOAD_OFFSET %u\n",headerbuff+ACTUAL_PAYLOAD_OFFSET); 
         memcpy(headerbuff+ACTUAL_PAYLOAD_OFFSET,hbuf,ccd+ACTUAL_PAYLOAD_OFFSET); 
         newframe=headerbuff; 

         // printing packet with raw buffer 

// weird logic is used don't try to understand this one. 
// forward(headerbuff, ccd+ACTUAL_PAYLOAD_OFFSET,tempFrom,1); 

         } 
        } 
     vxSocketfdSet=hwSocketfdSet=tapSocketfdSet=0; 
    } 
} 
+0

正確な問題を示す[mcve]を入力してください。誰もそのすべてのコードを調べたくはありません。 – Kevin

+0

Wiresharkはプロミスキャスモードを有効にします。さもなければあなたのインターフェイスはそれにアドレス指定されていないパケットを無視します。 – stark

+0

@starkプロミスモードにインターフェイスを設定して問題を解決していただきありがとうございます。私が受け入れる答えにしてください。 –

答えて

1

は、それが任意のアドレスのパケットを受信することができます。さもなければインターフェイスは外部アドレスのためのパケットを無視します。これを行うには、flags引数のIFF_PROMISCビットをSIOCSIFFLAGS ioctl呼び出しに設定します。

プログラムが終了したら、必ずオフにしてください。

+0

上記の呼び出しで見たようにioctl呼び出しを使用していないので、私はインターフェイス全体でプロミスモードを有効にしています。 –

+1

コマンドラインからやっているかもしれませんが、他のコードからioctlを呼び出すだけです。例えば ​​'ip link set eth1 promisc on'のようにします。 – stark

関連する問題