⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ne2000.c

📁 51单片机控制网卡实现上网程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                #if DEBUG == 1
                    sprintf(tmpstr,"ARP source ip %d.%d.%d.%d\n", (uint)source_ip[0], (uint)source_ip[1]
                                                          , (uint)source_ip[2], (uint)source_ip[3]);
					trans_str(tmpstr);
                    sprintf(tmpstr,"ARP dest   ip %d.%d.%d.%d\n", (uint)dest_ip[0], (uint)dest_ip[1]
                                                          , (uint)dest_ip[2], (uint)dest_ip[3]);
					trans_str(tmpstr);
                #endif

                if (dest_ip[0] == my_ip[0] && dest_ip[1] == my_ip[1] &&
                     dest_ip[2] == my_ip[2] && dest_ip[3] == my_ip[3]) {

                    // The ARP was for us, so let's respond

                    arp_response();

                    }
                break;

            case IP:
                #if DEBUG == 1
                    trans_str("IP");
                #endif

                // Recieve IP Header

                version = myinportb(NIC_DATA);
                hdr_len = (version & 0x0F) << 2;
                opt_len = hdr_len - 20;
                version = version >> 4 ;

//              if (hdr_len < 0)
//                  break;

                // discard type of service

                myinportb(NIC_DATA);

                // IP packet length

                IP_length = myinportb(NIC_DATA) << 8;
                IP_length += myinportb(NIC_DATA);

                // Identification

                identification = myinportb(NIC_DATA) << 8;
                identification += myinportb(NIC_DATA);

                // Fragment

                fragment = myinportb(NIC_DATA) << 8;
                fragment += myinportb(NIC_DATA);

                // dicard time to live (the packets already here)

                myinportb(NIC_DATA);

                // IP Protocol

                IP_protocol = myinportb(NIC_DATA);

                // get header checksum

                chksum = myinportb(NIC_DATA)<<8;
                chksum += myinportb(NIC_DATA);

                // get ip address of packet source

                for (i=0; i<4 ; i++)
                    source_ip[i] = myinportb(NIC_DATA);

                // get ip address of destination

                for (i=0; i<4 ; i++)
                    dest_ip[i] = myinportb(NIC_DATA);

                trans_str("\n");

                for (i=0; i<4 ; i++)
                {
                    sprintf(tmpstr,"%d.",(uint)source_ip[i]);
					trans_str(tmpstr);
                }
                trans_str("\n->");
                for (i=0; i<4 ; i++)
                {
                    sprintf(tmpstr,"%d.",(uint)dest_ip[i]);
					trans_str(tmpstr);
                }
                trans_str("\n");
                // discard options if any

                for (i=0; i<opt_len ; i++)
                    myinportb(NIC_DATA);

                #if DEBUG == 1
                    sprintf(tmpstr,"Option length = %d\n",(uint)opt_len);
					trans_str(tmpstr);
                #endif

                switch (IP_protocol) {

                    case ICMP:

                        #if DEBUG == 1
                            trans_str("-ICMP");
                        #endif

                        icmp_type = myinportb(NIC_DATA);

                        if (icmp_type == ECHO) {

                            #if DEBUG == 1
                                trans_str("--PING");
                            #endif

                            // This is a PING

                            // retrieve 'code'
                            icmp_code = myinportb(NIC_DATA);

                            // retrieve 'checksum'
                            icmp_checksum = myinportb(NIC_DATA)<<8;
                            icmp_checksum += myinportb(NIC_DATA);

                            // retrieve 'identifier'
                            icmp_identifier = myinportb(NIC_DATA)<<8;
                            icmp_identifier += myinportb(NIC_DATA);

                            // retrieve 'sequence'
                            icmp_sequence = myinportb(NIC_DATA)<<8;
                            icmp_sequence += myinportb(NIC_DATA);
                                                    
                            ping_response();
                        }
                        // Add other ICMP types here
                        
                        break;

                    case TCP:
                        
                        #if DEBUG == 1
                            trans_str("-TCP");
                        #endif

                        // retrieve 'source port'
                        tcp_source_port = myinportb(NIC_DATA)<<8;
                        tcp_source_port += myinportb(NIC_DATA);

                        // retrieve 'destination port'
                        tcp_dest_port = myinportb(NIC_DATA)<<8;
                        tcp_dest_port += myinportb(NIC_DATA);

                        // We only respond to port 80 (HTML requests)
                        if (tcp_dest_port != 80) break;

                        // retrieve sequence number
                        seq[0]=myinportb(NIC_DATA)<<8;
                        seq[0]+=myinportb(NIC_DATA);
                        seq[1]=myinportb(NIC_DATA)<<8;
                        seq[1]+=myinportb(NIC_DATA);

                        // retrieve acknowlegment number
                        ack[0]=myinportb(NIC_DATA)<<8;
                        ack[0]+=myinportb(NIC_DATA);
                        ack[1]=myinportb(NIC_DATA)<<8;
                        ack[1]+=myinportb(NIC_DATA);

                        // retrieve offset
                        offset=(myinportb(NIC_DATA) & 0xF0) >> 2;
                        tcp_options = (offset - 20);

                        // retrieve flags
                        flags=myinportb(NIC_DATA) & 0x3F;

                        if ((flags & TCP_SYN) == TCP_SYN) max_seg=0;

                        // retrieve windows
                        window0=myinportb(NIC_DATA) << 8;
                        window0+=myinportb(NIC_DATA);

                        // discard checksum
                        myinportb(NIC_DATA);
                        myinportb(NIC_DATA);

                        // discard urgent pointer
                        myinportb(NIC_DATA);
                        myinportb(NIC_DATA);

                        
                        // Handle options
                        for (i=0 ; i < tcp_options ; i++) {
                            kind = myinportb(NIC_DATA);
                            switch (kind) {
                                case 2:
                                    myinportb(NIC_DATA);
                                    if ((flags & TCP_SYN) == TCP_SYN) {
                                        max_seg = myinportb(NIC_DATA) << 8;
                                        max_seg += myinportb(NIC_DATA);
                                    } else {
                                        myinportb(NIC_DATA);
                                        myinportb(NIC_DATA);
                                    }
                                    i=i+3;
                                case 0:
                                case 1:
                                break;
                                }
                                                
                        }

                        tcp_response();
                        
                        break;

                    case UDP:

                        #if DEBUG == 1
                            trans_str("-UDP");
                        #endif

                        break;
                }                       

                
            }

        myoutportb(CR, 0x22);
        myoutportb(BNDRY, next_ptr);
    
        return FALSE;
        }
    return TRUE;
    }

// ********************************************************
void arp_response(void) {

    u16_t i;

    // prepare ethernet packet

    load_ethernet_header();

    // packet type

    myoutportb(NIC_DATA, ARP >> 8);
    myoutportb(NIC_DATA, ARP );

    // hardware type (0x0001 = ethernet)

    myoutportb(NIC_DATA, 0x00);
    myoutportb(NIC_DATA, 0x01);

    // protocol type (0x0800 = IP)

    myoutportb(NIC_DATA, 0x08);
    myoutportb(NIC_DATA, 0x00);

    // hardware address length (6 bytes)

    myoutportb(NIC_DATA, 0x06);

    // protocol address length (4 bytes)

    myoutportb(NIC_DATA, 0x04);

    // opcode (ARP reply)

    myoutportb(NIC_DATA, 0x00);
    myoutportb(NIC_DATA, 0x02);

    // my hardware address

    for (i=0 ; i<6 ; i++)
        myoutportb(NIC_DATA, physical_address[i]);

    // my ip address

    for (i=0 ; i<4 ; i++)
        myoutportb(NIC_DATA, my_ip[i]);

    // source hardware address

    for (i=0 ; i<6 ; i++)
        myoutportb(NIC_DATA, source_address[i]);

    // source ip address

    for (i=0 ; i<4 ; i++)
        myoutportb(NIC_DATA, source_ip[i]);

    // pad to 46 bytes (46-28=18)

    for (i=0 ; i<18 ;i++)
        myoutportb(NIC_DATA, 0x00);

    // packet assmebled so let's send it

    send_packet(60);

    }

// ********************************************************
void load_ethernet_header(void) {

    u16_t i;
    
    remote_dma_setup(WRITE, XMT_BUF_START << 8);

    // write hardware addresses

    for(i=0 ; i<6 ; i++)
        myoutportb(NIC_DATA, source_address[i]);
    for(i=0 ; i<6 ; i++)
        myoutportb(NIC_DATA, physical_address[i]);

    }

// ********************************************************
void send_packet(u16_t len) {

    myoutportb(CR, 0x22);
    myoutportb(TBCR0, len );
    myoutportb(TBCR1, len >> 8);
    myoutportb(TPSR, XMT_BUF_START);
    myoutportb(CR, 0x26);
    }

// ********************************************************
void ping_response() {

    u16_t prev_chksum;
    u16_t i;

    // prepare ethernet packet
    load_ethernet_header();                 // Load MAC source and destination addresses

    // prepare IP header
    load_IP_header(28,ICMP);                // load IP header

    chksum=0;

    myoutportw(NIC_DATA, (u16_t)icmp_code); // Type = 0 (echo reply)

    prev_chksum=chksum;
    chksum += icmp_identifier;
    if (chksum<prev_chksum) chksum++;

    prev_chksum=chksum;
    chksum += icmp_sequence;
    if (chksum<prev_chksum) chksum++;

    myoutportw(NIC_DATA, ~chksum);

    myoutportw(NIC_DATA, icmp_identifier);

    myoutportw(NIC_DATA, icmp_sequence);

    for (i=0 ; i<18 ; i++)
        myoutportb(NIC_DATA, 0x00);         // pad to 60 bytes + 4 for CRC = 64 (min ethernet packet)

    send_packet(60);

    }

// ********************************************************
void load_IP_header(u16_t IP_packet_length, u16_t IP_send_protocol) {

    u16_t i;
    u16_t prev_chksum;

    myoutportb(NIC_DATA, IP >> 8);              // IP packet
    myoutportb(NIC_DATA, IP);

    chksum = 0;

    myoutportw(NIC_DATA, 0x4500);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -