void processIP(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)); ipHeader->ip_ttl--; if (ipHeader->ip_p == ip_protocol_icmp) { /* ICMP request */ /* Ignore invalid packets */ if (!is_sane_icmp_packet(packet, len)) { return; } /* Process ICMP only if echo*/ struct sr_icmp_hdr *icmpHeader = (struct sr_icmp_hdr *)(packet + sizeof(struct sr_ethernet_hdr) + sizeof(struct sr_ip_hdr)); if (icmpHeader->icmp_type == icmp_echo_req_type) { icmp_send_echo_reply(sr, packet, len, interface); } } else if (ipHeader->ip_p == ip_protocol_tcp || ipHeader->ip_p == ip_protocol_udp) { /* TCP or UDP Payload */ icmp_send_port_unreachable(sr, packet, len, interface); } }
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); } } } }