На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Raw sockets - передача пакета между интерфейсами (мост) , Не удаётся передать пакет между интерфейсами.
      Доброго дня, други. Проблемка. Делаю мост L2 с помощью raw sockets.. Пакеты вижу с обоих интерфейсов (фильтрую по индексу интерфейса), вроде передаю в другой интерфейс (установив индекс) - ошибок не возникает, а связи через мост нет.. что делаю не так? Код ниже.. Может кто носом ткнуть?

      ExpandedWrap disabled
            char *opt_1 = "eth0";
            char *opt_2 = "eth1";
         
            int sock;
            int doexit = 0;
         
            sock = socket( AF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
            if (sock < 0)
            {
                printf("Can't open socket\n");
                return 4;
            }
         
         
            struct sockaddr_ll sll;
            int sll_size = sizeof( sll );
         
            unsigned char buf[ 1024 ];
            unsigned int  buf_size = 1024;
         
            struct ether_header *eh = (struct ether_header *) buf;
         
            struct ifreq if_idx1, if_idx2;
            struct ifreq if_flg1, if_flg2;
            int flg1, flg2;
         
         
         
            //-- Получаем индексы интерфейсов
            memset(&if_idx1, 0, sizeof(struct ifreq));
            strncpy(if_idx1.ifr_name, opt_1, IFNAMSIZ-1);
            if ( ioctl( sock, SIOCGIFINDEX, &if_idx1) < 0)
                perror("SIOCGIFINDEX 1");
         
            memset(&if_idx2, 0, sizeof(struct ifreq));
            strncpy(if_idx2.ifr_name, opt_2, IFNAMSIZ-1);
            if ( ioctl( sock, SIOCGIFINDEX, &if_idx2) < 0)
                perror("SIOCGIFINDEX 2");
         
         
         
            //-- ставим  promiscuous mode  на оба интерфейса
            memset(&if_flg1, 0, sizeof(struct ifreq));
            strncpy(if_flg1.ifr_name, opt_1, IFNAMSIZ-1);
            if ( ioctl( sock, SIOCGIFFLAGS, &if_flg1) < 0)
                perror("SIOCGIFFLAGS 1");
            flg1 = if_flg1.ifr_flags;
            if_flg1.ifr_flags |= IFF_PROMISC;
            if ( ioctl( sock, SIOCSIFFLAGS, &if_flg1) < 0)
                perror("SIOCSIFFLAGS 1");
         
         
            memset(&if_flg2, 0, sizeof(struct ifreq));
            strncpy(if_flg2.ifr_name, opt_2, IFNAMSIZ-1);
            if ( ioctl( sock, SIOCGIFFLAGS, &if_flg2) < 0)
                perror("SIOCGIFFLAGS 2");
            flg2 = if_flg2.ifr_flags;
            if_flg2.ifr_flags |= IFF_PROMISC;
            if ( ioctl( sock, SIOCSIFFLAGS, &if_flg2) < 0)
                perror("SIOCSIFFLAGS 2");
         
         
            int i;
         
            printf("ready\n");
         
         
            unsigned long readed;
         
         
         
            while( !doexit )
            {
         
                //-- читаем что-нибудь от кого-нибудь
                readed = recvfrom( sock, buf, buf_size, 0, (struct sockaddr *)&sll, &sll_size );
         
                //-- отфильтровываем пакеты с управляющего нтерфейса..
                if ( sll.sll_ifindex != if_idx1.ifr_ifindex  &&  sll.sll_ifindex != if_idx2.ifr_ifindex )
                    continue;
         
         
                if ( readed > 0 )
                {
         
                    //-- если пришло с одного интерфейса, шлём на другой (ставим нужный индекс интерфейса)
                    if ( sll.sll_ifindex == if_idx1.ifr_ifindex )
                    {
                        sll.sll_ifindex = if_idx2.ifr_ifindex;
                    }
                    else
                    {
                        sll.sll_ifindex = if_idx1.ifr_ifindex;
                    }
                    sll.sll_halen = ETH_ALEN;
         
         
                    //-- копируем адрес "кому" из исходного пакета
                    for( i=0; i<6; i++ )
                        sll.sll_addr[ i ] = eh->ether_dhost[ i ] & 0xFF;
         
         
                    if ( sendto( sock, buf, readed, 0, (struct sockaddr *)&sll, sizeof(struct sockaddr_ll) ) < 0 )
                    {
                        printf("Can't send to interface %d\n" , sll.sll_ifindex );
         
        //---- Ошибок не выдаёт, но и связи нет .....
         
                    }
         
                }
         
         
         
            }
         
         
            //-- по завершении - восстанавливаем флаги
         
            if_flg1.ifr_flags = flg1;
            if ( ioctl( sock, SIOCSIFFLAGS, &if_flg1) < 0)
                perror("SIOCSIFFLAGS 1x");
         
            if_flg2.ifr_flags = flg2;
            if ( ioctl( sock, SIOCSIFFLAGS, &if_flg2) < 0)
                perror("SIOCSIFFLAGS 2x");
         
         
            close( sock );
         
            printf("bye.\n");
         
            return 0;
        Запусти tcpdump на обоих интерфейсах, и посмотри там.
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0179 ]   [ 17 queries used ]   [ Generated: 28.03.24, 19:09 GMT ]