Example #1
0
/*******************************************************************
*   Every time handle_packet() is called, update_buffer() is called. The function walks through
*   the packet buffer and checks if the necessary mac address is now in the arp cache. If it is,
*   then the MAC address is added to the ethernet header and the packet is send and removed 
*   from the buffer. If the address is not in the cache and less than 5 arp requests have already
*   been sent, then another arp request is sent. Otherwise the packet is deleted from the buffer 
*   and an ICMP port unreachable is sent.
*******************************************************************/
void update_buffer(struct packet_state* ps,struct packet_buffer* queue)
{
	struct packet_buffer* buf_walker=0;
	buf_walker=queue;
	
	while(buf_walker)
	{
		uint32_t search_ip=buf_walker->gw_IP;
		struct arp_cache_entry* ent=search_cache(ps, search_ip);
		if(ent!=NULL)                   /*MAC Address is in ARP Cache. Send packet. */
		{
			struct sr_ethernet_hdr *eth = (struct sr_ethernet_hdr *)(buf_walker->packet);
			memmove(eth->ether_dhost, ent->mac, ETHER_ADDR_LEN);
			struct sr_if *iface=sr_get_interface(ps->sr, buf_walker->interface);
			memmove(eth->ether_shost, iface->addr, ETHER_ADDR_LEN);
			eth->ether_type = htons(ETHERTYPE_IP);
			
		    sr_send_packet(ps->sr, buf_walker->packet, buf_walker->pack_len, buf_walker->interface);
			buf_walker=delete_from_buffer(ps,buf_walker);
		}
		else if(buf_walker->num_arp_reqs < 5)   /*Send another arp request. */
		{
			buf_walker->num_arp_reqs++;
			sr_send_packet(ps->sr, buf_walker->arp_req, buf_walker->arp_len, buf_walker->interface);
			buf_walker=buf_walker->next;
		}
		else    /* 5 ARP Request already sent, send ICMP Port Unreachable and Delete from Buffer.*/
		{
			int off = sizeof(struct sr_ethernet_hdr) + sizeof(struct ip);
			ps->res_len=off;
			
			ps->response += sizeof(struct sr_ethernet_hdr);
			
			struct ip *res_ip = (struct ip*) ps->response; /*IP Header for ICMP Port Unreachable*/
			ps->response += sizeof(struct ip);
			
			ps->packet = buf_walker->packet;
			ps->packet += sizeof(struct sr_ethernet_hdr);
			
			struct ip *ip_hdr = (struct ip*) (ps->packet);  /*IP Header from original packet. */
			ps->packet += sizeof(struct ip);
			
			icmp_response(ps, ip_hdr, ICMPT_DESTUN, ICMPC_HOSTUN); /*Construct ICMP */
			memmove(res_ip, ip_hdr, sizeof(struct ip));
			res_ip->ip_len = htons(ps->res_len - sizeof(struct sr_ethernet_hdr));
			res_ip->ip_ttl = INIT_TTL;
			res_ip->ip_tos = ip_hdr->ip_tos;
			res_ip->ip_p = IPPROTO_ICMP;
			
			/* Finding interface to send ICMP out of*/
			struct sr_rt* iface_rt_entry=get_routing_if(ps, ip_hdr->ip_src);
			struct sr_if* iface=sr_get_interface(ps->sr, iface_rt_entry->interface);
			
			res_ip->ip_src.s_addr = iface->ip;
			res_ip->ip_dst = ip_hdr->ip_src;
			res_ip->ip_sum = 0;
			res_ip->ip_sum = cksum((uint8_t *)res_ip, sizeof(struct ip));
			res_ip->ip_sum = htons(res_ip->ip_sum);
			
			ps->response = (uint8_t *) res_ip - sizeof(struct sr_ethernet_hdr);
			struct sr_ethernet_hdr* eth_resp=(struct sr_ethernet_hdr*)ps->response;
			memmove(eth_resp->ether_dhost,buf_walker->old_eth->ether_shost,ETHER_ADDR_LEN);
			
			memmove(eth_resp->ether_shost,iface->addr, ETHER_ADDR_LEN);
			eth_resp->ether_type=htons(ETHERTYPE_IP);
			
			sr_send_packet(ps->sr, ps->response, ps->res_len, iface_rt_entry->interface);

			buf_walker=delete_from_buffer(ps,buf_walker);	
		}
	}
}
Example #2
0
int run_shell() {
	Value tmp_value;
	int ascii_code = -1;
	int cmd_code = -1;

	wprintf(L"");

	for (;;) {
		tmp_value = get_char();
		ascii_code = tmp_value.integer;

		// EXPECTATIONS
		cmd_code = analyse_expectations(ascii_code);

		//wprintf(L"%d %d %lc\n",ascii_code, cmd_code, tmp_value.character);

		switch(cmd_code) {
			case EOT_CMD:
				quit_shell();
				break;
			case DEL_L:
				delete_from_buffer(false);
				break;
			case DEL_R:
				delete_from_buffer(true);
				break;
			case UP_A_K:
				wprintf(L"UP");
				break;
			case DOWN_A_K:
				wprintf(L"DOWN");
				break;
			case RIGHT_A_K:
				move_cusor(CURSOR_DIR_RIGHT);
				break;
			case LEFT_A_K:
				move_cusor(CURSOR_DIR_LEFT);
				break;
			case BEGIN:
				move_cusor(CURSOR_DIR_BEGIN);
				break;
			case END:
				move_cusor(CURSOR_DIR_END);
				break;
			case ENTER_CMD:
				if(handle_cmd() == RET_ERROR) {
					print_error("Error while executing command!");
				}
				break;
			case NO_CMD:
				push_elem(buffer, tmp_value);
				print_buffer(true);
				break;
			default:
				//printf("%d => %c\n", ascii_code, tmp_value.character);
				break;
		}
	}

	return RET_OK;
}