Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Локальные сети персональных компьютеров. Использование протоколов IPX, SPX, NETBIOS

© Александр Фролов, Григорий Фролов
Том 4, М.: Диалог-МИФИ, 1993, 160 стр.

[Назад] [Содеожание] [Дальше]

4.2. Работа с протоколом NETBIOS

Протокол NETBIOS предоставляет программам интерфейс для передачи данных на уровне датаграмм и на уровне каналов связи. Для вызова NETBIOS программа должна создать в памяти управляющий блок, который называется NCB (Network Control Block - сетевой управляющий блок). Адрес заполненного блока NCB передается прерыванию INT 5Ch, в рамках которого и реализован интерфейс протокола NETBIOS. Есть также альтернативный интерфейс, реализованный в рамках прерывания INT 2Ah, который поддерживается эмулятором NETBIOS, разработанным фирмой Novell, а также операционной системой Windows for Workgroups версии 3.1.

4.2.1. Проверка присутствия NETBIOS

Первое, что должна сделать программа, желающая воспользоваться протоколом NETBIOS, - проверить наличие в системе интерфейса NETBIOS.

Ниже приведена программа, которая определяет, установлен ли драйвер NETBIOS.

С помощью функции getvect() программа получает указатель на обработчик прерывания INT 5Ch. Это прерывание используется для вызова NETBIOS. Если сегментная компонента адреса равна нулю или F000h, обработчик прерывания не установлен или установлена заглушка, расположенная в BIOS. В этом случае программа считает, что NETBIOS отсутствует.

// ===================================================
// Листинг 16. Проверка присутствия NETBIOS
//
// Файл nbver.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <mem.h>
#include <string.h>

void main(void) {
        void interrupt ( *int5C)(...);

        printf("Check if NETBIOS is installed\n");
        int5C = getvect(0x5c);
        if(FP_SEG(int5C) == 0x0000 || FP_SEG(int5C) == 0xF000) {
                printf("NETBIOS NOT installed.\n");
        }
        else printf("NETBIOS is installed!\n");

}

Другой способ проверки наличия интерфейса NETBIOS заключается в вызове прерывания INT 2Ah. Загрузите в регистр AH нулевое значение и вызовите прерывание INT 2Ah. Если после возврата из прерывания в регистре AH
попрежнему находится нуль, драйвер NETBIOS не установлен.

Данный способ проверки будет работать на виртуальной машине DOS, запущенной в среде Windows for Workgroups версии 3.1 (если Windows работает в расширенном режиме).

Приведенная ниже программа определяет присутствие NETBIOS с помощью вызова прерывания INT 2Ah (листинг 17):

// ===================================================
// Листинг 17. Проверка присутствия NETBIOS
//             с использованием интерфейса INT 2Ah
//
// Файл 2atest.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <mem.h>
#include <string.h>

void main(void) {

        union REGS regs;

        printf("Check if NETBIOS is installed\n");

        regs.h.ah = 0;
        int86(0x2a, &regs, &regs);

        if(regs.h.ah  == 0) {
                printf("NETBIOS NOT installed.\n");
        }
        else printf("NETBIOS is installed!\n");

}

Прерывание INT 2Ah используется в сетях фирм Microsoft и Lantastic. Эмулятор протокола NETBIOS, поставляющийся фирмой Novell вместе с операционной системой Novell NetWare, поддерживает как интерфейс прерывания INT 5Ch, так и интерфейс INT 2Ah.

4.2.2. Вызов команд протокола NETBIOS

Интерфейс протокола NETBIOS реализован в рамках прерывания INT 5Ch или INT 2Ah и очень прост.

Для вызова команд протокола NETBIOS вам достаточно подготовить блок NCB, загрузить его дальний адрес в регистры ES:BX и вызвать прерывание INT 5Ch.

Приведем формат вызова функции прерывания INT 2Ah, предназначенной для выполнения команд NETBIOS:

На входе: AH = 04h.
AL = Признак автоматического повтора команды при получении кодов ошибки 09h (недостаточно ресурсов), 12h (создание канала отвергнуто, так как на другом конце
не выдана команда NB_Listen), 21h (занят интерфейс):
00h - повторять команду;
FFh - не повторять команду.
ES:BX = Адрес заполненного блока NCB.
На выходе: AH = Код завершения:
00h - команда выполнилась без ошибок;
01h - при выполнении команды были ошибки.
AL = Если содержимое регистра AH после возврата из прерывания не равно нулю, регистр AL содержит код ошибки.

Вы можете использовать описанный выше вызов прерывания INT 2A для вызова NETBIOS из программы, работающей на виртуальной машине Windows for Workgroups версии 3.1.

Для вызова команд протокола NETBIOS из пограммы, составленной на языке Си, вы можете воспользоваться обычными средствами вызова программных прерываний, такими, как функция int86x().

4.2.3. Формат блока NCB

Приведем формат блока NCB:

struct _NCB {
        unsigned char Cmd;
        unsigned char CCode;
        unsigned char LocalSessionNumber;
        unsigned char NetworkNameNumber;
        void far *Buffer;
        unsigned Size;
        char CallName[16];
        char OurName[16];
        unsigned char ReceiveTimeout;
        unsigned char SendTimeout;
        void interrupt (*PostRoutine)(void);
        unsigned char AdapterNumber;
        unsigned char FinalCCode;
        unsigned char Reserved[14];
};

Поле Cmd содержит код команды, которую необходимо выполнить. Существуют команды для работы с именами станций, для передачи и приема дата-
грамм, для работы на уровне каналов и некоторые другие. Мы рассмотрим
команды NETBIOS в следующем разделе.

Поле CCode содержит код ошибки, возвращаемый NETBIOS до выполнения команды. Если, например, программа затребовала выполнение неправильной команды или задала для команды неправильные параметры, NETBIOS не будет выполнять такую команду и установит в поле CCode соответствующий код ошибки. Если же в этом поле после вызова NETBIOS находится нулевое значение, это еще не означает, что команда выполнилась правильно, однако она начала выполняться.

Поле LocalSessionNumber содержит номер канала, установленного с другой программой. Это поле необходимо заполнять при выдаче команд передачи данных через каналы.

Поле NetworkNameNumber содержит номер имени, который присваивается при добавлении обычного или группового имени. Это поле должно быть заполнено при приеме датаграмм.

Поле Buffer представляет собой дальний указатель в формате [сегмент:смещение] на буфер, который должен содержать данные перед выполнением передачи или на буфер, который будет использован для приема данных.

Размер буфера, используемого для приема или передачи данных, определяется содержимым поля Size.

Поле CallName заполняется именем станции, с которой ваша станция желает установить канал для передачи данных.

Поле OurName должно содержать имя вашей программы, под которым она будет принимать данные. В качестве этого имени может выступать обычное, групповое или постоянное имя.

Поля ReceiveTimeout и SendTimeout содержат интервал времени (измеряемый в 1/2 с), в течение которого ожидается завершение соответственно команд приема и передачи.

Поле PostRoutine - указатель на программу, которая получает управление после завершения команды. Эта программа (POST-программа) аналогична программе ESR протоколов IPX/SPX и вызывается только в том случае, если в поле PostRoutine был указан адрес программы. Если же это поле заполнить нулями, никакая программа вызываться не будет.

Поле AdapterNumber используется, если в станции установлено несколько сетевых адаптеров (в сетях Ethernet этого обычно не бывает). В этом поле указывается номер адаптера, для которого предназначена команда. Первый адаптер имеет номер 0, второй - 1.

Поле FinalCCode содержит во время выполнения команды значение 0xFF. После завершения выполнения команды в это поле записывается код ошибки, который относится к выполнению команды в целом (в отличие от кода в поле CCode). Если ваша программа не задала адрес для программы в поле PostRoutine, она должна опрашивать в цикле содержимое этого поля, ожидая, пока в нем не появится значение, отличное от 0xFF.

Поле Reserved зарезервировано для использования протоколом NETBIOS, ваша программа не должна изменять его содержимое.

4.2.4. POST-программа

POST-программа является программой обработки прерывания. Она получает управление в состоянии с запрещенными прерываниями. Регистры ES:BX содержат адрес блока NCB, который использовался при выполнении команды.
В регистр AL записано значение из поля FinalCCode блока NCB.

Учтите, что, как и из любой другой программы обработки прерывания, из POST-программы не следует вызывать функции MS-DOS.

Требования к POST-программе во многом такие же, как и к ESR-программе, используемой протоколами IPX и SPX. Она должна позаботиться о сохранении изменяемых регистров, установить регистр DS на сегмент данных программы (для обеспечения доступа к переменным). POST-программа должна работать как можно быстрее. Лучше всего если она будет использоваться только для установки флага, сигнализирующего основной программе о завершении выполнения команды.

Перед завершением своей работы POST-программа должна восстановить содержимое всех регистров и выполнить команду возврата из прерывания IRET.

Если вы составляете POST-программу на языке программирования Си, вы можете воспользоваться ключевым словом interrupt:

void interrupt NETBIOS_Post_Routine(void);

Лучше всего составить POST-программу на языке ассемблера, например, так:

.286
.MODEL SMALL

.DATA

        _completed_ncb_ptr dd 0

.CODE

        PUBLIC   _netbios_post
        PUBLIC  _completed_ncb_ptr

_netbios_post PROC FAR

                push ax
                push    ds
                push es
                push si

                mov     ax, DGROUP
                mov     ds, ax

                mov     word ptr _completed_ncb_ptr+2, es
                mov     word ptr _completed_ncb_ptr, si

                pop     si
                pop     es
                pop     ds
                pop     ax

                iret
_netbios_post ENDP

end

[Назад] [Содеожание] [Дальше]