u08 icmp_receive_packet( ip_header * p, u16 len ) { icmp_header * icmp = ( icmp_header * )__ip_payload( p ); log_printf( "icmp: got packet, type=%d code=%d\n", icmp->type, icmp->code ); if (icmp->type == 8 && icmp->code == 0) icmp_send_reply( p, icmp, len ); return 1; }
int sr_handle_arpreq(struct sr_instance *sr, struct sr_arpreq *request){ time_t now = get_now(&now); struct sr_packet * packetptr = request->packets; int i; if(difftime(now, request->sent) > 1.0){ if(request->times_sent >= 5){ while(packetptr != NULL){ icmp_send_reply(sr, (uint8_t *)packetptr, packetptr->len, packetptr->iface, 3, 1); /* send unreachable */ packetptr = packetptr->next; } sr_arpreq_destroy(&(sr->cache), request); return -1; }else{ struct sr_rt* entry; struct sr_rt* routing = sr->routing_table; for(entry = routing; entry != NULL; entry = routing->next){ struct sr_if * interface2 = sr_get_interface(sr, entry->interface); /*create arp packet*/ enum sr_arp_opcode opcode = arp_op_request; struct sr_packet *raw = malloc(sizeof(struct sr_arp_hdr) + ETHER_HDR_LEN); /* may need to memset here*/ struct sr_ethernet_hdr *eth = (struct sr_ethernet_hdr *)raw; struct sr_arp_hdr *req = (struct sr_arp_hdr *)(raw + ETHER_HDR_LEN); req->ar_hrd = 0; req->ar_pro = 0; req->ar_hln = 0; req->ar_pln = 0; req->ar_op = opcode; req->ar_sip = sr->sr_addr.sin_addr.s_addr; req->ar_tip = request->ip; for (i = 0; i < ETHER_ADDR_LEN; i++){ req->ar_tha[i] = 0xff; req->ar_sha[i] = interface2->addr[i]; eth->ether_dhost[i] = 0xff; eth->ether_shost[i] = interface2->addr[i]; } /*send packet to the interface on routing_table*/ sr_send_packet(sr, (uint8_t *)raw, sizeof(struct sr_arp_hdr) + ETHER_HDR_LEN, request->packets->iface); free(raw); } request->sent = now; request->times_sent++; } } return 0; }
//***************************************************************************************** // // Function : server_process // Description : Run web server and listen on port 80 // //***************************************************************************************** void server_process ( void ) { MAC_ADDR client_mac; IP_ADDR client_ip; // you can change rx,tx buffer size in includes.h BYTE rxtx_buffer[MAX_RXTX_BUFFER]; WORD plen; if ( flag1.bits.syn_is_sent ) return; // get new packet plen = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER ); //plen will ne unequal to zero if there is a valid packet (without crc error) if(plen==0) return; // copy client mac address from buffer to client mac variable memcpy ( (BYTE*)&client_mac, &rxtx_buffer[ ETH_SRC_MAC_P ], sizeof(MAC_ADDR) ); // check arp packet if match with avr ip let's send reply if ( arp_packet_is_arp( rxtx_buffer, (WORD_BYTES){ARP_OPCODE_REQUEST_V} ) ) { arp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac ); return; } // get client ip address memcpy ( (BYTE*)&client_ip, &rxtx_buffer[ IP_SRC_IP_P ], sizeof(IP_ADDR) ); // check ip packet send to avr or not? if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 ) { return; } // check packet if packet is icmp packet let's send icmp echo reply if ( icmp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac, (BYTE*)&client_ip ) ) { return; } // start web server at port 80, see http.c http_webserver_process ( (BYTE*)rxtx_buffer, (BYTE*)&client_mac, (BYTE*)&client_ip ); }