int simple_servercycle(void)
{
	uchar tIPAddr[4];
	char i,nS,freeSlot;
	unsigned int	j;
//		OSTimeDlyHMSM(0, 0, 0, 50);
        // get the next new packet:
        plen = enc28j60PacketReceive(BUFFER_SIZE, fbuf);
        //USART_DMASendData(USART1,fbuf,plen);

        /*plen will ne unequal to zero if there is a valid packet (without crc error) */
        if(plen==0)
        	{
            return;
        	}
        // arp is broadcast if unknown but a host may also
        // verify the mac address by sending it to 
        // a unicast address.
        if(eth_type_is_arp_and_my_ip(fbuf,plen))
        	{
			make_arp_answer_from_request(fbuf);
			//USART_DMASendText(USART1,"make_arp_answer_from_request\n");
            return;
        	}

        // check if ip packets are for us:
        if(eth_type_is_ip_and_my_ip(fbuf,plen)==0)
        	{
            return;
        	}

        
        if(fbuf[IP_PROTO_P]==IP_PROTO_ICMP_V && fbuf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
        	{
            // a ping packet, let's send pong	
			make_echo_reply_from_request(fbuf, plen);
			//USART_DMASendText(USART1,"make_echo_reply_from_request\n");
			return;
        	}
               // tcp port www start, compare only the lower byte

		if (fbuf[IP_PROTO_P]==IP_PROTO_TCP_V&&fbuf[TCP_DST_PORT_H_P]==(*PORTNUMBER)/256&&fbuf[TCP_DST_PORT_L_P]==(*PORTNUMBER)%256)
			{
			nS=101;
			freeSlot=9;
			for (i=0;i<MAX_SOCKET_COUNT;i++)
			{
				Sockets[i].Timeout--;
				if (Sockets[i].Timeout<0)
				{
					Sockets[i].Timeout=0;
					Sockets[i].IP_PHASE=0;
				}
				if (!Sockets[i].IP_PHASE) freeSlot=i;
				BufCpy(tIPAddr,Sockets[i].IP_source,4);
				if (check_ip_scr(fbuf,tIPAddr))
				{
					nS=i;break;
				}
			}
			if (nS>100) nS=freeSlot;
            //nS=0;

			if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
				{
                make_tcp_synack_from_syn(fbuf);
                // make_tcp_synack_from_syn does already send the syn,ack
        		Sockets[nS].IP_PHASE=ETH_HEAD;
        		Sockets[nS].Timeout=20;
	            BufCpy(Sockets[nS].IP_source,tIPAddr,4);

                return;
            	}
	        if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
				{
	            GlobData++;
	            init_len_info(fbuf); // init some data structures
	            // we can possibly have no data, just ack:
	            dat_p=get_tcp_data_pointer();
	            if (dat_p==0)
					{
	                if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
						{
	                    // finack, answer with ack
	                    make_tcp_ack_from_any(fbuf);
	                    return;
	                	}
	                // just an ack with no data, wait for next packet
	                }
	            else
	            {
					j=checksum(&fbuf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+info_data_len,2);
					if (j)	return;

	            }
	            check_ip_scr(fbuf,tIPAddr);
//	            GlobData++;
	            BufCpy(Sockets[nS].IP_source,tIPAddr,4);
	            SocketUpdate(nS,fbuf,dat_p,&plen);
	            if (plen)
	            	make_tcp_ack_with_data(fbuf,plen,0); // send data
	            else
	            	make_tcp_ack_from_any(fbuf); // send ack for http get
				return;
				}
			}
	// tcp port www end
	//

}
Beispiel #2
0
void EtherShield::ES_make_tcp_synack_from_syn(uint8_t *buf) {
	make_tcp_synack_from_syn(buf);
}
Beispiel #3
0
int main(void){
        uint16_t plen;
        uint16_t dat_p;
        uint8_t i=0;
        uint8_t payloadlen=0;

        // set the clock speed to 8MHz
        // set the clock prescaler. First write CLKPCE to enable setting of clock the
        // next four instructions.
        //CLKPR=(1<<CLKPCE);
        //CLKPR=0; // 8 MHZ
        _delay_loop_1(50); // 12ms

        // LED
        /* enable PB1, LED as output */
        DDRB|= (1<<DDB1);

        /* one blink for indicate of start programm */
        cbi(PORTB, PORTB1); // on
        _delay_ms(100);
        sbi(PORTB,PORTB1);  // off
        _delay_ms(100);
        cbi(PORTB,PORTB1);  // on

        /*initialize enc28j60*/
        enc28j60Init(mymac);
        enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
        _delay_loop_1(50); // 12ms

        /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
        // LEDB=yellow LEDA=green
        //
        // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
        // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
        enc28j60PhyWrite(PHLCON,0x476);
        _delay_loop_1(50); // 12ms

        /* set output to GND, red LED on */
        PORTB &= ~(1<<PORTB1);
        i=1;

        //init the ethernet/ip layer:
        init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

        while(1){
                // get the next new packet:
                plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

                /*plen will ne unequal to zero if there is a valid
                 * packet (without crc error) */
                if(plen==0){
                        continue;
                }
                // arp is broadcast if unknown but a host may also
                // verify the mac address by sending it to
                // a unicast address.
                if(eth_type_is_arp_and_my_ip(buf,plen)){
                        make_arp_answer_from_request(buf);
                        continue;
                }
                // check if ip packets (icmp or udp) are for us:
                if(eth_type_is_ip_and_my_ip(buf,plen)==0){
                        continue;
                }

                if (i){
                        /* set output to Vcc, LED off */
                        PORTB|= (1<<PORTB1);
                        i=0;
                }else{
                        /* set output to GND, LED on */
                        PORTB &= ~(1<<PORTB1);
                        i=1;
                }


                if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
                        // a ping packet, let's send pong
                        make_echo_reply_from_request(buf,plen);
                        continue;
                }
                // tcp port www start, compare only the lower byte
                if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
                                make_tcp_synack_from_syn(buf);
                                // make_tcp_synack_from_syn does already send the syn,ack
                                continue;
                        }
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
                                init_len_info(buf); // init some data structures
                                // we can possibly have no data, just ack:
                                dat_p=get_tcp_data_pointer();
                                if (dat_p==0){
                                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
                                                // finack, answer with ack
                                                make_tcp_ack_from_any(buf);
                                        }
                                        // just an ack with no data, wait for next packet
                                        continue;
                                }
                                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
                                        // head, post and other methods:
                                        //
                                        // for possible status codes see:
                                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                                }else{
                                        // the "get" method
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>OK, it works</p>"));
                                }

                                make_tcp_ack_from_any(buf); // send ack for http get
                                make_tcp_ack_with_data(buf,plen); // send data
                                continue;
                        }

                }
                // udp interface:
                if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                        // the received command has to start with t and be 4 char long
                        // e.g "test\0"
                        if (buf[UDP_DATA_P]=='t' && payloadlen==5){
                                make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
                        }
                }
        }
        return (0);
}
Beispiel #4
0
int simple_server(void)
	{      
    unsigned int plen;
    unsigned int dat_p;
    unsigned char i=0;
    unsigned char cmd_pos=0;
    unsigned char cmd;
    unsigned char payloadlen=0;
    char str[30];
    char cmdval;

        
//	Del_1ms(100);
	/*initialize enc28j60*/
	enc28j60Init(mymac);
	init_ip_arp_udp_tcp(mymac,myip,mywwwport);
    //ָʾµÆ״̬:0x476 is PHLCON LEDA(ÂÌ)=links status, LEDB(ºì)=receive/transmit
    enc28j60PhyWrite(PHLCON,0x7a4);	
	enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
//	Del_1ms(20);

	//init the ethernet/ip layer:
    while(1)
    	{
//		OSTimeDlyHMSM(0, 0, 0, 50);
        // get the next new packet:
        plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
        //USART_DMASendData(USART1,buf,plen);

        /*plen will ne unequal to zero if there is a valid packet (without crc error) */
        if(plen==0)
        	{
            continue;
        	}
        // arp is broadcast if unknown but a host may also
        // verify the mac address by sending it to 
        // a unicast address.
        if(eth_type_is_arp_and_my_ip(buf,plen))
        	{
			make_arp_answer_from_request(buf);
			//USART_DMASendText(USART1,"make_arp_answer_from_request\n");
            continue;
        	}

        // check if ip packets are for us:
        if(eth_type_is_ip_and_my_ip(buf,plen)==0)
        	{
            continue;
        	}

        
        if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
        	{
            // a ping packet, let's send pong	
			make_echo_reply_from_request(buf, plen);
			//USART_DMASendText(USART1,"make_echo_reply_from_request\n");
			continue;
        	}
               // tcp port www start, compare only the lower byte
		if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport)
			{
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
				{
                make_tcp_synack_from_syn(buf);
                // make_tcp_synack_from_syn does already send the syn,ack
                continue;
            	}
	        if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
				{
	            init_len_info(buf); // init some data structures
	            // we can possibly have no data, just ack:
	            dat_p=get_tcp_data_pointer();
	            if (dat_p==0)
					{
	                if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
						{
	                    // finack, answer with ack
	                    make_tcp_ack_from_any(buf);
	                	}
	                // just an ack with no data, wait for next packet
	                continue;
	                }
				if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
					{
			        // head, post and other methods:
			        //
			        // for possible status codes see:
			        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
			        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
			        goto SENDTCP;
					}
				if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0)
					{
			        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
			        plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: "));
			        plen=fill_tcp_data(buf,plen,baseurl);
			        plen=fill_tcp_data_p(buf,plen,PSTR("password</p>"));
			        goto SENDTCP;
					}
				cmd=analyse_get_url((char *)&(buf[dat_p+5]));
				// for possible status codes see:
				// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
				if (cmd==-1)
					{
			        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
			        goto SENDTCP;
					}
				if (cmd==1)
					{
			        //PORTD|= (1<<PD7);// transistor on
					//IOCLR |= (1<<26);
//                    LED1ON();
					i=1;
					}
				if (cmd==0)
					{
			        //PORTD &= ~(1<<PD7);// transistor off
					//IOSET |= (1<<26);
//                    LED1OFF();
					i=0;
					}
				// if (cmd==-2) or any other value
				// just display the status:
				plen=print_webpage(buf,(i));
				
				SENDTCP:
				make_tcp_ack_from_any(buf); // send ack for http get
				make_tcp_ack_with_data(buf,plen); // send data
				continue;
				}
			}
	// tcp port www end
	//
	// udp start, we listen on udp port 1200=0x4B0
		if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0)
			{
			payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
			// you must sent a string starting with v
			// e.g udpcom version 10.0.0.24
			if (verify_password((char *)&(buf[UDP_DATA_P])))
				{
				// find the first comma which indicates 
				// the start of a command:
				cmd_pos=0;
				while(cmd_pos<payloadlen)
					{
					cmd_pos++;
					if (buf[UDP_DATA_P+cmd_pos]==',')
						{
					    cmd_pos++; // put on start of cmd
					    break;
						}
					}
				// a command is one char and a value. At
				// least 3 characters long. It has an '=' on
				// position 2:
				if (cmd_pos<2 || cmd_pos>payloadlen-3 || buf[UDP_DATA_P+cmd_pos+1]!='=')
					{
					strcpy(str,"e=no_cmd");
					goto ANSWER;
					}
				// supported commands are
				// t=1 t=0 t=?
				if (buf[UDP_DATA_P+cmd_pos]=='t')
					{
					cmdval=buf[UDP_DATA_P+cmd_pos+2];
					if(cmdval=='1')
							{
						    //PORTD|= (1<<PD7);// transistor on
							//IOCLR |= (1<<26);
                            //LED1ON();
						    strcpy(str,"t=1");
						    goto ANSWER;
							}
						else if(cmdval=='0')
							{
						    //PORTD &= ~(1<<PD7);// transistor off
							//IOSET |= (1<<26);
                            //LED1OFF();
						    strcpy(str,"t=0");
						    goto ANSWER;
							}
						else if(cmdval=='?')
							{
	/*
						    if (IOPIN & (1<<26))
								{
					            strcpy(str,"t=1");
					            goto ANSWER;
						    	}
	*/
						    strcpy(str,"t=0");
						    goto ANSWER;
							}
					}
				strcpy(str,"e=no_such_cmd");
				goto ANSWER;
				}
			strcpy(str,"e=invalid_pw");
			ANSWER:
			make_udp_reply_from_request(buf,str,strlen(str),myudpport);
			
			}
		}
//        return (0);
	}
Beispiel #5
0
void flushSockets() {
    if (!(packetLength = enc28j60PacketReceive(BUFFER_SIZE, buffer))) { //No packet available for reading!
        return;
    }
    else if (eth_type_is_arp_and_my_ip(buffer, packetLength)) {
        if (arp_packet_is_myreply_arp(buffer)) {
#ifdef ETHERSHIELD_DEBUG
            ethershieldDebug("Received ARP reply.\r\n");
#endif
			// Add it to the arp cache list
			add_arpcacheentry(buffer+ETH_SRC_MAC_P, buffer+ETH_ARP_DST_IP_P);			
        }
        else {
            make_arp_answer_from_request(buffer);
#ifdef ETHERSHIELD_DEBUG
            ethershieldDebug("Answering ARP request.\r\n");
#endif
        }
    }
    else if (!eth_type_is_ip_and_my_ip(buffer, packetLength)) {
#ifdef ETHERSHIELD_DEBUG
        ethershieldDebug("Ignoring packet not for me.\r\n");
#endif
        return;
    }
    else if (buffer[IP_PROTO_P] == IP_PROTO_ICMP_V &&
            buffer[ICMP_TYPE_P] == ICMP_TYPE_ECHOREQUEST_V) {
        make_echo_reply_from_request(buffer, packetLength);
#ifdef ETHERSHIELD_DEBUG
        sprintf(debugStr, "Replying ICMP ECHO REQUEST from %d.%d.%d.%d.\r\n",
                buffer[IP_SRC_IP_P], buffer[IP_SRC_IP_P + 1],
                buffer[IP_SRC_IP_P + 2], buffer[IP_SRC_IP_P + 3]);
        ethershieldDebug(debugStr);
#endif
    }
    else if (buffer[IP_PROTO_P] == IP_PROTO_TCP_V) {
        //DEBUG: it's TCP and for me! Do I want it?
        uint16_t destinationPort = (buffer[TCP_DST_PORT_H_P] << 8) | buffer[TCP_DST_PORT_L_P];

#ifdef ETHERSHIELD_DEBUG
        sprintf(debugStr, "Received TCP packet from %d.%d.%d.%d:%u on port %d\r\n",
                buffer[IP_SRC_IP_P], buffer[IP_SRC_IP_P + 1],
                buffer[IP_SRC_IP_P + 2], buffer[IP_SRC_IP_P + 3],
                (buffer[TCP_SRC_PORT_H_P] << 8) | buffer[TCP_SRC_PORT_L_P],
                destinationPort);
        ethershieldDebug(debugStr);
#endif

        uint8_t i, socketSelected = MAX_SOCK_NUM;
        for (i = 0; i < MAX_SOCK_NUM; i++) {
            if (_SOCKETS[i].sourcePort == destinationPort) {
                socketSelected = i;
				if(_SOCKETS[i].state == SOCK_LISTEN) {
					_SOCKETS[i].destinationPort = (buffer[TCP_SRC_PORT_H_P] << 8) | buffer[TCP_SRC_PORT_L_P];
					memcpy(_SOCKETS[i].destinationIp, &buffer[IP_SRC_IP_P], 4);
				}
                break;
            }
        }
#ifdef ETHERSHIELD_DEBUG
        ethershieldDebug("  Socket selected: ");
        itoa(socketSelected, debugStr, 10);
        ethershieldDebug(debugStr);
        ethershieldDebug("\r\n");
#endif

        if (socketSelected == MAX_SOCK_NUM) {
            //TODO: reply and say that nobody is listening on that port
			return;
        }
        //TODO: change next 'if' to 'else if'
        //DEBUG: ok, the TCP packet is for me and I want it.
        if (buffer[TCP_FLAGS_P] == (TCP_FLAG_SYN_V | TCP_FLAG_ACK_V)) {
#ifdef ETHERSHIELD_DEBUG
            ethershieldDebug("  It is TCP SYNACK, sending ACK\r\n");
#endif
            make_tcp_ack_from_any(buffer);
            //TODO: verify if I'm waiting for this SYN+ACK
            _SOCKETS[socketSelected].clientState = SOCK_ESTABLISHED;
            return;
        }
        else if (buffer[TCP_FLAGS_P] & TCP_FLAGS_SYN_V) {
#ifdef ETHERSHIELD_DEBUG
            ethershieldDebug("  It is TCP SYN, sending SYNACK\r\n");
#endif
            _SOCKETS[socketSelected].state = SOCK_ESTABLISHED;
            make_tcp_synack_from_syn(buffer);
        }
        else if (buffer[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) {
            uint16_t data;

#ifdef ETHERSHIELD_DEBUG
                ethershieldDebug("  Got an ACK...\r\n");
#endif			
			
            init_len_info(buffer);
			
			_SOCKETS[socketSelected].packets = 0;
			_SOCKETS[socketSelected].ackNumber = (uint32_t)buffer[TCP_SEQ_H_P] << 24 | (uint32_t)buffer[TCP_SEQ_H_P + 1] << 16  |  (uint32_t)buffer[TCP_SEQ_L_P] << 8 | (uint32_t)buffer[TCP_SEQ_L_P + 1];
			
            data = get_tcp_data_pointer();
            if (!data) {
#ifdef ETHERSHIELD_DEBUG
                ethershieldDebug("  It is ACK with no data\r\n");
#endif
                if (buffer[TCP_FLAGS_P] & TCP_FLAGS_FIN_V) {
#ifdef ETHERSHIELD_DEBUG
                    ethershieldDebug("    It is ACKFIN, closing socket\r\n");
#endif
                    make_tcp_ack_from_any(buffer);
                    _SOCKETS[socketSelected].state = SOCK_CLOSED;
                    _SOCKETS[socketSelected].sendPacketLength = 0;
					_SOCKETS[socketSelected].ackNumber = 0;
					_SOCKETS[socketSelected].sentData = 0;
					_SOCKETS[socketSelected].packets = 0;
                    free(_SOCKETS[socketSelected].dataBuffer);
					_SOCKETS[socketSelected].bytesToRead = 0;
                }
                return;
            }
            else {
                int dataSize;

				make_tcp_ack_from_any(buffer); //TODO-ACK

				_SOCKETS[socketSelected].ackNumber = (uint32_t)buffer[TCP_SEQACK_H_P] << 24 | (uint32_t)buffer[TCP_SEQACK_H_P + 1] << 16  |  (uint32_t)buffer[TCP_SEQACK_L_P] << 8 | (uint32_t)buffer[TCP_SEQACK_L_P + 1];

                dataSize = packetLength - (&buffer[data] - buffer);
#ifdef ETHERSHIELD_DEBUG
                itoa(dataSize, debugStr, 10);
                ethershieldDebug("  It is ACK with data, ACK sent\r\n");
                ethershieldDebug("    # bytes: ");
                ethershieldDebug(debugStr);
                ethershieldDebug("\r\n");

#endif
                _SOCKETS[socketSelected].state = SOCK_ESTABLISHED;

				if(_SOCKETS[socketSelected].bytesToRead > 0) {
					_SOCKETS[socketSelected].dataBuffer = realloc(_SOCKETS[socketSelected].dataBuffer, _SOCKETS[socketSelected].bytesToRead + (dataSize * sizeof(char))); //TODO: and about the TCP/IP/Ethernet overhead?
					memcpy(_SOCKETS[socketSelected].dataBuffer+_SOCKETS[socketSelected].bytesToRead, &buffer[data], dataSize);
				} else {
					_SOCKETS[socketSelected].dataBuffer = malloc(dataSize * sizeof(char)); //TODO: and about the TCP/IP/Ethernet overhead?
					memcpy(_SOCKETS[socketSelected].dataBuffer, &buffer[data], dataSize);
				}					
				//TODO: Add handler to malloc returning: No enough SRAM)
				
                _SOCKETS[socketSelected].bytesToRead += dataSize;
#ifdef ETHERSHIELD_DEBUG
                ethershieldDebug("    Data:\r\n");
                for (i = 0; i < dataSize; i++) {
                    serial_write(_SOCKETS[socketSelected].dataBuffer[i]);
                }
                ethershieldDebug("\r\n");
#endif
                return;
            }
        }
        else {
#ifdef ETHERSHIELD_DEBUG
            ethershieldDebug("Don't know what to do!\r\n");
#endif
            //make_tcp_ack_from_any(buffer); //TODO-ACK: send ACK using tcp_client_send_packet
        }
    }
}
Beispiel #6
0
int main(void){
	
	uint16_t plen;
	uint16_t dat_p;
	uint8_t cmd;
	
	// set the clock speed to "no pre-scaler" (8MHz with internal osc or
	// full external speed)
	// set the clock prescaler. First write CLKPCE to enable setting of clock the
	// next four instructions.
	CLKPR=(1<<CLKPCE); // change enable
	CLKPR=0; // "no pre-scaler"
	uartInit();
	uartSetBaudRate(9600);
	
	_delay_loop_1(50); // 12ms
	/* enable PD2/INT0, as input */
	DDRD&= ~(1<<DDD2);
	
	
	
	// test button
	cbi(DDRD,PIND6);
	sbi(PORTD,PIND6); // internal pullup resistor on
	_delay_loop_1(50); // 12ms
	// read eeprom values unless, the PD6 pin is connected to GND during bootup
	// PD6 is used to reset to factory default. Note that factory default is
	// not stored back to eeprom.
	if (eeprom_read_byte((uint8_t *)0x0) == 19 && ! bit_is_clear(PIND,PIND6)){
		// ok magic number matches accept values
		eeprom_read_block((uint8_t *)myip,(void *)1,sizeof(myip));
		eeprom_read_block((uint8_t *)monitoredhost,(void *)6,sizeof(monitoredhost));
		pinginterval=eeprom_read_byte((uint8_t *)11);
		sendping=eeprom_read_byte((uint8_t *)12);
		eeprom_read_block((char *)password,(void *)13,sizeof(password));
		password[7]='\0'; // make sure it is terminated, should not be necessary
	}
	
	/*initialize enc28j60*/
	enc28j60Init(mymac);
	enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
	_delay_loop_1(50); // 12ms
	// LED
	/* enable PB1, LED as output */
	//DDRB|= (1<<DDB1);
	/* set output to Vcc, LED off */
	//LEDOFF;
	
	// the transistor on PD7
	DDRD|= (1<<DDD7);
	PORTD &= ~(1<<PIND7);// transistor off
	
	/* Magjack leds configuration, see enc28j60 datasheet, page 11 */
	// LEDB=yellow LEDA=green
	//
	// 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
	// enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
	enc28j60PhyWrite(PHLCON,0x476);
	_delay_loop_1(50); // 12ms
	
	
	//init the ethernet/ip layer:
	init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
	timer_init();
	_delay_ms(1000);
	uartFlushReceiveBuffer();
	sei(); // interrupt enable
	
	while(1){
		//uartSendByte('a');
		
		//checkForEthPacket(ethPacket);
		stop_timer=2;
		if (checkForEthPacket(ethPacket))
		{
			sendEthPacket(time, sm);
			time.hr = 99;
		}
		stop_timer=0;
		// 			wait_data++;
		// 			if (wait_data>40)
		// 				wait_data=0;
		//_delay_ms(500);
		// spontanious messages must not interfer with
		// web pages
		if (pagelock==0 && enc28j60hasRxPkt()==0){
			if (sendping &&  havemac==0){
				client_arp_whohas(buf,monitoredhost);
				havemac=2;
			}
			if (sendping && havemac==1 && pingnow){
				pingnow=0;
				client_icmp_request(buf,monitoredhost,PINGPATTERN);
				pingtimer++; // otheweise we would call this function again
				hoststatus++;
				if (hoststatus==0xff){
					hoststatus=1; // wrap to 1
				}
			}
		}
		// get the next new packet:
		plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
		
		/*plen will be unequal to zero if there is a valid 
		* packet (without crc error) */
		if(plen==0){
			continue;
		}
		
		// arp is broadcast if unknown but a host may also
		// verify the mac address by sending it to
		// a unicast address.
		if(eth_type_is_arp_and_my_ip(buf,plen)){
			if (eth_type_is_arp_req(buf)){
				make_arp_answer_from_request(buf);
			}
			if (eth_type_is_arp_reply(buf)){
				if (client_store_gw_mac(buf,monitoredhost)){
					havemac=1;
				}
			}
			continue;
		}
		
		// check if ip packets are for us:
		if(eth_type_is_ip_and_my_ip(buf,plen)==0){
			continue;
		}
		
		if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREPLY_V){
			if (buf[ICMP_DATA_P]== PINGPATTERN){
				if (check_ip_message_is_from(buf,monitoredhost)){
					// ping reply is from monitored host and ping was from us
					hoststatus=0;
					hostbackafterreboot=1;
				}
			}
		}
		if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
			if (check_ip_message_is_from(buf,monitoredhost)){
				// ping is from monitored host
				hoststatus=0;
				hostbackafterreboot=1;
			}
			// a ping packet, let's send pong
			make_echo_reply_from_request(buf,plen);
			continue;
		}
		// tcp port www start, compare only the lower byte
		if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){
			if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
				make_tcp_synack_from_syn(buf);
				// make_tcp_synack_from_syn does already send the syn,ack
				continue;
			}
			if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
				init_len_info(buf); // init some data structures
				// we can possibly have no data, just ack:
				dat_p=get_tcp_data_pointer();
				if (dat_p==0){
					if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
						// finack, answer with ack
						make_tcp_ack_from_any(buf);
					}
					// just an ack with no data, wait for next packet
					continue;
				}
				if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
					// head, post and other methods:
					//
					// for possible status codes see:
					// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
					plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
					goto SENDTCP;
				}
				if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
					plen=print_webpage(buf);
					goto SENDTCP;
				}
				cmd=analyse_get_url((char *)&(buf[dat_p+5]));
				pagelock=1; // stop automatic actions until webpage is displayed
				//
				// error, default, will get overwritte in case 
				// something else is selected:
				plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Error</h1>"));
				plen=fill_tcp_data(buf,plen,errmsg);
				plen=fill_tcp_data_p(buf,plen,PSTR("<br><br><a href=/>-&gt;continue</a>\n"));
				// for possible status codes see:
				// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
				if (cmd==1){
					resethost();
					plen=print_webpage_confirm(buf);
				}
				if (cmd==2){
					store_in_eeprom();
					plen=print_webpage_confirm(buf);
				}
				if (cmd==7){
					store_in_eeprom();
					plen=print_webpage_confirm(buf);
					reinitmac=1;
				}
				// start and stop of wd, this is not store in eeprom
				if (cmd==5){
					pingtimer=1; // wd on 
					plen=print_webpage_confirm(buf);
				}
				if (cmd==4){
					pingtimer=0; // wd off 
					plen=print_webpage_confirm(buf);
				}
				if (cmd==3){
					plen=print_webpage_now(buf);
				}
				if (cmd==6){
					plen=print_webpage_config(buf);
				}
				// testing the temp OK / NOK
				if (cmd==20){
					sm[0].temp= atoi(strbuf);
					plen=print_webpage_confirm(buf);
				}
				if (cmd==21){
					sm[1].temp= atoi(strbuf);
					plen=print_webpage_confirm(buf);
				}
				
				// on / off - slave-modules
				// ON slave-module-1
				if (cmd==34){
					sm[0].status = atoi(strbuf);
					plen=print_webpage_confirmrm1(buf);
				}
				// OFF slave-module-1
				if (cmd==31){
					sm[0].status = atoi(strbuf);
					plen=print_webpage_confirmrm1(buf);
				}
				// ON slave-module-2
				if (cmd==32){
					sm[1].status = atoi(strbuf);
					plen=print_webpage_confirmrm2(buf);
				}
				// OFF slave-module-2
				if (cmd==33){
					sm[1].status = atoi(strbuf);
					plen=print_webpage_confirmrm2(buf);
				}
				
				if (cmd==35){
					plen=print_webpage_confirmclk(buf);
				}
				if (cmd==36){
					plen=print_webpage_confirmclk(buf);
				}
				
				// Room-1
				if (cmd==10){
					plen=print_webpage_room1(buf);
				}
				// ROom-2
				if (cmd==11){
					plen=print_webpage_room2(buf);
				}
				// Clock & date
				if (cmd==12){
					plen=print_webpage_clk(buf);
				}
				
				//
				SENDTCP:
				make_tcp_ack_from_any(buf); // send ack for http get
				make_tcp_ack_with_data(buf,plen); // send data
				continue;
			}
			
		}
		// tcp port www end
		//
		// udp not implemented
	}
	return (0);
}
Beispiel #7
0
void ethernet_process(void)
{
	uint16_t plen;
	uint16_t dat_p;
	uint8_t cmd_pos=0;
	int8_t cmd;
	uint8_t payloadlen=0;
	char str[30];
	char cmdval;

    // get the next new packet:
    plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
    buf[BUFFER_SIZE]='\0';
    dat_p=packetloop_arp_icmp_tcp(buf,plen);
#if 0
    // tcp port 80 begin
    if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
    {
      // head, post and other methods:
      dat_p=http200ok();
      dat_p=ES_fill_tcp_data(buf,dat_p,"<h1>200 OK</h1>");
      goto SENDTCP;
    }
#endif
        /*plen will ne unequal to zero if there is a valid
         * packet (without crc error) */
        if(plen==0)
        {
                //continue;
        }

        // arp is broadcast if unknown but a host may also
        // verify the mac address by sending it to
        // a unicast address.
        if(eth_type_is_arp_and_my_ip(buf,plen))
        {
                make_arp_answer_from_request(buf);
                //continue;
        }

        // check if ip packets are for us:
        if(eth_type_is_ip_and_my_ip(buf,plen)==0)
        {
                //continue;
        }
#ifdef _DEBUG_
        // led----------
        if (i){
                /* set output to Vcc, LED off */
                PORTB|= (1<<PORTB1);
                i=0;
        }else{
                /* set output to GND, LED on */
                PORTB &= ~(1<<PORTB1);
                i=1;
        }
#endif
        if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
        {
                // a ping packet, let's send pong
                make_echo_reply_from_request(buf,plen);
                //continue;
        }
        // tcp port www start, compare only the lower byte
        if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
        {
                if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
                {
                        make_tcp_synack_from_syn(buf);
                        // make_tcp_synack_from_syn does already send the syn,ack
                        //continue;
                }
                if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
                {
                        init_len_info(buf); // init some data structures
                        // we can possibly have no data, just ack:
                        dat_p=get_tcp_data_pointer();
                        if (dat_p==0)
                        {
                                if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
                                {
                                        // finack, answer with ack
                                        make_tcp_ack_from_any(buf,1,0);
                                }
                                // just an ack with no data, wait for next packet
                                //continue;
                        }
                        if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
                        {
                                // head, post and other methods:
                                //
                                // for possible status codes see:
                                // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                                goto SENDTCP;
                        }
                        if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0)
                        {
                                plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
                                plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: http://host_or_ip/password</p>\n"));
                                goto SENDTCP;
                        }
                        cmd=analyse_get_url((char *)&(buf[dat_p+5]));
                        // for possible status codes see:
                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                        if (cmd==-1)
                        {
                                plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
                                goto SENDTCP;
                        }
#ifdef _DEBUG_
                        if (cmd==1)
                        {
                                PORTD|= (1<<PORTD7);// transistor on
                        }
                        if (cmd==0)
                        {
                                PORTD &= ~(1<<PORTD7);// transistor off
                        }
#endif
                        if (cmd==-3)
                        {
                                // redirect to add a trailing slash
                                plen=moved_perm(buf);
                                goto SENDTCP;
                        }
#ifndef _DEBUG_
                        // if (cmd==-2) or any other value
                        // just display the status:
                        //plen=print_webpage(buf,(PORTD & (1<<PORTD7)));
                        plen=print_webpage(buf);
                        //
#endif
SENDTCP:
                        plen=print_webpage(buf);
                        make_tcp_ack_from_any(buf,1,0);   // send ack for http get
                        make_tcp_ack_with_data(buf,plen); // send data
                        //continue;
                }

        }
        // tcp port www end
        //
        // udp start, we listen on udp port 1200=0x4B0
        if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0)
        {
                payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                // you must sent a string starting with v
                // e.g udpcom version 10.0.0.24
                if (verify_password((char *)&(buf[UDP_DATA_P])))
                {
                        // find the first comma which indicates
                        // the start of a command:
                        cmd_pos=0;
                        while(cmd_pos<payloadlen)
                        {
                                cmd_pos++;
                                if (buf[UDP_DATA_P+cmd_pos]==',')
                                {
                                        cmd_pos++; // put on start of cmd
                                        break;
                                }
                        }
                        // a command is one char and a value. At
                        // least 3 characters long. It has an '=' on
                        // position 2:
                        if (cmd_pos<2 || cmd_pos>payloadlen-3 || buf[UDP_DATA_P+cmd_pos+1]!='=')
                        {
                                strcpy(str,"e=no_cmd");
                                goto ANSWER;
                        }
                        // supported commands are
                        // t=1 t=0 t=?
                        if (buf[UDP_DATA_P+cmd_pos]=='t')
                        {
                                cmdval=buf[UDP_DATA_P+cmd_pos+2];
                                if(cmdval=='1')
                                {
                                        //PORTD|= (1<<PORTD7);// transistor on
                                        strcpy(str,"t=1");
                                        goto ANSWER;
                                }
                                else if(cmdval=='0')
                                {
                                        //PORTD &= ~(1<<PORTD7);// transistor off
                                        strcpy(str,"t=0");
                                        goto ANSWER;
                                }
                                else if(cmdval=='?')
                                {
                                       // if (PORTD & (1<<PORTD7)){
                                       //         strcpy(str,"t=1");
                                       //         goto ANSWER;
                                       // }
                                        strcpy(str,"t=0");
                                        goto ANSWER;
                                }
                        }
                        strcpy(str,"e=no_such_cmd");
                        goto ANSWER;
                }
                strcpy(str,"e=invalid_pw");
ANSWER:
                make_udp_reply_from_request(buf,str,strlen(str),MYUDPPORT);
        }
}
int main(void){

        
        uint16_t plen;
        uint16_t dat_p;
        uint8_t i=0;
        uint8_t payloadlen=0;
        char str[20];
        
        // set the clock speed to 8MHz
        // set the clock prescaler. First write CLKPCE to enable setting of clock the
        // next four instructions.
        CLKPR=(1<<CLKPCE);
        CLKPR=0; // 8 MHZ
        
        _delay_loop_1(50); // 12ms
        
        /*initialize enc28j60*/
        enc28j60Init(mymac);
        enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
        _delay_loop_1(50); // 12ms
        
        // LED
        /* enable PB1, LED as output */
        DDRB|= (1<<DDB1);

        /* set output to Vcc, LED off */
        PORTB|= (1<<PORTB1);
        
        /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
        // LEDB=yellow LEDA=green
        //
        // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
        // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
        enc28j60PhyWrite(PHLCON,0x476);
        _delay_loop_1(50); // 12ms
        
        /* set output to GND, red LED on */
        PORTB &= ~(1<<PORTB1);
        i=1;

        //init the ethernet/ip layer:
        init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

        while(1){
                // get the next new packet:
                plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

                /*plen will ne unequal to zero if there is a valid 
                 * packet (without crc error) */
                if(plen==0){
                        continue;
                }
                // arp is broadcast if unknown but a host may also
                // verify the mac address by sending it to 
                // a unicast address.
                if(eth_type_is_arp_and_my_ip(buf,plen)){
                        make_arp_answer_from_request(buf);
                        continue;
                }
                // check if ip packets (icmp or udp) are for us:
                if(eth_type_is_ip_and_my_ip(buf,plen)==0){
                        continue;
                }
                
                if (i){
                        /* set output to Vcc, LED off */
                        PORTB|= (1<<PORTB1);
                        i=0;
                }else{
                        /* set output to GND, LED on */
                        PORTB &= ~(1<<PORTB1);
                        i=1;
                }

                if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
                        // a ping packet, let's send pong
                        make_echo_reply_from_request(buf,plen);
                        continue;
                }

                // tcp port 80 start
                if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
                                make_tcp_synack_from_syn(buf);
                                // make_tcp_synack_from_syn does already send the syn,ack
                                continue;
                        }
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
                                init_len_info(buf); // init some data structures
                                // we can possibly have no data, just ack:
                                dat_p=get_tcp_data_pointer();
                                if (dat_p==0){
                                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
                                                // finack, answer with ack
                                                make_tcp_ack_from_any(buf);
                                        }
                                        // just an ack with no data, wait for next packet
                                        continue;
                                }
                                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
                                        // head, post and other methods:
                                        //
                                        // for possible status codes see:
                                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                                        goto SENDTCP;
                                }
                                // any GET, any url:
                                plen=print_webpage(buf,enc28j60getrev());
SENDTCP:
                                make_tcp_ack_from_any(buf); // send ack for http get
                                make_tcp_ack_with_data(buf,plen); // send data
                                continue;
                        }
                }
                // tcp port 80 end
                //
                // udp start, we listen on udp port 1200=0x4B0
                if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0){
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                        // you must sent a string starting with v
                        // e.g udpcom version 10.0.0.24
                        if (buf[UDP_DATA_P]=='v' ){
                                str[0]='v';
                                str[1]='e';
                                str[2]='r';
                                str[3]='=';
                                str[4]='B';
                                itoa((enc28j60getrev()),&(str[5]),10);
                                make_udp_reply_from_request(buf,str,strnlen(str,10),MYUDPPORT);
                        }
                }
        }
        return (0);
}
Beispiel #9
0
/*
 * 函数名:Web_Server
 * 描述  :在浏览器上创建一个web服务器,通过web里面的命令来控制开发板上的LED的亮灭。
 * 输入  :无
 * 输出  :无
 * 返回  :-0 运行成功
 * 应用  :1 在PC机的DOS界面输入: ping 192.168.1.15 (看能否ping通)
 *         2 在IE浏览器中输入:http://192.168.1.15/123456 则会出现一个网页,通过网页
 *           中的命令可以控制开发板中的LED的亮灭
 */
int Web_Server(void)
{   
	unsigned int plen, i1 = 0;
	unsigned int dat_p;
//	unsigned char i = 0;
	unsigned char cmd, *buf1;
	unsigned int payloadlen = 0;
  
  /* 初始化 enc28j60 的MAC地址(物理地址),这个函数必须要调用一次 */
  enc28j60Init(mymac);

	/* PHY LED 配置,LED用来指示通信的状态 */	
  enc28j60PhyWrite(PHLCON,0x476);	
	
	/* 将enc28j60第三引脚的时钟输出改为:from 6.25MHz to 12.5MHz(本例程该引脚NC,没用到) */	
  //enc28j60clkout(2);    
  
	/* 初始化以太网 IP 层 */
	init_ip_arp_udp_tcp(mymac,myip,mywwwport);
	printf("服务器初始化成功!\n");
  while(1)
  {   
			// get the next new packet:			
      plen = enc28j60PacketReceive(BUFFER_SIZE, buf);      
      
      // plen will ne unequal to zero if there is a valid packet (without crc error)			
      if(plen==0)
      {
          continue;
      }

      // arp is broadcast if unknown but a host may also
      // verify the mac address by sending it to 
      // a unicast address.		     
      if(eth_type_is_arp_and_my_ip(buf,plen))
      {
          make_arp_answer_from_request(buf);          
          continue;
      }
      
      // check if ip packets are for us:			
      if(eth_type_is_ip_and_my_ip(buf,plen)==0) 
      {
          continue;
      }      
      
      if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
      {
          // a ping packet, let's send pong  DOS 下的 ping 命令包		 
          make_echo_reply_from_request(buf, plen);          
          continue;
      }

/*-----------------tcp port www start, compare only the lower byte-----------------------------------*/
      if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport)
      {
          if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
          {
              make_tcp_synack_from_syn(buf);
              // make_tcp_synack_from_syn does already send the syn,ack
              continue;
          }
          if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
          {
              init_len_info(buf); // init some data structures
              // we can possibly have no data, just ack:
              dat_p=get_tcp_data_pointer();
              if (dat_p==0)
              {
                  if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
                  {
                      // finack, answer with ack
                      make_tcp_ack_from_any(buf);
                  }
                  // just an ack with no data, wait for next packet
                  continue;
              }
              if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
              {
                  // head, post and other methods:
                  //
                  // for possible status codes see:
                  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                  plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                  goto SENDTCP;
              }
              if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0)
              {
                  plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
                  plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: "));
                  plen=fill_tcp_data(buf,plen,baseurl);
                  plen=fill_tcp_data_p(buf,plen,PSTR("password</p>"));
                  goto SENDTCP;
              }
              cmd=analyse_get_url((char *)&(buf[dat_p+5]));
              // for possible status codes see:
              // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
              if (cmd==1)
              {
                  plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
                  goto SENDTCP;
              }
 //             if (cmd==1)	           // 用户程序
  //            {			
//									LED1(ON);
//                  i=1;							 // 命令 = 1
  //            }
//              if (cmd==0)						 // 用户程序
  //            {									
//									LED1(OFF);
    //              i=0;							 // 命令 = 0
    //          }
              // if (cmd==-2) or any other value
              // just display the status:
              plen=print_webpage(buf,1);
              
              SENDTCP:
              make_tcp_ack_from_any(buf);       // send ack for http get
              make_tcp_ack_with_data(buf,plen); // send data
              continue;
          }
      }
/*-------------------------------------- tcp port www end ---------------------------------------*/

/*--------------------- udp start, we listen on udp port 1200=0x4B0 -----------------------------*/
      if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0)
      {
          payloadlen=	  buf[UDP_LEN_H_P];
          payloadlen=payloadlen<<8;
          payloadlen=(payloadlen+buf[UDP_LEN_L_P])-UDP_HEADER_LEN;
          //payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
          
          ANSWER:
          //while(1){
          for(i1=0; i1<payloadlen; i1++) buf1[i1]=buf[UDP_DATA_P+i1];
          
          //make_udp_reply_from_request(buf,str,strlen(str),myudpport);
          make_udp_reply_from_request(buf,buf1,payloadlen,myudpport);          
          //}
      }
/*----------------------------------------udp end -----------------------------------------------*/
  }
          return (0);
}
void EtherShieldWrapper::ESW_make_tcp_synack_from_syn(uint8_t *buf){
	make_tcp_synack_from_syn(buf);
}	
Beispiel #11
0
int main(void){

        
        uint16_t plen;
        uint16_t dat_p;
        uint8_t i=0;
        uint8_t cmd_pos=0;
        int8_t cmd;
        uint8_t payloadlen=0;
        char str[30];
        char cmdval;
        
        // set the clock speed to "no pre-scaler" (8MHz with internal osc or 
        // full external speed)
        // set the clock prescaler. First write CLKPCE to enable setting of clock the
        // next four instructions.
        CLKPR=(1<<CLKPCE); // change enable
        CLKPR=0; // "no pre-scaler"
        delay_ms(1);

        /* enable PD2/INT0, as input */
        DDRD&= ~(1<<DDD2);

        /*initialize enc28j60*/
        enc28j60Init(mymac);
        enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
        delay_ms(10);
        
        // LED
        /* enable PB1, LED as output */
        DDRB|= (1<<DDB1);

        /* set output to Vcc, LED off */
        PORTB|= (1<<PB1);

        // the transistor on PD7
        DDRD|= (1<<DDD7);
        PORTD &= ~(1<<PD7);// transistor off
        
        /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
        // LEDB=yellow LEDA=green
        //
        // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
        // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
        enc28j60PhyWrite(PHLCON,0x476);
        delay_ms(20);
        
        /* set output to GND, red LED on */
        PORTB &= ~(1<<PB1);
        i=1;

        //init the ethernet/ip layer:
        init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

        while(1){
                // get the next new packet:
                plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

                /*plen will ne unequal to zero if there is a valid 
                 * packet (without crc error) */
                if(plen==0){
                        continue;
                }
                        
                // arp is broadcast if unknown but a host may also
                // verify the mac address by sending it to 
                // a unicast address.
                if(eth_type_is_arp_and_my_ip(buf,plen)){
                        make_arp_answer_from_request(buf);
                        continue;
                }

                // check if ip packets are for us:
                if(eth_type_is_ip_and_my_ip(buf,plen)==0){
                        continue;
                }
                // led----------
                if (i){
                        /* set output to Vcc, LED off */
                        PORTB|= (1<<PB1);
                        i=0;
                }else{
                        /* set output to GND, LED on */
                        PORTB &= ~(1<<PB1);
                        i=1;
                }
                
                if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
                        // a ping packet, let's send pong
                        make_echo_reply_from_request(buf,plen);
                        continue;
                }
                // tcp port www start, compare only the lower byte
                if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
                                make_tcp_synack_from_syn(buf);
                                // make_tcp_synack_from_syn does already send the syn,ack
                                continue;
                        }
                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
                                init_len_info(buf); // init some data structures
                                // we can possibly have no data, just ack:
                                dat_p=get_tcp_data_pointer();
                                if (dat_p==0){
                                        if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
                                                // finack, answer with ack
                                                make_tcp_ack_from_any(buf);
                                        }
                                        // just an ack with no data, wait for next packet
                                        continue;
                                }
                                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
                                        // head, post and other methods:
                                        //
                                        // for possible status codes see:
                                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                                        goto SENDTCP;
                                }
                                if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
                                        plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: http://host_or_ip/password</p>\n"));
                                        goto SENDTCP;
                                }
                                cmd=analyse_get_url((char *)&(buf[dat_p+5]));
                                // for possible status codes see:
                                // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                if (cmd==-1){
                                        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
                                        goto SENDTCP;
                                }
                                if (cmd==1){
                                        PORTD|= (1<<PD7);// transistor on
                                }
                                if (cmd==0){
                                        PORTD &= ~(1<<PD7);// transistor off
                                }
                                if (cmd==-3){
                                        // redirect to add a trailing slash
                                        plen=moved_perm(buf);
                                        goto SENDTCP;
                                }
                                // if (cmd==-2) or any other value
                                // just display the status:
                                plen=print_webpage(buf,(PORTD & (1<<PD7)));
                                //
SENDTCP:
                                make_tcp_ack_from_any(buf); // send ack for http get
                                make_tcp_ack_with_data(buf,plen); // send data
                                continue;
                        }

                }
                // tcp port www end
                //
                // udp start, we listen on udp port 1200=0x4B0
                if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0){
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                        // you must sent a string starting with v
                        // e.g udpcom version 10.0.0.24
                        if (verify_password((char *)&(buf[UDP_DATA_P]))){
                                // find the first comma which indicates 
                                // the start of a command:
                                cmd_pos=0;
                                while(cmd_pos<payloadlen){
                                        cmd_pos++;
                                        if (buf[UDP_DATA_P+cmd_pos]==','){
                                                cmd_pos++; // put on start of cmd
                                                break;
                                        }
                                }
                                // a command is one char and a value. At
                                // least 3 characters long. It has an '=' on
                                // position 2:
                                if (cmd_pos<2 || cmd_pos>payloadlen-3 || buf[UDP_DATA_P+cmd_pos+1]!='='){
                                        strcpy(str,"e=no_cmd");
                                        goto ANSWER;
                                }
                                // supported commands are
                                // t=1 t=0 t=?
                                if (buf[UDP_DATA_P+cmd_pos]=='t'){
                                        cmdval=buf[UDP_DATA_P+cmd_pos+2];
                                        if(cmdval=='1'){
                                                PORTD|= (1<<PD7);// transistor on
                                                strcpy(str,"t=1");
                                                goto ANSWER;
                                        }else if(cmdval=='0'){
                                                PORTD &= ~(1<<PD7);// transistor off
                                                strcpy(str,"t=0");
                                                goto ANSWER;
                                        }else if(cmdval=='?'){
                                                if (PORTD & (1<<PD7)){
                                                        strcpy(str,"t=1");
                                                        goto ANSWER;
                                                }
                                                strcpy(str,"t=0");
                                                goto ANSWER;
                                        }
                                }
                                strcpy(str,"e=no_such_cmd");
                                goto ANSWER;
                        }
                        strcpy(str,"e=invalid_pw");
ANSWER:
                        make_udp_reply_from_request(buf,str,strlen(str),MYUDPPORT);
                }
        }
        return (0);
}