Exemplo n.º 1
0
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
	//

}
Exemplo n.º 2
0
void EtherShield::ES_make_echo_reply_from_request(uint8_t *buf,uint16_t len) {
	make_echo_reply_from_request(buf,len);
}
Exemplo n.º 3
0
Arquivo: lnudp.c Projeto: AndTH/GCA
int main(void){

        
        uint16_t plen;
        uint8_t i=0;
        uint8_t cmd_pos=0;
        uint8_t payloadlen=0;
        char str[30];
        char cmdval;
        
        // 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_ms(10);
        
        /* enable PB0, reset as output */
        DDRB|= (1<<DDB0);

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

        /* set output to gnd, reset the ethernet chip */
        PORTB &= ~(1<<PB0);
        delay_ms(10);
        /* set output to Vcc, reset inactive */
        PORTB|= (1<<PB0);
        delay_ms(200);
        
        /*initialize enc28j60*/
        enc28j60Init(mymac);
        delay_ms(20);
        
        // 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(mymac,myip);

        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;
                }
                // 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;
                }
                        
                // 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,plen);
                        continue;
                }
                // check if ip packets (icmp or udp) 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);
                        continue;
                }
                // we listen on 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),myport);
                }
        }
        return (0);
}
Exemplo n.º 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);
	}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
static void _eth_spi_handle_frame() {
  u16_t rx_stat;
  int plen = enc28j60PacketReceive(ETHSPI_MAX_PKT_SIZE, ethspi.rxbuf, &rx_stat);
  if (plen == 0) {
    DBG(D_ETH, D_DEBUG, "ethspi no frame, rx_stat:%04x\n", rx_stat);
    return;
  }
#ifdef ETH_STATS
  ethspi.rx_frames++;
  ethspi.rx_data += plen;
#endif

  DBG(D_ETH, D_DEBUG, "ethspi got frame, len %i, rx_stat:%04x\n", plen, rx_stat);
  //printbuf(ethspi.rxbuf, MIN(64, plen));
  // doing dhcp, do not allow anything else right now
  if (ethspi.dhcp.query && ethspi.dhcp.active) {
    int dhcp_res;
    dhcp_res = check_for_dhcp_answer(ethspi.rxbuf, plen);
    DBG(D_ETH, D_DEBUG, "ethspi DHCP:%i state:%i\n", dhcp_res, dhcp_state());
    if (dhcp_state() == DHCP_STATE_OK) {
      ethspi.dhcp.query = FALSE;
      DBG(D_ETH, D_DEBUG, "ethspi DHCP OK\n");
      DBG(D_ETH, D_INFO, "ethspi DHCP ip   %i.%i.%i.%i\n", ethspi.dhcp.ipaddr[0], ethspi.dhcp.ipaddr[1], ethspi.dhcp.ipaddr[2], ethspi.dhcp.ipaddr[3]);
      DBG(D_ETH, D_DEBUG, "ethspi DHCP gwip %i.%i.%i.%i\n", ethspi.dhcp.gwip[0], ethspi.dhcp.gwip[1], ethspi.dhcp.gwip[2], ethspi.dhcp.gwip[3]);
      DBG(D_ETH, D_DEBUG, "ethspi DHCP mask %i.%i.%i.%i\n", ethspi.dhcp.mask[0], ethspi.dhcp.mask[1], ethspi.dhcp.mask[2], ethspi.dhcp.mask[3]);
      DBG(D_ETH, D_DEBUG, "ethspi DHCP dhcp %i.%i.%i.%i\n", ethspi.dhcp.dhcp_server[0], ethspi.dhcp.dhcp_server[1], ethspi.dhcp.dhcp_server[2], ethspi.dhcp.dhcp_server[3]);
      DBG(D_ETH, D_DEBUG, "ethspi DHCP dns  %i.%i.%i.%i\n", ethspi.dhcp.dns_server[0], ethspi.dhcp.dns_server[1], ethspi.dhcp.dns_server[2], ethspi.dhcp.dns_server[3]);
      memcpy(ip_address, ethspi.dhcp.ipaddr, 4);
      set_ip(ethspi.dhcp.ipaddr);
      client_set_gwip(ethspi.dhcp.gwip);
#ifdef CONFIG_ETH_DHCP_SHOW
      print("eth ip address %i.%i.%i.%i\n", ethspi.dhcp.ipaddr[0], ethspi.dhcp.ipaddr[1], ethspi.dhcp.ipaddr[2], ethspi.dhcp.ipaddr[3]);
#endif
    }
    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(ethspi.rxbuf, plen)) {
    make_arp_answer_from_request(ethspi.rxbuf);
    return;
  }

  // check if ip frames (icmp or udp) are for us or broadcast:
  if (eth_type_is_ip_and_broadcast(ethspi.rxbuf, plen) == 0) {
    if (eth_type_is_ip_and_my_ip(ethspi.rxbuf, plen) == 0) {
      return;
    }
    if (ethspi.rxbuf[IP_PROTO_P]==IP_PROTO_ICMP_V &&
        ethspi.rxbuf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
      // a ping frame, let's send pong
      make_echo_reply_from_request(ethspi.rxbuf, plen);
      return;
    }
  }

#if 0
  // we listen on port 0xcafe
  if (ethspi.rxbuf[IP_PROTO_P] == IP_PROTO_UDP_V
      && ethspi.rxbuf[UDP_DST_PORT_H_P] == 0xca  && ethspi.rxbuf[UDP_DST_PORT_L_P] == 0xf) {
    int payloadlen = ethspi.rxbuf[UDP_LEN_L_P];//plen - 34 - UDP_HEADER_LEN;
    DBG(D_ETH, D_DEBUG, "ethspi UDP len:%i\n", payloadlen);
    //char *nisse = "hello wurlde";
    //make_udp_reply_from_request(ethbuf, nisse, strlen(nisse), 1200);
    DBG(D_ETH, D_DEBUG, "ethspi eth mac dst: %02x.%02x.%02x.%02x.%02x.%02x\n",
        ethspi.rxbuf[0], ethspi.rxbuf[1], ethspi.rxbuf[2], ethspi.rxbuf[3], ethspi.rxbuf[4], ethspi.rxbuf[5]); // ETH_DST_MAC
    DBG(D_ETH, D_DEBUG, "ethspi eth mac src: %02x.%02x.%02x.%02x.%02x.%02x\n",
        ethspi.rxbuf[6], ethspi.rxbuf[7], ethspi.rxbuf[8], ethspi.rxbuf[9], ethspi.rxbuf[10], ethspi.rxbuf[11]); // ETH_SRC_MAC
    DBG(D_ETH, D_DEBUG, "ethspi eth type:    %02x %02x\n",
        ethspi.rxbuf[12], ethspi.rxbuf[13]); // ETH_TYPE_H_P, ETH_TYPE_L_P
    DBG(D_ETH, D_DEBUG, "ethspi ip src:  %i.%i.%i.%i\n",
        ethspi.rxbuf[26], ethspi.rxbuf[27], ethspi.rxbuf[28], ethspi.rxbuf[29]); // IP_SRC_P
    DBG(D_ETH, D_DEBUG, "ethspi ip dst:  %i.%i.%i.%i\n",
        ethspi.rxbuf[30], ethspi.rxbuf[31], ethspi.rxbuf[32], ethspi.rxbuf[33]); // IP_DST_P
    DBG(D_ETH, D_DEBUG, "ethspi udp src port:  %i\n",
        (ethspi.rxbuf[34] << 8) | ethspi.rxbuf[35]); // UDP_SRC_PORT_H_P
    DBG(D_ETH, D_DEBUG, "ethspi udp dst port:  %i\n",
        (ethspi.rxbuf[36] << 8) | ethspi.rxbuf[37]); // UDP_DST_PORT_H_P
    DBG(D_ETH, D_DEBUG, "ethspi udp len:       %04x\n",
        (ethspi.rxbuf[38] << 8) | ethspi.rxbuf[39]); // UDP_LEN_H_P
    DBG(D_ETH, D_DEBUG, "ethspi udp checksum:  %04x\n",
        (ethspi.rxbuf[40] << 8) | ethspi.rxbuf[41]); // UDP_CHECKSUM_H_P
  }
  IF_DBG(D_ETH, D_DEBUG) {
    printbuf(&ethspi.rxbuf[0], plen);
  }
Exemplo n.º 7
0
int main(void) {
	static uint8_t buffer[BufferSize + 1];
	int8_t   i;
	uint8_t  message[4] = { 0, 0, CID, P2CID };
	uint16_t received;
	snesIO   port0 = 0xffff, port1 = 0xffff;


	// Initialise basic I/O.
	initLed();
	initInput();
	initOutput();


	// Switched mode: B + Y.
	port0 = recvInput();
	if (port0 == 0xfffc) {
		switchedMode = Enabled;
		ledSignal(5);
	}
	ledOnRed();


	// Initialise network interface.
	enc28j60Init(mymac);
	_delay_ms(100);
	// 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(100);


	// Get the initial IP via DHCP and configure network.
	init_mac(mymac);
	while (i != 1) {
		received = enc28j60PacketReceive(BufferSize, buffer);
		buffer[BufferSize] = '\0';
		i = packetloop_dhcp_initial_ip_assignment(buffer, received, mymac[5]);
	}
	dhcp_get_my_ip(myip, netmask, gwip);
	client_ifconfig(myip, netmask);


	// Resolve MAC address from server IP.
	if (route_via_gw(serverip)) // Must be routed via gateway.
		get_mac_with_arp(gwip, TransNumGwmac, &arpresolverResultCallback);
	else                        // Server is on local network.
		get_mac_with_arp(serverip, TransNumGwmac, &arpresolverResultCallback);

	while (get_mac_with_arp_wait()) {
		received = enc28j60PacketReceive(BufferSize, buffer);
		// Call packetloop to process ARP reply.
		packetloop_arp_icmp_tcp(buffer, received);
	}


	// Lookup DNS of the server hostname.
	while (dnslkup_haveanswer() != 1) {
		uint16_t tmp;
		received = enc28j60PacketReceive(BufferSize, buffer);
		tmp      = packetloop_arp_icmp_tcp(buffer, received);

		if (received == 0) {
			if (!enc28j60linkup()) continue;
			dnslkup_request(buffer, ServerVHost, gwmac);
			_delay_ms(100);
			continue;
		}

		if (tmp == 0)
			udp_client_check_for_dns_answer(buffer, received);
	}
	dnslkup_get_ip(serverip);


	ledOnGreen(); // Connected.


	while (1) { // Main loop start.
		received = enc28j60PacketReceive(BufferSize, buffer);


		// Software reset: L + R + Select + Start.
		if (port0 == 0xf3f3) reset();


		// Do something while no packet in queue.
		if (received == 0) {
			port0 = recvInput();

			// Prepare message and send it to the server.
			for (i = 0; i < 8; i++) { // Lo-Byte.
				char *c = message;

				*c = port0 & (1 << i)
					? *c |  (1 << i)
					: *c & ~(1 << i);
			}

			for (i = 0; i < 8; i++) { // Hi-Byte.
				char *c = message + 1;

				*c = port0 & (1 << i + 8)
					? *c |  (1 << i)
					: *c & ~(1 << i);
			}

			send_udp(buffer, message, sizeof(message), 57351, serverip, 57350, gwmac);


			// Send controller data to SNES.
			if (switchedMode == Disabled)
				sendOutput(port0, port1);
			else
				sendOutput(port1, port0);

			continue;
		}


		// Answer to ARP requests.
		if (eth_type_is_arp_and_my_ip(buffer, received)) {
			make_arp_answer_from_request(buffer, received);
			continue;
		}


		// Check if IP packets (ICMP or UDP) are for us.
		if (eth_type_is_ip_and_my_ip(buffer, received) == 0)
			continue;


		// Answer ping with pong.
		if (
			buffer[IP_PROTO_P]  == IP_PROTO_ICMP_V &&
			buffer[ICMP_TYPE_P] == ICMP_TYPE_ECHOREQUEST_V) {

			make_echo_reply_from_request(buffer, received);
			continue;
		}


		// Listen for UDP packets on port 57351 (0xe007) and process
		// received data.
		if (
			buffer[IP_PROTO_P]       == IP_PROTO_UDP_V &&
			buffer[UDP_DST_PORT_H_P] == 0xe0 &&
			buffer[UDP_DST_PORT_L_P] == 0x07) {

			for (i = 0; i < 8; i++) {
				uint16_t *c = &port1;

				*c = buffer[UDP_DATA_P] & (1 << i)
					? *c |  (1 << i)
					: *c & ~(1 << i);
			}

			for (i = 0; i < 8; i++) {
				uint16_t *c = &port1;

				*c = buffer[UDP_DATA_P + 1] & (1 << i)
					? *c |  (1 << i + 8)
					: *c & ~(1 << i + 8);
			}
		}
	} // Main loop end.


	return (0);
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
int main(void){

        
        uint16_t plen;
        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
        
        /* enable PB0, reset as output */
        DDRB|= (1<<DDB0);

        /* set output to gnd, reset the ethernet chip */
        PORTB &= ~(1<<PB0);
        delay_ms(20);
        /* set output to Vcc, reset inactive */
        PORTB|= (1<<PB0);
        delay_ms(100);
        
        // LED
        /* enable PB1, LED as output */
        DDRB|= (1<<DDB1);

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

        /*initialize enc28j60*/
        enc28j60Init(mymac);
        delay_ms(20);
        
        /* 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(mymac,myip);

        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,plen);
                        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<<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;
                }
                if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
                        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
                        if (buf[UDP_DATA_P]=='t' && payloadlen==5){
                                make_udp_reply_from_request(buf,"hello",6,myport);
                        }
                }
        }
        return (0);
}
Exemplo n.º 10
0
uint8_t ReceiveFromEthernet()
{
	        
    uint16_t plen;
    uint8_t payloadlen=0;

	// 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){
			return FALSE;
	}
    	                    
	// 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);
			arp_record * rec = (arp_record*)&buf[ETH_ARP_DST_MAC_P];
			eth_arptable_add(rec);
			return TRUE;
	}

	// check if ip packets are for us:
	if(eth_type_is_ip_and_my_ip(buf,plen)==0){
			return TRUE;
	}
                
	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);
			return TRUE;
	}
	//
	// udp start, we listen on udp port 8000=0x1F40
	if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==0x1F&&buf[UDP_DST_PORT_L_P]==0x40){
			payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
			
			EthPacket * ppacket = (EthPacket*)&buf[UDP_DATA_P];
			if(ppacket->destId.ParentPart == g_parentid)
			{
				uint8_t id = ppacket->destId.ModuleAddr;
				EthPacket * pdest;
	
				if(dispat_inc_buffer(id, &pdest))
				{					
					PORTB ^= _BV(PORTB5);
					memcpy((void*)pdest, (void*)ppacket, sizeof(EthPacket));
				}	
				
				return TRUE;
			}							
	}			
	
	return FALSE;
//ANSWER:
			//make_udp_reply_from_request(buf,str,strlen(str),MYUDPPORT);
	//
}  
Exemplo n.º 11
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
        }
    }
}
Exemplo n.º 12
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);
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
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);
}