Страница 2 из 4
Re: простой виртуальный сетевой интерфейс
Добавлено: 03 апр 2012, 10:58
Olej
kit_D писал(а):
Хотелось бы этому же интерфейсу присвоить ещё один алиасный IP из другой подсетки: 192.168.50.1
Как?
Для этого надо использовать утилиту ip. ifconfig является устаревшим инструментом (не поддерживает netlink), в то время как утилита ip (пакета iproute2) является новым и гораздо более обширным средством настройки сетевой подсистемы.
Это я знаю (правда, я не помню кто такой netlink
).
Но я не называл бы ifconfig "устаревшим инструментом"(с) ... хотя бы потому, что эта утилита используется
во всех UNIX, а ip - это
новый мощный, но
сторонний пакет, который я видел только в Linux (ну, и, наверняка, портированный в какие-то ближайшие ОС).
Так что на пока они, скорее, сосуществуют.
Re: простой виртуальный сетевой интерфейс
Добавлено: 03 апр 2012, 11:04
Olej
Olej писал(а):
1.
как повторно загрузить модуль под другим именем?
(для сетевых интерфейсов, как устройств фиктивных
- это может иметь смысл)...
Поясняю подробнее:
- как? загрузить файл модуля xxx.ko так...
- что, если модуль xxx уже загружен,
- так он бы загрузился как xxx0 (но, скажем, с какими-то другими параметрами загрузки в командной строке).
Существуют же алиасы для модулей в файле modules.alias ?:
Код: Выделить всё
[olej@notebook 2.6.42.12-1.fc15.i686.PAE]$ cat modules.alias | head -n5
# Aliases extracted from modules themselves.
alias devname:cpu/microcode microcode
alias char-major-10-184 microcode
alias twofish-asm twofish_i586
alias twofish twofish_i586
[olej@notebook 2.6.42.12-1.fc15.i686.PAE]$ lsmod | grep microcode
microcode 18550 0
[olej@notebook 2.6.42.12-1.fc15.i686.PAE]$ lsmod | grep char-major
Причём, некоторые из них записаны в странной форме:
Код: Выделить всё
[olej@notebook 2.6.42.12-1.fc15.i686.PAE]$ cat modules.alias | grep devnam
alias devname:cpu/microcode microcode
alias devname:fuse fuse
alias devname:btrfs-control btrfs
alias devname:net/tun tun
alias devname:ppp ppp_generic
alias devname:uinput uinput
alias devname:snd/timer snd_timer
alias devname:snd/seq snd_seq
- что означает вот то двоеточие?
Re: простой виртуальный сетевой интерфейс
Добавлено: 03 апр 2012, 14:45
Olej
Ну, вот первый работающий вариант ("уже намазывается, но запах ещё сохраняется"(с)
), за основу взяты выдержки из разных вариантов примеров
kit_D (спасибо ему), но уже сильно покроено, а дальше будет ещё более
.
P.S. да, поменялись: имя модуля, имя интерфейса и т.д. - так мне удобнее.
Для тестирования достаточно на хосте запуска:
Код: Выделить всё
[olej@fedora16vm virt]$ sudo insmod virt.ko link=p7p1
[olej@fedora16vm virt]$ sudo ifconfig virt0 192.168.50.2
- и всё! link (имя физ. интерфейса) - подставьте свой, при запуске без параметра это будет eth0.
На тестирующей стороне (в LAN, VirtualBox), делается что-то типа:
Код: Выделить всё
[olej@nvidia ~]$ sudo ifconfig vboxnet0:1 192.168.50.1
- IP алиас на требуемую подсетку, роутинг должен при этом встать сам (в VirtualBox, по крайней мере).
И всё, можно наслаждаться новой
подсеткой:
Код: Выделить всё
[olej@nvidia ~]$ ssh 192.168.50.2
Nasty PTR record "192.168.50.2" is set up for 192.168.50.2, ignoring
olej@192.168.50.2's password:
Last login: Tue Apr 3 14:04:26 2012 from 192.168.50.1
[olej@fedora16vm ~]$ exit
logout
Connection to 192.168.50.2 closed.
Re: простой виртуальный сетевой интерфейс
Добавлено: 03 апр 2012, 14:51
Olej
Olej писал(а):
Существуют же алиасы для модулей в файле modules.alias ?:
Как?
... загрузить модуль из файла YYY.ko так, чтобы он встал как модуль (lsmod) как XXX?
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 11:16
Olej
Olej писал(а):
При инициализации перехвата интерфейса меняем то, что было:
Код: Выделить всё
memcpy( dev->dev_addr, slave->dev_addr, sizeof( slave->dev_addr ) );
memcpy(dev->broadcast, slave->broadcast, sizeof( slave->broadcast ) );
- это вообще непонятно что записано, учитывая, что slave->dev_addr - это
указатель... меняем на то, что стало:
Код: Выделить всё
memcpy( dev->dev_addr, slave->dev_addr, ETH_ALEN );
memcpy( dev->broadcast, slave->broadcast, ETH_ALEN );
(ETH_ALEN - это как-раз 6 байт - длина MAC-адреса).
Вот тот неправильный фрагмент, в котором длиной MAC-адреса записан размер указателя на MAC-адрес - он кочует из примера в пример, ещё с тех времён когда его авторы написали это ещё для ядра 2.4 (сначала Alessandro Rubini <
rubini@linux.it>, а затем Filippo Bistaffa <
liquidator87@gmail.com> - проект insane).
Меня всё удивлял вопрос: как же это у них всё работало, если его годами хоть как, но тестировали?
Думаю, что сейчас мне это понятно:
-
практически все разработчики сейчас ведут разработку на 64-бит платформе...
- на 64-бит, при 8 байт размере указателя, в качестве MAC-адреса копировались не 6 положенные (Ethernet), а 8 байт ... с точки зрения значений этого более чем достаточно, а вылезть за предел выделенной области памяти на 2 байта - маловероятно...
- но на 32-бит эта ошибка вылазит явно: первые 4 байт MAC-адреса - идентичные, а последние 2-байта - различные, естественно, что при этом ARP не отрабатывает нормально и приём не происходит.
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 11:22
kit_D
Ну подождите. Я всегда считал и до сих пор считаю, что
если char array[100], то sizeof(array) вернет не размер указателя, а размер массива байтах, в данном случае - 100.
Аналогично sizeof(array)/sizeof(array[0]) вернет количество элементов в массиве.
Вы же об этом говорите?
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 12:09
Olej
kit_D писал(а):Ну подождите. Я всегда считал и до сих пор считаю, что
если char array[100], то sizeof(array) вернет не размер указателя, а размер массива байтах, в данном случае - 100.
Аналогично sizeof(array)/sizeof(array[0]) вернет количество элементов в массиве.
Код: Выделить всё
#include <stdio.h>
#define SIZE 6
typedef int elem_t;
void func( elem_t* MAC ) {
printf( "in func: длина массива = %d, размерность массива = %d\n",
sizeof( MAC ), sizeof( MAC ) / sizeof( MAC[ 0 ] ) );
}
int main( void ) {
elem_t MAC[ SIZE ];
printf( "in main: длина массива = %d, размерность массива = %d\n",
sizeof( MAC ), sizeof( MAC ) / sizeof( MAC[ 0 ] ) );
func( MAC );
return 0;
}
- чтоб смешнее (нагляднее) я в качестве типа элемента взял не char, а int...
Код: Выделить всё
[olej@notebook size]$ make
cc size.c -o size
[olej@notebook size]$ ./size
in main: длина массива = 24, размерность массива = 6
in func: длина массива = 4, размерность массива = 1
P.S. А для char ещё смешнее
:
Код: Выделить всё
[olej@notebook size]$ ./size
in main: длина массива = 6, размерность массива = 6
in func: длина массива = 4, размерность массива = 4
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 12:51
kit_D
Не, ну это понятно. Когда вы в функцию передаете указатель, то sizeof вернет размер указателя. Но в примере с МАК адресами такого же не происходит, мы берем sizeof от массива и вероятно компилятор понимает что именно мы имеем ввиду.
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 12:54
Olej
Olej писал(а):kit_D писал(а):Ну подождите. Я всегда считал и до сих пор считаю, что
если char array[100], то sizeof(array) вернет не размер указателя, а размер массива байтах, в данном случае - 100.
Аналогично sizeof(array)/sizeof(array[0]) вернет количество элементов в массиве.
- чтоб смешнее (нагляднее) я в качестве типа элемента взял не char, а int...
Не совсем в тему, но к тому же вопросу ... чтоб смешнее было
:
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#define SIZE 6
//typedef int elem_t;
typedef char elem_t;
struct arr { elem_t MAC[ SIZE ]; };
void str_func( struct arr data ) {
printf( "in struct: длина массива = %d, размерность массива = %d\n",
sizeof( data.MAC ), sizeof( data.MAC ) / sizeof( data.MAC[ 0 ] ) );
}
void func( elem_t* MAC ) {
printf( "in func: длина массива = %d, размерность массива = %d\n",
sizeof( MAC ), sizeof( MAC ) / sizeof( MAC[ 0 ] ) );
}
int main( void ) {
elem_t MAC[ SIZE ];
printf( "in main: длина массива = %d, размерность массива = %d\n",
sizeof( MAC ), sizeof( MAC ) / sizeof( MAC[ 0 ] ) );
func( MAC );
struct arr data;
memcpy( (void*)&data, MAC, sizeof( MAC ) );
str_func( data );
return 0;
}
Результат:
Код: Выделить всё
[olej@notebook size]$ ./size
in main: длина массива = 6, размерность массива = 6
in func: длина массива = 4, размерность массива = 4
in struct: длина массива = 6, размерность массива = 6
P.S. кому интересно убедиться будет (или развить пример) так я пример прикреплю, чтоб не бить с экрана...
P.P.S. а ещё веселее, что на это (на тот же пример) скажет компилятор Microsoft Visual C, ... а он скажет по-другому
(ещё загадочнее) ... но, может, это от версии зависит, а я смотрел последний раз году в 2007-м.
Re: простой виртуальный сетевой интерфейс
Добавлено: 09 апр 2012, 13:04
Olej
kit_D писал(а):Не, ну это понятно. Когда вы в функцию передаете указатель, то sizeof вернет размер указателя. Но в примере с МАК адресами такого же не происходит, мы берем sizeof от массива и вероятно компилятор понимает что именно мы имеем ввиду.
Но там (<linux/netdevice.h>) в struct net_device описан dev_addr как
указатель (это ядро 2.6.42):
Код: Выделить всё
/* Interface address info used in eth_type_trans() */
unsigned char *dev_addr; /* hw address, (before bcast
because most packets are
unicast) */
...
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
Возможно раньше там было описание
массивом, так же как broadcast, который имеет ... а-а-афиговенную длину
в 32 байта.