Esempio n. 1
0
/*
  Send a host unreachable ICMP to the given source address
*/
void send_echo_reply(uint8_t source_addr, uint8_t *packet, struct sr_instance *sr){
  
  /*Allocate a buffer to hold the packet*/
  uint8_t *buf = malloc(sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t) + sizeof(sr_icmp_hdr_t));
  
  /*Create and send the host unreachable ICMP TO source, telling them that dest was unreachable*/
  /*First have to create the ICMP packet*/
  sr_icmp_t3_hdr_t *icmp_packet = (sr_icmp_hdr_t *)(buf + sizeof(sr_ip_hdr_t) + sizeof(sr_ethernet_hdr_t));
  icmp_packet->icmp_type = 1;
  icmp_packet->icmp_code = 1;
  icmp_packet->icmp_sum = 0;
  icmp_packet->icmp_sum = cksum((const void *)(icmp_packet.icmp_type + icmp_packet.icmp_code), 2);
  print_hdr_icmp(icmp_packet);
  /*Have to craft data.  Data will be the original packet header plus the first 8 bytes of the packet content.*/
  memcpy(icmp_packet->data, packet, ICMP_DATA_SIZE);
  
  /*Now have to form the ip packet to encase the icmp content*/
  sr_ip_hdr_t *ip_packet = (sr_ip_hdr_t *)(buf + sizeof(sr_ethernet_hdr_t));
  ip_packet->ip_p = 1;
  ip_packet->ip_tos;            /* type of service */
  ip_packet->ip_len;            /* total length */
  ip_packet->ip_id;         /* identification */
  ip_packet->ip_off;            /* fragment offset field */
  ip_packet->ip_ttl;            /* time to live */
  ip_packet->ip_p = 1;          /* protocol */
  ip_packet->ip_sum;            /* checksum */
  ip_packet->ip_src = sr->if_list[0]->ip;  /*Assign the packet source to one of the router's interfaces*/
  ip_packet->ip_dst = get_ip_addr(packet);  /*set the packet destination to the original source IP*/
  print_hdr_ip(ip_packet);
  memcpy((void *)arp_packet->ar_sha, (void *)sender_eth, ETHER_ADDR_LEN);
  /*Now make an ethernet frame to wrap the IP packet with the ICMP packet*/
  sr_ethernet_hdr_t *ether_packet = (sr_ethernet_hdr_t *)(buf);
  ether_packet->ether_dhost = source_addr;  /*Set ethernet destination*/
  ether_packet->ether_shost = sr->if_list[0]->addr;  /*Set ethernet source*/
  ether_packet->ether_type = sr_ethertype.ethertype_ip;
  print_hdr_eth(ether_packet);
  print_hdr_icmp(uint8_t *buf);
  /*Now send off the packet*/
  int size = 32+20+8+28; /*Size of the packet. Ether header = 32, ip header = 20, ICMP header = 8, ICMP data = 28.*/
  sr_send_packet(sr, buf, size, sr->if_list);
  

}
Esempio n. 2
0
/* Create type3 icmp header */
void create_icmp_t3_hdr(sr_ip_hdr_t *ip_hdr, sr_icmp_t3_hdr_t *icmp_t3_hdr, uint8_t icmp_type, uint8_t icmp_code) {
    assert(icmp_t3_hdr);
    /* type here should be 3 actually */
    icmp_t3_hdr->icmp_type = icmp_type;
    /* get the icmp code from the input */
    icmp_t3_hdr->icmp_code = icmp_code;
    icmp_t3_hdr->unused = 0;
    icmp_t3_hdr->next_mtu = 0;
    memcpy(icmp_t3_hdr->data, ip_hdr, ICMP_DATA_SIZE); 
	icmp_t3_hdr->icmp_sum = 0;
    uint16_t checksum = cksum(icmp_t3_hdr, sizeof(sr_icmp_t3_hdr_t));
    icmp_t3_hdr->icmp_sum = checksum;
	print_hdr_icmp((uint8_t*)icmp_t3_hdr);
    return;
}
Esempio n. 3
0
/* Create icmp header */
void create_icmp_hdr(sr_icmp_hdr_t *icmp_hdr, sr_icmp_hdr_t *new_icmp_hdr, unsigned int len) {
    assert(icmp_hdr);
    assert(new_icmp_hdr);
    memcpy(new_icmp_hdr, icmp_hdr, sizeof(sr_icmp_hdr_t));
    /* here we construct a echo reply icmp */
	unsigned int icmp_whole_size = len - IP_PACKET_LEN;
    new_icmp_hdr->icmp_type = 0;
    /* code and checksum should be the same */
    new_icmp_hdr->icmp_code = 0;
    /* do we need to check the checksum??? */
    new_icmp_hdr->icmp_sum = 0;
    memcpy(new_icmp_hdr+sizeof(sr_icmp_hdr_t), icmp_hdr+sizeof(sr_icmp_hdr_t), icmp_whole_size-sizeof(sr_icmp_hdr_t));
    new_icmp_hdr->icmp_sum = cksum(new_icmp_hdr, icmp_whole_size);
	print_hdr_icmp((uint8_t*)new_icmp_hdr);
    return;
}