void check_packet_protocol(sr_router* router, struct ip* ip_header, byte* payload, uint16_t payload_len, interface_t* intf, byte* ip_packet) { if(ip_header->ip_p == IP_PROTOCOL_ICMP) { //icmp printf(" ** ip_handle_packet(..) protocol: ICMP \n"); icmp_handle_packet(router, payload, payload_len, ip_header, intf); } else if(ip_header->ip_p == IP_PROTOCOL_TCP) { //tcp printf(" ** ip_handle_packet(..) protocol: TCP \n"); sr_transport_input(ip_packet); } else if(ip_header->ip_p == IP_PROTOCOL_UDP) { //udp printf(" ** ip_handle_packet(..) protocol: UDP \n"); //udp_handle_packet(payload, ip_header, intf); printf(" ** ip_handle_packet(..) protocol: Error! Not supported. Dropping and sending ICMP response: port unreachable \n"); uint8_t code = ICMP_TYPE_CODE_DST_UNREACH_PORT; icmp_type_dst_unreach_send(&code, ip_packet, (uint16_t*)&ip_header->ip_len, ip_header); } else if(ip_header->ip_p == IP_PROTOCOL_OSPF) { //ospf printf(" ** ip_handle_packet(..) protocol: OSPF \n"); pwospf_handle_packet(payload, payload_len, ip_header, intf, router); }else { //otherwise printf(" ** ip_handle_packet(..) protocol: Error! Not supported. Dropping and sending ICMP response \n"); uint8_t code = ICMP_TYPE_CODE_DST_UNREACH_PROTOCOL; icmp_type_dst_unreach_send(&code, ip_packet, (uint16_t*)&ip_header->ip_len, ip_header); } }
int handle_ip_pkt(struct sr_instance* sr, uint8_t* Pkt, char* interface, unsigned int len, uint8_t srcMAC[]) { //actually I have to pass in a uint8_t* packet not an sr_ip_pkt... /* Extract the IP header Header actions: 1) check the IP checksum -> discard if wrong 2) check if TTL expired -> send ICMP type 11 (0) 3) check if it is our message -> if yes jump to "OURS:" Not Ours: 1) Find the next hop in rtable 2) Decrement TTL, recalculate Checksum 3) Assemble new packet 4) Send on correct interface OURS: 1) Check type of packet -> ICMP -> UDP/TCP ICMP: 1) Check type 2) respond as appropriate UDP/TCP 1) Pass up the stack */ assert(Pkt); assert(sr); assert(interface); //struct sr_router* subsystem = (struct sr_router*)sr_get_subsystem(sr); struct sr_vns_if* myIntf = sr_get_interface(sr, interface); uint32_t myIP = myIntf->ip; struct ip* pktHdr = (struct ip*)Pkt; uint8_t* payload = (uint8_t*)malloc_or_die(len - 20); uint8_t* ptr = Pkt + 20; memcpy(payload, ptr, len-20); uint32_t originIP = pktHdr->ip_src.s_addr; //first thing is to update ARP - no point wasiting useful information is there! time_t now = time(NULL); int checkArp; checkArp = find_and_update(sr, originIP, srcMAC, now); if(pktHdr->ip_hl != 5) { //means there were IP options so unerachable (host or network?) printf("@@@@@@@@@@@@@@@@@@@@@@@@@@ IP hdr length was %u. Should have been 5 (e.g. 20 bytes)\n", pktHdr->ip_hl); uint8_t* data = (uint8_t*)malloc_or_die(28); memcpy(data, Pkt, 28); int tmp; tmp = create_ICMP_pkt(sr, interface, originIP, 3, 1, 0, 0, data, 28); return -3; } if(cksum((uint8_t*)pktHdr, 20)) { printf("@@@@@@@@@@@@@@@@@@@@@@ CHECKSUM 0x%hx WAS INVALID SO WE WILL DROP THE PACKET\n", pktHdr->ip_sum); return -2; } if(pktHdr->ip_ttl < 2) { printf("@@@@@@@@@@@@@@@@@@@@@@ TTL has expired so we will send back an ICMP\n"); //get the data (IP hdr + 8 bytes of packet) uint8_t* data = (uint8_t*)malloc_or_die(28); memcpy(data, Pkt, 28); int tmp; tmp = create_ICMP_pkt(sr, interface, originIP, 11, 0, 0, 0, data, 28); return -1; } if(check_my_interface(sr, (uint32_t)pktHdr->ip_dst.s_addr)) { // printf("This is my packet so I will process it\n"); switch(pktHdr->ip_p) { case IPPROTO_ICMP: ; //printf("\nThis is an IP ICMP packet of length %d\n", len); // printf("After removing the IP header we are left with %d bytes\n", datalen); int datalen = len - sizeof(struct ip); uint8_t* ICMP = (uint8_t*) malloc_or_die(datalen); //ICMP = array_cpy(Pkt->payload, datalen); memcpy(ICMP, payload, datalen); int tmp; tmp = process_ICMP_pkt(sr, interface, originIP, ICMP, datalen); return tmp; case IPPROTO_TCP: printf("TCP packet sent up the stack\n"); sr_transport_input(Pkt); return 1; default: return 0; } } else { //printf("********** Not my packet, so I will forward it\n"); return 3; } return 0; }