void send_icmp_destination_host_unreachable(struct sr_instance* sr, uint8_t *buf, unsigned int len) { /* sr_ethernet_hdr_t* ether_hdr = (sr_ethernet_hdr_t*)buf; */ print_hdrs(buf, len); }
void sr_handlepacket(struct sr_instance* sr, uint8_t * packet/* lent */, unsigned int len, char* interface/* lent */) { printf("Router Accessed\n"); /* REQUIRES */ assert(sr); assert(packet); assert(interface); struct sr_if * iface = sr_get_interface(sr, interface); printf("*** -> Received packet of length %d \n",len); /* Ethernet Protocol */ if(len>=34){ uint8_t* ether_packet = malloc(len+28); memcpy(ether_packet,packet,len); print_hdrs(packet,len); uint16_t package_type = ethertype(ether_packet); enum sr_ethertype arp = ethertype_arp; enum sr_ethertype ip = ethertype_ip; if (strcmp(iface->name,interface) == 0){ printf("Right interface\n"); if(package_type==arp){ /* ARP protocol */ sr_handleARPpacket(sr, ether_packet, len, iface); }else if(package_type==ip){ /* IP protocol */ if (sr->mode == 1){ sr_natHandleIP(sr,ether_packet,len,iface); } else{ sr_handleIPpacket(sr, ether_packet,len, iface); } }else{ /* drop package */ printf("bad protocol! BOO! \n"); } } free(ether_packet); } }/* end sr_ForwardPacket */
/*--------------------------------------------------------------------- * Method: eth_frame_send_with_mac(struct sr_instance* sr, uint8_t* packet, unsigned int len, unsigned char* mac, char* iface) * Scope: Global * * send the ethernet frame * *---------------------------------------------------------------------*/ int eth_frame_send_with_mac( struct sr_instance* sr, uint8_t* packet, unsigned int len, unsigned char* mac, char* iface) { printf("Sending Packet\n"); // Cast the packet in order to update fields. sr_ethernet_hdr_t* e_packet = (sr_ethernet_hdr_t *)(packet); struct sr_if* interface = sr_get_interface(sr, iface); // Set fields memcpy(e_packet->ether_dhost, mac, ETHER_ADDR_LEN); memcpy(e_packet->ether_shost, interface->addr, ETHER_ADDR_LEN); // Send the packet print_hdrs(packet, len); sr_send_packet(sr, packet, len, iface); return 0; }
void send_arp_request(struct sr_instance* sr, struct sr_arpreq* req) { /* send arp request, make arp header and ether header.*/ struct sr_if* interface_sr_if = sr_get_interface(sr, req->packets->iface); sr_arp_hdr_t* arp_header = (struct sr_arp_hdr*)malloc(sizeof(struct sr_arp_hdr)); arp_header->ar_hrd = htons(arp_hrd_ethernet); arp_header->ar_pro = htons(ethertype_ip); arp_header->ar_hln = ETHER_ADDR_LEN; arp_header->ar_pln = sizeof(uint32_t); arp_header->ar_op = htons(arp_op_request); arp_header->ar_sip = interface_sr_if->ip; arp_header->ar_tip = req->ip; memcpy(arp_header->ar_sha, interface_sr_if->addr, ETHER_ADDR_LEN); unsigned int len_packet = sizeof(struct sr_arp_hdr) + sizeof(struct sr_ethernet_hdr); uint8_t* packet = (uint8_t*)malloc(len_packet); sr_ethernet_hdr_t* ether_header = (sr_ethernet_hdr_t*)malloc(sizeof(struct sr_ethernet_hdr)); ether_header->ether_type = htons(ethertype_arp); memset(ether_header->ether_dhost, 255, ETHER_ADDR_LEN); memcpy(ether_header->ether_shost, interface_sr_if->addr, ETHER_ADDR_LEN); memcpy(packet, ether_header, sizeof(struct sr_ethernet_hdr)); memcpy(packet + sizeof(struct sr_ethernet_hdr), arp_header, sizeof(struct sr_arp_hdr)); print_hdrs(packet, len_packet); sr_send_packet(sr, packet, len_packet, interface_sr_if->name); /* free(arp_header); */ }
void sr_send_ip(struct sr_instance* sr, uint8_t* packet, unsigned int len, char* iface) { printf("Forwarding IP packet...\n"); struct sr_if* interface = sr_get_interface(sr, iface); struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t)); /* Fetch the outgoing MAC from the ARP table */ struct sr_arpentry * arpCacheEntry = sr_arpcache_lookup(&(sr->cache), ipHeader->ip_dst); /* Build the ethernet header */ struct sr_ethernet_hdr* ethHeader = (struct sr_ethernet_hdr*)packet; memcpy(ethHeader->ether_shost, (char*)interface->addr, ETHER_ADDR_LEN); memcpy(ethHeader->ether_dhost, (char*)arpCacheEntry->mac, ETHER_ADDR_LEN); ethHeader->ether_type = htons(ethertype_ip); print_hdrs(packet, len); sr_send_packet(sr, packet, len, iface); printf("Sent on interface...%s\n", iface); free(arpCacheEntry); }/* -- sr_send_ip -- */
/* * Forward the packet to the next hop. */ void forward_packet(struct sr_instance *sr, char *interface, unsigned char *dest_mac, unsigned int len, uint8_t *pkt) { uint8_t *packet = (uint8_t *) malloc(len); memcpy(packet, pkt, len); struct sr_if *rt_if = (struct sr_if *)malloc(sizeof(struct sr_if)); rt_if = (struct sr_if *)sr_get_interface(sr, interface); /* Prepare ethernet header. */ sr_ethernet_hdr_t *ether_hdr = (sr_ethernet_hdr_t *) packet; ether_hdr->ether_type = htons(ethertype_ip); memcpy(ether_hdr->ether_shost, rt_if->addr, ETHER_ADDR_LEN); memcpy(ether_hdr->ether_dhost, &(dest_mac), ETHER_ADDR_LEN); /* Recompute checksum. */ sr_ip_hdr_t *ip_hdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t)); ip_hdr->ip_sum = 0; ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t)); /* Forward to next hop. */ print_hdrs(packet, len); sr_send_packet(sr, packet, len, interface); free(packet); }
/* * handle arp reply */ void sr_handle_arpreply(struct sr_instance* sr, unsigned char *mac, uint32_t ip, struct sr_if* iface) { /* if(ip == 167985324) {return;} */ Debug("\nhandle_arpreply called\n"); Debug("mac: %s, ip: %d, interface: %s", mac, ip, iface->name); struct sr_arpreq *req = sr_arpcache_insert(&(sr->cache), mac, ip); struct sr_packet *packet; if(req) { Debug("\nhandle_arpreply -> sending out packets waiting for the arp_reply\n"); for(packet = req->packets; packet != NULL; packet = packet->next) { int i; for (i = 0; i < ETHER_ADDR_LEN; i++) { packet->buf[i]= mac[i]; } printf("---------------before send packet----------------\n"); print_hdrs(packet->buf, packet->len); sr_send_packet(sr, packet->buf, packet->len, iface->name); /*printf("--------------------i-------------------------: %d\n", i);i++;*/ /*free(packet->buf);*/ } sr_arpreq_destroy(&(sr->cache), req); Debug("Hey, finished sending packets"); } }
void sr_send_icmp(struct sr_instance* sr, uint8_t* packet, unsigned int len, unsigned int type, unsigned int code) { unsigned int responseLen; uint8_t* responsePacket; struct sr_ip_hdr* responseIPHeader; /* Build the message depending on whether echo or another type */ if(type == icmp_type_echoreply) { printf("Creating Echo Reply...\n"); /* Get the length of the message to be built */ struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t)); unsigned int payloadLen = len - sizeof(sr_ip_hdr_t) - sizeof(sr_icmp_hdr_t); responseLen = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)+ sizeof(sr_icmp_hdr_t) + payloadLen; responsePacket = (uint8_t*) malloc(responseLen); memcpy(responsePacket, packet, responseLen); /* Build ICMP header */ struct sr_icmp_hdr* responseICMPHeader = (struct sr_icmp_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)); responseICMPHeader->icmp_type = type; responseICMPHeader->icmp_code = code; responseICMPHeader->icmp_sum = 0x0000; responseICMPHeader->icmp_sum = cksum((uint16_t*)responseICMPHeader, sizeof(sr_icmp_hdr_t) + payloadLen); /* Build IP header */ responseIPHeader = (struct sr_ip_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t)); responseIPHeader->ip_hl = 5; responseIPHeader->ip_v = 4; responseIPHeader->ip_tos = 0; responseIPHeader->ip_len = htons( sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t) + payloadLen); responseIPHeader->ip_id = 0; responseIPHeader->ip_off = 0; responseIPHeader->ip_ttl = 64; responseIPHeader->ip_p = ip_protocol_icmp; responseIPHeader->ip_sum = 0x0000; responseIPHeader->ip_dst = ipHeader->ip_src; char* iface = sr_get_routing_entry_interface(sr, ipHeader->ip_src); struct sr_if* interface = sr_get_interface(sr, iface); responseIPHeader->ip_src = interface->ip; responseIPHeader->ip_sum = cksum((uint8_t*)responseIPHeader, sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t) + payloadLen); /* Build Ethernet header */ struct sr_ethernet_hdr* ethernetHeader = (struct sr_ethernet_hdr*)packet; struct sr_ethernet_hdr* responseEthernetHeader = (struct sr_ethernet_hdr*)responsePacket; memcpy(responseEthernetHeader->ether_dhost, ethernetHeader->ether_shost, ETHER_ADDR_LEN); memcpy(responseEthernetHeader->ether_shost, interface->addr, ETHER_ADDR_LEN); responseEthernetHeader->ether_type = htons(ethertype_ip); } else { printf("Creating ICMP message...\n"); /* Get the length of the message to be built */ responseLen = sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)+ sizeof(sr_icmp_t3_hdr_t) + 8; responsePacket = (uint8_t*) malloc(responseLen); /* Build ICMP header */ struct sr_ip_hdr* ipHeader = (struct sr_ip_hdr*)(packet + sizeof(sr_ethernet_hdr_t)); struct sr_icmp_t3_hdr* responseICMPHeader = (struct sr_icmp_t3_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)); responseICMPHeader->icmp_type = type; responseICMPHeader->icmp_code = code; responseICMPHeader->icmp_sum = 0x0000; memcpy(responseICMPHeader->data, ipHeader, sizeof(sr_ip_hdr_t) + 8); responseICMPHeader->icmp_sum = cksum((uint16_t*)responseICMPHeader, sizeof(sr_icmp_t3_hdr_t)); /* Build IP header */ responseIPHeader = (struct sr_ip_hdr*)(responsePacket + sizeof(sr_ethernet_hdr_t)); responseIPHeader->ip_hl = 5; responseIPHeader->ip_v = 4; responseIPHeader->ip_tos = 0; responseIPHeader->ip_len = htons( sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_t3_hdr_t)); responseIPHeader->ip_id = 0; responseIPHeader->ip_off = 0; responseIPHeader->ip_ttl = 64; responseIPHeader->ip_p = ip_protocol_icmp; responseIPHeader->ip_sum = 0x0000; responseIPHeader->ip_dst = ipHeader->ip_src; char* iface = sr_get_routing_entry_interface(sr, ipHeader->ip_src); struct sr_if* interface = sr_get_interface(sr, iface); responseIPHeader->ip_src = interface->ip; responseIPHeader->ip_sum = cksum((uint8_t*)responseIPHeader, sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_t3_hdr_t)); /* Build Ethernet header */ struct sr_ethernet_hdr* ethernetHeader = (struct sr_ethernet_hdr*)packet; struct sr_ethernet_hdr* responseEthernetHeader = (struct sr_ethernet_hdr*)responsePacket; memcpy(responseEthernetHeader->ether_dhost, ethernetHeader->ether_shost, ETHER_ADDR_LEN); memcpy(responseEthernetHeader->ether_shost, interface->addr, ETHER_ADDR_LEN); responseEthernetHeader->ether_type = htons(ethertype_ip); } /* Look up the interface that the packet should be sent on */ char* iface = sr_get_routing_entry_interface(sr, responseIPHeader->ip_dst); if(iface == NULL) return; /* Send the packet */ print_hdrs(responsePacket, responseLen); sr_send_packet(sr, responsePacket, responseLen, iface); printf("Sent on interface...%s\n", iface); free(responsePacket); }/* -- sr_send_icmp -- */
void sr_handlepacket(struct sr_instance* sr, uint8_t * packet/* lent */, unsigned int len, char* interface/* lent */) { /* Function implemented by g1izzyw and gustan50404 */ /* REQUIRES */ assert(sr); assert(packet); assert(interface); struct sr_if *ether_interface = (struct sr_if *) sr_get_interface(sr, interface); /* Check if it an ethernet interface. */ if (ether_interface) { /* Now we deal with the ethernet header */ struct sr_ethernet_hdr *ether_hdr = (struct sr_ethernet_hdr *) packet; /* Check to see if we are dealing with an ARP request/reply */ if (ether_hdr->ether_type == htons(ethertype_arp)) { fprintf(stderr, "We Got an ARP Packet\n"); /* Handle ARP for ethernet */ struct sr_arp_hdr * arp_hdr = (struct sr_arp_hdr *)(packet + sizeof(struct sr_ethernet_hdr)); if (arp_hdr->ar_hrd == htons(arp_hrd_ethernet)) { if (arp_hdr->ar_op == htons(arp_op_request)) { /* arp request */ struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip); if (interface_for_ip) { /* Target ip is one of the router interfaces */ fprintf(stderr, "ARP req for one of our interfaces\n"); /* Now we want to make an arp reply and send it back */ uint8_t *buf = (uint8_t *) malloc(len); memcpy(buf, packet, len); /*Make Arp Header*/ make_arprply_hdr(interface_for_ip->addr, arp_hdr->ar_sha, interface_for_ip->ip, arp_hdr->ar_sip, buf); /*Make Ethernet Header*/ make_ether_hdr(interface_for_ip->addr, ether_hdr->ether_shost, ethertype_arp, buf); /* Now we send the packet */ sr_send_packet(sr, buf, len, interface_for_ip->name); free(buf); fprintf(stderr, "ARP reply sent\n"); } } else if (arp_hdr->ar_op == htons(arp_op_reply)) { fprintf(stderr, "We got an ARP Reply, need to check for intfc tho \n"); /* arp reply */ struct sr_if *interface_for_ip = get_interface_for_ip(sr, arp_hdr->ar_tip); if (interface_for_ip) { fprintf(stderr, "We got an ARP Reply for one of our interfaces\n"); /*We first want to insert into Arp cache*/ struct sr_arpreq *request = sr_arpcache_insert(&(sr->cache), arp_hdr->ar_sha, arp_hdr->ar_sip); fprintf(stderr, "Signalling all waiting packets\n"); if (request) { struct sr_packet *cur_packet = request->packets; while(cur_packet) { fprintf(stderr, "About to forward \n"); print_hdrs(cur_packet->buf, cur_packet->len); forward_packet(sr, cur_packet->iface, arp_hdr->ar_sha, cur_packet->len, cur_packet->buf); fprintf(stderr, "Packet Forwarded\n"); cur_packet = cur_packet->next; } } } } } } else if (ether_hdr->ether_type == htons(ethertype_ip)) { /* Get the ip header from the ethernet header*/ sr_ip_hdr_t *ip_hdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t)); /*IP Checksum Stuff*/ uint16_t temp_ip_sum = ip_hdr->ip_sum; ip_hdr->ip_sum = 0; ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t)); if (temp_ip_sum == ip_hdr->ip_sum) { /*We got here means IP Cheksum is alright, so we extract the interface*/ struct sr_if *interface_for_ip = get_interface_for_ip(sr, ip_hdr->ip_dst); /*Check to make sure interface is one of ours*/ if (interface_for_ip) { fprintf(stderr, "IP Packet destined towards our interface\n"); /*Check if our IP packet is UDP or TCP*/ if (ip_hdr->ip_p == 6 || ip_hdr->ip_p == 17) { fprintf(stderr, "We Got TCP or UDP, sending ICMP error msg\n"); send_icmp_error(3, 3, sr, interface, len, packet); } else { /* Get the ICMP header */ sr_icmp_hdr_t *icmp_hdr = (struct sr_icmp_hdr *) (packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)); /*Now we do the ICMP checksum chek*/ /*This covers the ICMP echo case*/ uint16_t temp_icmp_sum = icmp_hdr->icmp_sum; temp_icmp_sum = icmp_hdr->icmp_sum; icmp_hdr->icmp_sum = 0; if (temp_icmp_sum == cksum(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t), len - sizeof(sr_ethernet_hdr_t) - sizeof(sr_ip_hdr_t))) { /*Everything is fine so we send an ICMP echo back*/ fprintf(stderr, "Sending ICMP echo reply\n"); send_icmp_echo(sr, interface, len, packet); } } } else { /*IP Packet not destined towards one of our interfaces*/ fprintf(stderr, "IP packet not destined to our interface\n"); /*Decremenrt TTL by 1*/ fprintf(stderr, "TTL modified \n"); print_hdrs(packet, len); if (ip_hdr->ip_ttl <= 1) { fprintf(stderr, "Packte with TTL < 0 found, sending ICMP error \n"); /*TTL is less than 0 so send an ICMP ERROR*/ send_icmp_error(11, 0, sr, interface, len, packet); } else { /*Recompute Checksum over new header TTL is fine*/ /*Check if it exists in the routing table*/ ip_hdr->ip_ttl = ip_hdr->ip_ttl - 1; fprintf(stderr, "Recomputing Checksum after modifying TTl\n"); ip_hdr->ip_sum = 0; ip_hdr->ip_sum = cksum(packet + sizeof(sr_ethernet_hdr_t), sizeof(sr_ip_hdr_t)); struct sr_if *dst_if = (struct sr_if *)malloc(sizeof(struct sr_if)); dst_if = next_hop(sr, interface, ip_hdr->ip_dst); if (!(dst_if)) { fprintf(stderr, "IP packet has no longest matching prefix sending ICMP error\n"); /*dst ip has no longest macthing prefix*/ /*So we send a type 3 code 0 ICMP error*/ send_icmp_error(3, 0, sr, interface, len, packet); } else { /*This is the case where we do have a longest macthing prefix*/ fprintf(stderr, "Found Longest mathcing prefix in RT\n"); struct sr_arpcache *cache = &(sr->cache); struct sr_arpentry *in_cache = sr_arpcache_lookup(cache, ip_hdr->ip_dst); if (in_cache) { fprintf(stderr, "Found IP->MAC mapping in ARP cache forwarding packet \n"); /*this is the case where ip->mac maping is already in cache*/ forward_packet(sr, dst_if->name, in_cache->mac, len, packet); free(in_cache); } else { fprintf(stderr, "IP->MAC mapping not in ARP cache %u \n", ip_hdr->ip_dst); /*Case where ip->mapping is not in cache*/ sr_arpcache_queuereq(cache, ip_hdr->ip_dst, packet, len, dst_if->name); fprintf(stderr, "Added Arp Req to queu \n"); } } } } } } } } /* end sr_ForwardPacket */
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); print_hdrs(packet, len); sr_arp_hdr_t* arpHdr = (sr_arp_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t)); sr_ethernet_hdr_t* ethHdr = (sr_ethernet_hdr_t*)packet; sr_ip_hdr_t* ipHdr = (sr_ip_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t)); sr_icmp_hdr_t* icmpHdr = (sr_icmp_hdr_t*)(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t)); struct sr_rt* route = sr->routing_table; struct sr_arpentry* ent; char ifBuf[INET_ADDRSTRLEN]; char ipBuf[INET_ADDRSTRLEN]; if(strcmp(arpHdr->ar_tha, "\0") == 0){ sr_arpcache_queuereq(&(sr->cache), arpHdr->ar_tip, packet, len, interface); printf("added arpreq to queue.\n\n"); return; } printf("arp rep: %d\n", ntohs(arpHdr->ar_op)); printf("opcode: %d\n", arp_op_reply); if(ntohs(arpHdr->ar_op) == arp_op_reply){ ent = sr_arpcache_lookup(&sr->cache, arpHdr->ar_sip); if( ent == NULL){ // printf("Added %s to cache\n", ntohl(arpHdr->ar_sip)); printf("Incoming arp response\n"); // sleep(2); struct sr_arpreq* req = sr->cache.requests; printf("%p, %p\n", req, sr->cache.requests); while(req != NULL){ if(req->ip == arpHdr->ar_sip){ struct sr_packet* pkt = req->packets; while(pkt != NULL){ if(route != NULL){ do{ sr_ip_hdr_t* reqIpHdr = (sr_ip_hdr_t*)(pkt->buf + sizeof(sr_ethernet_hdr_t)); sr_ethernet_hdr_t* reqEthHdr = (sr_ethernet_hdr_t*)(pkt->buf); // sr_print_routing_entry(route); inet_ntop(AF_INET, &route->dest, ifBuf, sizeof(char) * INET_ADDRSTRLEN); convert_addr_ip_int(ntohl(reqIpHdr->ip_dst), ipBuf); printf("%s dest: %s\n",route->interface, ifBuf); printf("ip dest: %s\n", ipBuf); if(strcmp(ifBuf, ipBuf) == 0){ memcpy(reqEthHdr->ether_shost, (uint8_t*)(sr_get_interface(sr, route->interface)->addr), sizeof(uint8_t) * ETHER_ADDR_LEN); memcpy(reqEthHdr->ether_dhost, (uint8_t*)arpHdr->ar_sha, sizeof(uint8_t) * ETHER_ADDR_LEN); print_hdrs(pkt->buf, pkt->len); sr_send_packet(sr, pkt->buf, pkt->len, &(route->interface)); printf("pkt sent down %s\n\n", route->interface); // free(ent); //return; break; } route = route->next; } while(route != NULL); pkt = pkt->next; } } free(ent); sr_arpreq_destroy(&sr->cache, req); break; } req = req->next; } } sr_arpcache_insert(&(sr->cache), arpHdr->ar_sha, arpHdr->ar_sip); //sr_arpcache_dump(&sr->cache); free(ent); return; } ent = sr_arpcache_lookup(&sr->cache, ipHdr->ip_dst); route = sr->routing_table; //Make and queue requests if dest isn't in arpcache if( ent == NULL ){ if(route != NULL){ do{ inet_ntop(AF_INET, &route->dest, ifBuf, 100); convert_addr_ip_int(ntohl(ipHdr->ip_dst), ipBuf); if(strcmp(ifBuf, ipBuf) == 0){ sr_arpcache_queuereq(&sr->cache, ipHdr->ip_dst, packet, len, route->interface); free(ent); return; } route = route->next; } while(route != NULL); sr_arpcache_queuereq(&sr->cache, ipHdr->ip_dst, packet, len, "eth1"); } } //Forwards packet to interface if(route != NULL){ do{ // sr_print_routing_entry(route); inet_ntop(AF_INET, &route->dest, ifBuf, sizeof(char) * INET_ADDRSTRLEN); convert_addr_ip_int(ntohl(ipHdr->ip_dst), ipBuf); printf("%s dest: %s\n",route->interface, ifBuf); printf("ip dest: %s\n", ipBuf); if(strcmp(ifBuf, ipBuf) == 0){ memcpy(ethHdr->ether_shost, (uint8_t*)(sr_get_interface(sr, route->interface)->addr), sizeof(uint8_t) * ETHER_ADDR_LEN); memcpy(ethHdr->ether_dhost, (uint8_t*)ent->mac, sizeof(uint8_t) * ETHER_ADDR_LEN); print_hdrs(packet, len); sr_send_packet(sr, packet, len, &(route->interface)); printf("pkt sent down %s\n\n", route->interface); free(ent); return; } route = route->next; } while(route != NULL); } free(ent); }/* end sr_ForwardPacket */