uint8_t handle_ethernet_packet() { uint16_t packet_size = 0; packet_size = Enc28j60PacketReceive(sizeof(ethernet_buffer), ethernet_buffer); if (packet_size == 0){ return 0; } // char buffer[30]; // sprintf(buffer, "ETH packet length: %" PRIu16, packet_size); // DBG_DYNAMIC(buffer); struct ethernet_header * header = (struct ethernet_header*)ethernet_buffer; packet_size -=sizeof(*header); uint8_t* data = (uint8_t*)(header +1); uint8_t ret=1; switch(header->type) { case HTON16(ETHERNET_TYPE_IP): //DBG_STATIC("Recieved IP packet."); //IP handle packet ret = ip_handle_packet((struct ip_header*)data,packet_size,(const ethernet_address*)&header->src); break; case HTON16(ETHERNET_TYPE_ARP): //DBG_STATIC("Recieved ARP packet."); //ARP handle packet ret = arp_handle_packet((struct arp_header*)data,packet_size); // if(ret){ // DBG_STATIC("ARP packet successfully handled."); // } else { // DBG_STATIC("ARP packet FAILURE.") // } break; default: return 0; } ethernet_stats.rx_packets++; return ret; }
void LanTask (void) { uint16_t plen, dat_p = 0; bool send; while (1) { plen = Enc28j60PacketReceive(BUFFER_SIZE, buf); /*plen will 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(buf, plen)) { Make_arp_answer_from_request(buf); continue; } // check if the ip packet is for us: if (Eth_type_is_ip_and_my_ip(buf, plen) == 0) { continue; } // ping if((buf[IP_PROTO_P] == IP_PROTO_ICMP_V) && (buf[ICMP_TYPE_P] == ICMP_TYPE_ECHOREQUEST_V)) { 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 dat_p = Get_tcp_data_pointer(); if (dat_p == 0) { // we can possibly have no data, just ack: if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V) { Make_tcp_ack_from_any(buf); } continue; } } send = false; 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>")); send = true; } if (!send) { char *p; p = (char*) &(buf[dat_p+4]); // start of incomming payload switch (GetCommand(p)) { case 0: break; case 1: countUp0 = false; break; case 2: countUp0 = true; break; } plen = PrintWebpage(buf); send = true; } 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) { uint8_t 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(payloadlen) { char msg1[]="Hello"; Make_udp_reply_from_request(buf,msg1,sizeof(msg1),MYUDPPORT); } }// End udp interface. }// End while(1) }// End LanTask