Назад Вперед Оглавление

17. Работа с сетью в DOSEmu

Мини-HOWTO Барта Хартгерса (Bart Hartgers) <barth@stack.nl> (подробное описание см. ниже )

17.1 Виртуальное устройство DOSNET.

Dosnet.o - модуль ядра, реализующий особое виртуальное сетевое устройство. Вместе с pktdrv.c и libpacket.c, он позволяет нескольким сессиям dosemu и ядру linux образовать виртуальную сеть. Каждая имеет собственное сетевое устройство и адрес ethernet.

Это значит, что вы можете зайти с помощью telnet или ftp из dos-сессии на telnetd/ftpd работающий на linux и, если в ядре включен IP forwarding, подключиться к любому компьютеру в сети.

17.2 Установка виртуального TCP/IP

Перейдите в ./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 зайти на собственную машину!

17.3 Подробное описание

Подробное описание, автор Vinod G Kulkarni <vinod@cse.iitb.ernet.in>

Позволяет программе иметь собственный стэк сетевых протоколов.

Как результат несколько dosemu могут использовать netware, ncsa telnet и т.д.

Введение

Возможность доступа к сети из dosemu - важное свойство. Разработчикам сетевых продуктов для PC это даст удобное средство разработки с полным контролем над трафиком без необходимости работать на нескольких разных компьютерах. Это позволит уже существующим клиент-серверным приложениям работать под досэмулятором (в предположении, что они предназначены для работы с пакетным драйвером - это сейчас ;-)

Для выполнения этого требуется, чтобы сторонние стеки протоколов сосуществовали с IP-стеком Linux. Один из способов достичь этого - добавить дополнительную сетевую карту. Однако это неуклюже и позволяет максимум 2-3 стэка. Другой способ - использовать виртуальное сетевое устройство, которое будет передавать пакеты стекам, работающим как пользовательские программы.

Основные идеи

Нужно иметь виртуальное устройство, которое представляет собой маршрутизируемый интерфейс с одной стороны (так что со стороны Linux он выглядит сетевым устройством), а с другой стороны передает и посылает пакеты пользовательским стекам.

Все пользовательские стеки И виртуальные устройства виртуально соединены в сеть (аналог физического кабеля). Все широковещательные пакеты (отправленные как пользовательским стеком, так и интерфейсом виртуального устройства) должны быть посланы всем пользовательским стекам и маршрутизаторам. Все не-широковещательные пакеты могут посылаться непосредственно друг другу.

Каждый пользовательский стек (в данном случае DOSEmu) имеет базовый интерфейс, позволяющий передавать и принимать пакеты. Поверх него может быть построен нужный интерфейс более высокого уровня (например, пакетного драйвера). В DOSEmu эмулируется пакетный драйвер.

Каждый пользовательский стек имеет собственный виртуальный Ethernet-адрес.

Реализация

Пакет включает в себя:

  1. Модуль dosnet. Работает как виртуальное сетевое устройство, представляющее интерфейс 'dsn0'. Он предоставляет основной сетевой интерфейс И также возможность обмена с другими dosemu.
  2. Модифицированный пакетный драйвер (файлы pktnew.c and libdosemu.c) для взаимодействия с dosnet. Модификация включает следующее:
    1. Генерация уникального адреса ethernet для каждого dosemu. Я использовал младшую часть (минор) номера терминала (tty) как часть адреса. Это работает, если не запускать два dosemu на одном и том же терминале.
    2. Взаимодействие с устройством dosnet происводится через открытие сокета SOCK_PACKET специального типа.
  3. Программный код для передачи пакетов (IPX bridge) между eth0 и dsn0 для множественного доступа к сети. Версия 0.1 не интеллектуальная, обе версии в стадии альфа-тестирования. На самом деле маршрутизация IPX имеется в ядре. Кому-нибудь удалось ее использовать? Еще одна альтернатива - использование IP-туннелирования пакетов IPX (в соответствии с RFC 1234). У Novell есть соответствующая NLM для использования со стороны NetWare. Со стороны Linux нужно запускать процесс, реализующий этот RFC.

Виртуальное устройство 'dsn0'

Скомпилируйте модуль dosnet, загрузите его (с помощью insmod), дайте ему IP адрес с новым адресом сети IP. Теперь нужно установить соответствующие таблицы маршрутизации на всех машинах, к которым вы собираетесь присоединаться. Так что интерфейс со стороны Linux прост для установки.

Замечание: Модуль использует тройку символов ядра, не экспортируемых kernel/ksyms.c в коде ядра. Вам придется либо добавить эти символы туда, либо пользоваться улучшенным 'insmod' syscall Manager). В этом случае, модуль извлечет эти символы из из файла zSystem.map.

Это устройство получает виртуальный адрес ethernet, заданный в dosnet.h.

Это устройство - обычный загружаемый модуль (Кто-нибудь, проверьте, можно ли его сделать более эффективным). Однако, что интересно, это способ, которым он организует доступ к пользовательским стекам (dosemu), т.е. его передаточный интерфейс.

Пакет приходит в dosnet из Linux для нашей виртуальной внутренней сети (после маршрутизации). Если это широковещательный пакет, dosnet должен передать его всем dosemu/пользовательским стекам. Если это обычный пакет, он должен быть послан только определенному стеку, который имеет тот же адрес назначения ethernet.

Этот процесс производится следующим методом, с использованием интерфейса SOCK_PACKET (и без ввода новых устройств):

DOSEmu открывает SOCK_PACKET типа 'x' через устройство dosnet. Результатом этого будет добавление входа в таблицу дескрипторов для типа 'x'. Эта таблица содержит типы и соответствующие им дескрипторы функций, которые нужно вызвать при прибытии пакета данного типа.

Каждый dosemu открывает интерфейс с уникальным 'x'.

отправка пакетов из dosemu в dosnet

SOCK_PACKET позволяет отправить пакет "как есть". Никаких проблем.

dosnet -> dosemu

Здесь есть трюк. Пакет просто передается устройством 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>


Примечание переводчика:Похоже, это тоже устаревший кусок, судя по дате "заплаты" - 94й год! Лучше ничего в ядре не трогайте...


        From macleajb@ednet.ns.ca Mon Oct 10 06:16:35 1994

        Return-Path: <macleajb@ednet.ns.ca>

        

        Я компилирую dosnet.c командой :

        cc -o dosnet.o  -D__KERNEL__ -DLINUX -O6 dosnet.c -c

        а insmod заявляет:

        _eth_type_trans undefined

        _eth_header undefined

        _eth_rebuild_header undefined

[ Замечание 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.

Доступ к Novell netware

Поскольку 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.


Назад Вперед Оглавление
Перевод: Валерий Груздев (grue@vpti.vladimir.ru)

Banner.Novgorod.Ru