📄 packetdriverm.c
字号:
Packet Driver实例程序。
//以太介质访问层处理模块
#include <rscman.h>
#include <pktdrv.h>
#include <stdlib.h>
#include <subs.h>
#include <ether.h>
//各种外部数据定义申明
extern struct Q_LAN_IN qLanIn[MAX_LAN_IN]; //LAN接收报文队列
extern struct QUEUE_INFO queue[122];
extern struct MCB __mcb;
int PktDrv_Handle; //网卡Packet Driver句柄号
char PktDrvId[]="PKT DRVR"; //Packet Driver安装标志
char macAddr[6];
extern unsigned int int_times;
//功能: 检查 Packet Driver 是否已安装,且只能安装在0x62上
int PktDrvLoaded(void)
{
unsigned int pktdrvVect[2];
char id[10];
int j;
*( unsigned long * )pktdrvVect = get_vect( PKTDRV_INT );
//获取中断向量
// 取Packet Driver标志
for( j=0; j<8; j++ ) id[j] = get_char( pktdrvVect[1], pktdrvVect[0]+3+j );
if ( !memcmp( PktDrvId, id, 8) ) return SUCCESS;
//已安装,返回SUCCESS.
return FAIL; //未安装, 返回FAIL
}
//以太帧接收中断处理程序
//调用以太网接收程序 unsigned char ethPackReceive( void )
void interrupt frameReceiver ( struct INT_REGS r )
{
int bufNo;
char far * tmp_ptr;
if( r.bx != PktDrv_Handle) //句柄不同, 出错
{
r.es = r.di = 0;
}
else
{
if( r.ax == 0 ) //第一次调用
{
// int_times++;
//报文缓冲区申请
if ( (bufNo = bufReq( _Q_LAN_IN )) == ERR_BUF_REQ )
{
r.es = r.di = 0;
return;
}
qLanIn[bufNo].packetLen = r.cx; //设置数据包的长度
// r.es = FP_SEG(&qLanIn[bufNo].packet); //设置数据包的接收
缓冲区地址
// r.di = FP_OFF(&qLanIn[bufNo].packet);
tmp_ptr = qLanIn[bufNo].packet;
//设置数据包的接收缓冲区地址
asm push ax
asm mov ax, word ptr tmp_ptr
r.di = _AX;
asm mov ax, word ptr tmp_ptr+2
r.es = _AX;
asm pop ax
}
else
{
}
}
}
// 功能:初始化网络接口
int InitNIC( void )
{
int result = FAIL;
asm push ax
asm push bx
asm push cx
asm push dx
asm push si
asm push di
//1. 初始化网卡
asm push ds
asm push es
asm mov ah, 0x02 //PktDrv 功能号
asm mov al, 0x01 //网络种类号(Ethernet)
asm mov dl, 0x01 //网络接口号(第一个)
asm mov bx, 0xffff //网卡类型号(通用型)
asm mov cx, 0 //数据包类型长度
asm push ax //数据包类型指针DS:SI (NULL)
asm mov ax, 0
asm mov ds, ax
asm pop ax
asm mov si, 0
asm push ax //数据包接收中断处理程序入口ES:DI
asm mov ax, seg frameReceiver
asm mov es, ax
asm pop ax
asm mov di, offset frameReceiver
asm mov dh, 0 //初始化错误代码(清0)
asm int 62h //调Packet Driver中断,进行初始化
asm pop es
asm pop ds
asm jc end //出错
PktDrv_Handle = _AX; //初始化成功, 记录Packet Driver句柄
//2. 获取网卡物理地址
asm push es
asm push ds
asm mov ah, 0x06 //功能号
asm mov bx, PktDrv_Handle //句柄
asm mov cx, 0x06 //物理地址长度
asm mov di, offset macAddr
//设置网卡物理地址存放地址ES:DI
asm push ax
asm mov ax, seg macAddr
asm mov es, ax
asm pop ax
asm mov dh, 0 //错误代码(清 0)
asm int 62h //调Packet Driver中断
asm pop ds
asm pop es
asm jc end //出错
memcpy( __mcb.macAddr, macAddr, 6);
//3. 设置接收模式
asm mov ah, 20 //功能号
asm mov bx, PktDrv_Handle //句柄
asm mov cx, 3 //模式3:只接收本站包及广播包
asm mov dh, 0 //错误代码(清 0)
asm int 62h //调Packet Driver中断
asm jc end //出错
result = SUCCESS; //初始化成功,返回SUCCESS
end:
asm pop di
asm pop si
asm pop dx
asm pop cx
asm pop bx
asm pop ax
return result;
}
//功能: 关闭网络接口
int CloseNIC( void )
{
int result = FAIL;
asm push ax
asm push bx
asm push dx
asm mov ah, 0x03 //功能号
asm mov bx, PktDrv_Handle //句柄
asm mov dh, 0 //错误代码(清0)
asm int 62h //调用Packet Driver 中断
asm jc end //失败
result = SUCCESS; //成功
end:
asm pop dx
asm pop bx
asm pop ax
return result;
}
//报文的实际发送程序
int SendPkt( unsigned int packetLen, unsigned char * packet )
{
int result = FAIL;
asm push ax
asm push bx
asm push cx
asm push dx
asm push ds
asm push es
asm push si
asm push di
asm mov ah, 4 //发送功能号
asm mov cx, packetLen //发送帧长度
asm mov bx, PktDrv_Handle //句柄
asm mov si, word ptr packet
//指定发送帧的内存地址(ds:si)
asm push ax
asm mov ax, word ptr packet+2
asm mov ds, ax
asm pop ax
asm int 62h //调用Pktdrv中断
asm jc end //失败
result = SUCCESS; //成功
end:
asm pop di
asm pop si
asm pop es
asm pop ds
asm pop dx
asm pop cx
asm pop bx
asm pop ax
return result; //发送成功
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -