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

📄 ne2000.c

📁 51单片机控制网卡实现上网程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:

    myoutportw(NIC_DATA, IP_packet_length);

    myoutportw(NIC_DATA, identification);

    myoutportw(NIC_DATA, 0x0000);               // Okay to fragment

    myoutportw(NIC_DATA, 0xFF00 + IP_send_protocol);
                                            // Time-To-Live set to max 255

    prev_chksum = chksum;
    chksum += ((u16_t)my_ip[0]<<8) + my_ip[1];
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)my_ip[2]<<8) + my_ip[3];
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)source_ip[0]<<8) + source_ip[1];
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)source_ip[2]<<8) + source_ip[3];
    if (chksum < prev_chksum) chksum++;

    #if DEBUG > 1
        trans_str("-----");
        trans_str("4500");
        sprintf(tmpstr,"%X\n",(uint)IP_packet_length);
		trans_str(tmpstr);
        sprintf(tmpstr,"%X\n",(uint)identification);
		trans_str(tmpstr);
        trans_str("0000");
        sprintf(tmpstr,"%X\n",(uint)(0xFF00+IP_send_protocol));
		trans_str(tmpstr);
        sprintf(tmpstr,"%X\n",(uint)(~chksum));
		trans_str(tmpstr);
        sprintf(tmpstr,"%X%X\n",(uint)my_ip[0],(uint)my_ip[1]);
		trans_str(tmpstr);
        sprintf(tmpstr,"%X%X\n",(uint)my_ip[2],(uint)my_ip[3]);
		trans_str(tmpstr);
        sprintf(tmpstr,"%X%X\n",(uint)source_ip[0],(uint)source_ip[1]);
		trans_str(tmpstr);
        sprintf(tmpstr,"%X%X\n",(uint)source_ip[2],(uint)source_ip[3]);
		trans_str(tmpstr);
    #endif

    myoutportw(NIC_DATA, ~chksum);              // Header Checksum

    for (i=0 ; i<4 ; i++)                   // source IP address for this packet
        myoutportb(NIC_DATA, my_ip[i]);

    for (i=0 ; i<4 ; i++)                   // destination IP address for this packet
        myoutportb(NIC_DATA, source_ip[i]);


    }

// ********************************************************
void tcp_response(void) {

    u16_t i;

    switch (html_socket) {

        case LISTEN:
            trans_str("L");

            // *** We are expecting a SYN without an ACK
            // *** Could get a RST, FIN, PSH or URG but we'll ignore the PSH or URG
            if (flags & TCP_SYN) {
                // SYN set
                // We should check to be sure an ACK wasn't also sent
                if (flags & TCP_ACK) {
                    break;                  // Ignore it for now. We'll add code to handle later
                    }
                // We shouldn't have a RST or FIN with a SYN
                if (flags & TCP_RST || flags & TCP_FIN) {
                    break;                  // Ignore it for now. We'll add code to hanlde later
                    }
                // Everything looks okay so handle the SYN request
                // Save the senders sequence number

                tcp_listen();

            }

            break;

        case SYN_RCVD:
            trans_str("S");

            // Check if addressed for this socket

            if (port!=tcp_source_port || ip[0]!=source_ip[0] || ip[1]!=source_ip[1] ||
                ip[2]!=source_ip[2] || ip[3]!= source_ip[3])
                break;

            // We are expecting an ACK without a SYN
            if (flags & TCP_ACK) {
                // ACK set
                // We should check to be sure an SYN wasn't also sent
                if (flags & TCP_SYN) {
                    break;                  // Ignore it for now. We'll add code to handle later
                    }
                // We shouldn't have a RST or FIN with an ACK
                if (flags & TCP_RST || flags & TCP_FIN) {
                    break;                  // Ignore it for now. We'll add code to hanlde later
                    }
                // Everything looks okay so handle the ACK response

                tcp_syn_rcvd();

            }

            break;


        case ESTAB:
            trans_str("E");

            // We are expecting an ACK without or SYN
            // We could receive a FIN
            if (flags & TCP_ACK) {
                // ACK set
                // We should check to be sure an SYN wasn't also sent
                    if (flags & TCP_SYN) {
                    break;                  // Ignore it for now. We'll add code to handle later
                    }
                // We shouldn't have a RST with an ACK
                if (flags & TCP_RST ) {
                    break;                  // Ignore it for now. We'll add code to hanlde later
                    }


                // ************************************************************
                // *** - check received sequence number to be sure it's     ***
                // ***   what we expected                                   ***
                // *** - check acknowledgement number to be sure it's what  ***
                // ***   we are going to send                               ***
                // *** - check source ip address and source port to be sure ***
                // ***   they are correct                                   ***
                // ************************************************************



                if (seq[0] != xm_ack[0] || seq[1] != xm_ack[1] ||
                    ack[0] != xm_seq[0] || ack[1] != xm_seq[1])
                        break;



                if (port != tcp_source_port)
                    break;



                if (ip[0] != source_ip[0] || ip[1] != source_ip[1] ||
                    ip[2] != source_ip[2] || ip[3] != source_ip[3])
                        break;

                trans_str("I-");

                // Everything looks okay so handle the ACK response

                tcp_estab();

                }       
            
        }   
    
    }

// ********************************************************
void load_TCP_header(u16_t data_flags, u16_t tcp_chksum, u16_t tcp_length) {

    u16_t prev_chksum;

    chksum = tcp_chksum;

    // calculate checksum of pseudo header

    prev_chksum = chksum;
    chksum += ((u16_t)my_ip[0]<<8) + my_ip[1];
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)my_ip[2]<<8) + my_ip[3];
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)source_ip[0]<<8) + source_ip[1]; 
    if (chksum < prev_chksum) chksum++;

    prev_chksum = chksum;
    chksum += ((u16_t)source_ip[2]<<8) + source_ip[3];
    if (chksum < prev_chksum) chksum++;

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

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

    // source port

    myoutportw(NIC_DATA, tcp_dest_port);

    // destination port

    myoutportw(NIC_DATA, tcp_source_port);

    // sequence number

    myoutportw(NIC_DATA, xm_seq[0]);
    myoutportw(NIC_DATA, xm_seq[1]);

    // acknowledment number

    myoutportw(NIC_DATA, xm_ack[0]);
    myoutportw(NIC_DATA, xm_ack[1]);

    // data offset and flags

    myoutportw(NIC_DATA, data_flags);

    // window0

    myoutportw(NIC_DATA, 1460);

    // checksum

    myoutportw(NIC_DATA, ~chksum);

    // urgent pointer

    myoutportw(NIC_DATA, 0);


    }

// ********************************************************
void tcp_listen(void) {

    u16_t i;

    xm_ack[0] = seq[0];
    xm_ack[1] = seq[1];

    port = tcp_source_port;

    // Save the source IP address

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

    // Calculate data length

    tcp_data_len = IP_length - (hdr_len + offset);

    // Increment sequence to account for SYN and add data

    xm_ack[1] += tcp_data_len + 1;
    if (xm_ack[1] < seq[1] )
        xm_ack[0]++;

    // *** Need to handle data if any here.

    // Let's reply with our on SYN and an ACK
    // We should include a Max Recieve window0 option

    xm_seq[1]++;
    if (xm_seq[1] == 0)
        xm_seq[0]++;

    load_ethernet_header();     // 12 bytes (2 bytes for protocol included in load_IP..)

    load_IP_header(48,TCP);     // Number of bytes included in call (add 2 for protocol)
                                // 20 for IP header
                                // 20 for TCP header
                                // 8 for Options


    load_TCP_header( 0x7000 | TCP_SYN | TCP_ACK, 0x07B8, 28);
                                // Number of bytes include in load_IP_header call 
    
    // Send options

    myoutportb(NIC_DATA,0x02);
    myoutportb(NIC_DATA,0x04);
    myoutportb(NIC_DATA,0x05);
    myoutportb(NIC_DATA,0xb4);
    myoutportb(NIC_DATA,0x00);
    myoutportb(NIC_DATA,0x00);
    myoutportb(NIC_DATA,0x00);
    myoutportb(NIC_DATA,0x00);

    send_packet(62);

    // Calculate the next sequence number to send
    // In this case we add 1 since we only sent a SYN

    xm_seq[1]++;
    if (xm_seq[1] == 0)
        xm_seq[0]++;
    
    html_socket = SYN_RCVD;
    
}

// ********************************************************
void tcp_syn_rcvd(void) {


    // Calculate data length

    tcp_data_len = IP_length - (hdr_len + offset);

    // Increment sequence to account for data

    xm_ack[1] += tcp_data_len;
    if (xm_ack[1] < seq[1] )
        xm_ack[0]++;

    // *** Need to handle data if any here.
    // We'll assume there isn't any for now so no response is needed

    html_socket = ESTAB;

}

// ********************************************************
void tcp_estab(void) {

    tcp_data_len = IP_length - (hdr_len + offset);

    // This is the next sequence number we expect

    xm_ack[1] += tcp_data_len;
    if (xm_ack[1] < seq[1] )
        xm_ack[0]++;

    // Let's cheat and send an HTML response

    load_ethernet_header();     // 12 bytes (2 bytes for protocol included in load_IP..)

    load_IP_header(188,TCP);        // Number of bytes included in call (add 2 for protocol)
                                // 20 for IP header
                                // 20 for TCP header
                                // 148 for Data


    load_TCP_header( 0x5000 | TCP_ACK | TCP_FIN, 0x07AC, 148);
                                // Number of bytes include in load_IP_header call


    myoutportstr(NIC_DATA,"HTTP/1.0 200 OK\r\n"
                                 "Content-type: text/html\r\n\r\n"
                                 "<HTML><body>SimmStick&reg; Web Server<br>"
                                 "using a PIC 16F874<br>"
                                 "by David C. Witt (12/24/00)</body></HTML>");

    xm_ack[1] += 148;
    if (xm_ack[1] < seq[1])
        xm_ack[0]++;

    send_packet(202);

    html_socket = LISTEN;

}
// ********************************************************

⌨️ 快捷键说明

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