Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

2004 г.

7.2. Сетевые драйверы

Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru

Читатели, знакомые с телекоммуникационными протоколами, могут заинтересоваться тем, как писать прикладные программы для работы с пакетами. Прикладная программа взаимодействует с драйвером сетевого интерфейса. Ethernet-интерфейс, как и всякий другой, содержит несколько статусных управляющих регистров (CSR) и один или несколько регистров данных. Запись (чтение) в эти регистры выполняется в IBM/PC с помощью команд IN (OUT). Каждому регистру ставится в соответствие определенный номер порта. Блок номеров портов задается с помощью переключателей на интерфейсе или в процессе постановки пакетного драйвера. В последнем случае в AUTOEXEC-файле должна присутствовать строка, например (для DOS):

NE2000 0x60 0x5 0x300, (если ваша ЭВМ снабжена интерфейсом типа NE2000).

Здесь предполагается, что интерфейс будет использовать номер прерывания 0x60, аппаратное прерывание 0x5 и блок портов, начиная с шестнадцатеричного адреса 0x300 (io_addr). Следует иметь в виду, что разные интерфейсы могут иметь разное число CSR-регистров и отличные от приведенных ниже функции (NE2100). Интерфейс характеризуется тремя целыми числами: класс (8 бит), тип (16 бит) и номер. Класс говорит о том, для какой из сетевых сред предназначен данный прибор (PPP, DIX Ethernet, IEEE 802.3, IEEE 802.5, Pronet-10, Appletalk и т.д.). Тип описывает конкретную реализацию интерфейса (NE2000, NI5210, 3C501 и т.д.). Тип 0xffff соответствует всем интерфейсам данного класса. В случае, когда ЭВМ оснащена более чем одним интерфейсом идентичного типа, для их идентификации используется номер. На рис. 7.2.1 показана структура управляющего (CSR) регистра сетевого интерфейса. В таблице 7.2.1 приведен перечень основных классов с примерами определенных типов интерфейсов.

Рис. 7.2.1.А Структура CSR-регистра интерфейса (CSR0)
Initинициализация (initialize);
Strtстарт;
Stopстоп;
Tdndзапрос передачи (transmit demand);
Txonвключение передачи;
Rxonвключение приема;
Ineaразрешение прерываний (interrupt enable);
Intrпрерывание;
Idonинициализация выполнена (стирание записью 1);
Tintпрерывание при передаче (стирание записью 1);
Rintпрерывание при чтении (стирание записью 1);
Merrошибка при тайм-ауте на шине (стирание записью 1);
Missнет буфера для приема (стирание записью 1);
Cerrошибка из-за столкновения (стирание записью 1);
Lablтайм-аут при передаче (стирание записью 1);
Errошибка типа Babl, Cerr, Miss, Merr (только для чтения).

CSR1 (доступ разрешен при CSR0[stop] = 1)

Рис. 7.2.1.Б. CSR1

CSR2 (доступ разрешен при CSR0[stop] = 1)

Рис. 7.2.1В. CSR2
Bcon0 = <0:7> перестановка байтов адресов
Acon0 = ale, 1 = /as
Bswp0 = /bm1, bm0, /hold;

csr3 (доступ разрешен при CSR0[stop] = 1)

Рис. 7.2.1.Г. CSR3

Таблица 7.2.1.

Сетевая средаКлассФирма, интерфейсТип интерфейса
dec/intel/Xerox13com 3C500/3C5011
"Bluebook" ethernet3com 3C5052
Interlan NI50103
Micom-Interlan NP6006
Ungermann-bass PC-nic8
Univation NC-5169
TRW PC-200010
Interlan NI521011
3com 3C50312
3com 3C52313
Western digital WD800314
Spider systems S415
Torus frame level16
10net communications17
Gateway PC-bus18
Gateway at-bus19
Gateway MCA-bus20
IMC PCnic21
1IMC PCnic II22
Micromatic research25
Clarkson "multiplexor"26
D-link 16-bit28
D-link ps/229
Research machines 1631
Research machines MCA32
Interlan NI921034
Interlan NI651035
Novell NE200036
Allied telesis pc/xt/at38
Allied telesis NEC PC-9839
Ungermann-bass NIC/PS241
Tiara lancard/E AT42
Tiara Lancard/E MC43
Tiara Lancard/E TP44
AT&T Starlan NAU47
AT&T Starlan-10 NAU48
AT&T Ethernet NAU49
Pronet-102Proteon P13001
Proteon P18002

IEEE 802.5/pronet-4
IBM Token Ring интерфейс

3Proteon P13402
Proteon P13443
Gateway PC-bus4
Gateway AT-bus5
Gateway MCA-bus6
Omninet4  
Appletalk5  
Последовательный интерфейс6Clarkson 8250-slip1
Clarkson "multiplexor"2
Starlan7  
Arcnet8Datapoint RIM1
AX.259  
KISS10  
IEEE 802.3 w/802.2 HDRS11  
FDDI W/802.2 HDRS12  
Internet X.2513Western Digital1
N.T. Lanstar (encap. dix)14NT Lanstar/81
NT Lanstar/mc2
SLFP15  
Netrom16  
Nclass17  

Любой пакетный драйвер имеет блок исходных данных (MS-DOS), напр.:
EADDR_LENequ 6 ; длина физического адреса
init_blockstruc  
init_modedw0 
init_addrdbeaddr_len dup(?); ethernet-адрес
init_filterdb8 dup(0); Логический адресный фильтр (multicast filter).
init_receivedw?,?; Указатель входного кольцевого буфера
init_transmitdw?,?; Указатель выходного кольцевого буфера.
init_blockends  

Структура переменных init_mode (смещение = 0) имеет вид

Рис. 7.2.2. Структура переменных init_mode
Drxзапрет приема;
Dtxзапрет передачи;
Loopцикл;
Dtcrзапрет передачи crc;
Collстолкновение;
Drtyзапрет повторов;
Intlвнутренний цикл;
Promрежим приема всех пакетов (promiscuous mode).

Кольцевой входной буфер имеет следующую структуру:
rcv_msg_dscpstruc
rd_addrdw ?; Младшая часть адреса входного буфера
rd_statdw ?; Статусная часть + старшая часть адреса
rd_bcntdw ?; Размер буфера в байтах
rd_mcntdw ?; Длина сообщения в байтах
rcv_msg_dscpends

Структура переменных rd_stat имеет вид

Рис. 7.2.3. Структура переменных rd_stat
Enpконец пакета;
Stpначало пакета;
Buffошибка в буфере;
CRCCRC-ошибка;
Ofloпереполнение буфера;
Framошибка при записи в буфер;
Errналичие ошибки;
Own0 = полное заполнение.

Выходной буфер имеет сходную структуру.

Я не буду описывать здесь то, как следует писать системные драйверы (Исчерпывающую информацию по написанию таких драйверов читатель может найти в книге "Написание драйверов для MS-DOS" Р.Лея и "Уэйт Груп", Москва "Мир", 1995), тем более что существует достаточное их количество в депозитариях общего доступа (Например, анонимное FTP по адресам ftp.funet.fi, ftp.switch.ch или oak.oakland.edu, депозитарий SimTel ). Приведенное выше описание регистров интерфейса не является единственно возможным (см. также руководство по сетевому контроллеру 8390 и файл NE2.ASM из ссылки ftp.funet.fi. Структура драйверов варьируется для разных операционных систем. Для системных программистов полезно иметь возможность настраивать драйвер или непосредственно интерфейс на определенный режим, например, на прием всех пакетов, проходящих по кабельному сегменту. Последнее может представлять интерес в диагностических целях, так как вслед за пакетным драйвером загружается Etherdrv, Winsock или winpkt и т.д., блокирующие режим приема всех пакетов (mode=6). Ниже приведен пример описания основных параметров драйвера:
BLUEBOOKequ1 
IEEE8023equ11 
ADDR_LENequ6; размер Ethernet-адреса
MAX_M_CASTequ8; максимальное число мультикаст-адресов.

Publicint_no,io_addr 
int_nodb2,0,0,0; должно иметь 4 байта для get_number.
io_addrdw0300h,0; I/O адрес карты (переключатели)

publicdriver_classdriver_type,driver_name,driver_function,parameter_list
driver_classdbBLUEBOOK, IEEE8023, 0; из спецификации интерфейса
driver_typedw54; из спецификации интерфейса
driver_namedb'NE2000',0; имя драйвера.
driver_functiondb2 
parameter_listlabelbyte 
 db1;
 db9;
 db14; длина списка параметров в байтах
 dbADDR_LEN; длина адреса MAC-уровня в байтах
 dwGIANT; MTU, включая MAC-заголовок
 dwMAX_M_CAST * ADDR_LEN 

; размер буфера для мультикаст-адресов
 dw0;(# принимаемых подряд пакетов с; размером MTU) - 1
 dw0; (# посылаемых подряд пакетов) - 1
int_numdw0; Номер прерывания

Работа с пакетным драйвером в MS-DOS

Существует множество пакетных драйверов. Можно обнаружить несколько модификаций для одного и того же типа интерфейса. Эти драйверы могут быть ориентированы на работу в разных программных средах (Novell, UNIX, MS-DOS и т.д.) и иметь разные возможности. Для MS-DOS сложился неофициальный стандарт, который позволяет использовать драйвер для самых разных приложений. Драйвер может использовать минимум возможностей интерфейса (базовый уровень), реализовать более широкий набор функций (мультикастинг, сбор статистики и т.д.) или поддерживать практически все, на что способен данный прибор. В последнем случае он занимает больше места в памяти. Описания операций с пакетными драйверами, приведенные ниже, выполнены в нотации ассемблера IBM/PC. При написании программы следует помнить, что порядок байтов в Ethernet противоположен тому, который используется в вашей IBM/PC.

Пакетные драйверы используют программные прерывания в интервале 0x60 - 0x80. Следует сразу заметить, что не все прерывания из этого списка свободны и при конфигурировании системы следует проявлять осмотрительность. Для того чтобы избежать конфликтов с другими внешними устройствами, предусматривается возможность реконфигурации прерываний. Предполагается, что программа обработки прерываний начинается с команды безусловной передачи управления (JMP), за которой следует текстовая строка "PKT DRVR". Именно эта строка служит указателем при поиске адреса пакетного прерывания. Практически все драйверы могут работать с различными протоколами (TCP/IP, OSI и др.). Решить задачу мультиплексирования на связном уровне помогает процедура access_type, которая обеспечивает доступ для пакетов определенного типа.

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

При работе с драйвером следует проявлять осторожность и спасать нужные вам регистры. Следует также помнить, что порядок байтов в PC и в некоторых сетях, включая Ethernet, не совпадает. Описание основных запросов, посылаемых пакетному драйверу:

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

driver_info AH == 1,
AL == 255 (код запроса)
public_driver_info
_driver_infoproc near 
 mov AX, 1FFH; ah=1, al=255
 call int_pkt; обращение к драйверу
 jnc lv 
 mov AX, seg _PARAM.ER_CODE 
 mov DS, AX 
 mov _PARAM.ER_CODE, 272; Устанавливаем код "Нет инф. о драйвере"
lv:ret
_driver_infoendp

int_pkt: ; Подпрограмма обращения к драйверу
 push ds 
 push es 
 pushf 
 cli 
 call _param.Handler ; адрес _param.Handler должен быть определен раньше
 pop es 
 pop ds 
 ret 

Целочисленный указатель (handle) должен быть занесен в регистр BX (для старых драйверов). В случае ошибки устанавливается флаг carry, а код ошибки заносится в регистр DH. Сообщение BAD_HANDLE (неверный указатель) возможно только для старых драйверов. При благополучном исполнении флаг carry равен нулю, а в регистры будет занесены следующие параметры:
BXверсия;
CHкласс;
CLномер;
DXтип;
DS:SIуказывают на строку имени драйвера;
ALфункциональные возможности.
AL = 1гарантируется выполнение базовых функций;
= 2обеспечено выполнение базового и расширенного набора функций;
= 5выполняется базовый и экстра-набор функций;
= 6выполним полный набор функций;
= 255драйвер не установлен.

Ниже приведен пример программы, реализующей некоторые из описанных запросов.
.MODELsmall 
PUBLIC_INFACE 
VERSIONEQU1
EXTRN_PARAM:BYTE 
EXTRN_Q:BYTE 

.DATA
INCLUDEDEF.ASM; Определения некоторых констант
P_LISTSTRUC 
LINTNDB32 dup(0); Список активных номеров прерываний
HANDLESDW? 
HANDLEPDW? 
ER_CODEDW? 
ERNUMDW?; Код ошибки
HANDLERDD? 
MODEDW?; Текущий режим приема пакетов
MLISTDB0,0,0,0,0,0; Список допустимых режимов; 1 => имеется
PKT_INDW?,?; Диагностический массив
pkt_outDW?,? 
byte_inDW?,? 
byt_outDW?,? 
err_inDW?,? 
err_outDW?,? 
pk_dropDW?,? 
L1DW0; Версия драйвера
L2DW0; класс/номер
L3DW0; Тип
L4DW0; Функция
_NAMEDB0,0,0,0,0,0,0,0,0,0; Имя интерфейса
ETHER_ADRDBADDR_LEN dup(-1); Ethernet-адрес
S_ADRDBEADDR_LEN+5 dup(-1); Ethernet-адрес получателя
D_ADRDBEADDR_LEN+5 dup(-1); Ethernet-адрес отправителя
P_LISTENDS
QUEUESTRUC
LengDW15000,?; Длина очереди
TailDW?; Смещение последнего элемента очереди
HeadDW?; Смещение первого элемента очереди
_endDW?; Указатель на конец очереди
p_lenDW?; Длина пакета
P_startDW?; Указатель на текущий пакет = Q_head - Q_begin +2
NEWDB0; Флаг нового пакета
LineDB?; Строка экрана
NpacksDD0; Счетчик принятых пакетов
BDW?; смещение Q_beg
PointDW380 dup(?) 
BegDB31000 dup(?); Пакетный буфер
QUEUEENDS

 
ether_bdcstDBEADDR_LEN dup(-1); Широковещательный адрес Ethernet, заполненный -1.
ether_addrDBEADDR_LEN dup(-1) 
bogus_typeDB0,0; 
signatureDB'PKT DRVR',0; Сигнатура пакетного драйвера
signature_lenequ$-signature 
SAFEDW? 
DFLAGDB0 

.CODE
 PUBLIC_INFACE
_INFACEPROCNEAR

 CLD 
 MOV DFLAG, 0; Очистка флага драйвера
 MOV _PARAM.ER_CODE, 0; Очистка флага ошибки
 PUSH BP; Спасение регистров
 MOV BP, SP 
 PUSH SI 
 PUSH DI 
 PUSH ES 
 PUSH DS 

 MOV CX, 32 
 MOV AL, 60H; Установка начального номера прерывания
 LEA SI, _PARAM.LINTN; Формирование указателя на список номеров прерывания
CHECK:PUSH AX 
 PUSH CX 
 PUSH SI 
 CALL CHK_INT 
 POP SI 
 POP CX 
 MOV byte ptr [SI], 0 ; 
 JNE NO_SIGNATURE 
 INC DFLAG; Установка флага <Это драйвер>
 MOV BYTE PTR [SI], 1; Установка флага наличия

NO_SIGNATURE:
 POP AX 
 INC AL; Следующий номер прерывания
 INC SI; Актуализация указателя
 LOOP CHECK 

 CMP DFLAG, 0; Драйвер присутствует?
 JNE HAVE_SIGNATURE 
 MOV _PARAM.ER_CODE, 271; Установка флага <No signature>
 JMP OKAY 

INT_PKT:
 PUSH ES
 pushf
 cli
 call _PARAM.HANDLER
 POP ES
 RET

CHK_INT:PUSH ES; AL = номер прерывания
 PUSH DI 

 MOV AH, 35H ; Получение вектора прерывания
 INT 21H; ES:BX=seg:offs драйвера

 MOV _PARAM.HANDLER.OFFS,BX ; Записываем адрес драйвера
 MOV _PARAM.HANDLER.SEGM, ES 
 LEA DI, 3[BX]; Устанавливаем смещение сигнатуры драйвера
 MOV SI, OFFSET SIGNATURE; Проверка сигнатуры драйвера
 MOV CX, SIGNATURE_LEN; Присутствует ли здесь драйвер?
 REPE CMPSB ; DS:[SI] - ES:[DI] 

 POP DI
 POP ES
 RET

HAVE_SIGNATURE:
 MOV CX, 32; Установка начального значения счетчика
 LEA SI, _PARAM.LINTN; Устанавливаем указатель списка
 MOV AL, 60H; Задаем начальный номер прерывания
CHOICE:CMP BYTE PTR [SI], 0 
 JNE SETDRV 
 INC AL 
 LOOP CHOICE 

SETDRV:MOV AH, 35H 
 INT 21H 
 MOV _PARAM.HANDLER.OFFS,BX; Определяем адрес драйвера
 MOV _PARAM.HANDLER.SEGM, ES 

 PUSH DS 
 POP ES 
 MOV CX, EADDR_LEN 
 MOV SI, OFFSET ETHER_ADDR 
 MOV DI, OFFSET ETHER_BDCST 
 REPE CMPSB 
 JE GET_MODE; Адрес не определен

 MOV AH, 25; Записываем ethernet-адрес
 MOV DI, offset ETHER_ADDR 
 MOV CX, EADDR_LEN 
 call int_pkt 
 MOV _PARAM.ER_CODE, DX; Устанавливаем код ошибки
 JMP OKAY 

GET_MODE:
 MOV SAFE, DS; Спасаем DS
 PUSH DS 
 MOV AH, 2; Открываем доступ пакетам
 MOV AL, 1; Класс интерфейса
 MOV BX, -1; Тип интерфейса
 MOV DL, 0; Номер интерфейса
 MOV CX, 2; Используем длину type = 2
 MOV SI, OFFSET BOGUS_TYPE 
 PUSH CS; ES:DI -> Receiver.
 POP ES 
 MOV DI, OFFSET RECEIVER 
 call INT_PKT 
 JNC $_$ 
 MOV _PARAM.ER_CODE, DX; Устанавливаем код ошибки
$_$:MOV _PARAM.HANDLES, AX; Записываем указатель-Handle

 MOV AH, 6; Определяем ethernet-адрес интерфейса
 PUSH DS 
 POP ES 
 MOV DI, offset _PARAM.ETHER_ADR 
 MOV CX, EADDR_LEN 
 MOV BX, _PARAM.HANDLES 
 call int_pkt 
 JNC NOBAD 
 MOV _PARAM.ER_CODE, 273; Ошибка при определении Ethernet-адреса
 POP DS 
 JMP OKAY 

NOBAD:
 MOV AX, 1FFH; Запрашиваем информацию о драйвере
 MOV BX, _PARAM.HANDLES; Устанавливаем указатель
 call INT_PKT 
 JNC N_BAD 
 MOV _PARAM.ER_CODE, 272; Ошибка при получении информации о драйвере
 POP DS 
 JMP OKAY 

N_BAD:PUSH DS
 PUSH SS
&nsp;POP DS
 MOV ES, SAFE

 MOV _PARAM.L1, BX; Версия драйвера
 MOV _PARAM.L2, CX; номер/класс
 MOV _PARAM.L3, DX; Тип
 MOV _PARAM.L4, AX; Функциональность
 LEA BX, _PARAM._NAME 
 POP DS 
 MOV CX, 8 
ZFIND:CMP byte ptr [SI], 0 
 MOV AL, byte ptr [SI] 
 MOV byte ptr ES:[BX], AL 
 JE ZERO_ 
 INC SI 
 INC BX 
 LOOP ZFIND 
ZERO_:POP DS 
 MOV AH, 21; Запрашиваем код режима приема пакетов
 MOV BX, _PARAM.HANDLES 
 call INT_PKT 
 MOV _PARAM.MODE, AX; Записываем код режима

.........................
OKAY:POP DS
 POP ES
 POP DI
 POP SI
 MOV SP, BP
 POP BP
 RET

RECEIVER:

; Подпрограмма RECEIVER, вызываемая при получении пакета

 OR AX, AX; Первый или второй вызов?
 JNE RECV 
 MOV AX, seg _Q.beg; Указатель буфера ES:DI
 MOV ES, AX 
 MOV DI, offset _Q.beg 

RECV:RETF

2. Организация доступа для пакетов данного типа
access_type(if_class, if_type, if_number, type, typelen, receiver)
AH ==2 (код запроса)

Запрос access_type инициализирует доступ для пакетов определенного типа (type). Аргумент typelen - длина спецификации типа в байтах, для PC/TCP равна 5 (наименьшее значение - 2, для IP и ARP). Аргумент receiver является указателем на подпрограмму, которая вызывается при приеме пакета. Получая пакет, драйвер дважды обращается к этой программе. Первый раз (при AX==0) это делается с целью получения адреса буфера, куда должен быть положен пакет. Прикладная программа в этом случае должна выдать указатель буфера в регистры ES:DI. Если прикладной процесс не имеет свободного буфера,то возвращается значение 0:0. Пакет выбрасывается и повторное обращение к программе receiver отменяется. Форма реализации запроса аналогична приведенному для driver_info:
Intif_class; AL; класс интерфейса
Intif_type; BX; тип интерфейса
Intif_number; DL; номер интерфейса
Charfar *type; DS:SI 
Unsignedtypelen; CX 
Int(far *receiver); ES:DI 

access:mov ah, 2 
  style="font-family:arial;font-size:12pt"mov al, ch; установка класса; здесь предполагается, что содержимое регистров соответствует тому, что получено в результате обращения к driver_info
 mov bx, dx; устанавливаем параметр type
 mov dl, cl; устанавливаем параметр number, при одном интерфейсе number=0
 xor cx, cx; длина type равна нулю
 push cs; устанавливаем сегментный регистр receiver
 pop es 
 mov di, offset RECEIVER; вызов подпрограммы receiver
 call int_pkt; обращение к пакетному драйверу

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:
2NO_CLASS не найдено интерфейса указанного класса;
3NO_TYPE не найдено интерфейса указанного типа;
4NO_NUMBER не найдено интерфейса с указанным номером;
5BAD_TYPE специфицирован неправильный тип пакета;
9NO_SPACE недостаточно места в памяти;
10TYPE_INUSE было обращение к данному типу и он пока занят.

При успешном выполнении запроса флаг carry=0, а в регистр AX занесен указатель (handle).

Обращение к приемнику (receiver):

(*receiver)(handle, flag, len [, buffer])
int handle;BX; указатель
int flag;AX; флаг вызова(0/1)
unsigned len;CX; целое без знака - длина пакета

if AX == 1,
char far *buffer;DS:SI; адрес буфера

Если параметр typelen равен нулю, прикладной процесс готов получать все пакеты. Очень важно, чтобы при первом обращении к receiver (AX==0) CX (длина пакета) была указана правильно, что позволит выделить нужное место в памяти. CX должна включать в себя длину MAC-заголовка и размер самого сообщения без контрольной суммы (CRC). Повторный вызов (AX==1) программы receiver указывает на то,что пакет записан в буфер и прикладная программа может с ним работать. Адрес буфера будет указан в регистрах DS:SI.

3. Завершение доступа пакетов данного типа release_type

int release_type(handle) AH == 3;
код запроса int handle;
BX ; указатель определяет тип пакетов

_release_type proc near
 push bp; спасение регистров
 push ds 
 push es 
 mov ah, 3; задаем код запроса
 mov bx, _param.handle; заносим указатель
 pushf 
 cli 
 call _param.handler; обращение к драйверу
 mov _param.er_CODE, dx; занесение кода ошибки
 pop es; восстановление регистров
 pop ds 
 pop bp 
 ret 
 _release_typeendp

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможная ошибка: BAD_HANDLE (не верный указатель). При успешном выполнении запроса флаг carry=0. Эта операция прерывает доступ пакетов, соответствующих указателю, полученному с помощью запроса access_type. Старый указатель после выполнения этого запроса не действителен.

4. Процедура посылки пакета send_packet(buffer, length)

AH == 4 (код запроса)
char far *buffer; DS:SI (адрес буфера)
unsigned length; CX (длина пакета в байтах)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки 12 CANT_SEND. send_packet отправляет пакет с числом байт, равным CX. Пакет должен в исходный момент лежать, начиная с адреса DS:SI. Прикладная программа должна сформировать все необходимые заголовки. Информация, нужная для осуществления демультиплексирования пакетов (MAC или LLC), также должна быть записана в пакет, так как при этом запросе не сообщается значение указателя (handle).

5. Завершение работы драйвера terminate(handle)

AH == 5 (код запроса)
int handle; BX (указатель)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

1 BAD_HANDLE;
7 CANT_TERMINATE.

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

6. Получение физического адреса интерфейса get_address(handle,buf,len)

AH == 6 (код запроса)
int handle; BX (указатель)
char far *buf; ES:DI (адрес буфера)
int len; CX (длина адреса в байтах)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

1 BAD_HANDLE;
9 NO_SPACE. При успешном выполнении запроса флаг carry=0, а в регистр CX занесена длина адреса.

Копирует текущее значение сетевого (физического) адреса интерфейса в буфер. Если получено сообщение NO_SPACE, это означает, что выделенного места (len=CX) для копирования адреса не хватило.

7. Возвращение интерфейса в исходное состояние reset_interface(handle)

AH == 7 (код запроса)
int handle; BX (указатель)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

1 BAD_HANDLE;
15 CANT_RESET.

Возвращает интерфейс в исходное состояние, прерывая все процессы. Местное значение физического сетевого адреса, если оно было изменено, восстанавливается из ROM, прием переключается в режим 3, а список мультикастинг-адресов обнуляется. При работе с несколькими указателями (handle) возможны серьезные неприятности, по этому выполнение запроса блокируется и присылается сообщение CANT_RESET.

8. Запрос установки режима приема пакетов set_rcv_mode(handle,mode)

AH == 20 (код запроса) int handle;
BX (входные параметры - указатель) int mode;
CX (код режима приема пакетов)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

1 BAD_HANDLE;
8 BAD_MODE.

Устанавливает режим приема пакетов. Режим 3 используется по умолчанию. Возможны (но не для всех интерфейсов) следующие режимы:
РежимЗначение
1выключение приема пакетов;
2прием пакетов, адресованных только данному интерфейсу;
3режим 2 плюс бродкастинг-пакеты;
4режим 3 плюс некоторые мультикастинг-пакеты;
5режим 3 плюс все мультикастинг-пакеты;
6все пакеты.

9. Считывание действующего режима приема пакетов get_rcv_mode(handle)

AH == 21 (код запроса)

int handle; BX (входной параметр - указатель)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки 1 BAD_HANDLE. При успешном выполнении запроса флаг carry=0, а в регистр AX заносится код режима приема пакетов.

10. Занесение списка мультикастинг-адресов в интерфейс set_multicast_list(addrlst,len)

AH == 22 (код запроса)
char far *addrlst; ES:DI (адрес буфера, где лежат адреса)
int len; CX (длина списка адресов)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

6 NO_MULTICAST;
9 NO_SPACE;
14 BAD_ADDRESS.

Список адресов представляет собой счетную последовательность, начинающуюся с байта числа адресов в списке. На список адресов указывает комбинация регистров ES:DI. Сообщение NO_SPACE присылается, если указатель адреса отсутствует, или число адресов превосходит аппаратные возможности интерфейса. Прежде чем заносить список, полезно сначала ознакомиться с имеющимся уже списком, выполнив запрос get_multicast_list. При получении сообщения NO_SPACE рекомендуется попытаться установить режим приема 3 с помощью запроса set_rcv_mode.

11. Получение рабочего списка мультикастинг-адресов

get_multicast_list

AH == 23 (код запроса)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

6 NO_MULTICAST;
9 NO_SPACE.

При успешном выпонении запроса флаг carry=0, в регистр CX заносится длина списка адресов, а регистры ES:DI указывают на начало счетной оследовательности, где запрошенный список лежит. Прикладная программа не должна модифицировать этот список.

12. Получение статистических данных об ошибках и трафике через данный интерфейсget_statistics(handle)

AH == 24 (код запроса)
int handle; BX (указатель)
char far *statistics; DS:SI (адрес буфера, куда записываются статистические данные)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки 1 BAD_HANDLE. При успешном выполнении запроса флаг carry=0, а в массиве, начиная с адреса DS:SI, лежит запрошенная информация.

struct statistics {
unsigned long packets_in;( Число принятых пакетов для всех указателей)
unsigned long packets_out;( Число посланных пакетов)
unsigned long bytes_in;( Число принятых байтов, включая MAC заголовки)
unsigned long bytes_out;( Число посланных байтов)
unsigned long errors_in;( Полное число ошибок при приеме)
unsigned long errors_out;( Число ошибок при посылке пакетов)
unsigned long packets_lost;( Число потерянных пакетов из-за отсутствия свободного буфера или других ресурсов)

};

Статистические данные имеют вид целых 32-разрядных чисел в формате IBM/PC.

13. Смена физического адреса интерфейса

set_address(addr, len) AH == 25
char far *addr; ES:DI (адрес буфера, где лежит новое значение адреса)
int len; CX (длина адреса в байтах)

В случае ошибки флаг carry=1, а в регистр DH заносится код ошибки. Возможные ошибки:

13 CANT_SET;
14 BAD_ADDRESS.

При благоприятном выполнении запроса флаг carry=0, а значение регистра CX сохраняется.

Запрос используется в случае, когда необходим специфический физический адрес интерфейса (например, в случае DECNET). При наличии более одного указателя (handle) драйвер откажется исполнить данный запрос и пришлет сообщение CANT_SET.

Этим не исчерпывается перечень возможных запросов, существует некоторое количество операций, относящихся к экстра-набору функций (код функциональности 5 или 6, смотри описание запроса driver_info).

Назад: 7.1. Winsock (для UNIX, Windows-95 и -NT)
Оглавление: Телекоммуникационные технологии
Вперёд: 8. Заключение

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...