Протокол SPX и использование драйвера Novell Netware

Модератор: push0ret

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

Протокол SPX и использование драйвера Novell Netware

Сообщение push0ret »

Hello, world!

Ранее я описал протокол IPX, использование драйвера Novell Netware для работы с протоколом IPX. В этой статье опишу протокол SPX и опишу функции драйвера для работы с ним, также напишу простую систему клиент - сервер на языке ассемблера.

SPX является протоколом сеансового уровня и также "надстройкой" для протокола IPX. Для передачи данных необходимо сначала создать канал связи, а затем уже передавать данные, канал связи даёт гарантию того, что данные дойдут до адресата, в отличии от датаграмм.

Структура пакета SPX

Структура пакета SPX схожа со структурой пакета IPX, но имеет дополнительные поля (см. картинку):
spx_packet.PNG
spx_packet.PNG (19.99 КБ) 25 просмотров
Поля ConnControl и DataStreamType можно рассматривать числа, обозначающие состояние передачи данных:

1. ConnControl:

01h-08h Зарезервировано

10h End-of-Message. Этот бит может использоваться программой для сигнализации окончания передачи данных.
Драйвер SPX передает этот бит программе в неизменном виде, причем сам драйвер протокола SPX этот бит
игнорирует

20h Attention. Этот бит игнорируется драйвером SPX и передается в неизменном виде программе

40h Acknowledgement Required. Бит используется драйвером SPX. Вам не следует модифицировать его значение

80h System Packet. Этот бит устанавливается драйвером SPX при передаче системных пакетов, которые
используются самим драйвером и не передаются в программу пользователя

2. DataStreamType:

00h-FDh Эти значения игнорируются драйвером SPX и могут быть использованы программой произвольным образом

FEh End-of-Connection. Когда программа вызывает функцию, закрывающую SPX-канал, драйвер SPX посылает
партнеру по связи последний пакет, в поле DataStreamType которого записано значение FEh. Это служит
требованием завершить связь и закрыть канал

FFh End-of-Connection-Acknowledgement. Это значение отмечает пакет, подтверждающий завершение связи. Такой
пакет является системным и не передается в программу пользователя

Поле SourceConnID содержит номер канала связи, присвоенный драйвером SPX.
Поле SeqNumber содержит количество пакетов, переданных по каналу связи.
Поле AckNumber содержит номер следующего пакета.
Поле AllocNumber содержит количество областей памяти, выделенных для приема пакетов.

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

В статье про использование драйвера IPX упоминалась структура ECB (event control block), для использования драйвера SPX используется точно такая же структура.

Т.к. драйвер у Novell Netware служит для использования протоколов IPX/SPX, то и использование драйвера для передачи данных по протоколу SPX абсолютно такое же, отличается лишь логическая часть, я расскажу об этом ниже.

Описание функций SPX

SPXCheckInstallation

На входе:

BX = 10h
AL = 00h

На выходе:

AL = Код завершения:
00h - SPX не установлен;
FFh - SPX установлен.

BH = Верхний номер версии SPX.
BL = Нижний номер версии SPX.
CX = Максимальное количество каналов SPX, поддерживаемых драйвером SPX.
DX = Количество доступных каналов SPX.

SPXListenForConnection

На входе:

BX = 12h.
AL = Счетчик повторов попыток создать канал связи.
AH = Флаг включения системы периодической проверки связи.
ES:SI = Адрес блока ECB.

Эта функция используется для создания канала связи, ожидает пакета от функции SPXEstablishConnection.
Программа-сервер вызывает SPXListenForConnection, передавая ей адрес блока ECB. Этот блок будет использован для образования канала связи.

В блоке ECB необходимо определить значение поля ESRAddress и указать номер сокета. Для каждого сокета можно создать несколько каналов.

После образования канала связи, когда в поле InUse будет записано нулевое значение, поле CCode блока ECB будет содержать код завершения:

00 канал связи создан, ошибок нет;

FFh указанный в ECB сокет не был открыт;

FCh запрос SPXListenForConnection был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);

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

SPXEstablishConnection

На входе:

BX = 11h.
AL = Счетчик повторов попыток создать канал связи.
AH = Флаг включения системы периодической проверки связи.
ES:SI = Адрес блока ECB.

На выходе:

AL = Промежуточный код завершения:

00h - выполняется попытка создать канал;
FFh - указанный в блоке ECB сокет закрыт;
FDh - сбойный пакет: либо счетчик фрагментов не равен 1, либо размер фрагмента не равен 42;
EFh - переполнение локальной таблицы номеров каналов связи.

DX = Присвоенный номер канала.

Функция устанавливает канал связи с программой, вызвавшей функцию SPXListenForConnection.

Для функции необходимо подготовить блок ECB и пакет в формате SPX, состоящий из одного заголовка. В блоке ECB необходимо заполнить поля ESRAddress, Socket, счетчик количества фрагментов (нужен один фрагмент) и указатель на фрагмент размером 42 байта. В заголовке SPX-пакета необходимо заполнить поля DestNetwork, DestNode, DestSocket.

Кроме того, перед вызовом функции SPXListenForConnection программа должна выделить хотя бы один ECB для приема SPX-пакета. Это нужно сделать при помощи функции SPXListenForSequencedPacket

Если по каким-либо причинам канал создать не удалось, в поле CCode будет записан код ошибки:

00h канал связи создан, ошибок нет;

FCh запрос SPXListenForConnection был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);

FDh сбойный пакет: либо счетчик фрагментов не равен единице, либо размер фрагмента не равен 42;

FFh указанный в ECB сокет не был открыт;

EFh переполнилась внутренняя таблица номеров каналов связи; до тех пор, пока какой-нибудь канал не будет закрыт, вы не сможете образовать новые каналы;

EDh адресат не отвечает или сообщает, что он не может создать канал; этот код может возникнуть либо как результат неисправности сетевого аппаратного обеспечения, либо если функция SPXEstablishConnection была отменена при помощи функции SPXAbortConnection.

SPXListenForSequencedPacket

На входе:

BX = 17h
ES:SI = Адрес блока ECB.

Функция обеспечивает прием пакетов средствами протокола SPX.Функция обеспечивает прием пакетов средствами протокола SPX. Используемый блок ECB ставится в очередь на приём, а функция возвращает управление вашей программе.

Перед вызовом функции необходимо заполнить в структуре ECB поля ESRAddress, Socket, счетчик фрагментов и адреса и размеры фрагментов. Необходимо также открыть используемый сокет при помощи функции IPXOpenSocket.

После того как пакет будет принят, в поле InUse блока ECB устанавливается нулевое значение, а в поле CCode - код завершения:

00h пакет принят без ошибок;

FCh запрос SPXListenForSequencedPacket был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);

FDh переполнение пакета - принятый пакет имеет длину, которая превосходит размер буферов, указанных в дескрипторах фрагментов;

EDh система периодической проверки связи обнаружила разрыв канала, номер разрушенного канала записан в первых двух байтах поля IPXWorkspace блока ECB;

FFh указанный в ECB сокет не был открыт.

SPXSendSequencedPacket

На входе:

BX = 16h
ES:SI = Адрес блока ECB.
DX = Номер канала связи.

Перед вызовом функции программа должна заполнить поле ESRAddress, счетчик фрагментов и адреса и размеры фрагментов блока ECB, а также бит End-Of-Message в поле ConnControl и поле DataStreamType в заголовке передаваемого пакета.

Если партнер не успевает принимать передаваемые пакеты, они ставятся в очередь на передачу, чем обеспечивается правильная последовательность доставки пакетов.

После завершения передачи пакета поле InUse блока ECB имеет нулевое значение. Если определена программа ESR, она вызывается. В поле CCode находится код завершения:

00h пакет был передан и успешно принят партнером;

FCh указанный в ECB сокет был закрыт, программа ESR не вызывается;

FDh сбойный пакет: либо счетчик фрагментов равен нулю, либо размер первого фрагмента меньше 42 байт, либо размер всего пакета больше 576 байт;

EEh неправильное значение в регистре DX;

EDh либо система периодической проверки связи обнаружила разрыв канала, либо канал был уничтожен функцией SPXAbortConnection (номер разрушенного канала записан в первых двух байтах поля IPXWorkspace блока ECB);

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

Простая система клиент - сервер

Алгоритм:

Определяем наличие драйвера IPX и SPX, аналогично серверу IPX из предыдущей статьи. Затем открывается сокет для протокола IPX, подготавливается ECB для приема пакета от клиента (да, сначала надо обменяться пакетами по протоколу IPX, чтобы знать сетевые адреса клиента и сервера!). Программа сервер ожидает широковещательного пакета от клиента, клиент посылает широковещательный пакет.

После того, как сервер примет пакет, он копирует адрес клиента из поля ImmAddress структуры ECB и отправляет ответный IPX пакет клиенту, затем клиент копирует адрес сервера из поля ImmAddress структуры ECB, теперь клиент и сервер знают адреса друг друга.

После этого сервер и клиент открывают ещё один сокет, который будет использоваться для протокола SPX (для протокола SPX и IPX необходимо выделять разные сокеты).

Когда сервер и клиент знают адреса друг друга, сокеты для работы с протоколами IPX и SPX открыты, сервер подготавливает структуру ECB для приема пакета SPX от клиента, заполняя необходимые поля, затем вызывается функция SPXListenForSequencedPacket.

Программа - сервер подготавливает ещё один блок ECB для создания канала и вызывает функцию SPXListenForConnection.

Программа - клиент подготавливает блок ECB для отправки запроса на создание канала и вызывает функцию SPXEstablishConnection.

После того, как канал создан, сервер и клиент завершают свою работу (не забываем закрывать сокеты, я использую короткоживущие сокеты).

Сервер:

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

.model  tiny
.286
code    segment
org     100h

start:

;Check IPX

pusha

mov ax, 7A00h
int 2Fh

cmp al, 0FFh
jnz exit_err_ipx

mov word ptr [ipx_entry], di
mov word ptr [ipx_entry+2], es

;Check SPX

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

cmp ax, 0FFh
jnz exit_err_spx

popa

;Open socket

pusha

xor bx, bx
xor al, al
mov dx, 4444h
call dword ptr [ipx_entry]

mov ecbrx.socket, dx
mov ecbtx.socket, dx
mov ipxtx.destsocket, dx

popa

;IPXListenForPacket

pusha

push cs
pop es

mov bx, 4d
mov ecbrx.fragmentcnt, 2d
mov ax, offset ipxrx
mov ecbrx.address1, ax
mov ecbrx.address1+2, es
mov ax, offset rxbuf
mov ecbrx.address2, ax
mov ecbrx.address2+2, es
xor ax, ax
mov si, offset ecbrx.link
call dword ptr [ipx_entry]

popa

wait_rx:

cmp ecbrx.inuse, 0FEh
jnz done_rx

pusha

mov bx, 0Ah
call dword ptr [ipx_entry]

popa

jmp wait_rx

done_rx:

mov ah, 9d
mov dx, offset donerx
int 21h

;Write ImmAdress

push cx
push si
push di

mov si, offset ecbrx.immaddress
mov di, offset ecbtx.immaddress

cld
mov cx, 6d
rep movsb

pop di
pop si
pop cx

;IPXSendPacket

push cs
pop es

pusha

mov bx, 3d
mov ecbtx.fragmentcnt, 2d
mov ipxtx.packettype, 4d
mov ax, offset ipxtx
mov ecbtx.address1, ax
mov ecbtx.address1+2, es
mov ax, offset txbuf
mov ecbtx.address2, ax
mov ecbtx.address2+2, ax 
mov si, offset ecbtx.link
xor ax, ax
call dword ptr [ipx_entry]

popa

wait_tx:

cmp ecbtx.immaddress-7, 0FFh
jnz done_tx

pusha

mov bx, 0Ah
call dword ptr [ipx_entry]

popa

jmp wait_tx

done_tx:

mov ah, 9d
mov dx, offset donetx
int 21h
			  
;SPX BLOCK

;Open socket

xor bx, bx
xor ax, ax
mov dx, 4545h

pusha
call dword ptr [ipx_entry]
mov spxsocket, dx
popa

;Ready ECB for receive packet

mov ax, spxsocket
mov ecbspx.socket, ax
mov ecbspx.fragmentcnt, 2d
mov ax, offset spxpack
mov ecbspx.address1, ax
mov ecbspx.address1+2, es
mov ax, offset rxbuf
mov ecbspx.address2, ax
mov ecbspx.address2+2, es

;Fill ImmAddress in ecbspx

mov si, offset ecbtx.immaddress
mov di, offset ecbspx.immaddress
mov cx, 6d
cld
rep movsb

;ListenForSequencedPacket

mov bx, 17h
mov si, offset ecbspx
call dword ptr [ipx_entry]

;Ready SPX header for waiting channel

mov spxconn.packettype, 5d
mov spxconn.transportctrl, 0
mov ax, spxsocket
mov spxconn.destsocket, ax

;Copy Immediate address in SPXconn

mov si, offset ecbspx.immaddress
mov di, offset spxconn.destnode
mov cx, 6d
rep movsb

;Ready ECB

mov ecbconn.socket, ax
mov ecbconn.fragmentcnt, 1d
mov ax, offset spxconn
mov ecbconn.address1, ax
mov ecbconn.address1+2, ax

;Wait request on making channel

mov bx, 12h
mov al, 0
mov ah, 0
mov si, offset ecbconn

pusha
call dword ptr [ipx_entry]

popa

wait_req:

cmp ecbconn.inuse, 0
jz done_ch

pusha
mov bx, 0Ah
call dword ptr [ipx_entry]
popa

jmp wait_req

done_ch:

mov ah, 9d
mov dx, offset doneconn
int 21h

jmp exit

exit_err_spx:

mov ah, 9d
mov dx, offset err_spx
int 21h
jmp exit

exit_err_ipx:

mov ah, 9d
mov dx, offset err_ipx
int 21h

exit:

push 0FFFEh
pop sp

mov ax, 4C00h
int 21h

err_ipx         db      'IPX NOT LOADED', 0Ah, 0Dh, 24h
err_spx         db      'SPX NOT LOADED', 0Ah, 0Dh, 24h
donetx          db      'Packet Send!', 0Ah, 0Dh, 24h
donerx          db      'Packet Received!', 0Ah, 0Dh, 24h
doneconn        db      'SPX|Connected!', 0Ah, 0Dh, 24h

rxbuf           db      512d dup(0)
txbuf           db      'Client Demo', 500d dup(0)

mysocket        dw      ?
spxsocket       dw      ?

ipx_entry       dw      2d dup(0)

IPXtx_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      4d
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0FFh)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?

IPXtx_         ends

ECBtx_          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)
ImmAddress      db      6d dup(0FFh)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof ipxtx
Address2        dw      2d dup(0)
Size_2          dw      sizeof txbuf

ECBtx_          ends

IPXrx_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      ?
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?

IPXrx_          ends

ECBrx_          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)
ImmAddress      db      6d dup(0)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof ipxrx
Address2        dw      2d dup(0)
Size_2          dw      sizeof rxbuf

ECBrx_          ends

SPXCONN_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      4d
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0FFh)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?
ConnControl     db      ?
DataStrType     db      ?
SourceConnID    dw      ?
DestConnID      dw      ?
SeqNumber       dw      ?
AckNumber       dw      ?
AllocNumber     dw      ?

SPXCONN_         ends

ECBconn_          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)
ImmAddress      db      6d dup(0)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof spxconn

ECBconn_          ends

SPXpack_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      4d
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?
ConnControl     db      ?
DataStrType     db      ?
SourceConnID    dw      ?
DestConnID      dw      ?
SeqNumber       dw      ?
AckNumber       dw      ?
AllocNumber     dw      ?

SPXpack_         ends

ECBspx_          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)
ImmAddress      db      6d dup(0FFh)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof spxpack
Address2        dw      2d dup(0)
Size_2          dw      sizeof rxbuf

ECBspx_         ends

ecbtx           ECBtx_          <>
ipxtx           IPXtx_          <>
ecbrx           ECBrx_          <>
ipxrx           IPXrx_          <>
ecbconn         ECBconn_        <>
ecbspx          ECBspx_         <>
spxconn         SPXconn_        <> 
spxpack         SPXpack_        <>

code    ends
end     start
Клиент:

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

.model  tiny
.286
code    segment
org     100h

start:

;Check IPX

pusha

mov ax, 7A00h
int 2Fh

cmp al, 0FFh
jnz exit_err_ipx

mov word ptr [ipx_entry], di
mov word ptr [ipx_entry+2], es

;Check SPX

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

cmp ax, 0FFh
jnz exit_err_spx

popa

;Open socket

pusha

xor bx, bx
mov al, 0FFh
mov dx, 4444h
call dword ptr [ipx_entry]

mov ecbtx.socket, dx
mov ecbrx.socket, dx
mov ipxtx.destsocket, dx

popa

;IPXSendPacket

push cs
pop es

pusha

mov bx, 3d
;mov ax, mysocket
;mov ecbtx.socket, ax
mov ecbtx.fragmentcnt, 2d
mov ipxtx.packettype, 4d
mov ax, offset ipxtx
mov ecbtx.address1, ax
mov ecbtx.address1+2, es
mov ax, offset txbuf
mov ecbtx.address2, ax
mov ecbtx.address2+2, ax 
mov si, offset ecbtx.link
xor ax, ax
call dword ptr [ipx_entry]

popa

wait_tx:

cmp ecbtx.immaddress-7, 0FFh
jnz done_tx

pusha

mov bx, 0Ah
call dword ptr [ipx_entry]

popa

jmp wait_tx

done_tx:

cmp ecbtx.ccode, 0

mov ah, 9d
mov dx, offset donetx
int 21h

;IPXListenForPacket

pusha

push cs
pop es

mov bx, 4d
mov ecbrx.fragmentcnt, 2d
mov ax, offset ipxrx
mov ecbrx.address1, ax
mov ecbrx.address1+2, es
mov ax, offset rxbuf
mov ecbrx.address2, ax
mov ecbrx.address2+2, es
xor ax, ax
mov si, offset ecbrx.link
call dword ptr [ipx_entry]

popa

wait_rx:

cmp ecbrx.inuse, 0FEh
jnz done_rx

pusha

mov bx, 0Ah
call dword ptr [ipx_entry]

popa

jmp wait_rx

done_rx:

mov ah, 9d
mov dx, offset donerx
int 21h

;SPX block

;Copy server immediate address

push ds
pop es

mov si, offset ecbrx.immaddress
mov di, offset ecbspx.immaddress
mov cx, 6d
rep movsb

sub si, 6d
mov cx, 6d
mov di, offset spxconn.destnode
rep movsb

;Open socket

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

mov ecbspx.socket, dx
mov spxconn.destsocket, dx
mov ecbconn.socket, dx

;SPXListenForSequencedPacket

mov ecbspx.fragmentcnt, 2d
mov ax, offset spxtx
mov ecbspx.address1, ax
mov ecbspx.address1+2, es
mov ax, offset rxbuf
mov ecbspx.address2, ax
mov ecbspx.address2+2, es

mov si, offset ecbspx
pusha
mov bx, 17h
call dword ptr [ipx_entry]
popa

;Ready SPX header

mov spxconn.packettype, 5d
mov spxconn.transportctrl, 0

;Ready ECB for connection

mov ecbconn.fragmentcnt, 1d
mov ax, offset spxconn
mov ecbconn.address1, ax
mov ecbconn.address1+2, es

;Connect

pusha

mov bx, 11h
xor ax, ax
mov si, offset ecbconn
call dword ptr [ipx_entry]

popa

wait_connect:

cmp ecbconn.inuse, 0
jz done_connect

pusha

mov bx, 10d
call dword ptr [ipx_entry]

popa

jmp wait_connect

done_connect:

mov ah, 9d
mov dx, offset doneconn
int 21h

jmp exit

exit_err_spx:

mov ah, 9d
mov dx, offset err_spx
int 21h
jmp exit

exit_err_ipx:

mov ah, 9d
mov dx, offset err_ipx
int 21h

exit:

push 0FFFEh
pop sp

mov ax, 4C00h
int 21h

err_ipx         db      'IPX NOT LOADED', 0Ah, 0Dh, 24h
err_spx         db      'SPX NOT LOADED', 0Ah, 0Dh, 24h
donetx          db      'Packet Send!', 0Ah, 0Dh, 24h
donerx          db      'Packet Received!', 0Ah, 0Dh, 24h
doneconn	db	'Channel created!', 0Ah, 0Dh, 24h

rxbuf           db      512d dup(0)
txbuf           db      'Client Demo', 500d dup(0)

mysocket        dw      ?

ipx_entry       dw      2d dup(0)

IPXtx_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      4d
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0FFh)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?

IPXtx_         ends

ECBtx_          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)
ImmAddress      db      6d dup(0FFh)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof ipxtx
Address2        dw      2d dup(0)
Size_2          dw      sizeof txbuf

ECBtx_          ends

IPXrx_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      ?
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?

IPXrx_          ends

ECBrx_          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)
ImmAddress      db      6d dup(0)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof ipxrx
Address2        dw      2d dup(0)
Size_2          dw      sizeof rxbuf

ECBrx_          ends

ECBconn_          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)
ImmAddress      db      6d dup(0)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof spxconn

ECBconn_          ends


ECBspx_          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)
ImmAddress      db      6d dup(0)
FragmentCnt     dw      ?
Address1        dw      2d dup(0)
Size_1          dw      sizeof spxtx
Address2        dw      2d dup(0)
Size_2          dw      sizeof rxbuf

ECBspx_          ends

SPXrx_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      ?
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?
ConnControl     db      ?
DataStrType     db      ?
SourceConnID    dw      ?
DestConnID      dw      ?
SeqNumber       dw      ?
AckNumber       dw      ?
AllocNumber     dw      ?

SPXrx_          ends

SPXconn_          struc

Checksum        dw      ?
Len             dw      ?
TransportCtrl   db      ?
PacketType      db      ?
DestNetwork     db      4d dup(0)
DestNode        db      6d dup(0)
DestSocket      dw      ?
SourceNetwork   db      4d dup(0)
SourceNode      db      6d dup(0)
SourceSocket    dw      ?
ConnControl     db      ?
DataStrType     db      ?
SourceConnID    dw      ?
DestConnID      dw      ?
SeqNumber       dw      ?
AckNumber       dw      ?
AllocNumber     dw      ?

SPXconn_          ends

ecbtx           ECBtx_          <>
ipxtx           IPXtx_          <>
ecbrx           ECBrx_          <>
ipxrx           IPXrx_          <>
ecbspx          ECBspx_         <>
ecbconn         ECBconn_        <>
spxtx           SPXrx_          <>
spxconn         SPXconn_        <>

code    ends
end     start
Была использована версия компилятора MASM 6.11 в контексте операционной системы MS DOS 6.22, а также драйверы Novell Netware!

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

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

push 0
ret
Ответить

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