Использование драйвера IPX/SPX в сети Novell Netware

Модератор: push0ret

Ответить
Аватара пользователя
push0ret
Набирающий обороты
Сообщения: 27
Зарегистрирован: Вс дек 29, 2024 2:48 pm
Благодарил (а): 16 раз
Поблагодарили: 26 раз

Использование драйвера IPX/SPX в сети Novell Netware

Сообщение push0ret »

Hello World!

Ранее я уже рассказал про структуру протокола IPX. Пора начать использовать драйвер IPX/SPX из набора программного обеспечения "NetWare C-Interface for DOS". В этой теме опишу функции драйвера IPX/SPX, а также расскажу как его использовать при помощи языка ассемблера. Их названия набора программного обеспечения можно понять, что данный драйвер подразумевает то, что будет использоваться с помощью языка С, я же буду использовать язык ассемблера.

Инициализация драйвера в программе

Для начала работы с функциями драйвера IPX/SPX необходимо получить адрес резидентной программы, которую загружает в память драйвер. Для этого используем мультиплексное прерывание 2Fh с параметром в регистре AX = 7A00h. Если после выполнения прерывания регистр AL будет равен 0FFh, то драйвер IPX загружен и с ним можно работать, адрес точки входа (дальний адрес резидентной программы) будет записан в регистрах ES:DI, его необходимо сохранить для последующего использования. Процедура инициализации драйвера IPX:

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

.286
.model	tiny
code	segment
org	100h

init_ipx:

mov ax, 7A00h
int 2Fh

cmp al, 0FFh
jnz exit

mov ipx_entry, di
mov ipx_entry+2, es

exit:

mov ax, 4C00h
int 21h

ipx_entry	dw	2d dup(0)

code	ends
end	init_ipx
Теперь мы знаем в какой области памяти находится процедура драйвера IPX/SPX и можем использовать функции драйвера.

Структура для работы с драйвером IPX/SPX

Взаимодействие программы с драйвером происходит с помощью структуры ECB (Event control block). Структура имеет следующий вид:
ecb.PNG
ecb.PNG (18.67 КБ) 79 просмотров
При использовании языка С, структуру можно объявить таким образом:

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

struct ECB {
                void far        *Link;
                void far        (*ESRAddress)(void);
                unsigned char   InUse;
                unsigned char   CCode;
                unsigned int    Socket;
                unsigned int    ConnectionId;
                unsigned int    RrestOfWorkspace;
                unsigned char   DriverWorkspace[12];
                unsigned char   ImmAddress[6];
                unsigned int    FragmentCnt;
                struct {
                        void far        *Address;
                        unsigned int Size;
                } Packet[2];
};
При использовании языка ассемблера, структуру можно объявить так:

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

ECB	struc

Link		dw	2d dup(0)
ESRAddress	dw	2d dup(0)
InUse		db	?
CCode		db	?
Socket		dw	?
IPXWorkspace	db	4d dup(0)
DrvWorkspace	db	12d dup(0)
ImmAdress	db	6d dup(0)
FragmentCnt	dw	?
Address		dw	2d dup(0)
Size_		dw	?

ECB		ends
Перед тем как вызвать функцию IPX, программа записывает в поле InUse нулевое значение. Пока операция приёма или передачи данных, связанная с данным ECB, не завершилась, поле InUse содержит ненулевые значения:

FFh ECB используется для передачи пакета данных;
FEh ECB используется для приема пакета данных, предназначенного программе с определенным сокетом;
FDh ECB используется функциями асинхронного управления событиями AES (Asynchronous Event Sheduler), ECB
находится в состоянии ожидания истечения заданного временного интервала;
FBh пакет данных принят или передан, но ECB находится во внутренней очереди IPX в ожидании завершения обработки.

Если блок ECB использовался для приема пакета, то в поле CCode могут находиться следующие значения:

00 пакет был принят без ошибок;
FFh указанный в ECB сокет не был предварительно открыт программой;
FDh переполнение пакета: либо поле количества фрагментов в пакете FragmentCnt равно нулю, либо буферы, описанные дескрипторами фрагментов, имеют недостаточный размер для записи принятого пакета;
FCh запрос на прием данного пакета был отменен специальной функцией драйвера IPX.

Если ECB использовался для передачи пакета, в поле CCode после завершения передачи могут находиться следующие значения:

00 пакет был передан без ошибок (что, кстати, не означает, что пакет был доставлен по назначению и успешно принят станцией-адресатом, так как протокол IPX не обеспечивает гарантированной доставки пакетов);
FFh пакет невозможно передать физически из-за неисправности в сетевом адаптере или в сети;
FEh пакет невозможно доставить по назначению, так как станция с указанным адресом не существует или неисправна;
FDh сбойный: либо имеет длину меньше 30 байт, либо первый фрагмент пакета по размеру меньше размера стандартного заголовка пакета IPX, либо поле количества фрагментов в пакете FragmentCnt равно нулю;
FCh запрос на передачу данного пакета был отменен специальной функцией драйвера IPX.

Также необходимо объявлять в программе структуру пакета, т.к. её адрес и размер указываются в полях Adress и Size структуры ECB, структура пакета IPX была показана здесь: viewtopic.php?t=366

Описание функций драйвера IPX/SPX

IPXOpenSocket

Параметры:

BX = 0
AL = тип сокета (0 - короткоживущий, 0FFh - долгоживущий)
DX = запрашиваемый номер сокета или 0, если хотим получить динамический номер сокета

Возвращаемые значения:

AL = результат работы функции (0 - сокет открыт, 0FFh - сокет уже был открыт раньше, 0FEh - таблица сокетов переполнена)
DX = присвоенный номер сокета

Данная процедура открывает сокет, желательно номер открытого сокета записать куда-либо.

IPXCloseSocket

Параметры:

BX = 1d
DX = номер закрываемого сокета

Не сложно догадаться для чего нужна эта функция, для того, чтобы закрыть ранее открытый сокет.

IPXListenForPacket

Параметры:

BX = 4d
ES:DI = адрес заполненного блока ECB

В блоке ECB необходимо заполнить поля:

ESRAddress;
Socket;
FragmentCnt;
Address;
Size.

После прихода пакета в поле CCode использованного блока ECB драйвер IPX записывает код результата приема пакета, а в поле ImmAddress - адрес станции, которая прислала пакет. Если пакет пришел из другой сети, в этом поле будет записан адрес моста.

IPXSendPacket

Параметры:

BX = 3d
ES:DI = адрес заполненного блока ECB

В блоке ECB необходимо заполнить поля:

ESRAddress;
Socket;
ImmAddress;
FragmentCnt;
Address;
Size.

Также необходимо заполнить структуру пакета IPX, а конкретно поля:

PacketType;
DestNetwork;
DestNode;
DestSocket.

Сразу после вызова функции IPXSendPacket в поле InUse записывается значение FFh. После завершения процесса передачи пакета в поле InUse записывается значение 00h. Результат выполнения передачи пакета можно узнать, если из поля CCode.

Пример использования функции драйвера IPX/SPX:

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

.model	tiny
code	segment
org	100h

start

;Init IPX

pusha

mov ax, 7A00h
int 2Fh

cmp al, 0FFh
jnz exit

;Write adress of resident program

mov ipx_entry, di
mov ipx_entry+2, es

popa

;Open socket

pusha

xor bx, bx
mov dx, 4001h
xor ax, ax
call dword ptr [ipx_entry]

popa

exit:

mov ax, 4C00h
int 21h

ipx_entry	dw	2d dup(0)

code	ends
end	start
Привёл в пример использование функции открытия сокета, я описал все функции, которыми пользовался сам, на самом деле функций больше, можно посмотреть в документации "NetWare C-Interface for DOS".

Была использована версия компилятора MASM 6.11 в контексте операционной системы MS-DOS 6.22, а также набор программ от Novell Netware Client.

Спасибо за внимание!
С уважением, push0ret!
Ответить

Вернуться в «Системное программирование»