void Arp::receive(Packet_ptr pckt) { PRINT("<ARP handler> got %i bytes of data\n", pckt->size()); header* hdr = reinterpret_cast<header*>(pckt->layer_begin()); /// cache entry this->cache(hdr->sipaddr, hdr->shwaddr); /// always try to ship waiting packets when someone talks auto waiting = waiting_packets_.find(hdr->sipaddr); if (waiting != waiting_packets_.end()) { PRINT("<Arp> Had a packet waiting for this IP. Sending\n"); transmit(std::move(waiting->second.pckt), hdr->sipaddr); waiting_packets_.erase(waiting); } switch(hdr->opcode) { case H_request: { // Stat increment requests received requests_rx_++; PRINT("<Arp> %s is looking for %s\n", hdr->sipaddr.str().c_str(), hdr->dipaddr.str().c_str()); if (hdr->dipaddr == inet_.ip_addr()) { // The packet is for us. Respond. arp_respond(hdr, inet_.ip_addr()); } else if (proxy_ and proxy_(hdr->dipaddr)){ // The packet is for an IP to which we know a route arp_respond(hdr, hdr->dipaddr); } else { // Drop PRINT("\t NO MATCH for My IP (%s). DROP!\n", inet_.ip_addr().str().c_str()); } break; } case H_reply: { // Stat increment replies received replies_rx_++; PRINT("\t ARP REPLY: %s belongs to %s (waiting: %u)\n", hdr->sipaddr.str().c_str(), hdr->shwaddr.str().c_str(), waiting_packets_.size()); break; } default: PRINT("\t UNKNOWN OPCODE\n"); break; } //< switch(hdr->opcode) }
void arp_handle(struct sr_instance* sr, uint8_t * packet, unsigned int length, char* interface) { if(!arp_valid(packet, length)) { fprintf(stderr, "ARP packet does not match the recognized format.\n"); return; } struct sr_if *sr_interface = sr_get_interface(sr, interface); if(sr_interface == 0) { fprintf(stderr, "Failed to retrieve interface %s.\n", interface); return; } struct sr_arphdr *arp_hdr = (struct sr_arphdr *)(packet + sizeof(struct sr_ethernet_hdr)); if(ntohs(arp_hdr->ar_op) == ARP_REQUEST) { if(arp_hdr->ar_tip == sr_interface->ip) arp_respond(sr, packet, sr_interface); else printf("Received ARP packet destined for %d\n", arp_hdr->ar_tip); } else if(ntohs(arp_hdr->ar_op) == ARP_REPLY) { struct sr_arp_record *record = cache_add_record(sr, packet); if(record == NULL) { fprintf(stderr, "Received ARP response that does not match any outstanding ARP requests.\n"); return; } cache_send_outstanding(sr, record); } else { fprintf(stderr, "ARP packet opcode must be of type request or reply.\n"); } }
void arp_layer_receive( struct sk_buff *comer_skb ){ assert(comer_skb->pkgsize = 14 + 28); struct arphdr *arphdr = (void *)(comer_skb->ethhdr + 1); comer_skb->arphdr = arphdr; ////////////Entry here !! ///////////network byte order to host order, only performed on arp header BYTE_ENDIAN_FLIP2(arphdr->hardware); BYTE_ENDIAN_FLIP2(arphdr->protocol); BYTE_ENDIAN_FLIP2(arphdr->operation); BYTE_ENDIAN_FLIP4(arphdr->myip); BYTE_ENDIAN_FLIP4(arphdr->yourip); //////////done //u8 *mac = arphdr->mymac; //oprintf("arp layer receive: operation=%u, from mac(%x %x %x %x %x %x)", arphdr->operation, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); if(arphdr->operation == 1){ /* it's an inquiry */ arp_respond(comer_skb); } else if(arphdr->operation == 2){ /* it's a REPLY */ arp_act(comer_skb); } else spin("unknown operation"); //oprintf(" ARP layer exit\n"); }
void Arp::bottom(Packet_ptr pckt) { debug2("<ARP handler> got %i bytes of data\n", pckt->size()); header* hdr = reinterpret_cast<header*>(pckt->buffer()); debug2("Have valid cache? %s\n", is_valid_cached(hdr->sipaddr) ? "YES" : "NO"); cache(hdr->sipaddr, hdr->shwaddr); switch(hdr->opcode) { case H_request: { // Stat increment requests received requests_rx_++; debug2("\t ARP REQUEST: "); debug2("%s is looking for %s\n", hdr->sipaddr.str().c_str(), hdr->dipaddr.str().c_str()); if (hdr->dipaddr == inet_.ip_addr()) { arp_respond(hdr); } else { debug2("\t NO MATCH for My IP (%s). DROP!\n", inet_.ip_addr().str().c_str()); } break; } case H_reply: { // Stat increment replies received replies_rx_++; debug2("\t ARP REPLY: %s belongs to %s (waiting: %u)\n", hdr->sipaddr.str().c_str(), hdr->shwaddr.str().c_str(), waiting_packets_.size()); auto waiting = waiting_packets_.find(hdr->sipaddr); if (waiting != waiting_packets_.end()) { debug("Had a packet waiting for this IP. Sending\n"); transmit(std::move(waiting->second)); waiting_packets_.erase(waiting); } break; } default: debug2("\t UNKNOWN OPCODE\n"); break; } //< switch(hdr->opcode) }