Exemple #1
0
void send_icmp_destination_host_unreachable(struct sr_instance* sr,
                                            uint8_t *buf, unsigned int len) {
    
    /* sr_ethernet_hdr_t* ether_hdr = (sr_ethernet_hdr_t*)buf; */
    
    print_hdrs(buf, len);
}
Exemple #2
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  printf("Router Accessed\n");
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);
  struct sr_if * iface = sr_get_interface(sr, interface);
  printf("*** -> Received packet of length %d \n",len);
  
  /* Ethernet Protocol */
  if(len>=34){
    uint8_t* ether_packet = malloc(len+28);
    memcpy(ether_packet,packet,len);
    print_hdrs(packet,len);

    uint16_t package_type = ethertype(ether_packet);
    enum sr_ethertype arp = ethertype_arp;
    enum sr_ethertype ip = ethertype_ip;

    if (strcmp(iface->name,interface) == 0){ 
      printf("Right interface\n"); 
      if(package_type==arp){
        /* ARP protocol */
        sr_handleARPpacket(sr, ether_packet, len, iface);
      }else if(package_type==ip){
        /* IP protocol */
        if (sr->mode == 1){
          sr_natHandleIP(sr,ether_packet,len,iface);
        } else{
          sr_handleIPpacket(sr, ether_packet,len, iface);
        }
      }else{
        /* drop package */
        printf("bad protocol! BOO! \n");
      }
    }
    free(ether_packet);
  }
}/* end sr_ForwardPacket */
Exemple #3
0
/*---------------------------------------------------------------------
 * Method: eth_frame_send_with_mac(struct sr_instance* sr,
    uint8_t* packet,
    unsigned int len,
    unsigned char* mac,
    char* iface)
 * Scope:  Global
 *
 * send the ethernet frame
 *
 *---------------------------------------------------------------------*/
int eth_frame_send_with_mac(
    struct sr_instance* sr,
    uint8_t* packet,
    unsigned int len,
    unsigned char* mac,
    char* iface) {

  printf("Sending Packet\n");

  // Cast the packet in order to update fields. 
  sr_ethernet_hdr_t* e_packet = (sr_ethernet_hdr_t *)(packet);
  struct sr_if* interface = sr_get_interface(sr, iface);

  // Set fields 
  memcpy(e_packet->ether_dhost, mac, ETHER_ADDR_LEN);
  memcpy(e_packet->ether_shost, interface->addr, ETHER_ADDR_LEN);

  // Send the packet
  print_hdrs(packet, len);
  sr_send_packet(sr, packet, len, iface);
  return 0;
}
Exemple #4
0
void send_arp_request(struct sr_instance* sr, struct sr_arpreq* req) {
    /* send arp request, make arp header and ether header.*/
    
    struct sr_if* interface_sr_if = sr_get_interface(sr, req->packets->iface);
    sr_arp_hdr_t* arp_header =
    (struct sr_arp_hdr*)malloc(sizeof(struct sr_arp_hdr));
    
    arp_header->ar_hrd = htons(arp_hrd_ethernet);
    arp_header->ar_pro = htons(ethertype_ip);
    arp_header->ar_hln = ETHER_ADDR_LEN;
    arp_header->ar_pln = sizeof(uint32_t);
    arp_header->ar_op = htons(arp_op_request);
    arp_header->ar_sip = interface_sr_if->ip;
    arp_header->ar_tip = req->ip;
    memcpy(arp_header->ar_sha, interface_sr_if->addr, ETHER_ADDR_LEN);
    
    unsigned int len_packet = sizeof(struct sr_arp_hdr)
    + sizeof(struct sr_ethernet_hdr);
    
    uint8_t* packet = (uint8_t*)malloc(len_packet);
    
    sr_ethernet_hdr_t* ether_header =
    (sr_ethernet_hdr_t*)malloc(sizeof(struct sr_ethernet_hdr));
    
    ether_header->ether_type = htons(ethertype_arp);
    memset(ether_header->ether_dhost, 255, ETHER_ADDR_LEN);
    memcpy(ether_header->ether_shost, interface_sr_if->addr, ETHER_ADDR_LEN);
    
    
    memcpy(packet, ether_header, sizeof(struct sr_ethernet_hdr));
    memcpy(packet + sizeof(struct sr_ethernet_hdr), arp_header,
           sizeof(struct sr_arp_hdr));
    
    print_hdrs(packet, len_packet);
    sr_send_packet(sr, packet, len_packet, interface_sr_if->name);
    
    /* free(arp_header); */
    
}
Exemple #5
0
void sr_send_ip(struct sr_instance* sr, uint8_t* packet,
                unsigned int len, char* iface)
{
  printf("Forwarding IP packet...\n");

  struct sr_if* interface = sr_get_interface(sr, iface);
  struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t));

  /* Fetch the outgoing MAC from the ARP table */
  struct sr_arpentry * arpCacheEntry = sr_arpcache_lookup(&(sr->cache), ipHeader->ip_dst);

  /* Build the ethernet header */
  struct sr_ethernet_hdr* ethHeader = (struct sr_ethernet_hdr*)packet;

  memcpy(ethHeader->ether_shost, (char*)interface->addr, ETHER_ADDR_LEN);
  memcpy(ethHeader->ether_dhost, (char*)arpCacheEntry->mac, ETHER_ADDR_LEN);
  ethHeader->ether_type = htons(ethertype_ip);
  
  print_hdrs(packet, len);
  sr_send_packet(sr, packet, len, iface);
  printf("Sent on interface...%s\n", iface);
  free(arpCacheEntry);

}/* -- sr_send_ip -- */
Exemple #6
0
/*
 * Forward the packet to the next hop.
 */
void forward_packet(struct sr_instance *sr, char *interface, 
					unsigned char *dest_mac, unsigned int len, uint8_t *pkt) {
	
	uint8_t *packet = (uint8_t *) malloc(len);
	memcpy(packet, pkt, len);
	struct sr_if *rt_if = (struct sr_if *)malloc(sizeof(struct sr_if));
	rt_if = (struct sr_if *)sr_get_interface(sr, interface);
	
	/* Prepare ethernet header. */
	sr_ethernet_hdr_t *ether_hdr = (sr_ethernet_hdr_t *) packet;
	ether_hdr->ether_type = htons(ethertype_ip);
	memcpy(ether_hdr->ether_shost, rt_if->addr, ETHER_ADDR_LEN);
	memcpy(ether_hdr->ether_dhost, &(dest_mac), ETHER_ADDR_LEN);
	
	/* Recompute checksum. */
	sr_ip_hdr_t *ip_hdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t));
	ip_hdr->ip_sum = 0;
	ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t));
		
	/* Forward to next hop. */
	print_hdrs(packet, len);
	sr_send_packet(sr, packet, len, interface);
	free(packet);
}
/*
 * handle arp reply
 */
void sr_handle_arpreply(struct sr_instance* sr, unsigned char *mac, uint32_t ip, struct sr_if* iface)
{
	/*      
	if(ip == 167985324)
	{return;}
	*/
	 Debug("\nhandle_arpreply called\n");
	 Debug("mac: %s, ip: %d, interface: %s", mac, ip, iface->name); 
	    struct sr_arpreq *req = sr_arpcache_insert(&(sr->cache), mac, ip);

	
        struct sr_packet *packet;
        if(req)
		{
            Debug("\nhandle_arpreply -> sending out packets waiting for the arp_reply\n");
	    
            for(packet = req->packets; packet != NULL; packet = packet->next)
			{
		int i;
           	 for (i = 0; i < ETHER_ADDR_LEN; i++)
                        {
                packet->buf[i]= mac[i];
            }
                printf("---------------before send packet----------------\n");
				print_hdrs(packet->buf, packet->len);
				sr_send_packet(sr, packet->buf, packet->len, iface->name);    
                /*printf("--------------------i-------------------------: %d\n", i);i++;*/
				/*free(packet->buf);*/
		
            }

			sr_arpreq_destroy(&(sr->cache), req);
			Debug("Hey, finished sending packets");

        }
}
Exemple #8
0
void sr_send_icmp(struct sr_instance* sr, uint8_t* packet, unsigned int len,
                  unsigned int type, unsigned int code)
{
  unsigned int responseLen;
  uint8_t* responsePacket;
  struct sr_ip_hdr* responseIPHeader;

  /* Build the message depending on whether echo or another type */
  if(type == icmp_type_echoreply)
  {
    printf("Creating Echo Reply...\n");

    /* Get the length of the message to be built */
    struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t));
    unsigned int payloadLen = len - sizeof(sr_ip_hdr_t) - sizeof(sr_icmp_hdr_t);

    responseLen = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)+ sizeof(sr_icmp_hdr_t) + payloadLen;
    responsePacket = (uint8_t*) malloc(responseLen);
    memcpy(responsePacket, packet, responseLen);

    /* Build ICMP header */
    struct sr_icmp_hdr* responseICMPHeader = (struct sr_icmp_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
    responseICMPHeader->icmp_type = type;
    responseICMPHeader->icmp_code = code;
    responseICMPHeader->icmp_sum = 0x0000;
    responseICMPHeader->icmp_sum = cksum((uint16_t*)responseICMPHeader, sizeof(sr_icmp_hdr_t) + payloadLen);

    /* Build IP header */
    responseIPHeader = (struct sr_ip_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t));
    responseIPHeader->ip_hl = 5;
    responseIPHeader->ip_v = 4;
    responseIPHeader->ip_tos = 0;
    responseIPHeader->ip_len = htons( sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t) + payloadLen);
    responseIPHeader->ip_id = 0;
    responseIPHeader->ip_off = 0;
    responseIPHeader->ip_ttl = 64;
    responseIPHeader->ip_p = ip_protocol_icmp;
    responseIPHeader->ip_sum = 0x0000;
    responseIPHeader->ip_dst = ipHeader->ip_src;
    char* iface = sr_get_routing_entry_interface(sr, ipHeader->ip_src);
    struct sr_if* interface = sr_get_interface(sr, iface);
    responseIPHeader->ip_src = interface->ip;
    responseIPHeader->ip_sum = cksum((uint8_t*)responseIPHeader, sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t) + payloadLen);

    /* Build Ethernet header */
    struct sr_ethernet_hdr* ethernetHeader = (struct sr_ethernet_hdr*)packet;
    struct sr_ethernet_hdr* responseEthernetHeader = (struct sr_ethernet_hdr*)responsePacket;
    memcpy(responseEthernetHeader->ether_dhost, ethernetHeader->ether_shost, ETHER_ADDR_LEN);
    memcpy(responseEthernetHeader->ether_shost, interface->addr, ETHER_ADDR_LEN);
    responseEthernetHeader->ether_type = htons(ethertype_ip);
  }
  else
  {
    printf("Creating ICMP message...\n");
    /* Get the length of the message to be built */
    responseLen = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)+ sizeof(sr_icmp_t3_hdr_t) + 8;
    responsePacket = (uint8_t*) malloc(responseLen);

    /* Build ICMP header */
    struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t));
    struct sr_icmp_t3_hdr* responseICMPHeader = (struct sr_icmp_t3_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
    
    responseICMPHeader->icmp_type = type;
    responseICMPHeader->icmp_code = code;
    responseICMPHeader->icmp_sum = 0x0000;
    memcpy(responseICMPHeader->data, ipHeader, sizeof(sr_ip_hdr_t) + 8);
    responseICMPHeader->icmp_sum = cksum((uint16_t*)responseICMPHeader, sizeof(sr_icmp_t3_hdr_t));

    /* Build IP header */
    responseIPHeader = (struct sr_ip_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t));
    responseIPHeader->ip_hl = 5;
    responseIPHeader->ip_v = 4;
    responseIPHeader->ip_tos = 0;
    responseIPHeader->ip_len = htons( sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_t3_hdr_t));
    responseIPHeader->ip_id = 0;
    responseIPHeader->ip_off = 0;
    responseIPHeader->ip_ttl = 64;
    responseIPHeader->ip_p = ip_protocol_icmp;
    responseIPHeader->ip_sum = 0x0000;
    responseIPHeader->ip_dst = ipHeader->ip_src;
    char* iface = sr_get_routing_entry_interface(sr, ipHeader->ip_src);
    struct sr_if* interface = sr_get_interface(sr, iface);
    responseIPHeader->ip_src = interface->ip;
    responseIPHeader->ip_sum = cksum((uint8_t*)responseIPHeader, sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_t3_hdr_t));

    /* Build Ethernet header */
    struct sr_ethernet_hdr* ethernetHeader = (struct sr_ethernet_hdr*)packet;
    struct sr_ethernet_hdr* responseEthernetHeader = (struct sr_ethernet_hdr*)responsePacket;
    memcpy(responseEthernetHeader->ether_dhost, ethernetHeader->ether_shost, ETHER_ADDR_LEN);
    memcpy(responseEthernetHeader->ether_shost, interface->addr, ETHER_ADDR_LEN);
    responseEthernetHeader->ether_type = htons(ethertype_ip);
  }

  /* Look up the interface that the packet should be sent on */
  char* iface = sr_get_routing_entry_interface(sr, responseIPHeader->ip_dst);
  if(iface == NULL)
    return;

  /* Send the packet */ 
  print_hdrs(responsePacket, responseLen); 
  sr_send_packet(sr, responsePacket, responseLen, iface);
  printf("Sent on interface...%s\n", iface);
  free(responsePacket);

}/* -- sr_send_icmp -- */
Exemple #9
0
void sr_handlepacket(struct sr_instance* sr, uint8_t * packet/* lent */,
					unsigned int len, char* interface/* lent */) {
	/* Function implemented by g1izzyw and gustan50404 */
	/* REQUIRES */
	assert(sr);
	assert(packet);
	assert(interface);
	
	struct sr_if *ether_interface = (struct sr_if *) sr_get_interface(sr, interface); 
	
	/* Check if it an ethernet interface. */
	if (ether_interface) {
		/* Now we deal with the ethernet header */
		struct sr_ethernet_hdr *ether_hdr = (struct sr_ethernet_hdr *) packet;
	    
		/* Check to see if we are dealing with an ARP request/reply */
		if (ether_hdr->ether_type == htons(ethertype_arp)) {
			
			fprintf(stderr, "We Got an ARP Packet\n");
			/* Handle ARP for ethernet */ 
			struct sr_arp_hdr * arp_hdr = (struct sr_arp_hdr *)(packet + sizeof(struct sr_ethernet_hdr));
			if (arp_hdr->ar_hrd == htons(arp_hrd_ethernet)) {

				if (arp_hdr->ar_op == htons(arp_op_request)) {
				/* arp request */
					struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip);	
					if (interface_for_ip) {
  			
						/* Target ip is one of the router interfaces */
						fprintf(stderr, "ARP req for one of our interfaces\n");

						/* Now we want to make an arp reply and send it back */
						uint8_t *buf = (uint8_t *) malloc(len);
						memcpy(buf, packet, len);
    			
						/*Make Arp Header*/
						make_arprply_hdr(interface_for_ip->addr, arp_hdr->ar_sha, interface_for_ip->ip,
														arp_hdr->ar_sip, buf);
														
						/*Make Ethernet Header*/
						make_ether_hdr(interface_for_ip->addr, ether_hdr->ether_shost, ethertype_arp, buf);

						/* Now we send the packet */
						sr_send_packet(sr, buf, len, interface_for_ip->name);
						free(buf);
						fprintf(stderr, "ARP reply sent\n");
					}
				} else if (arp_hdr->ar_op == htons(arp_op_reply)) {

					fprintf(stderr, "We got an ARP Reply, need to check for intfc tho \n");
					/* arp reply */
					struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip);	
					if (interface_for_ip) {
			
						fprintf(stderr, "We got an ARP Reply for one of our interfaces\n");
						/*We first want to insert into Arp cache*/
						struct sr_arpreq *request = sr_arpcache_insert(&(sr->cache), 
																		arp_hdr->ar_sha, 
																		arp_hdr->ar_sip);
						fprintf(stderr, "Signalling all waiting packets\n");
						if (request) {
							struct sr_packet *cur_packet = request->packets;
							while(cur_packet) {
								fprintf(stderr, "About to forward \n");
								print_hdrs(cur_packet->buf, cur_packet->len);
								forward_packet(sr, cur_packet->iface, arp_hdr->ar_sha, 
															cur_packet->len, cur_packet->buf); 
								fprintf(stderr, "Packet Forwarded\n");							
								cur_packet = cur_packet->next;
							}
						}
					}
				}		
			}      
    	} else if (ether_hdr->ether_type == htons(ethertype_ip)) {
					
			/* Get the ip header from the ethernet header*/
			sr_ip_hdr_t *ip_hdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t));
			/*IP Checksum Stuff*/
			uint16_t temp_ip_sum = ip_hdr->ip_sum;
			ip_hdr->ip_sum = 0;
			ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t));																	
			if (temp_ip_sum == ip_hdr->ip_sum) {
			
				/*We got here means IP Cheksum is alright, so we extract the interface*/
				struct sr_if *interface_for_ip = get_interface_for_ip(sr, ip_hdr->ip_dst);
				
				/*Check to make sure interface is one of ours*/
				if (interface_for_ip) {
					
					fprintf(stderr, "IP Packet destined towards our interface\n");
					/*Check if our IP packet is UDP or TCP*/
					if (ip_hdr->ip_p == 6 || ip_hdr->ip_p == 17) {
						fprintf(stderr, "We Got TCP or UDP, sending ICMP error msg\n");
						send_icmp_error(3, 3, sr, interface, len, packet);
					
					} else {
						
						/* Get the ICMP header */
						sr_icmp_hdr_t *icmp_hdr = (struct sr_icmp_hdr *) (packet + 
																		sizeof(sr_ethernet_hdr_t) + 
																		sizeof(sr_ip_hdr_t));
						
						/*Now we do the ICMP checksum chek*/
						/*This covers the ICMP echo case*/
						uint16_t temp_icmp_sum = icmp_hdr->icmp_sum;
						temp_icmp_sum = icmp_hdr->icmp_sum;
						icmp_hdr->icmp_sum = 0;
						if (temp_icmp_sum == cksum(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t), 
												len - sizeof(sr_ethernet_hdr_t) - sizeof(sr_ip_hdr_t))) {
							/*Everything is fine so we send an ICMP echo back*/
							fprintf(stderr, "Sending ICMP echo reply\n");
	    					send_icmp_echo(sr, interface, len, packet);
	    				}
	    			}
				} else {
					/*IP Packet not destined towards one of our interfaces*/
					
					fprintf(stderr, "IP packet not destined to our interface\n");
					/*Decremenrt TTL by 1*/
					
					fprintf(stderr, "TTL modified \n");
					print_hdrs(packet, len);
					if (ip_hdr->ip_ttl <= 1) {
						fprintf(stderr, "Packte with TTL < 0 found, sending ICMP error \n");
						/*TTL is less than 0 so send an ICMP ERROR*/
						send_icmp_error(11, 0, sr, interface, len, packet);
						
					} else {
						
						/*Recompute Checksum over new header TTL is fine*/
						/*Check if it exists in the routing table*/
						ip_hdr->ip_ttl = ip_hdr->ip_ttl - 1;
						fprintf(stderr, "Recomputing Checksum after modifying TTl\n");
						ip_hdr->ip_sum = 0;																			
						ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t));
						struct sr_if *dst_if = (struct sr_if *)malloc(sizeof(struct sr_if));
						dst_if = next_hop(sr, interface, ip_hdr->ip_dst);
						
						if (!(dst_if)) {
						
							fprintf(stderr, "IP packet has no longest matching prefix sending ICMP error\n");
							/*dst ip has no longest macthing prefix*/
							/*So we send a type 3 code 0 ICMP error*/
							send_icmp_error(3, 0, sr, interface, len, packet);
							
						} else {
							
							/*This is the case where we do have a longest macthing prefix*/
							fprintf(stderr, "Found Longest mathcing prefix in RT\n");
							struct sr_arpcache *cache = &(sr->cache);
							struct sr_arpentry *in_cache = sr_arpcache_lookup(cache, ip_hdr->ip_dst);
							if (in_cache) {
							
								fprintf(stderr, "Found IP->MAC mapping in ARP cache forwarding packet \n");
								/*this is the case where ip->mac maping is already in cache*/
								forward_packet(sr, dst_if->name, in_cache->mac, len, packet);
								free(in_cache);
								
							} else {
							
								fprintf(stderr, "IP->MAC mapping not in ARP cache %u \n", ip_hdr->ip_dst);
								/*Case where ip->mapping is not in cache*/
								sr_arpcache_queuereq(cache, ip_hdr->ip_dst, packet, len, dst_if->name);
								fprintf(stderr, "Added Arp Req to queu \n"); 						
							}
						}					
					}
				}
			}
		}
	} 
	
} /* end sr_ForwardPacket */
Exemple #10
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

  print_hdrs(packet, len);

  sr_arp_hdr_t* arpHdr = (sr_arp_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t));
  sr_ethernet_hdr_t* ethHdr = (sr_ethernet_hdr_t*)packet;
  sr_ip_hdr_t* ipHdr = (sr_ip_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t));
  sr_icmp_hdr_t* icmpHdr = (sr_icmp_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
 

  struct sr_rt* route = sr->routing_table;
  struct sr_arpentry* ent;
  char ifBuf[INET_ADDRSTRLEN];
  char ipBuf[INET_ADDRSTRLEN];



  if(strcmp(arpHdr->ar_tha, "\0") == 0){
    sr_arpcache_queuereq(&(sr->cache), arpHdr->ar_tip, packet, len, interface);
    printf("added arpreq to queue.\n\n");
    return;
  }
  printf("arp rep: %d\n", ntohs(arpHdr->ar_op));
  printf("opcode: %d\n", arp_op_reply);
  if(ntohs(arpHdr->ar_op) == arp_op_reply){
    ent = sr_arpcache_lookup(&sr->cache, arpHdr->ar_sip);
    if( ent == NULL){
      //      printf("Added %s to cache\n", ntohl(arpHdr->ar_sip));
      printf("Incoming arp response\n");
      //      sleep(2);
      

      struct sr_arpreq* req = sr->cache.requests;
      printf("%p, %p\n", req, sr->cache.requests);
      while(req != NULL){
	if(req->ip == arpHdr->ar_sip){
	  struct sr_packet* pkt = req->packets;
	  while(pkt != NULL){
	    if(route != NULL){
	      do{
		sr_ip_hdr_t* reqIpHdr = (sr_ip_hdr_t*)(pkt->buf + sizeof(sr_ethernet_hdr_t));
		sr_ethernet_hdr_t* reqEthHdr = (sr_ethernet_hdr_t*)(pkt->buf);
		//      sr_print_routing_entry(route);
		inet_ntop(AF_INET, &route->dest, ifBuf, sizeof(char) * INET_ADDRSTRLEN);
		convert_addr_ip_int(ntohl(reqIpHdr->ip_dst), ipBuf);
		printf("%s dest: %s\n",route->interface, ifBuf);
		printf("ip dest: %s\n", ipBuf);
		if(strcmp(ifBuf, ipBuf) == 0){
		  
		  memcpy(reqEthHdr->ether_shost, (uint8_t*)(sr_get_interface(sr, route->interface)->addr), sizeof(uint8_t) * ETHER_ADDR_LEN);
		  memcpy(reqEthHdr->ether_dhost, (uint8_t*)arpHdr->ar_sha, sizeof(uint8_t) * ETHER_ADDR_LEN);
		  print_hdrs(pkt->buf, pkt->len);
		  sr_send_packet(sr, pkt->buf, pkt->len, &(route->interface));
		  printf("pkt sent down %s\n\n", route->interface);
		  //	  free(ent);
		  //return;
		  break;
		}
		route = route->next;
	      } while(route != NULL);
	      pkt = pkt->next;
	    }

	  }
	  free(ent);
	  sr_arpreq_destroy(&sr->cache, req);
	  break;
	}
	req = req->next;
      }

    }
    sr_arpcache_insert(&(sr->cache), arpHdr->ar_sha, arpHdr->ar_sip);  




    //sr_arpcache_dump(&sr->cache);
    free(ent);
    return;
  }

  ent = sr_arpcache_lookup(&sr->cache, ipHdr->ip_dst);
  route = sr->routing_table;
  //Make and queue requests if dest isn't in arpcache
  if( ent == NULL ){
    if(route != NULL){
      do{
	inet_ntop(AF_INET, &route->dest, ifBuf, 100);
	convert_addr_ip_int(ntohl(ipHdr->ip_dst), ipBuf);
	if(strcmp(ifBuf, ipBuf) == 0){
	  sr_arpcache_queuereq(&sr->cache, ipHdr->ip_dst, packet, len, route->interface);
	  free(ent);
	  return;
	}
	route = route->next;
      } while(route != NULL);
      sr_arpcache_queuereq(&sr->cache, ipHdr->ip_dst, packet, len, "eth1");

    }
  }

  //Forwards packet to interface
  if(route != NULL){
    do{
      //      sr_print_routing_entry(route);
      inet_ntop(AF_INET, &route->dest, ifBuf, sizeof(char) * INET_ADDRSTRLEN);
      convert_addr_ip_int(ntohl(ipHdr->ip_dst), ipBuf);
      printf("%s dest: %s\n",route->interface, ifBuf);
      printf("ip dest: %s\n", ipBuf);
      if(strcmp(ifBuf, ipBuf) == 0){
	
	memcpy(ethHdr->ether_shost, (uint8_t*)(sr_get_interface(sr, route->interface)->addr), sizeof(uint8_t) * ETHER_ADDR_LEN);
	memcpy(ethHdr->ether_dhost, (uint8_t*)ent->mac, sizeof(uint8_t) * ETHER_ADDR_LEN);
	print_hdrs(packet, len);
	sr_send_packet(sr, packet, len, &(route->interface));
	printf("pkt sent down %s\n\n", route->interface);
	free(ent);
	return;
      }
      route = route->next;
    } while(route != NULL);
  }

  free(ent);
  


}/* end sr_ForwardPacket */