1 / 24

網路程式

網路程式. 目前提供的嵌入式 UDP/IP 程式. 當有封包暫存於網卡時, 8051 向網卡取出一個封包置於 8051 內部 SRAM 後,釋放此封包佔用網卡空間,才開始處理此封包。 目前此版提供的功能,主要是令本機端處於被動模式。 提供 ARP Reply ,不提供 ARP Request 。. 主程式架構. Main() { var_init(); NICInit(); while(1) { while (HavePacketRecev()) {

jackie
Download Presentation

網路程式

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 網路程式

  2. 目前提供的嵌入式UDP/IP程式 • 當有封包暫存於網卡時,8051向網卡取出一個封包置於8051內部SRAM後,釋放此封包佔用網卡空間,才開始處理此封包。 • 目前此版提供的功能,主要是令本機端處於被動模式。 • 提供ARP Reply,不提供ARP Request。

  3. 主程式架構 Main() { var_init(); NICInit(); while(1) { while (HavePacketRecev()) { if (RecvPacket(E_recv,512)) // packet < 512 bytes { Ni_in(); } } } }

  4. void main() { xdata char daaa[100]; int j=0; InitSerial(); var_init(); delay(1000); NICInit(); for (i=0;i<100;i++) { daaa[i]=my_IP[j]; j++; if (j>3) { j=0; } } while(1) { delay(1000); delay(1000); delay(1000); delay(1000); delay(1000); P11=~P11; SendPacket(daaa,100); while (HavePacketRecev()) { if(RecvPacket(E_recv,512)) // packet < 512 bytes { Ni_in(); } } } }

  5. void var_init(void); • 設定傳送封包時本地MAC Address • 當有封包欲傳送時,若需要Source MAC Address會取自此陣列(unsigned char my_MAC[6];) • 設定傳送封包時本地IP Address • 當有封包欲傳送時,若需要Source IP address會取自此陣列(unsigned char my_IP[6];) • 設定next_page=0x46 • 當欲檢查網卡是否收到封包時,將讀取網卡內部CURR暫存器內容並與此變數比較 • 使用者也可把其它需初始化的變數放於此含函數內一起初始化

  6. Var_init() : 設定MAC/IP Address void var_init() { next_page=0x46; my_MAC[0]=0x11; my_MAC[1]=0x80; my_MAC[2]=0xAD; my_MAC[3]=0x84; my_MAC[4]=0xF8; my_MAC[5]=0x44; my_IP[0]=140; my_IP[1]=125; my_IP[2]=33; my_IP[3]=206; memcpy(&E_send[6],my_MAC,6); }

  7. void NICInit(void) • 初始化網卡內部暫存器 • CR、DCR、RBCR0、RBCR1、TPSR、TCR、PSTART、BNRY、PSTOP、RCR、ISR、IMR、CURR、PAR0-5 • Ex: 規劃TPSR=0x40、PSTART=0x40、PSTOP=0x60、BNRY=0x5F、CURR=0x40

  8. char HavePacketRecev(void) • 檢查網卡內部是否有封包 • 判斷next_page是否等於網卡內部CURR。是則代表無封包,不等則代表有封包 • 回傳 • 無封包回傳0,有封包回傳非1

  9. char HavePacketRecev(void) { unsigned char curr; fEthernet_Write(CR,0x62); curr=fEthernet_Read(CURR); fEthernet_Write(CR,0x22); if (curr==next_page) return 0; else return 1; }

  10. unsigned int RecvPacket(unsigned char *buf_packet, int limit) • unsigned char *buf_packet • 提供一個空間給收封包函數放資料的地方 • int limit • 告訴函數最多不超過Limit指定的封包大小 • 回傳 • 告知填入幾Bytes資料於buf_packet陣列中。若網卡內封包長度大於Limit規定,則回傳0,並將此封包丟棄

  11. void SendPacket(unsigned char *buf_packet, unsigned int packetlength) • unsigned char *buf_packet • 告知函數欲傳送至Ethernet的資料起始位置 • unsigned int packetlength • 資料量長度 • 回傳 • 無

  12. void Ni_in(void) • 解析經由RecvPacket( )函數所收的網卡封包 • Ni_in( )做demux功能,根據所收封包格式, 呼叫相對應函數進行進一步處理。 • 若為ARP協定則呼叫ARP_in( ), • 若為IP協定則呼叫IP_in( )。 • 非以上兩種協定之封包時,將丟棄此封包。

  13. void Ni_in() { if ( E_recv[12]==0x08 ) // Ethernet Frame type 0x08 { switch (E_recv[13]) // Ethernet Frame type 0x00 IP , 0x06 ARP { case 0x00: if (!is_broadcast_MAC(E_recv)) IP_in(); break; case 0x06: if (is_broadcast_MAC(E_recv)) ARP_in(); break; } } }

  14. void ARP_in(void); • 檢查所收封包的payload • 若為ARP協定之ARP Request,則產生ARP Reply格式資料,並置於E_send[ ]陣列中 • 呼叫SendPacket( )函數將資料組成Ethernet封包格式送至Ethernet。 • 此版本之程式不會主動發出ARP Request格式封包,故收到ARP Reply封包時,不予以理會。

  15. void ARP_in() { ARP *arp,*arp2; arp=(ARP *) &E_recv[14]; arp2=(ARP *) &E_send[14]; if (arp->op==0x0001) // ARP request { if ( !memcmp(arp->DIP,my_IP,4) ) // is my IP, ARP reply { memcpy(E_send,arp->SHA,6); // Target MAC memcpy(&E_send[6],my_MAC,6); // Source MAC memcpy(&E_send[12],&E_recv[12],8); // Frame type... arp2->op=0x0002; // ARP reply code memcpy(arp2->SHA,my_MAC,6); memcpy(arp2->DIP,arp->SIP,4); memcpy(arp2->DHA,arp->SHA,6); memcpy(arp2->SIP,my_IP,4); SendPacket(E_send,60); } } }

  16. void IP_in(void) • 檢查IP協定表頭,若所帶之資料為ICMP協定格式資料,則呼叫ICMP_in( )處理。若為UDP協定格式資料,則呼叫UDP_in( )。 • 目前只能處理ICMP與UDP協定,若非此兩種協定則不處理。 • 目前版本之IP_in( )函數內並不作CheckSum運算。雖失去IP協定之CheckSum用意(可靠性),以加快處理IP層處理。

  17. void IP_in() { IP_header *ip; ip=(IP_header *) &E_recv[14]; if ( !memcmp(my_IP,ip->ip_dst,4) ) // is my IP, My IP packet { switch (ip->ip_proto) { case 0x01: // ICMP code ICMP_in(); break; case 0x11: // UDP code UDP_in(); break; } } }

  18. void ICMP_in(void) • 若為ICMP協定中之ECHO Request,則產生ECHO Reply格式資料放置於E_send[ ]陣列中,並呼叫IP_out( )函數將ICMP ECHO Reply封包資料送出。 • 若非ICMP之ECHO Request封包,則不處理 • 實作此協定為了檢查之用,當系統Power-On後,於電腦端使用Ping程式檢查是否可與本系統做基本網路通訊之測試。

  19. void ICMP_in() { IP_header *ip,*ip2; unsigned int *sum; if (E_recv[34]==0x08) // is ECHO request, must ECHO reply { ip=(IP_header *) &E_recv[14]; ip2=(IP_header *) &E_send[14]; sum=(unsigned int *)&(ip2->ip_data[2]); memcpy(E_send,&E_recv[6],6); // Target_MAC ip2->ip_proto=0x01; // ICMP packet ip2->ip_data[0]=0x00; // ECHO reply ip2->ip_data[1]=0x00; // Code 00 ip2->ip_data[2]=0x00; // ICMP checksum ip2->ip_data[3]=0x00; memcpy(&ip2->ip_data[4],&ip->ip_data[4],(ip->ip_len)-24); //ID & seq NO. & data *sum=cksum( (unsigned short *)&(ip2->ip_data),((ip->ip_len)-20)>>1 ); IP_out(&E_recv[26],0x40,ip->ip_len); // Dest IP out } }

  20. void IP_out(void *dip,unsigned char ttl,int size) • 添加IP-Head於E_send[ ]陣列中,呼叫SendPacket將資料組成Ethernet封包格式送至Ethernet。 • void *dip • 目的地IP Address • unsigned char ttl • 設定IP-Head之TTL • int size • IP-Head加上IP-Data總長度 • 回傳 • 無

  21. void IP_out(void *dip,unsigned char ttl,int size) { static int id=1; IP_header *ip; ip=(IP_header *) &E_send[14]; memcpy(ip->ip_dst,dip,4); // Target IP address memcpy(ip->ip_src,my_IP,4); // My IP address memcpy(&E_send[6],my_MAC,6); // Source MAC E_send[12]=0x08; // Ethernet Type = 08 00 ,IP E_send[13]=0x00; // Ethernet Type ip->ip_verlen=0x45; // Version 4, Header length 20 byte (5*4) ip->ip_tos=0x00; // Type of Service ip->ip_ttl=ttl; // TTL ip->ip_fragoff=0x0000; // non-fragement ip->ip_id=id++; // IP identify, a seq NO. ip->ip_len=size; // IP length ip->ip_cksum=0x0000; ip->ip_cksum=cksum((unsigned short *) &E_send[14],20>>1); size=size+14; if (size<60) size=60; SendPacket(E_send,size); }

  22. void UDP_in(void) • 當IP協定之上層協定為UDP時,將會呼叫此函數。而此函數之功能由使用者自行設計。

  23. void UDP_in() { UDP *udp,*udp2; udp=(UDP *) &E_recv[34]; if (udp->d_port==1024) // Dest port is 1024, ack & save data { udp2=(UDP *) &E_send[34]; udp2->s_port=1024; udp2->d_port=udp->s_port; udp2->udp_len=0x000c; // UDP packet length udp2->checksum=0x0000; udp2->udp_data[0]=0x00; // ACK is 0x00 udp2->udp_data[1]=udp->udp_data[1]; // seq No. udp2->udp_data[2]=0xff; // ACK format udp2->udp_data[3]=0xff; // ACK format udp2->checksum=udp_chksum( (unsigned short *)udp2,12>>1); memcpy(E_send,&E_recv[6],6); // Target_MAC E_send[23]=0x11; // UDP protocol code IP_out(&E_recv[26],0x40,32); // IP + UDP + Data, 20+8+4 } }

  24. RAM記憶體配置(Data)

More Related