Пример #1
0
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);
   }
}
Пример #2
0
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;
}