Example #1
0
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);
            }
        }
    }    
}
Example #2
0
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);
		}
	}
}