📄 ethernet.c
字号:
//****test ram 0xFDF0-0xFE0F ,write and read, compare two value so that test 8019as physical circuit.
//****mac ---txdnet(source MAC) init8019as;add mask command
//****host ---txdnet
//****initNIC ---txdnet(source MAC/IP)
//SNMP==UDP?
//****add lc/ls command to display host mask mac.../arp table
//****arp_process ---force to write to some location when table full.
//****ping_echo ---print IP answer.and set pinganswerd flag.
//****subnet/net/self.(ping/udp)
//****add ping/udp command.
//findmacadr add index parameter
//****Don't set global varible before read.(Host/Mac...)
//开始时发ARP包;主动更新ARP缓存;不是给自己的ARP广播也用于刷新缓存;收到ARP应答
//则更新定时器。
//
//extern long int secondtimer;
#include <general.h>
//#include <serial.h>
//#include <snmp.h>
//#include <word.h>
//#include <ethernet.h>
//#include <SerEEROM.h>
//#include <convert.h>
//#include <string.h>
//#include <mystring.h>
//extern long int secondtimer;
static long int secondtimer=0;
xdata union ethernet_address_type my_ethernet_address; //本机的以太网地址
xdata union ethernet_address_type gateway_ethernet_address; //网关的以太网地址
xdata union ethernet_address_type ping_ethernet_address; //用来ping的以太网地址
xdata union ip_address_type my_ip_address; //本机的ip地址
xdata union ip_address_type gateway_ip_address; //网关的ip地址
xdata union ip_address_type mask_ip_address; //子网掩码
xdata union ip_address_type SNMP_ip_address; //网管SNMP主机的ip地址
xdata union ip_address_type ping_ip_address; //用于ping命令
xdata union ip_address_type temp_ip_address; //临时变量
xdata union arp_table_type arp_tab[MaxLenARPtable];
bit txd_buffer_select=0; //选择网卡的发送缓冲区
unsigned char ping_count; //ping的次数
unsigned char udp_count; //udp的次数
xdata union netcard rxdnet;
xdata union netcard txdnet;
unsigned char index=0; //ARP table 循环加入点
unsigned int frameindex=0; //IP包的序列号
struct TXBUF{
unsigned char status;
unsigned char ttl;
union ip_address_type ip;
unsigned char type;
unsigned char pinganswerd;
unsigned int length;
union netcard pack;
} txdbuf[MaxLenTxBuf];
void page(unsigned char pagenumber)//ne2000页选择
{
unsigned char data temp;
temp=reg00&0x3B;//注意txp位不能要
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
reg00=temp;
}
void getadr(unsigned char id,unsigned char *bytes)//读取MAC地址参数
{
int len;
if(id==MACADR) len=6; //不是很安全,没有检测参数错误!
else len=4;
opx5045(READ,id,len,bytes); //读出地址存到bytes[]里
}
void setadr(unsigned char id,unsigned char *bytes)//设置MAC地址参数
{
int len;
unsigned char i,WIP;
if(id==MACADR) len=6; //不是很安全,没有检测参数错误!
else len=4;
//
do{
opx5045(RDSR,0,0,&WIP);
}while((WIP&0x1)==1);
//
for(i=0;i<len;i++,id++){ //将地址写入X5045.
opx5045(WREN,id,1,&bytes[i]);
opx5045(WRITE,id,1,&bytes[i]);
//
do{
opx5045(RDSR,0,0,&WIP);
}while((WIP&0x1)==1);
//
}
}
void initNIC(void)//初始化网卡配置参数
{
unsigned char i;
getadr(MACADR,&my_ethernet_address.bytes[0]);//读出网卡的物理地址存到my_ethernet_address.bytes[6]里
page(1);//init 8019as PAR
reg01=my_ethernet_address.bytes[0];
reg02=my_ethernet_address.bytes[1];
reg03=my_ethernet_address.bytes[2];
reg04=my_ethernet_address.bytes[3];
reg05=my_ethernet_address.bytes[4];
reg06=my_ethernet_address.bytes[5];
for(i=0;i<3;i++)
txdnet.etherframe.sourcenodeid[i]=my_ethernet_address.words[i];
getadr(HOST,&my_ip_address.bytes[0]);//读出本机IP地址存到my_ip_address.bytes[4]里
getadr(MASK,&mask_ip_address.bytes[0]);//读出本机掩码存到mask_ip_address.bytes[4]里
getadr(GATEWAY,&gateway_ip_address.bytes[0]);//读出网关IP地址存到gateway_ip_address.bytes[4]里
getadr(SNMPHOST,&SNMP_ip_address.bytes[0]);//读出SNMP网管主机IP地址存到SNMP_ip_address.bytes[4]里
}
void delay_ms(unsigned char ms_number)//延时
{
//延时子程序,延时时间单位为1毫秒,晶振使用22。1184兆赫,芯片使用mcs51兼容芯片
//ms_number为需要延时的毫秒数,最大为255毫秒 误差小于1 %
unsigned int i;
unsigned char j;
for(j=0;j<ms_number;j++)
for(i=0;i<229;i++);
}
void rtl8019as_rst()//RTL8019AS复位
{
unsigned char temp;
delay_ms(200);
temp=reg1f;//读网卡的复位端口
reg1f=temp; //写网卡的复位端口
delay_ms(200);
}
void ne2000init()//ne2000网卡初始化
{
rtl8019as_rst();
//??????????????????????????????????删
#ifdef debug
page(2);
PrintStr("\nPSTART=");
PrintByte(reg01);
PrintStr("\nPSTOP=");
PrintByte(reg02);
PrintStr("\nTPSR=");
PrintByte(reg04);
PrintStr("\nRCR=");
PrintByte(reg0c);
PrintStr("\nTCR=");
PrintByte(reg0d);
PrintStr("\nDCR=");
PrintByte(reg0e);
#endif
}
void send_packet(union netcard *txdnet,unsigned int length)//ne2000发包子程序
{//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
unsigned char i;
unsigned int ii;
//??????????????????????????????????删
reg00=0x3E; //to sendpacket;
}
bit recv_packet(union netcard *rxdnet)//ne2000收包子程序
{
unsigned char i;
unsigned int ii;
unsigned char bnry,curr;
//??????????????????????????????????删
return 0;
}
void trans_pack(union netcard *txdnet,union ip_address_type destip,unsigned int length,unsigned char type)//发包至缓冲区
{
unsigned char i;
unsigned int j;
for(i=0;i<MaxLenTxBuf;i++){
if(txdbuf[i].status==0){
txdbuf[i].status=1;
txdbuf[i].length=length;
txdbuf[i].type=type;
txdbuf[i].ip.dwords=destip.dwords;
txdbuf[i].ttl=8;
if(type==PINGTYPE) txdbuf[i].pinganswerd=1;
for(j=0;j<length;j++)
txdbuf[i].pack.bytes.bytebuf[j]=txdnet->bytes.bytebuf[j];
break;
}
}
}
void process_trans_pack()//发包缓冲区发送处理
{
unsigned char i,j;
unsigned char ipstr[16];
for(i=0;i<MaxLenTxBuf;i++){
if(txdbuf[i].status==1){
if(txdbuf[i].type==PINGTYPE){
if(txdbuf[i].ttl==0)
txdbuf[i].status=0;
else{
txdbuf[i].ttl--;
ping_ip_address.dwords=txdbuf[i].ip.dwords;
if(txdbuf[i].pinganswerd==0){
PrintStr("\n\tRequest timed out.(");
HEXToIPadr(ipstr,&txdbuf[i].ip.dwords);
PrintStr(ipstr);
PrintStr(")\n");
}
else
txdbuf[i].pinganswerd=0;
if(ping_ip_address.dwords==my_ip_address.dwords){
PrintStr("\n\tReply from ");
HEXToIPadr(ipstr,&txdbuf[i].ip.dwords);
PrintStr(ipstr);
//PrintLong(txdbuf[i].ip.dwords);
PrintStr(" TTL=80\n");
txdbuf[i].pinganswerd=1;
}
else if((ping_ip_address.dwords&mask_ip_address.dwords)!=(my_ip_address.dwords&mask_ip_address.dwords))
ping_ip_address.dwords=gateway_ip_address.dwords;//not in same subnet.
if(findmacadr(ping_ip_address,&ping_ethernet_address)==1){
ping_request();
//for(j=0;j<3;j++)
// txdbuf[i].pack.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
for(j=0;j<3;j++)
txdnet.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
//send_packet(&txdbuf[i].pack,txdbuf[i].length);
send_packet(&txdnet,txdbuf[i].length);
}
else{
arp_request(ping_ip_address.dwords);
}
}
}
else if(txdbuf[i].type==UDPTYPE){
if(txdbuf[i].ttl==0)
txdbuf[i].status=0;
else{
txdbuf[i].ttl--;
ping_ip_address.dwords=txdbuf[i].ip.dwords;
if(ping_ip_address.dwords==my_ip_address.dwords){
PrintStr("\nUDP myself ERROR!\n");
txdbuf[i].ttl=0;
}
else if((ping_ip_address.dwords&mask_ip_address.dwords)!=(my_ip_address.dwords&mask_ip_address.dwords))
ping_ip_address.dwords=gateway_ip_address.dwords;//not in same subnet.
if(findmacadr(ping_ip_address,&ping_ethernet_address)==1){
for(j=0;j<3;j++)
txdbuf[i].pack.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
//remake_udp(&txdbuf[i].pack);
send_packet(&txdbuf[i].pack,txdbuf[i].length);
txdbuf[i].ttl=0;
}
else{
arp_request(ping_ip_address.dwords);
}
}
}
}
}
}
void arp_request(unsigned long ip_address)//ARP请求
{//请求解析ip地址
unsigned char i;
//??????????????????????????????????删
for(i=0x2E;i<(0x2E+18);i++)
txdnet.bytes.bytebuf[i]=0x00;
send_packet(&txdnet,60);
}
void arp_answer()//ARP应答
{
unsigned char i;
//??????????????????????????????????删
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -