How to write a C Program contains all the functions that interact directly with the routing table, as well as the main entry method for routing in C Programming Language ?
Solution:
/*
* Description:
* This C Program contains all the functions that interact directly
* with the routing table, as well as the main entry method
* for routing.
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "sr_if.h"
#include "sr_rt.h"
#include "sr_router.h"
#include "sr_protocol.h"
#include "sr_arpcache.h"
#include "sr_utils.h"
void sr_handleip(struct sr_instance* sr, uint8_t * packet/* lent */, unsigned int len, char* interface/* lent */);
void sr_handlearp(struct sr_instance* sr, uint8_t * packet/* lent */, unsigned int len, char* interface/* lent */);
void sr_handlearpreq(struct sr_instance* sr, struct sr_arpreq *req);
/*---------------------------------------------------------------------
* Method: sr_init(void)
* Scope: Global
*
* Initialize the routing subsystem
*
*---------------------------------------------------------------------*/
void sr_init(struct sr_instance* sr)
{
/* REQUIRES */
assert(sr);
/* Initialize cache and cache cleanup thread */
sr_arpcache_init(&(sr->cache));
pthread_attr_init(&(sr->attr));
pthread_attr_setdetachstate(&(sr->attr), PTHREAD_CREATE_JOINABLE);
pthread_attr_setscope(&(sr->attr), PTHREAD_SCOPE_SYSTEM);
pthread_attr_setscope(&(sr->attr), PTHREAD_SCOPE_SYSTEM);
pthread_t thread;
pthread_create(&thread, &(sr->attr), sr_arpcache_timeout, sr);
/* Add initialization code here! */
} /* -- sr_init -- */
/*---------------------------------------------------------------------
* Method: sr_handlepacket(uint8_t* p,char* interface)
* Scope: Global
*
* This method is called each time the router receives a packet on the
* interface. The packet buffer, the packet length and the receiving
* interface are passed in as parameters. The packet is complete with
* ethernet headers.
*
* Note: Both the packet buffer and the character's memory are handled
* by sr_vns_comm.c that means do NOT delete either. Make a copy of the
* packet instead if you intend to keep it around beyond the scope of
* the method call.
*
*---------------------------------------------------------------------*/
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);
/* fill in code here */
/* Get Ethernet Header */
sr_ethernet_hdr_t *eth_hdr;
eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet, sizeof(sr_ethernet_hdr_t));
/* Sanity Check */
int minlength = sizeof(sr_ethernet_hdr_t);
if (len < minlength) {
fprintf(stderr, "Failed to print ETHERNET header, insufficient length\n");
return;
}
uint16_t ethtype = ethertype((uint8_t *)eth_hdr);
print_hdr_eth((uint8_t *)eth_hdr);
if (ethtype == ethertype_ip){ /* IP */
printf("Received the IP Packet!\n");
sr_handleip(sr, packet, len, interface);
} else if (ethtype == ethertype_arp){ /* ARP */
printf("Received the ARP Packet!\n");
sr_handlearp(sr, packet, len, interface);
}
}/* end sr_ForwardPacket */
void sr_handleip(struct sr_instance* sr,
uint8_t * packet/* lent */,
unsigned int len,
char* interface/* lent */)
{
/* REQUIRES */
assert(sr);
assert(packet);
assert(interface);
/* Get ethernet header */
sr_ethernet_hdr_t *eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet, sizeof(sr_ethernet_hdr_t));
/* Get IP header */
sr_ip_hdr_t *ip_hdr;
ip_hdr = malloc(sizeof(sr_ip_hdr_t));
memcpy(ip_hdr, (sr_ip_hdr_t *) (packet + sizeof(sr_ethernet_hdr_t)), sizeof(sr_ip_hdr_t));
/* Sanity Check */
int minlength = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t);
if (len < minlength){
fprintf(stderr, "Failed to print IP header, insufficient length\n");
return;
}
print_hdr_ip((uint8_t *)ip_hdr);
uint8_t received_cksum = ip_hdr->ip_sum;
ip_hdr->ip_sum = 0;
uint8_t computed_cksum = cksum(ip_hdr, ip_hdr->ip_hl * 4);
if (received_cksum != computed_cksum){
fprintf(stderr, "IP Header checksum varies\n");
return;
}
/* Decrement TTL */
ip_hdr->ip_ttl = ip_hdr->ip_ttl - 1;
if (ip_hdr->ip_ttl == 0){
fprintf(stdout, "IP TTL is now 0. Discarding the packet\n");
return;
} else {
ip_hdr->ip_sum = 0;
ip_hdr->ip_sum = cksum(ip_hdr, ip_hdr->ip_hl * 4);
}
/* Determine if packet is directed to this router */
int me = 0;
struct sr_if *if_walker = 0;
if_walker = sr->if_list;
while(if_walker){
if(if_walker->ip == ip_hdr->ip_dst){
me = 1;
}
if_walker = if_walker->next;
}
uint8_t ip_proto = ip_protocol(packet + sizeof(sr_ethernet_hdr_t));
if (me){ /* Directed to this router */
if (ip_proto == ip_protocol_icmp){
/* Get ICMP header */
sr_icmp_hdr_t *icmp_hdr;
icmp_hdr = malloc(sizeof(sr_icmp_hdr_t));
memcpy(icmp_hdr, (sr_icmp_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)), sizeof(sr_icmp_hdr_t));
/* Sanity Check */
minlength = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t);
if (len < minlength){
fprintf(stderr, "Failed to print ICMP header, insufficient length\n");
return;
}
uint8_t received_cksum = icmp_hdr->icmp_sum;
icmp_hdr->icmp_sum = 0;
uint8_t computed_cksum = cksum(icmp_hdr, ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl*4));
if(!(received_cksum != computed_cksum)){
fprintf(stderr, "IP Header checksum varies\n");
return;
}
if (icmp_hdr->icmp_type == ICMP_ECHO_REQUEST){
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t);
uint8_t *reply_packet = malloc(len);
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *)reply_packet;
memcpy(reply_eth_hdr->ether_dhost, eth_hdr->ether_shost, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, if_walker->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
/* Make IP header */
sr_ip_hdr_t *reply_ip_hdr = (sr_ip_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t));
memcpy(reply_ip_hdr, ip_hdr, sizeof(sr_ip_hdr_t));
/* Now update it */
reply_ip_hdr->ip_src = ip_hdr->ip_dst;
reply_ip_hdr->ip_dst = ip_hdr->ip_src;
/* Make ICMP Header */
sr_icmp_hdr_t *reply_icmp_hdr = (sr_icmp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
reply_icmp_hdr->icmp_type = ICMP_ECHO_REPLY;
reply_icmp_hdr->icmp_code = 0;
reply_icmp_hdr->icmp_sum = cksum(reply_icmp_hdr, ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl*4));
sr_send_packet(sr, reply_packet, len, if_walker->name);
free(reply_packet);
} else {
printf("Received ICMP packet of unknown type\n");
return;
}
} else if (ip_proto == ip_protocol_tcp || ip_proto == ip_protocol_udp){
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t);
uint8_t *reply_packet = malloc(len);
sr_ethernet_hdr_t *eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet, sizeof(sr_ethernet_hdr_t));
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *)reply_packet;
memcpy(reply_eth_hdr->ether_dhost, eth_hdr->ether_shost, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, if_walker->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
/* Make IP header */
sr_ip_hdr_t *reply_ip_hdr = (sr_ip_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t));
memcpy(reply_ip_hdr, ip_hdr, sizeof(sr_ip_hdr_t));
/* Now update it */
reply_ip_hdr->ip_src = ip_hdr->ip_dst;
reply_ip_hdr->ip_dst = ip_hdr->ip_src;
/* Make ICMP Header */
sr_icmp_hdr_t *reply_icmp_hdr = (sr_icmp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
reply_icmp_hdr->icmp_type = ICMP_UNREACHABLE_REPLY;
reply_icmp_hdr->icmp_code = 3;
reply_icmp_hdr->icmp_sum = cksum(reply_icmp_hdr, ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl*4));
sr_send_packet(sr, reply_packet, len, if_walker->name);
free(reply_packet);
return;
}
} else {
printf("The packet wasn't directed to this router\n");
struct sr_rt *prefix = sr_longest_prefix(sr, ip_hdr->ip_dst);
if (prefix){
printf("Found the match in routing table\n");
struct sr_arpentry *entry = sr_arpcache_lookup(&sr->cache, prefix->gw.s_addr);
if (entry){
printf("Found the ARP in the cache\n");
struct sr_if *router_if = sr_get_interface(sr, prefix->interface);
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *)packet;
memcpy(reply_eth_hdr->ether_dhost, entry->mac, sizeof(unsigned char)*6);
memcpy(reply_eth_hdr->ether_shost, router_if->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
print_hdrs(packet, len);
sr_send_packet(sr, packet, len, router_if->name);
return;
} else {
printf("ARP Cache miss\n");
struct sr_if *router_if = sr_get_interface(sr, prefix->interface);
struct sr_arpreq *req = sr_arpcache_queuereq(&(sr->cache), ip_hdr->ip_dst, packet, len, router_if->name);
sr_handlearpreq(sr, req);
return;
}
} else {
printf("Match not found in routing table\n");
printf("Sending ICMP net unreachable...\n");
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t);
uint8_t *reply_packet = malloc(len);
struct sr_if *router_if = sr_get_interface(sr, prefix->interface);
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *)reply_packet;
memcpy(reply_eth_hdr->ether_dhost, eth_hdr->ether_shost, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, router_if->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
/* Make IP header */
sr_ip_hdr_t *reply_ip_hdr = (sr_ip_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t));
memcpy(reply_ip_hdr, ip_hdr, sizeof(sr_ip_hdr_t));
/* Now update it */
reply_ip_hdr->ip_src = ip_hdr->ip_dst;
reply_ip_hdr->ip_dst = ip_hdr->ip_src;
/* Make ICMP Header */
sr_icmp_hdr_t *reply_icmp_hdr = (sr_icmp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
reply_icmp_hdr->icmp_type = ICMP_UNREACHABLE_REPLY;
reply_icmp_hdr->icmp_code = 0;
reply_icmp_hdr->icmp_sum = cksum(reply_icmp_hdr, ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl*4));
print_hdrs(reply_packet, len);
sr_send_packet(sr, reply_packet, len, prefix->interface);
free(reply_packet);
return;
}
}
}
void sr_handlearp(struct sr_instance* sr,
uint8_t * packet/* lent */,
unsigned int len,
char* interface/* lent */)
{
/* REQUIRES */
assert(sr);
assert(packet);
assert(interface);
/* Get ARP header */
sr_arp_hdr_t *arp_hdr;
arp_hdr = malloc(sizeof(sr_arp_hdr_t));
memcpy(arp_hdr, (sr_arp_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t)), sizeof(sr_arp_hdr_t));
/* Sanity Check */
int minlength = sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t);
if (len < minlength){
fprintf(stderr, "Failed to print ARP header, insufficient length\n");
return;
}
print_hdr_arp((uint8_t *)arp_hdr);
if (ntohs(arp_hdr->ar_op) == arp_op_request){ /* ARP Request */
printf("It is ARP Request\n");
/* Determine if packet is directed to this router */
int me = 0;
struct sr_if *if_walker = 0;
if_walker = sr->if_list;
while(if_walker){
if(if_walker->ip == arp_hdr->ar_tip){
me = 1;
break;
}
if_walker = if_walker->next;
}
if (me){ /* Directed to this router */
printf("It is the ARP request directed to me\n");
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t);
uint8_t *reply_packet = malloc(len);
sr_ethernet_hdr_t *eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet, sizeof(sr_ethernet_hdr_t));
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *) reply_packet;;
memcpy(reply_eth_hdr->ether_dhost, eth_hdr->ether_shost, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, if_walker->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
/* Make ARP header */
sr_arp_hdr_t *reply_arp_hdr = (sr_arp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t));
reply_arp_hdr->ar_hrd = arp_hdr->ar_hrd;
reply_arp_hdr->ar_pro = arp_hdr->ar_pro;
reply_arp_hdr->ar_hln = arp_hdr->ar_hln;
reply_arp_hdr->ar_pln = arp_hdr->ar_pln;
reply_arp_hdr->ar_op = htons(arp_op_reply);
memcpy(reply_arp_hdr->ar_sha, if_walker->addr, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_sip = if_walker->ip;
memcpy(reply_arp_hdr->ar_tha, arp_hdr->ar_sha, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_tip = arp_hdr->ar_sip;
print_hdrs(reply_packet, len);
sr_send_packet(sr, reply_packet, len, if_walker->name);
free(reply_packet);
} else {
printf("Got ARP Request directed to other router. Dropping packet\n");
return;
}
} else if (ntohs(arp_hdr->ar_op) == arp_op_reply){ /* ARP Reply */
int me = 0;
struct sr_if *if_walker = 0;
if_walker = sr->if_list;
while(if_walker){
if(if_walker->ip == arp_hdr->ar_tip){
me = 1;
break;
}
if_walker = if_walker->next;
}
if (me){
printf("Caching the request and sending reply\n");
struct sr_arpreq *req = sr_arpcache_insert(&(sr->cache), arp_hdr->ar_sha, arp_hdr->ar_sip);
sr_ethernet_hdr_t *eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet, sizeof(sr_ethernet_hdr_t));
if (req){
struct sr_packet *packet = req->packets;
while (packet){
/*struct sr_if *if_walker = sr_get_interface(sr, packet->iface);*/
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *) packet->buf;
memcpy(reply_eth_hdr->ether_dhost, arp_hdr->ar_sha, sizeof(unsigned char)*ETHER_ADDR_LEN);
/*memcpy(reply_eth_hdr->ether_shost, arp_hdr->ar_tha, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
sr_arp_hdr_t *reply_arp_hdr = (sr_arp_hdr_t *) (packet->buf + sizeof(sr_ethernet_hdr_t));
reply_arp_hdr->ar_op = htons(arp_op_reply);
memcpy(reply_arp_hdr->ar_sha, if_walker->addr, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_sip = if_walker->ip;
memcpy(reply_arp_hdr->ar_tha, arp_hdr->ar_sha, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_tip = arp_hdr->ar_sip;*/
print_hdrs(packet->buf, packet->len);
sr_send_packet(sr, packet->buf, packet->len, packet->iface);
packet = packet->next;
}
sr_arpreq_destroy(&sr->cache, req);
}
} else {
printf("Got ARP Reply directed to other router. Dropping packet\n");
return;
}
}
}
void sr_handlearpreq(struct sr_instance*sr, struct sr_arpreq *req)
{
time_t curr_time;
time(&curr_time);
if(difftime(curr_time, req->sent) > 1){
printf("Packet hasn't been sent since 1 sec\n");
if((req->times_sent) >= 5){
printf("Packet resent tried 5 times\n");
struct sr_packet *packet = req->packets;
while(packet){
struct sr_if *if_walker = sr_get_interface(sr, packet->iface);
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t);
uint8_t* reply_packet = malloc(len);
sr_ethernet_hdr_t* eth_hdr;
eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, packet->buf, sizeof(sr_ethernet_hdr_t));
sr_ip_hdr_t* ip_hdr;
ip_hdr = malloc(sizeof(sr_ip_hdr_t));
memcpy(ip_hdr, (sr_ip_hdr_t *)(packet->buf + sizeof(sr_ethernet_hdr_t)), sizeof(sr_ip_hdr_t));
/* Decrement TTL */
ip_hdr->ip_ttl = ip_hdr->ip_ttl - 1;
if (ip_hdr->ip_ttl == 0){
fprintf(stdout, "IP TTL is now 0. Discarding the packet\n");
return;
} else {
ip_hdr->ip_sum = 0;
ip_hdr->ip_sum = cksum(ip_hdr, ip_hdr->ip_hl * 4);
}
sr_icmp_hdr_t* icmp_hdr;
icmp_hdr = malloc(sizeof(sr_icmp_hdr_t));
memcpy(icmp_hdr, (sr_icmp_hdr_t*)(packet->buf + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)), sizeof(sr_icmp_hdr_t));
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *) reply_packet;
memcpy(reply_eth_hdr->ether_dhost, eth_hdr->ether_shost, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, if_walker->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = eth_hdr->ether_type;
/* Make IP header */
sr_ip_hdr_t *reply_ip_hdr = (sr_ip_hdr_t*)(reply_packet + sizeof(sr_ethernet_hdr_t));
memcpy(reply_ip_hdr, ip_hdr, sizeof(sr_ip_hdr_t));
/* Now update it */
reply_ip_hdr->ip_src = ip_hdr->ip_dst;
reply_ip_hdr->ip_dst = ip_hdr->ip_src;
/* Make ICMP header */
sr_icmp_hdr_t *reply_icmp_hdr = (sr_icmp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));
reply_icmp_hdr->icmp_type = ICMP_UNREACHABLE_REPLY;
reply_icmp_hdr->icmp_code = 1;
reply_icmp_hdr->icmp_sum = cksum(reply_icmp_hdr, ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl*4));
print_hdrs(reply_packet, len);
sr_send_packet(sr, reply_packet, len, if_walker->name);
packet = packet->next;
}
sr_arpreq_destroy(&sr->cache, req);
} else {
/* Send arp request */
printf("Sending ARP Request\n");
struct sr_packet *packet = req->packets;
struct sr_if *if_walker = sr_get_interface(sr, packet->iface);
int len = sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t);
uint8_t *reply_packet = malloc(len);
sr_ethernet_hdr_t *eth_hdr = malloc(sizeof(sr_ethernet_hdr_t));
memcpy(eth_hdr, (sr_ethernet_hdr_t *) packet->buf, sizeof(sr_ethernet_hdr_t));
/* sr_arp_hdr_t *arp_hdr = malloc(sizeof(sr_arp_hdr_t));
memcpy(arp_hdr, (sr_arp_hdr_t *)(packet->buf + sizeof(sr_ethernet_hdr_t)), sizeof(sr_arp_hdr_t)); */
/* Make ethernet header */
sr_ethernet_hdr_t *reply_eth_hdr = (sr_ethernet_hdr_t *) reply_packet;
memset(reply_eth_hdr->ether_dhost, 255, sizeof(uint8_t)*ETHER_ADDR_LEN);
memcpy(reply_eth_hdr->ether_shost, if_walker->addr, sizeof(uint8_t)*ETHER_ADDR_LEN);
reply_eth_hdr->ether_type = htons(ethertype_arp);
/* Make ARP header */
sr_arp_hdr_t *reply_arp_hdr = (sr_arp_hdr_t *)(reply_packet + sizeof(sr_ethernet_hdr_t));
reply_arp_hdr->ar_hrd = htons(arp_hrd_ethernet);
reply_arp_hdr->ar_pro = htons(ethertype_ip);
reply_arp_hdr->ar_hln = ETHER_ADDR_LEN;
reply_arp_hdr->ar_pln = sizeof(uint32_t);
reply_arp_hdr->ar_op = htons(arp_op_request);
memcpy(reply_arp_hdr->ar_sha, if_walker->addr, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_sip = if_walker->ip;
memset(reply_arp_hdr->ar_tha, 255, sizeof(unsigned char)*ETHER_ADDR_LEN);
reply_arp_hdr->ar_tip = req->ip;
print_hdrs(reply_packet, len);
sr_send_packet(sr, reply_packet, len, if_walker->name);
free(reply_packet);
}
req->sent = curr_time;
req->times_sent = req->times_sent + 1;
}
}