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

📄 ip_arp_udp_tcp.c

📁 Control ENC28J60 codevision
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "net.h"#include "enc28j60.h"
#include <mega64.h>
#include "usart.h"
unsigned char wwwport=80;unsigned char macaddr[6];unsigned char ipaddr[4];unsigned int info_hdr_len=0;unsigned int info_data_len=0;unsigned char seqnum=0xa; // my initial tcp sequence number// The Ip checksum is calculated over the ip header only starting// with the header length field and a total length of 20 bytes// unitl ip.dst// You must set the IP checksum field to zero before you start// the calculation.// len for ip is 20.//// For UDP/TCP we do not make up the required pseudo header. Instead we // use the ip.src and ip.dst fields of the real packet:// The udp checksum calculation starts with the ip.src field// Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len// In other words the len here is 8 + length over which you actually// want to calculate the checksum.// You must set the checksum field to zero before you start// the calculation.// len for udp is: 8 + 8 + data length// len for tcp is: 4+4 + 20 + option len + data length//// For more information on how this algorithm works see:// http://www.netfor2.com/checksum.html// http://www.msc.uky.edu/ken/cs471/notes/chap3.htm// The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.htmlunsigned char checksum(unsigned char *buf, unsigned int len,unsigned char type)
{        // type 0=ip         //      1=udp        //      2=tcp        unsigned long int sum = 0;        //if(type==0){        //        // do not add anything        //}        if(type==1){                sum+=IP_PROTO_UDP_V; // protocol udp                // the length here is the length of udp (data+header len)                // =length given to this function - (IP.scr+IP.dst length)                sum+=len-8; // = real tcp len        }        if(type==2){                sum+=IP_PROTO_TCP_V;                 // the length here is the length of tcp (data+header len)                // =length given to this function - (IP.scr+IP.dst length)                sum+=len-8; // = real tcp len        }        // build the sum of 16bit words        while(len >1)
        {                sum +=( 0xFFFF & ((*buf)<<8|*(buf+1)) );                buf+=2;                len-=2;        }        // if there is a byte left then add it (padded with zero)        if (len){                sum += (0xFF & *buf)<<8;        }        // now calculate the sum over the bytes in the sum        // until the result is only 16bit long        while (sum>>16){                sum = (sum & 0xFFFF)+(sum >> 16);        }        // build 1's complement:        return( (unsigned char) sum ^ 0xFFFF);}// you must call this function once before you use any of the other functions:void init_ip_arp_udp_tcp(unsigned char *mymac,unsigned char *myip,unsigned char wwwp)
{        unsigned char i=0;        wwwport=wwwp;        while(i<4){                ipaddr[i]=myip[i];                i++;        }        i=0;        while(i<6){                macaddr[i]=mymac[i];                i++;        }}unsigned char eth_type_is_arp_and_my_ip(unsigned char* buf,unsigned int len)
{        unsigned char i=0;
        //
                  if (len<41)
        {
                     return(0);        }        if( (buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V) || (buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V) )        
        {                
                DDRD.6=1;PORTD.6=~PORTD.6;
                return(0);
                        }        while(i<4)
        {                if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i])                
                {                        return(0);                }                i++;        }
        
                return(1);}unsigned char eth_type_is_ip_and_my_ip(unsigned char* buf,unsigned char len)
{        unsigned char i=0;        //eth+ip+udp header is 42
         
         putchar1(' ');
         putchar1((len/100)%10+'0');
         putchar1((len/10)%10+'0');
         putchar1(len%10+'0');
         putchar1(' ');
         for(i=0;i<len;i++)
         {
            convert(i);
            putchar1(' ');
            convert( *(buf+i) );
            putchar1(' ');
            putchar1(' ');
         }
         putchar1('\n');
         putchar1('\r');
         i=0;
        
                if (len<42)
        {                return(0);        }        if(buf[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V || buf[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V)
        {                DDRD.4=1;PORTD.4=~PORTD.4;
                return(0);        }        if (buf[IP_HEADER_LEN_VER_P]!=0x45)
        {                // must be IP V4 and 20 byte header                return(0);        }        while(i<4)
        {                if(buf[IP_DST_P+i]!=ipaddr[i]){                        return(0);                }                i++;        }        return(1);}// make a return eth header from a received eth packetvoid make_eth(unsigned char *buf){        unsigned char i=0;        //        //copy the destination mac from the source and fill my mac into src        while(i<6){                buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i];                buf[ETH_SRC_MAC +i]=macaddr[i];                i++;        }}// make a new eth header for IP packetvoid make_eth_ip_new(unsigned char *buf, unsigned char* dst_mac){        unsigned char i=0;        //        //copy the destination mac from the source and fill my mac into src        while(i<6){                buf[ETH_DST_MAC +i]=dst_mac[i];                buf[ETH_SRC_MAC +i]=macaddr[i];                i++;        }            buf[ ETH_TYPE_H_P ] = ETHTYPE_IP_H_V;      buf[ ETH_TYPE_L_P ] = ETHTYPE_IP_L_V;}void fill_ip_hdr_checksum(unsigned char *buf){        unsigned char ck;        // clear the 2 byte checksum        buf[IP_CHECKSUM_P]=0;        buf[IP_CHECKSUM_P+1]=0;        buf[IP_FLAGS_P]=0x40; // don't fragment        buf[IP_FLAGS_P+1]=0;  // fragement offset        buf[IP_TTL_P]=64; // ttl        // calculate the checksum:        ck=checksum(&buf[IP_P], IP_HEADER_LEN,0);        buf[IP_CHECKSUM_P]=ck>>8;        buf[IP_CHECKSUM_P+1]=ck& 0xff;}static unsigned char ip_identifier = 1;// make a new ip header for tcp packet// make a return ip header from a received ip packetvoid make_ip_tcp_new(unsigned char *buf, unsigned char len,unsigned char *dst_ip){    unsigned char i=0;         // set ipv4 and header length   buf[ IP_P ] = IP_V4_V | IP_HEADER_LENGTH_V;   // set TOS to default 0x00   buf[ IP_TOS_P ] = 0x00;   // set total length   buf[ IP_TOTLEN_H_P ] = (len >>8)& 0xff;   buf[ IP_TOTLEN_L_P ] = len & 0xff;      // set packet identification   buf[ IP_ID_H_P ] = (ip_identifier >>8) & 0xff;   buf[ IP_ID_L_P ] = ip_identifier & 0xff;   ip_identifier++;      // set fragment flags      buf[ IP_FLAGS_H_P ] = 0x00;   buf[ IP_FLAGS_L_P ] = 0x00;      // set Time To Live   buf[ IP_TTL_P ] = 128;      // set ip packettype to tcp/udp/icmp...   buf[ IP_PROTO_P ] = IP_PROTO_TCP_V;      // set source and destination ip address        while(i<4){                buf[IP_DST_P+i]=dst_ip[i];                buf[IP_SRC_P+i]=ipaddr[i];                i++;        }        fill_ip_hdr_checksum(buf);}// make a return ip header from a received ip packetvoid make_ip(unsigned char *buf){        unsigned char i=0;        while(i<4){                buf[IP_DST_P+i]=buf[IP_SRC_P+i];                buf[IP_SRC_P+i]=ipaddr[i];                i++;        }        fill_ip_hdr_checksum(buf);}// make a return tcp header from a received tcp packet// rel_ack_num is how much we must step the seq number received from the// other side. We do not send more than 255 bytes of text (=data) in the tcp packet.// If mss=1 then mss is included in the options list//// After calling this function you can fill in the first data byte at TCP_OPTIONS_P+4// If cp_seq=0 then an initial sequence number is used (should be use in synack)// otherwise it is copied from the packet we receivedvoid make_tcphead(unsigned char *buf,unsigned char rel_ack_num,unsigned char mss,unsigned char cp_seq){        unsigned char i=0;        unsigned char tseq;        while(i<2){                buf[TCP_DST_PORT_H_P+i]=buf[TCP_SRC_PORT_H_P+i];                buf[TCP_SRC_PORT_H_P+i]=0; // clear source port                i++;        }        // set source port  (http):        buf[TCP_SRC_PORT_L_P]=wwwport;        i=4;        // sequence numbers:        // add the rel ack num to SEQACK        while(i>0){                rel_ack_num=buf[TCP_SEQ_H_P+i-1]+rel_ack_num;                tseq=buf[TCP_SEQACK_H_P+i-1];                buf[TCP_SEQACK_H_P+i-1]=0xff&rel_ack_num;                if (cp_seq){                        // copy the acknum sent to us into the sequence number                        buf[TCP_SEQ_H_P+i-1]=tseq;                }else{                        buf[TCP_SEQ_H_P+i-1]= 0; // some preset vallue                }                rel_ack_num=rel_ack_num>>8;                i--;        }        if (cp_seq==0){                // put inital seq number                buf[TCP_SEQ_H_P+0]= 0;                buf[TCP_SEQ_H_P+1]= 0;                // we step only the second byte, this allows us to send packts                 // with 255 bytes or 512 (if we step the initial seqnum by 2)                buf[TCP_SEQ_H_P+2]= seqnum;                 buf[TCP_SEQ_H_P+3]= 0;                // step the inititial seq num by something we will not use                // during this tcp session:                seqnum+=2;        }        // zero the checksum        buf[TCP_CHECKSUM_H_P]=0;        buf[TCP_CHECKSUM_L_P]=0;        // The tcp header length is only a 4 bit field (the upper 4 bits).        // It is calculated in units of 4 bytes.         // E.g 24 bytes: 24/4=6 => 0x60=header len field        //buf[TCP_HEADER_LEN_P]=(((TCP_HEADER_LEN_PLAIN+4)/4)) <<4; // 0x60        if (mss){                // the only option we set is MSS to 1408:                // 1408 in hex is 0x580                buf[TCP_OPTIONS_P]=2;                buf[TCP_OPTIONS_P+1]=4;                buf[TCP_OPTIONS_P+2]=0x05;                 buf[TCP_OPTIONS_P+3]=0x80;                // 24 bytes:                buf[TCP_HEADER_LEN_P]=0x60;        }else{                // no options:                // 20 bytes:                buf[TCP_HEADER_LEN_P]=0x50;        }}void make_arp_answer_from_request(unsigned char *buf){        unsigned char i=0;        //        make_eth(buf);        buf[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V;        buf[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V;        // fill the mac addresses:        while(i<6){                buf[ETH_ARP_DST_MAC_P+i]=buf[ETH_ARP_SRC_MAC_P+i];                buf[ETH_ARP_SRC_MAC_P+i]=macaddr[i];                i++;        }        i=0;        while(i<4){                buf[ETH_ARP_DST_IP_P+i]=buf[ETH_ARP_SRC_IP_P+i];                buf[ETH_ARP_SRC_IP_P+i]=ipaddr[i];                i++;        }        // eth+arp is 42 bytes:        enc28j60PacketSend(42,buf); }void make_echo_reply_from_request(unsigned char *buf,unsigned int len){

⌨️ 快捷键说明

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