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 processForward(struct sr_instance* sr, uint8_t * packet, unsigned int len, char* interface) { struct sr_ip_hdr *ipHeader = (struct sr_ip_hdr *) (packet + sizeof(struct sr_ethernet_hdr)); /* Reply with timeout if TTL exceeded */ ipHeader->ip_ttl = ipHeader->ip_ttl - 1; if (ipHeader->ip_ttl == 0) { icmp_send_time_exceeded(sr, packet, len, interface); return; } /* At this point, all checks passed, check routing table */ struct sr_rt *closestMatch = findLongestMatchPrefix(sr->routing_table, ipHeader->ip_dst); if (closestMatch == NULL) { /* No match found. Send net unreachable */ icmp_send_net_unreachable(sr, packet, len, interface); } else { /* Match found. Lookup MAC address in ARP cache */ struct sr_arpentry *arpEntry = sr_arpcache_lookup(&(sr->cache), ntohl(closestMatch->gw.s_addr)); if (arpEntry != NULL) { /* Found MAC address. Send the packet */ struct sr_rt *arpClosestMatch = findLongestMatchPrefix(sr->routing_table, ntohl(arpEntry->ip)); send_packet_to_dest(sr, packet, len, arpClosestMatch->interface, arpEntry->mac, ntohl(arpEntry->ip)); } else { /* Could not find MAC address. Queue request for ARP */ sr_arpcache_queuereq(&(sr->cache), ntohl(closestMatch->gw.s_addr), packet, len, interface); } } }