простой виртуальный сетевой интерфейс

Вопросы программного кода и архитектуры Linux

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: простой виртуальный сетевой интерфейс

Непрочитанное сообщение Olej » 16 июл 2012, 17:56

Возвращаюсь к вопросу:

- как создать виртуальный сетевой интерфейс, не пользуясь API netdev_rx_handler_register(), довольно путанным + появившемся в ядре после 2.6.36?

- то, что обсуждалось здесь в соседней родственной теме ещё 10 мая 2012 ... да руки как-то не доходили - viewtopic.php?f=18&t=1624&start=40#p3838:
yevgen.kopylov писал(а):
Olej писал(а): - как без использования netdev_rx_handler_register(), который появился с 2.6.37, делался перехват виртуальным интерфейсом потока принимаемых (RX, с TX всё понятно и проще) сокетных буферов?
- ведь виртуальные интерфейсы создавались задолго до 2.6.37? ... тот же Cisco-клиент VPN... и мн.др.
про "Cisco-клиент VPN", к сожалению, ничего не знаю. Кстати, dev_add_pack - это не то что Вы искали?
- то, как это делалось во всех прежних реализациях (ядра)? ... во многих разных пакетах.

1-й вариант (но всё работающее) - прикладывается ;-)
Вложения
virt-proto.tgz
(6.29 КБ) 469 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: простой виртуальный сетевой интерфейс

Непрочитанное сообщение Olej » 16 июл 2012, 18:10

Olej писал(а): - как создать виртуальный сетевой интерфейс, не пользуясь API netdev_rx_handler_register(), довольно путанным + появившемся в ядре после 2.6.36?
Всё проще, чем даже с netdev_rx_handler_register() ...
yevgen.kopylov писал(а):Кстати, dev_add_pack - это не то что Вы искали?
... и именно на протокольном уровне, как-раз на сетевом уровне L3 (но не транспортном L4), и именно с dev_add_pack() ...
Olej писал(а):1-й вариант (но всё работающее) - прикладывается ;-)
Там в архиве 2 варианта:
- упрощённый модуль virtl.ko (lite ;-) ), который замещает родительский...
- и полный virt.ko, который анализирует ARP & IP4, и затрагивает только трафик к нему относящийся - этот код громоздкий, вдвое больше...

Если кому интересен будет именно принцип для начала, то лучше посмотреть virtl.ko - там всё элементарно понятно:

1. после регистрации сетевого интерфейса virt0 в init() (всё-всё это уже многократно мусолилось здесь в теме), делается

Код: Выделить всё

   proto_parent.dev = priv->parent;
   dev_add_pack( &proto_parent );    // установить обработчик фреймов для родителя
2. а proto_parent - это и есть структура протокольного обработчика для всех протоколов (ETH_P_ALL = ETH_P_ARP + ETH_P_IP ):

Код: Выделить всё

// приём фрейма
int pack_parent( struct sk_buff *skb, struct net_device *dev,
                 struct packet_type *pt, struct net_device *odev ) {
   skb->dev = child;          // передача фрейма в виртуальный интерфейс
   stats.rx_packets++;
   stats.rx_bytes += skb->len;
   DBG( "tx: injecting frame from %s to %s with length: %u",
        dev->name, skb->dev->name, skb->len );
   return skb->len;
};
   
static struct packet_type proto_parent = {
   __constant_htons( ETH_P_ALL ), // перехватывать все пакеты: ETH_P_ARP & ETH_P_IP 
   NULL,
   pack_parent,
   (void*)1,
   NULL
};
3. и перенаправить весь этот трафик в виртуальный (дочерний) интерфейс.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: простой виртуальный сетевой интерфейс

Непрочитанное сообщение Olej » 16 июл 2012, 18:25

Olej писал(а): - и полный virt.ko, который анализирует ARP & IP4, и затрагивает только трафик к нему относящийся - этот код громоздкий, вдвое больше...
А вот virt.ko позволяет в параллель работать и виртуальному интерфейсу virt0, и реальному на который он "посажен" p7p1 (если это Fedora 16 и более) или eth0 (если это Debian или другой более нормальный дистрибутив):

1. делаем отдельную подсетку для тестирования виртуального интерфейса (алиасный IP для интерфейса):

Код: Выделить всё

[olej@nvidia ~]$ sudo ifconfig vboxnet0:1 192.168.50.1
[olej@nvidia 16]$ ip address vboxnet0
3: vboxnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 0a:00:27:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.1/24 brd 192.168.56.255 scope global vboxnet0
    inet 192.168.50.1/24 brd 192.168.50.255 scope global vboxnet0:0
    inet6 fe80::800:27ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
2. на удалённом хосте (Fedora 16) делаем виртуальный интерфейс и конфигурирем:

Код: Выделить всё

[olej@fedora16vm virt-proto]$ sudo insmod ./virtl.ko link=p7p1 debug=1
[olej@fedora16vm virt-proto]$ sudo ifconfig virt0 192.168.50.17
3. и + две сессии ssh: одна на созданный виртуальный интерфейс, а вторая на родительский p7p1:

Код: Выделить всё

[olej@nvidia 16]$ ssh olej@192.168.50.17
...
[olej@nvidia 16]$ ssh olej@192.168.56.101
[olej@fedora16vm ~]$ who
olej     tty1         2012-07-16 09:29 (:0)
olej     pts/0        2012-07-16 09:33 (:0.0)
olej     pts/1        2012-07-16 12:22 (192.168.1.9)
olej     pts/3        2012-07-16 15:44 (192.168.50.1)
olej     pts/4        2012-07-16 15:52 (192.168.1.9)
olej     pts/6        2012-07-16 17:29 (192.168.50.1)
olej     pts/7        2012-07-16 17:31 (192.168.56.1)
(2 последних строчки - с 2-х алиасных IP единого хоста).

4. замечательно этот же интерфейс "ест" tcpdump:

Код: Выделить всё

[olej@fedora16vm virt-proto]$ sudo tcpdump -i virt0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on virt0, link-type EN10MB (Ethernet), capture size 65535 bytes
17:27:54.914885 ARP, Reply 192.168.50.17 is-at 08:00:27:9e:02:02 (oui Unknown), length 28
17:27:54.918023 IP 192.168.50.17 > 192.168.50.1: ICMP echo reply, id 8067, seq 1, length 64
17:27:55.912516 IP 192.168.50.17 > 192.168.50.1: ICMP echo reply, id 8067, seq 2, length 64
17:27:56.912419 IP 192.168.50.17 > 192.168.50.1: ICMP echo reply, id 8067, seq 3, length 64
17:27:57.912541 IP 192.168.50.17 > 192.168.50.1: ICMP echo reply, id 8067, seq 4, length 64
17:27:59.933696 ARP, Request who-has 192.168.50.1 tell 192.168.50.17, length 28
(это результат ping - хорошо видно ARP разрешение).

P.S. ;-)

Код: Выделить всё

[olej@nvidia 16]$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.1.20             ether   08:00:27:14:ca:91   C                     eth0
192.168.50.17            ether   08:00:27:9e:02:02   C                     vboxnet0
192.168.50.13                    (incomplete)                              vboxnet0
192.168.1.21             ether   08:00:27:52:b9:e0   C                     eth0
192.168.56.101           ether   08:00:27:9e:02:02   C                     vboxnet0
192.168.1.1              ether   c8:64:c7:8a:50:16   C                     eth0
192.168.1.5              ether   00:15:60:c4:ee:02   C                     eth0

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: простой виртуальный сетевой интерфейс

Непрочитанное сообщение Olej » 13 окт 2012, 15:42

Позавчера здесь на сайте выложили перевод статьи по программному использованию библиотеки libpcap - http://rus-linux.net/MyLDP/algol/libpcap.html:

Код: Выделить всё

Захват пакетов при помощи библиотеки libpcap
Оригинал: Capturing Packets in Your C Program, with libpcap 
Автор: Pankaj Tanwar 
Дата публикации: 1 Февраля 2011 г. 
Перевод: А.Панин 
Дата перевода: 11 октября 2012 г.
Это именно та библиотека (libpcap), которая крайне нужна разработчику сетевых модулей ядра - именно посредством неё можно написать самый разный вспомогательный инструмент своего проекта, без которого такой проект просто не отладить, и не довести до ума.

Обратите внимание!

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя