void sr_send_arp_req(struct sr_instance *sr, uint32_t target_ip){ char * iface = sr_get_iface_from_gw_ip(sr, target_ip); if(iface){ uint8_t target[ETHER_ADDR_LEN]; int i; for(i = 0; i < ETHER_ADDR_LEN; i++){ target[i] = BROADCAST; } sr_send_arp(sr, arp_op_request, iface, (unsigned char*)target, target_ip); } }
/* This function gets called every second. For each request sent out, we keep checking whether we should resend an request or destroy the arp request. See the comments in the header file for an idea of what it should look like. */ void sr_arpcache_sweepreqs(struct sr_instance *sr) { // A broadcast ethernet address unsigned char broadcast_addr[ETHER_ADDR_LEN]; for(int i = 0; i < ETHER_ADDR_LEN; i++) broadcast_addr[i] = 0xff; // Loop through all the outstanding ARP requests struct sr_arpreq* arp_req = sr->cache.requests; struct sr_arpreq* next_arp_req = 0; while(arp_req) { // Set the next ARP request before trying to process the current one. Because the // function sr_can_send_arp_req() automatically removes the passed in ARP request // if it's been sent too many times next_arp_req = arp_req->next; // Checks to see if this ARP request can be sent again. Based on when the last // time it has been sent and how many time it has been sent if(sr_can_send_arp_req(sr, arp_req)) { // Extract the ethernet and IP headers from the first packet in the linked list sr_ethernet_hdr_t* ether_hdr = (sr_ethernet_hdr_t*)arp_req->packets->buf; // Look up outgoing interface using source of Ethernet header struct sr_if* outgoing_interface = sr_get_interface_from_eth_addr(sr, ether_hdr->ether_shost); // Build and send the ARP request sr_arp_hdr_t* arp_hdr = malloc(sizeof(sr_arp_hdr_t)); sr_build_arp(ether_hdr->ether_shost, ntohl(outgoing_interface->ip), broadcast_addr, htonl(arp_req->ip), arp_op_request, arp_hdr); sr_send_arp(sr, (uint8_t*)arp_hdr, sizeof(sr_arp_hdr_t)); free(arp_hdr); } arp_req = next_arp_req; } }
void sr_send_arp_reply(struct sr_instance *sr, char *iface, unsigned char * target_eth_addr, uint32_t target_ip){ sr_send_arp(sr, arp_op_reply, iface, target_eth_addr, target_ip); }