Esempio n. 1
0
  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)

  }
Esempio n. 2
0
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");
	}
}
Esempio n. 3
0
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");
}
Esempio n. 4
0
  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)
  }