void __forwarding_table_hw_write_a(uint32_t subnet, uint32_t mask, uint32_t next_hop,
                             char * interface, void * userdata, int * finished)
{
    struct __forwarding_table_hw_write_i * hwi = (struct __forwarding_table_hw_write_i *)userdata;
    struct nf2device * device = &ROUTER(hwi->sr)->device;
    if(hwi->count >= ROUTER_OP_LUT_ROUTE_TABLE_DEPTH)
    {
        *finished = 1;
    }
    else if(subnet > 0)
    {
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_IP, ntohl(subnet));
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_MASK, ntohl(mask));
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_NEXT_HOP_IP, ntohl(next_hop));
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_OUTPUT_PORT,
                 interface_list_get_output_port(hwi->sr, interface));
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_WR_ADDR, hwi->count);
        hwi->count += 1;
    }

    if(subnet == 0)
    {
        hwi->def = 1;
        hwi->next_hop = next_hop;
        hwi->port = interface_list_get_output_port(hwi->sr, interface);
    }
}
static void forwarding_table_hw_write(struct sr_instance * sr)
{
#ifdef _CPUMODE_
    struct __forwarding_table_hw_write_i  hwi = {0,sr,0,0,0};
    struct nf2device * device = &ROUTER(sr)->device;
    struct assoc_array * array = assoc_array_create(__forwarding_table_get_key_mask,assoc_array_key_comp_int);
    int i;

    __forwarding_table_loop(FORWARDING_TABLE(sr)->array_d, __combine_arrays, array);
    __forwarding_table_loop(FORWARDING_TABLE(sr)->array_s, __combine_arrays, array);
    __forwarding_table_loop(array, __forwarding_table_hw_write_a, &hwi);

    if(hwi.def)
    {
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_IP, 0);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_MASK, 0);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_NEXT_HOP_IP, ntohl(hwi.next_hop));
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_OUTPUT_PORT, hwi.port);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_WR_ADDR,
                 hwi.count >= ROUTER_OP_LUT_ROUTE_TABLE_DEPTH ? ROUTER_OP_LUT_ROUTE_TABLE_DEPTH - 1 : hwi.count);
        hwi.count ++;
    }

    for(i = hwi.count; i < ROUTER_OP_LUT_ROUTE_TABLE_DEPTH; i++)
    {
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_IP, 0);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_MASK, 0xffffffff);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_NEXT_HOP_IP, 0);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_ENTRY_OUTPUT_PORT, 0);
        writeReg(device, ROUTER_OP_LUT_ROUTE_TABLE_WR_ADDR, i);
    }
    assoc_array_delete_array(array,__delete_forwarding_table);
#endif
}
Beispiel #3
0
void ip_handle_incoming_packet(struct sr_packet * packet)
{
    struct ip * ip_hdr = IP_HDR(packet);

    if(ip_hdr->ip_sum != checksum_ipheader(ip_hdr))
    {
        printf("\nchecksums differ %x, %x\n", ip_hdr->ip_sum, checksum_ipheader(ip_hdr));
    }
    else if(ip_hdr->ip_v != 4)
    {
        printf("\nip version is %d; only accepting 4\n",ip_hdr->ip_v);
    }
    else
    {
        if(dhcp_packet(packet))
        {
            dhcp_handle_incoming(packet);
        }
        /* if packet is not for one of our interfaces then forward */
        else if(!interface_list_ip_exists(ROUTER(packet->sr)->iflist, ip_hdr->ip_dst.s_addr) &&
                ntohl(ip_hdr->ip_dst.s_addr) != OSPF_AllSPFRouters)
        {
            if(ip_hdr->ip_ttl <= 1)
            {
                icmp_send_time_exceeded(packet);
            }
            else
            {
                if(ip_hdr->ip_p == IP_P_TCP || ip_hdr->ip_p == IP_P_UDP)
                {
                    tcp_handle_incoming_not_for_us(packet);
                }
                else
                {
                    ip_forward(packet);
                }
            }
        }
        else
        {
            switch(ip_hdr->ip_p)
            {
            case IP_P_ICMP:
                icmp_handle_incoming_packet(packet);
                break;
            case IP_P_TCP: case IP_P_UDP:
                tcp_handle_incoming_for_us(packet);
                break;
            case IP_P_OSPF:
                ospf_handle_incoming_packet(packet);
                break;
            default:
                icmp_send_port_unreachable(packet);
            }
        }
    }    
}
void forwarding_table_create(struct sr_instance * sr)
{
    NEW_STRUCT(ret,forwarding_table);
    ROUTER(sr)->fwd_table = ret;
    ret->array_s = assoc_array_create(__forwarding_table_get_key_mask,assoc_array_key_comp_int);
    ret->array_d = assoc_array_create(__forwarding_table_get_key_mask,assoc_array_key_comp_int);
    ret->array_nat = assoc_array_create(__forwarding_table_get_key_mask,assoc_array_key_comp_int);    
    ret->mutex = mutex_create();
    ret->running_dijkstra = 0;
}
Beispiel #5
0
/* look up arp and send  */
void ip_send(struct sr_packet * packet, uint32_t next_hop, char * thru_interface)
{
    struct sr_ethernet_hdr * eth_hdr = ETH_HDR(packet);

    if(!arp_cache_get_MAC_from_ip(ROUTER(packet->sr)->a_cache, next_hop, eth_hdr->ether_dhost))
    {
        arp_request_handler_make_request(packet,next_hop,thru_interface);
    }
    else
    {
        if(interface_list_get_MAC_and_IP_from_name(ROUTER(packet->sr)->iflist,thru_interface,eth_hdr->ether_shost,NULL))
        {
            if(sr_integ_low_level_output(packet->sr,packet->packet,packet->len,thru_interface) == -1)
            {
                printf("\nfailed to send packet\n");
            }
        }
    }
}
Beispiel #6
0
/* if packet->interface = NULL then the packet has been generated by the router  */
void ip_forward(struct sr_packet * packet)
{
    struct ip * ip_hdr = IP_HDR(packet);
    uint32_t next_hop;
    char thru_interface[SR_NAMELEN];

    /* if the destination is to one of our ports, then just forward it there  */
    if(interface_list_get_interface_by_ip(INTERFACE_LIST(packet->sr), ip_hdr->ip_dst.s_addr))
    {
        ip_handle_incoming_packet(packet);
    }
    else
    {
        if(forwarding_table_lookup_next_hop(ROUTER(packet->sr)->fwd_table,
                                            ip_hdr->ip_dst.s_addr, &next_hop, thru_interface,
                                            interface_list_inbound(packet->sr, packet->interface)) &&
           interface_list_forward_packet(packet->sr, packet->interface, thru_interface))
        {
            if(next_hop == 0)
            {
                next_hop = ip_hdr->ip_dst.s_addr;
            }
            ip_hdr->ip_ttl --;
            ip_hdr->ip_sum = checksum_ipheader(ip_hdr);
            ip_send(packet,next_hop,thru_interface);
        }
        else
        {
            if(forwarding_table_lookup_next_hop(ROUTER(packet->sr)->fwd_table,
                                                ip_hdr->ip_src.s_addr, 0,0,
                                                interface_list_inbound(packet->sr, packet->interface)))
            {
                icmp_send_host_unreachable(packet);
            }
        }
    }
}
Beispiel #7
0
int ip_send_packet(struct sr_packet * packet)
{
    struct ip * ip_hdr = IP_HDR(packet);
    uint32_t next_hop;
    char thru_interface[SR_NAMELEN];
    if(forwarding_table_lookup_next_hop(ROUTER(packet->sr)->fwd_table,
                                        ip_hdr->ip_dst.s_addr, &next_hop, thru_interface, 0))
    {
        if(next_hop == 0)
        {
            next_hop = ip_hdr->ip_dst.s_addr;
        }
        ip_send(packet,next_hop,thru_interface);
        return 1;
    }
    return 0;
}
Beispiel #8
0
  tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0);
  tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0);
  tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0);

 done:
  /* If a connection is never set up, connection_free chokes on it. */
  if (mocked_connection) {
    buf_free(mocked_connection->inbuf);
    buf_free(mocked_connection->outbuf);
  }
  tor_free(mocked_connection);
  UNMOCK(connection_get_by_type_addr_port_purpose);
}

#undef TEST_ADDR_STR
#undef TEST_DIR_PORT

#define NODE(name, flags) \
  { #name, test_routerlist_##name, (flags), NULL, NULL }
#define ROUTER(name,flags) \
  { #name, test_router_##name, (flags), NULL, NULL }

struct testcase_t routerlist_tests[] = {
  NODE(initiate_descriptor_downloads, 0),
  NODE(launch_descriptor_downloads, 0),
  NODE(router_is_already_dir_fetching, TT_FORK),
  ROUTER(pick_directory_server_impl, TT_FORK),
  END_OF_TESTCASES
};