Набор протоколов IPX/SPX
В пункте 2.1.1 отмечалось, что взаимодействие между станциями осуществляется с помощью кадров. Пакет является частью кадра и имеет свой заголовок. В дальнейшем под протоколом будем понимать системную программу, которая обрабатывает определённые поля кадра.
NetWare поддерживает следующие уровни протоколов в классификации OSI:
Для рабочей станции с ОС DOS протоколы IPX и SPX входят в состав программы IPXODI.COM, которая загружается с помощью bat-файла STARTNET.BAT.
Протокол IPX (Internetwork Packet Exchange) обрабатывает так называемый пакет IPX, являющийся основным средством, которое используется при передаче данных в сетях NetWare. Формат пакета IPX представлен на рис 2.14.
Все поля, указанные на рис 2.14, кроме последнего (Data), образуют заголовок пакета. Особенностью формата пакета является то, что все поля заголовка содержат значения в перевёрнутом формате: по младшему адресу записывается старший байт данных.
Рассмотрим подробнее назначение отдельных полей пакета.
Поле Checksum предназначено для хранения контрольной суммы пакета или другой служебной информации. В прикладных программах обычно не используется.
2 | Checksum | - | контрольная сумма
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | Length | - | общая длина пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | TransportControl | - | счетчик пройденных маршрутизаторов | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | PacketType | - | тип пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | DestNetwork | - | номер сети получателя пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | DestNode | - | адрес станции-получателя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | DestSocket | - | гнездо программы-получателя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | SourceNetwork | - | номер сети отправителя пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | SourceNode | - | адрес станции-отправителя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | SourceSocket | - | гнездо программы-отправителя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
длина | Data | - | передаваемые данные |
Рис. 2.14. Структура пакета IPX
Поле Length определяет общий размер пакета вместе с заголовком. NetWare поддерживает следующие максимальные длины пакетов: Token Ring и ARCnet - 4202 байта, Ethernet - 1514 байтов.
Это поле устанавливается протоколом IPX передающей станции.
Поле TransportControl служит как бы счетчиком маршрутизаторов, которые проходит пакет на своём пути от передающей станции к принимающей. В начале это поле устанавливается в 0 протоколом IPX передающей станции.
Поле PacketType определяет тип передаваемого пакета. Программа, которая передаёт пакет средствами IPX, должна записывать в это поле значение 0х04.
Поле DestNetwork определяет номер сети, в которую передаётся пакет. Устанавливается в прикладной программе. Если в поле указывается нулевое значение, то пакет предаётся в сеть (сегмент), к которой подключена станция.
Поле DestNode определяет адрес станции, которой предназначен пакет. Устанавливается прикладной программой. Если пакет предназначен всем станциям в сети (сегменте), то в поле указывается значение FFFFFFFFh.
Поле DestSocket предназначено для определения программы, которая запущена на станции-получателе и должна принять пакет. Это поле устанавливается в прикладной программе.
Поля SourceNetwork, SourceNode, SourceSocket содержат соответственно номер сети, из которой посылается пакет, адрес передающей станции и гнездо программы, которая передаёт пакет. Эти поля заполняются протоколом IPX передающей станции.
Поле Data в пакете IPX содержит передаваемые данные. Это поле формируется протоколом IPX передающей станции на основании описания блока ECB (рисунок 2.15).
Блок ECB состоит из фиксированной части размером 36 байтов и массива дескрипторов, описывающих отдельные фрагменты передаваемого или принимаемого пакета данных.
Рассмотрим назначение отдельных полей блока ECB.
Поле Link предназначено для организации списков, состоящих из блоков ECB. Устанавливается протоколом IPX.
Поле ESRAddress содержит адрес программного модуля, который получает управление при завершении процесса чтения или передачи пакета IPX. При необходимости устанавливается прикладной программой.
Поле InUse служит индикатором завершения операции приёма или передачи пакета.
Вначале устанавливается в 0 прикладной программой.
Поле Ccode содержит код результата выполнения функции API-интерфейса.
4 | Link | - | указатель на следующий ECB | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | ESRAddress | - | адрес программы ESR | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | InUse | - | флаг состояния ECB | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | CCode | - | код завершения запроса | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | Socket | - | номер гнезда для приёма или передачи | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | IPXWorkspace | - | рабочий буфер для IPX | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
12 | DriverWorkspace | - | рабочий буфер | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | ImmAddress | - | адрес той станции сегмента, которой непосредственно передаётся пакет | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | FragmentCnt | - | количество фрагментов в пакете. Каждая следующая пара полей образует дескриптор фрагмента | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | Address | - | адрес 1-го фрагмента | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | Size | - | размер 1-го фрагмента | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | Address | - | адрес 2-го фрагмента | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | Size | - | размер 2-го фрагмента | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...... | ........ | и так далее |
Поле Socket содержит номер гнезда. Если ECB используется для приёма, то это поле должно содержать номер гнезда принимающей программы. Если ECB используется для передачи, то поле содержит номер гнезда передающей программы. Заполняется в прикладной программе и используется протоколом IPX для заполнения поля SourceSocket пакета IPX (рисунок 2.14).
Поля IPXWorkspace и DriverWorkspace зарезервированы для использования протоколом IPX.
Поле ImmAddress содержит при передаче адрес узла сегмента, куда непосредственно будет направлен пакет. Если пакет передаётся в пределах одного сегмента, поле содержит адрес станции-получателя (такой же, как и в поле DestNode заголовка пакета IPX). Если пакет предназначен для другого сегмента и будет проходить через маршрутизатор, поле ImmAddress содержит адрес этого маршрутизатора. Если пакет предназначен всем узлам сегмента, то в поле указывается значение FFFFFFFFh. При передаче пакета это поле заполняется в прикладной программе. Важно отметить, что значение этого поля используется драйвером сетевого адаптера для формирования адреса-получателя в заголовке кадра.
При приёме поле ImmAddress содержит адрес станции сегмента, от которой пришёл пакет.
В этом случае поле заполняется протоколом IPX. Следует отметить, что этот адрес станции выбирается из заголовка кадра (поле "адрес отправителя") и, как правило, используется прикладной программой для передачи ответа.
Поле FragmentCnt устанавливается прикладной программой и содержит количество фрагментов, на которое надо разбить принятый пакет или из которых надо собрать передаваемый пакет. Т. е. в программе можно указать отдельные буферы для приёма/передачи заголовка и данных пакета. В этом случае значение поля FragmentCnt должно быть равно 2.
Таблица 2.3. Примитивы API-интерфейсов для работы по протоколу IPX
Примитив | Описание | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXOpenSocket | Открыть гнездо. Вход - тип гнезда, номер открываемого гнезда. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXCloseSocket | Закрыть гнездо. Вход - номер закрываемого гнезда | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXGetLocalTarget | Применяется для вычисления значения непосредственного адреса. Вход - адрес 12-байтового поля с полным адресом конечной станции-назначения (номер сети - 4 байта, адрес станции - 6 байтов, номер гнезда - 2 байта). Выход - значение адреса той станции сегмента (например, маршрутизатора или файлового сервера), которой непосредственно передаётся пакет (значение поля ImmAddress блока ECB). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXGetInternetworkAddress | С помощью этого примитива программа может узнать сетевой адрес станции, на которой она работает. Выход - 10-байтовый адрес станции (номер сети - 4 байта, адрес станции - 6 байтов). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXListenForPacket (для программы на рабочей станции) IPXReceive (для NLM-модуля) | Используется для приёма пакета из сети. Вход - адрес блока ECB. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXSendPacket (для программы на рабочей станции) IPXSend (для NLM-модуля) | Используется для передачи пакета в сеть. Вход - адрес блока ECB. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IPXRelinquishControl (для программы на рабочей станции) ThreadSwitch (для NLM-модуля) | Используется, чтобы освободить процессор для выделения процессорного времени протоколу IPX. Применяется в том случае, если поле InUse блока ECB (рисунок 2.15) в цикле опрашивается прикладной программой. |
Фирма Novell предлагает API- интерфейсы для работы по протоколу IPX на рабочей станции и файловом сервере. В таблице 2.3 перечислены примитивы (функции) этих интерфейсов.
Как видно из таблицы 2.3, имена многих примитивов совпадают для программ на рабочей станции и для NLM-модулей файлового сервера.
Следует отметить, что для поддержки на файловом сервере служб протокола IPX используется библиотека CLIB.NLM. Для организации доступа к этим службам следует дополнительно загрузить NLM-модуль IPXS.NLM в стек протоколов, основанных на STREAMS.
Протокол IPX определяет самый быстрый уровень передачи данных в сетях NetWare. Он относится к классу датаграммных протоколов типа "точка-точка" без установления соединения. Это означает, что вашей прикладной программе не требуется устанавливать специальное соединение с получателем. Впрочем IPX имеет несколько недостатков:
Т. е. обработка ошибок, возникающих при передаче пакетов IPX, возлагается на прикладную программу, принимающую пакеты.
Указанных недостатков не имеет протокол транспортного уровня SPX (Sequenced Packet eXchange), ориентированный на установление соединения. Протокол SPX обрабатывает пакет SPX, формат которого представлен на рисунке 2.16.
2 | Checksum | - | ПОЛЯ IPX контрольная сумма | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | Length | - | общая длина пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | TransportControl | - | счетчик пройденных маршрутизаторов | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | PacketType | - | тип пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | DestNetwork | - | номер сети получателя пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | DestNode | - | адрес станции-получателя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | DestSocket | - | гнездо программы-получателя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | SourceNetwork | - | номер сети отправителя пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | SourceNode | - | адрес станции-отправителя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | SourceSocket | - | гнездо программы-отправителя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | ConnControl | - | ПОЛЯ SPX управление потоком данных | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | DataStreamType | - | тип данных в пакете | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | SourceConnID | - | идентификатор канала отправителя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | DestConnID | - | идентификатор канала получателя | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | SeqNumber | - | счётчик переданных пакетов | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | AckNumber | - | номер следующего пакета | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | AllocNumber | - | количество буферов для приёма | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
длина | Data | - | передаваемые данные |
Рис. 2.16. Структура пакета SPX
Первые десять полей пакета совпадают с заголовком пакета IPX. Рассмотрим остальные поля заголовка SPX.
Поле ConnControl содержит набор битовых флагов, управляющих передачей данных по каналу SPX.
Поле DataStreamType также состоит из однобитовых флагов, которые используются для классификации данных, передаваемых или принимаемых при помощи протокола SPX.
Поле SourceConnID содержит номер канала связи передающей программы, присвоенный протоколом SPX при создании канала связи. Полем управляет протокол SPX.
Поле DestConnID содержит номер канала связи принимающей стороны. Так как все пакеты, приходящие на один номер гнезда, могут принадлежать разным каналам связи (на одном гнезде можно открыть несколько каналов связи), то приходящие пакеты следует классифицировать по номеру канала связи. Полем управляет протокол SPX.
Поле SeqNumber содержит счётчик пакетов, переданных по каналу в одном направлении. На каждой стороне канала используется свой счётчик. При достижении значения FFFFh счётчик сбрасывается в 0, после чего процесс счёта продолжается. Содержимым поля управляет протокол SPX.
Поле AckNumber содержит номер следующего пакета, который должен быть принят протоколом SPX. Содержимым этого поля управляет протокол SPX.
Поле AllocNumber содержит количество буферов, отведенных программой для приёма пакетов. Содержимым этого поля управляет протокол SPX.
Таблица 2.4. Примитивы API-интерфейсов для работы по протоколу SPX
Примитив | Описание | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXListenForConnection | Используется в паре с функцией SPXEstablishConnection для образования канала связи. Вход - адрес блока ECB. Прикладную программу, в которой используется функция SPXListenForConnection, принято называть программой-сервером (она принимает первый пакет канала). Прикладную программу, в которой используется функция SPXEstablishConnection, называют программой-клиентом (она посылает первый пакет программе-серверу). При использовании примитива SPXListenForConnection в программе-сервере необходимо выполнить следующие шаги: Выполнить обращение к функции SPXListenForSequencedPacket, чтобы обеспечить в дальнейшем приём пакета от программы-клиента. Выполнить обращение к функции SPXListenForConnection. После успешного образования канала в поля InUse и Ccode блока ECB будет записано нулевое значение. Ожидать приёма пакета (см. шаг 1). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXEstablishConnection | Используется в программе-клиенте для образования канала связи. Вход - адрес блока ECB. При использовании этого примитива в программе-клиенте необходимо выполнить следующие шаги: Выполнить обращение к функции SPXListenForSequencedPacket, чтобы обеспечить в дальнейшем приём пакета от программы-сервера. Выполнить обращение к функции SPXEstablishConnection. После успешного образования канала в поля InUse и Ccode блока ECB будет записано нулевое значение, а поле SourceConnID заголовка пакета SPX будет содержать номер образованного канала связи. С помощью функции SPXSendSequencedPacket выполнить передачу первого пакета программе-серверу. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXListenForSequencedPacket | Обеспечивает приём пакета средствами протокола SPX. Вход - адрес блока ECB. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXSendSequencedPacket | Обеспечивает передачу пакета. Вход - адрес блока ECB, а также номер канала, используемый программой-получателем. Номер канала следует выбирать из поля SourceConnID заголовка принятого пакета. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXGetConnectionStatus | Проверить состояние канала. Вход - номер канала и указатель на буфер, куда записывается информация о состоянии канала. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXTerminateConnection | Эта функция автоматически посылает удалённому партнёру пакет, который состоит из одного заголовка. В поле DataStreamType этого заголовка находится значение FEh, которое говорит программе получателя закрыть канал (т.е. выполнить в ответ функцию SPXTerminateConnection). Вход - адрес блока ECB и номер канала связи. Далее обе программы должны закрыть используемые гнёзда. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPXAbortConnection | Функция разрывает канал связи без согласования с программой получателя. Используется только в катастрофических случаях, когда невозможно выполнить нормальную процедуру закрытия канала. Вход - номер канала связи. |
Для протокола SPX используется точно такой же блок ECB, что и для протокола IPX. Прикладная программа, в которой используются примитивы API-интерфейса с протоколом SPX, обычно включает выполнение следующих шагов:
Фирма Novell предлагает API-интерфейсы для работы по протоколу SPX на рабочей станции и на файловом сервере. В таблице 2.4 перечислены основные примитивы этих интерфейсов.
Как видно из таблицы 2.4, имена примитивов совпадают для программ на рабочей станции и для NLM-модулей файлового сервера.
Следует отметить, что для поддержки на файловом сервере служб протокола SPX используется библиотека CLIB.NLM. Для организации доступа к этим службам следует дополнительно загрузить NLM-модуль SPXS.NLM в стек протоколов, основанных на STREAMS.
Оценивая рассмотренные выше протоколы IPX и SPX, можно сказать, что протокол IPX быстр, но SPX надёжен.