Пример #1
0
nano_mesh_response_t nano_mesh_forward(addrtype_t type, address_t address, route_check_t *r_check )
{
	dest_delivery_t table_check;
	nano_mesh_response_t forward_response = NANOMESH_NO_ROUTE;
	
	if( xSemaphoreTake( table_lock, ( portTickType ) 5 ) == pdTRUE )
	{
		table_check = check_neighbour_table(type, address);
		switch (table_check)
		{
			case BROADCAST:
				forward_response = NANOMESH_BROADCAST;
				break;
	
			case NEIGHBOR:
				forward_response = NANOMESH_NEIGHBOUR;
				break;
	
			case NEIGHBOR_LOW_RSSI:
			case NOT_NEIGHBOR:
				if(r_check != NULL)
				{
#ifdef HAVE_ROUTING
					if(check_routing_table(type, address, r_check ) == pdTRUE)
						forward_response = NANOMESH_FORWARD;
					else
					{
						if(table_check==NEIGHBOR_LOW_RSSI)
							forward_response = NANOMESH_NEIGHBOUR;
						else
							forward_response = NANOMESH_NO_ROUTE;
					}
#else
					if(table_check==NEIGHBOR_LOW_RSSI)
							forward_response = NANOMESH_NEIGHBOUR;
						else
							forward_response = NANOMESH_NO_ROUTE;
#endif
				}
				else
					forward_response = NANOMESH_NO_ROUTE;
				break;
			default:
				break;
	
		}
		xSemaphoreGive( table_lock ); /*free lock*/
	}
	return forward_response;
}
Пример #2
0
/*Returns 0 on success and error code on fail*/
int sr_handleip(struct sr_instance* sr, 
                uint8_t* packet,
                unsigned int len, 
                struct sr_if* in_f, 
                uint8_t** ethernet_data_addr){
  sr_ip_hdr_t* ip_header_buffer = (sr_ip_hdr_t*) *ethernet_data_addr;

  /* Get headers from packet */
  /*sr_ethernet_hdr_t* eth_hdr = (sr_ethernet_hdr_t*) packet;
  uint8_t * ip_pkt_buf = packet + sizeof(sr_ethernet_hdr_t);
  sr_ip_hdr_t* ip_hdr = (sr_ip_hdr_t*) (packet + sizeof(sr_ethernet_hdr_t)); */
  uint8_t * icmp_pkt_buf = packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t);
  sr_icmp_hdr_t* icmp_hdr = (sr_icmp_hdr_t*) icmp_pkt_buf;
  struct sr_if* ret_if; /* return interface */

  if (check_ip_sum(ip_header_buffer) == 0) { /*Pass Checksum*/
    printf("Checksum Pass\n");
  }
  else { /*Fail Checksum*/
    printf("Checksum Fail\n");
    return -1;
  }

  /*If the TTL went to 0*/
  if (decrement_ttl(ip_header_buffer) == -1) {
    /*Send ICMP with the proper TTL decrease type and icmp code*/
    printf("TTL reached 0\n"); 
    send_icmp(sr, packet, len, in_f, time_exceed_type, time_exceed_code);
    return -1;
  }

  /*Check if the IP packet is for us and not a echo request*/
  ret_if = sr_get_interface_from_ip(sr, ip_header_buffer->ip_dst);
  if(ret_if &&  !(ip_header_buffer->ip_p == ip_protocol_icmp && 
      icmp_hdr->icmp_type == echo_req_type && icmp_hdr->icmp_code == echo_req_code)) {
    /* The IP packet is FOR US */    
    printf("FOR US, NOT ECHO REQ");

    /* Check if it is an echo request */
    if (ip_header_buffer->ip_p == ip_protocol_tcp || 
               ip_header_buffer->ip_p == ip_protocol_udp) {
      /* It is TCP/UDP send ICMP port unreachable 
         SEND: an ICMP port unreachable to sending host*/
      send_icmp(sr, packet, len, in_f, port_unreach_type, port_unreach_code);
    } else {
      ;
      /* According to the Assignment: IGNORE THE PACKET*/
    }

  } else {
    
    /*If it's not in the routing table, send ICMP net unreachable*/
    struct sr_rt * routing_node;

    uint32_t ip_dest;

    /*If it's for us, we want to send back to the source, so check for the source in the routing table*/
    if (ret_if) {
      /* The IP packet is FOR US */
      printf("FOR US\n");
      ip_dest = ip_header_buffer->ip_src;
    }
    /*If not for us, we want to keep forwarding to the destination so check for that in the routing table*/
    else {
      /* The IP packet is NOT FOR US */
      printf("NOT FOR US\n");
      ip_dest = ip_header_buffer->ip_dst;
    }

    if ((routing_node = check_routing_table(sr, ip_dest)) == NULL) { 
      printf("NOT in routing table\n");
      send_icmp(sr, packet, len, in_f, dest_net_unreach_type, dest_net_unreach_code);
    }
    else {
      printf("In routing table\n");
      /*Got the routing table node in routing_node */

      /*Next hop IP address is in gateway
       *Look it up in arpcache_lookup to see if we know the MAC address
      */
      uint32_t nexthopIP = routing_node->gw.s_addr;
      struct sr_arpentry *arp_dest = sr_arpcache_lookup(&(sr->cache), nexthopIP);
      struct sr_if* nexthopInterface = sr_get_interface(sr, routing_node->interface);


      /*Create an ethernet header in front of the packet to forward regardless of
        whether or not we've found the next hop IP: need it in both cases*/

      /*Allocate space for ethernet header and packet, copy in contents of packet*/
      uint8_t* eth_header_packet = malloc(len);

      uint8_t* ip_header = eth_header_packet + sizeof(sr_ethernet_hdr_t);

      uint8_t* only_packet = eth_header_packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t);

      memcpy(ip_header, ip_header_buffer, sizeof(sr_ip_hdr_t));

      memcpy(only_packet, (packet+sizeof(sr_ethernet_hdr_t)+sizeof(sr_ip_hdr_t)), len-sizeof(sr_ethernet_hdr_t)-sizeof(sr_ip_hdr_t));

      /*Save it in struct form*/
      sr_ethernet_hdr_t* packet_to_forward = (sr_ethernet_hdr_t*)eth_header_packet;

      /*Now set the actual ethernet header for the packet*/
      packet_to_forward->ether_type = htons(ethertype_ip);
      memcpy(packet_to_forward->ether_shost, nexthopInterface->addr, ETHER_ADDR_LEN);




      /*If NULL, send out the arp request*/
      if(arp_dest == NULL){
        printf("Not in arp cache: need to send an ARP request!\n");
        broadcast_arp_req(sr, nexthopIP, packet_to_forward, len, routing_node, nexthopInterface);

      }

      /*Otherwise just forward the packet to arp_dest's MAC address*/
      else {

        /*It's for us, it must be an echo request*/
        if (ret_if) {
          /*Doesn't have a code so just passing 0 as code*/
          struct sr_if *interface = sr_get_interface(sr, routing_node->interface);
          send_icmp_echo_reply(sr, packet, len, interface, arp_dest->mac, echo_reply_type, 0);
        }
        else {

          printf("In arp cache: just forwarding the packet\n");

          memcpy(packet_to_forward->ether_dhost, arp_dest->mac, ETHER_ADDR_LEN);
          sr_send_packet(sr, (uint8_t*)packet_to_forward, len, routing_node->interface);
          
          /*Free the arp_dest that sr_arpcache_lookup created*/
          free(arp_dest);
        }
      }


    }

  }

  return 0;
}