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 // }
void EtherShield::ES_make_tcp_synack_from_syn(uint8_t *buf) { make_tcp_synack_from_syn(buf); }
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); }
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); }
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 } } }
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=/>->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); }
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); }
/* * 函数名: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); }
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); }