/* Given a destination ip address: * - find interface the packet would be shipped through * - return this interface's ip address as the src ip address */ uint32_t find_srcip(uint32_t dest) { struct sr_instance* sr = sr_get_global_instance(0); router_state* rs = (router_state*)sr->interface_subsystem; iface_entry* iface_struct; char *iface = 0; struct in_addr dst; struct in_addr src; uint32_t srcip; iface = calloc(32, sizeof(char)); dst.s_addr = dest; src.s_addr = 0; lock_if_list_rd(rs); lock_rtable_rd(rs); if(get_next_hop(&src, iface, 32, rs, &dst)) { srcip = 0; } else { iface_struct = get_iface(rs, iface); assert(iface_struct); srcip = iface_struct->ip; } unlock_rtable(rs); unlock_if_list(rs); return srcip; }
void* arp_thread(void *param) { assert(param); struct sr_instance *sr = (struct sr_instance *)param; router_state *rs = get_router_state(sr); while (1) { lock_arp_cache_wr(rs); expire_arp_cache(sr); unlock_arp_cache(rs); lock_arp_cache_rd(rs); lock_arp_queue_wr(rs); lock_if_list_rd(rs); lock_rtable_rd(rs); /* because we may send an icmp packet back, requiring get next hop */ process_arp_queue(sr); unlock_rtable(rs); unlock_if_list(rs); unlock_arp_queue(rs); unlock_arp_cache(rs); sleep(1); } }