Мини-HOWTO Барта Хартгерса (Bart Hartgers) <barth@stack.nl> (подробное описание см. ниже )
Dosnet.o - модуль ядра, реализующий особое виртуальное сетевое устройство. Вместе с pktdrv.c и libpacket.c, он позволяет нескольким сессиям dosemu и ядру linux образовать виртуальную сеть. Каждая имеет собственное сетевое устройство и адрес ethernet.
Это значит, что вы можете зайти с помощью telnet или ftp из dos-сессии на telnetd/ftpd работающий на linux и, если в ядре включен IP forwarding, подключиться к любому компьютеру в сети.
Перейдите в ./src/dosext/net/v-net скомпилируйте dosnet.o. Как root, сделайте insmod dosnet.o. Снова как root, сконфигурируйте интерфейс dsn0 (например: ifconfig dsn0 192.168.74.1 netmask 255.255.255.0), и добавьте роутинг на него (например: route add -net 192.168.74.0 netmask 255.255.255.0 dsn0).
Наконец, запустите dosemu, и задайте клиенту TCP/IP IP-адрес в подсетке, которую только что сконфигурировали. Этот адрес должен быть уникальным, т.е. ни другие dosemu, ни ядро не должны иметь того же адреса. Для примера, приведенного выше, подойдут адреса 192.168.74.2-192.168.74.254. Теперь можно с помощью dos-овского telnet зайти на собственную машину!
Подробное описание, автор Vinod G Kulkarni <vinod@cse.iitb.ernet.in>
Позволяет программе иметь собственный стэк сетевых протоколов.
Как результат несколько dosemu могут использовать netware, ncsa telnet и т.д.
Возможность доступа к сети из dosemu - важное свойство. Разработчикам сетевых продуктов для PC это даст удобное средство разработки с полным контролем над трафиком без необходимости работать на нескольких разных компьютерах. Это позволит уже существующим клиент-серверным приложениям работать под досэмулятором (в предположении, что они предназначены для работы с пакетным драйвером - это сейчас ;-)
Для выполнения этого требуется, чтобы сторонние стеки протоколов сосуществовали с IP-стеком Linux. Один из способов достичь этого - добавить дополнительную сетевую карту. Однако это неуклюже и позволяет максимум 2-3 стэка. Другой способ - использовать виртуальное сетевое устройство, которое будет передавать пакеты стекам, работающим как пользовательские программы.
Нужно иметь виртуальное устройство, которое представляет собой маршрутизируемый интерфейс с одной стороны (так что со стороны Linux он выглядит сетевым устройством), а с другой стороны передает и посылает пакеты пользовательским стекам.
Все пользовательские стеки И виртуальные устройства виртуально соединены в сеть (аналог физического кабеля). Все широковещательные пакеты (отправленные как пользовательским стеком, так и интерфейсом виртуального устройства) должны быть посланы всем пользовательским стекам и маршрутизаторам. Все не-широковещательные пакеты могут посылаться непосредственно друг другу.
Каждый пользовательский стек (в данном случае DOSEmu) имеет базовый интерфейс, позволяющий передавать и принимать пакеты. Поверх него может быть построен нужный интерфейс более высокого уровня (например, пакетного драйвера). В DOSEmu эмулируется пакетный драйвер.
Каждый пользовательский стек имеет собственный виртуальный Ethernet-адрес.
Пакет включает в себя:
Скомпилируйте модуль dosnet, загрузите его (с помощью insmod), дайте ему IP адрес с новым адресом сети IP. Теперь нужно установить соответствующие таблицы маршрутизации на всех машинах, к которым вы собираетесь присоединаться. Так что интерфейс со стороны Linux прост для установки.
Замечание: Модуль использует тройку символов ядра, не экспортируемых kernel/ksyms.c в коде ядра. Вам придется либо добавить эти символы туда, либо пользоваться улучшенным 'insmod' net.h.
Это устройство - обычный загружаемый модуль (Кто-нибудь, проверьте, можно ли его сделать более эффективным). Однако, что интересно, это способ, которым он организует доступ к пользовательским стекам (dosemu), т.е. его передаточный интерфейс.
Пакет приходит в dosnet из Linux для нашей виртуальной внутренней сети (после маршрутизации). Если это широковещательный пакет, dosnet должен передать его всем dosemu/пользовательским стекам. Если это обычный пакет, он должен быть послан только определенному стеку, который имеет тот же адрес назначения ethernet.
Этот процесс производится следующим методом, с использованием интерфейса SOCK_PACKET (и без ввода новых устройств):
DOSEmu открывает SOCK_PACKET типа 'x' через устройство dosnet. Результатом этого будет добавление входа в таблицу дескрипторов для типа 'x'. Эта таблица содержит типы и соответствующие им дескрипторы функций, которые нужно вызвать при прибытии пакета данного типа.
Каждый dosemu открывает интерфейс с уникальным 'x'.
SOCK_PACKET позволяет отправить пакет "как есть". Никаких проблем.
Здесь есть трюк. Пакет просто передается устройством dosnet на вышележащий уровень. Однако, верхний уровень вызывает функцию для определения типа пакета, которая зависит от устройства (по умолчанию eth_type_trans().). Эта функция, которая возвращает тип указанного пакета, должна присутствовать для каждого устройства. Для dosnet это играет особую роль. Если пакет имеет тип 'x', верхний уровень (net/inet/dev.c) вызовет обработчик для 'x'.
Взглянув на ethernet адрес назначения пакета, мы можем заключить, что это пакет для dosemu, и его тип 'x' (т.к. 'x' "встроен" в виртуальный адрес ethernet эмулятора). Функция-обработчик для 'x' - это функция приема пакетов SOCK_PACKET, которая отсылает пакеты обратно досэмулятору.
Замечание: поле "type" расположено в адресе ethernet, а не на своем обычном месте, которое зависит от типа фрейма. Следовательно, сам пакет остается неизменным - не используется никаких функций-врапперов и т.п. Нужно брать тип 'x', который больше никем не используется, тогда пакет сможет нести _любой_ протокол, т.к. поле данных остается нетронутым.
Мы используем общий тип 'y' для широковещаний dosnet. Каждый dosemu регистрирует 'y' также, как и тип 'x' с помощью SOCK_PACKET. Это 'y' одно для всех dosemu. (Пакет дуплицируется, если более одного SOCK_PACKET запрашивают тот же тип).
Я добавил код для обработки множественных протоколов.
Когда пакет прибывает, он поступает одному из двух обработчиков SOCK_PACKET, которые нужны, чтобы определить, какой из зарегистрированных протоколов должен обрабатываться. (Предыдущие версии открывали множественные сокеты, по одному на каждый тип IPX. Теперь это не нужно, так как мы используем *любые* типы). Когда регистрируется новый тип, он добавляется к Type list. Когда прибывает пакет, сначала мы выясняем тип фрейма (и, следовательно, позицию поля типа в пакете), а затем пытаемся сопоставить с его с зарегистрированными типами. Затем вызывается обработчик в соответствии с дескриптором этого типа.
По крайней мере, мы можем запускать множественные dosemu и входить в сеть с каждого из них... Однако, вы ДОЛЖНЫ настроить ТАБЛИЦЫ МАРШРУТИЗАЦИИ и т.п.
Vinod G Kulkarni <vinod@cse.iitb.ernet.in>
[ Замечание JES : Если хотите, можете использовать ../syscallmgr/insmod Ханса с флагом -m вместо патченья ядра ]
Я забыл отметить: Ядро нужно слегка пропатчить. (Так сейчас бывает с каждым новым модулем ;-) Вот что нужно делать: единственный изменяемый файл - kernel/ksyms.c в исходниках ядра:
*** ksyms.c.old Mon Oct 10 11:12:01 1994
--- ksyms.c Mon Oct 10 11:13:31 1994
***************
*** 28,33 ****
--- 28,39 ----
#include <linux/serial.h>
#ifdef CONFIG_INET
#include <linux/netdevice.h>
+ extern unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev);
+ extern int eth_header(unsigned char *buff, struct device *dev, unsigned
+ short type, void *daddr, void *saddr, unsigned len, struct
+ sk_buff *skb);
+ extern int eth_rebuild_header(void *buff, struct device *dev, unsigned long
+ dst, struct sk_buff *skb);
#endif
#include <asm/irq.h>
***************
*** 183,188 ****
--- 189,197 ----
X(dev_rint),
X(dev_tint),
X(irq2dev_map),
+ X(eth_type_trans),
+ X(eth_header),
+ X(eth_rebuild_header),
#endif
/********************************************************
После этого, перетранслируйте ядро. Его нужно компилировать с включенной опцией "IP FORWARD" (для разрешения маршрутизации). С этим ядром 'insmod dosnet' будет работать. После этого шага 'cat /proc/net/dev' должно показать устройство dsn0.
Теперь административные вещи:
Я выполняю такие команды: (144.16.112.1 это "специальный" адрес. 'dsn0' - имя нового интерфейса.)
ifconfig dsn0 144.16.112.1 broadcast 144.16.112.255 netmask 255.255.255.0
route add -net 144.16.112.0 dsn0
Скомпилируйте dosemu с новыми pktnew.c и libpacket.c (их нужно положить в каталог net). Запустите dosemu. Теперь можно запустить 'telbin 144.16.112.1' после присвоения IP адреса (скажем, 144.16.112.10) для dosemu в файле CONFIG.TEL. Каждый процесс dosemu должен получить новый IP адрес.
На других машинах должна быть маршрутизация на эту "новую" сеть. Простейший способ - это установить статическую маршрутизацию для IP-сети dosnet на машинах, на которые вы хотите заходить. После того, как прошли все тесты, можно сделать ее постоянной (в конфигурации gated и т.п.). Однако, "новые" адреса должны быть внутренними для вашей арганизации и не должны выходить наружу. На эту тему есть соответствующий RFC. Как пример, я работаю на 144.16.98.20. Внутренняя сеть, которую я создал - 144.16.112.0 (см. команду route выше по тексту). Для подключения к другому компьютеру 144.16.98.26 из dosemu я включаю статическую маршрутизацию командой 'route add -net 144.16.112.0 gw 144.16.98.20' на этом компьютере. Дополнительные сложности появляются, если вам понадобиться выходить за пределыы сети 144.16.98.0.
Поскольку dosemu теперь на "отдельном устройстве", IPX должен переправляться (bridge) или маршрутизироваться (route). В первом случае не требуется никакого дополнительного администрирования, просто запустите программу 'ipxbridge', прилагаемую к исходным текстам dosnet. (Есть две версии; 0.1 копирует все пакеты между обоими интерфейсами. 0.2 "интеллектуальна", она копирует пакет в другой интерфейс только если адрес назначения лежит за этим интерфейсом)
Если вы хотите использовать маршрутизацию IPX, то нужно включить IPX в ядре. Затем, нужно выбрать номер сети, который не будет конфликтовать с другими. Установите статические маршруты IPX на Linux, а затем на одном из серверов Novell netware, который присоединен непосредственно, без промежуточных роутеров (Здесь нужно связаться с администратором Novell). Идея в том, что сервер работает как route broadcaster. (Я это еще не тестировал, и мы работаем над получением программ, которые сделают Linux нормальным IPX-маршрутизатором.)
Надеюсь, это поможет
Vinod.
Я только что понял еще одно: ipxbridge-0.2 считает, что у вас есть два интерфейса - 'eth0' и 'eth1' и использует этот факт при решении, в какой интерфейс направить пакет. Так что он не заметит, когда будет использоваться 'dsn0'.
ipxbridge-0.1 все-таки будет работать.
Также учтите, что обе программы переводят плату в promiscuous mode.
Так что мой совет - "как нибудь" заставить IPX маршрутизироваться linux-ом!
Vinod.