Ejemplo n.º 1
0
void send_ip_handler(char *packet, unsigned int size)
{
	ip_optlen = ip_opt_build(ip_opt);

	if (!opt_fragment && (size+ip_optlen+20 > h_if_mtu))
	{
		/* auto-activate fragmentation */
		virtual_mtu = h_if_mtu-20;
		virtual_mtu = virtual_mtu - (virtual_mtu % 8);
		opt_fragment = TRUE;
		opt_mf = opt_df = FALSE; /* deactivate incompatible options */
		if (opt_verbose || opt_debug)
			printf("auto-activate fragmentation, fragments size: %d\n", virtual_mtu);
	}

	if (!opt_fragment)
	{
		unsigned short fragment_flag = 0;

		if (opt_mf) fragment_flag |= MF; /* more fragments */
		if (opt_df) fragment_flag |= DF; /* dont fragment */
		send_ip((char*)&local.sin_addr,
			(char*)&remote.sin_addr,
			packet, size, fragment_flag, ip_frag_offset,
			ip_opt, ip_optlen);
	}
	else
	{
		unsigned int remainder = size;
		int frag_offset = 0;

		while(1) {
			if (remainder <= virtual_mtu)
				break;

			send_ip((char*)&local.sin_addr,
				(char*)&remote.sin_addr,
				packet+frag_offset,
				virtual_mtu, MF, frag_offset,
				ip_opt, ip_optlen);

			remainder-=virtual_mtu;
			frag_offset+=virtual_mtu;
		}

		send_ip((char*)&local.sin_addr,
			(char*)&remote.sin_addr,
			packet+frag_offset,
			remainder, NF, frag_offset,
			ip_opt, ip_optlen);
	}
}
Ejemplo n.º 2
0
void send_tcp(tcp_pkt* pkt1,ip_pkt* pkt2)
{
	unsigned short tmp;
	pkt2->buf.len = pkt1->buf.len+20;
	pkt2->pr = 0x06;
	pkt2->buf.ptr[0]=pkt1->p_s >> 8;
	pkt2->buf.ptr[1]=pkt1->p_s & 0xFF;
	pkt2->buf.ptr[2]=pkt1->p_d >> 8;
	pkt2->buf.ptr[3]=pkt1->p_d & 0xFF;
	pkt2->buf.ptr[4]=(pkt1->n_tr >> 24) & 0xFF;
	pkt2->buf.ptr[5]=(pkt1->n_tr >> 16) & 0xFF;
	pkt2->buf.ptr[6]=(pkt1->n_tr >> 8) & 0xFF;
	pkt2->buf.ptr[7]=(pkt1->n_tr) & 0xFF;
	pkt2->buf.ptr[8]=(pkt1->n_rcv >> 24) & 0xFF;
	pkt2->buf.ptr[9]=(pkt1->n_rcv >> 16) & 0xFF;
	pkt2->buf.ptr[10]=(pkt1->n_rcv >> 8) & 0xFF;
	pkt2->buf.ptr[11]=(pkt1->n_rcv) & 0xFF;
	pkt2->buf.ptr[12]=0x50;
	pkt2->buf.ptr[13]=pkt1->fl;
	pkt2->buf.ptr[14]=0x04; pkt2->buf.ptr[15]=0x00;
	pkt2->buf.ptr[16]=0x00;pkt2->buf.ptr[17]=0x00;
	pkt2->buf.ptr[18]=0x00;pkt2->buf.ptr[19]=0x00;
	for(tmp=0;tmp<pkt1->buf.len;tmp++) pkt2->buf.ptr[20+tmp]=pkt1->buf.ptr[tmp];
	send_ip(pkt2);
}
Ejemplo n.º 3
0
void update_arp_queue(struct sr_instance* sr, arp_hdr* arp_header, const char* interface) {
	router_state* rs = get_router_state(sr);
	node* n = rs->arp_queue;
	node* next = NULL;

	while (n) {
		next = n->next;
		arp_queue_entry* aqe = (arp_queue_entry*)n->data;

		/* Does this arp reply match an entry waiting for it? */
		if (arp_header->arp_sip.s_addr == aqe->next_hop.s_addr) {
			/* send out the packets */
			node* cur_packet_node = aqe->head;
			node* next_packet_node = NULL;

			while (cur_packet_node) {
				next_packet_node = cur_packet_node->next;
				arp_queue_packet_entry* aqpe = (arp_queue_packet_entry*)cur_packet_node->data;

				/* send_ip takes responsibility for the packet so we don't need to free it */
				send_ip(sr, aqpe->packet, aqpe->len, &(aqe->next_hop), aqe->out_iface_name);

				node_remove(&(aqe->head), cur_packet_node);
				cur_packet_node = next_packet_node;
			}

			node_remove(&(rs->arp_queue), n);
		}
		n = next;
	}
}
Ejemplo n.º 4
0
/*
 * NOT THREAD SAFE! Lock cache rd, queue wr
 *
 *
 */
void send_queued_packets(struct sr_instance* sr, struct in_addr* dest_ip, char* dest_mac) {
	node* n = get_router_state(sr)->arp_queue;
	node* next = NULL;

	while (n) {
		next = n->next;

		arp_queue_entry* aqe = (arp_queue_entry*)n->data;

		/* match the arp reply sip to our entry next hop ip */
		if (dest_ip->s_addr == aqe->next_hop.s_addr) {
			node* cur_packet_node = aqe->head;
			node* next_packet_node = NULL;

			while (cur_packet_node) {
				next_packet_node = cur_packet_node->next;

				/* send the packet */
				arp_queue_packet_entry* aqpe = (arp_queue_packet_entry*)cur_packet_node->data;

				send_ip(sr, aqpe->packet, aqpe->len, &(aqe->next_hop), aqe->out_iface_name);
				node_remove(&(aqe->head), cur_packet_node);

				cur_packet_node = next_packet_node;
			}

			/* free the arp queue entry for this destination ip, and patch the list */
			node_remove(&(get_router_state(sr)->arp_queue), n);
		}

		n = next;
	}
}
Ejemplo n.º 5
0
/**
 * DNS: Sends a standard DNS-query (read request package) to a DNS-server.
 *      DNS-server respones with host IP or signals some error condition.
 *      Responses from the server are handled by handle_dns function.
 *
 * @param  fd          socket descriptor
 * @param  domain_name the domain name given as series of labels preceded
 *                     with length(label) and terminated with 0  
 *                     <br>(e.g. "\3,w,w,w,\4,h,o,s,t,\3,o,r,g,\0")
 * @see                handle_dns
 */
static void
dns_send_query(int fd, int8_t * domain_name, uint8_t ip_version)
{
	int qry_len = strlen((char *) domain_name) + 5;
	int iphdr_len = (ip_version == 4) ? sizeof(struct iphdr) : sizeof(struct ip6hdr);
	ip6_addr_t server_ipv6;

	uint32_t packetsize = iphdr_len +
	                      sizeof(struct udphdr) + sizeof(struct dnshdr) +
	                      qry_len;

	memset(ether_packet, 0, packetsize);
	fill_dnshdr(&ether_packet[
	            iphdr_len + sizeof(struct udphdr)],
	            domain_name,
		    ip_version);
	fill_udphdr(&ether_packet[iphdr_len],
		    sizeof(struct dnshdr) +
		    sizeof(struct udphdr) + qry_len,
	            UDPPORT_DNSC, UDPPORT_DNSS);
	if (ip_version == 4) {
		fill_iphdr(ether_packet,
			   sizeof(struct dnshdr) + sizeof(struct udphdr) +
			   iphdr_len + qry_len,
			   IPTYPE_UDP, 0, dns_server_ip);
	} else {
		memcpy(server_ipv6.addr, dns_server_ipv6, 16);
		fill_ip6hdr(ether_packet,
			    sizeof(struct dnshdr) + sizeof(struct udphdr) + qry_len,
			    IPTYPE_UDP, get_ipv6_address(),
			    &server_ipv6);
	}

	send_ip(fd, ether_packet, packetsize);
}
Ejemplo n.º 6
0
void ping_echo(icmp_pkt* pkt1,ip_pkt* pkt2)
{
	unsigned short tmp;
	for(tmp=0;tmp<4;tmp++) pkt2->ip_d[tmp] = pkt2->ip_s[tmp];
	pkt2->pr = 0x01;
	pkt2->buf.ptr[0]=0x00;
	pkt2->buf.ptr[1]=0x00;
	pkt2->buf.ptr[2]=0x00;
	pkt2->buf.ptr[3]=0x00;
	pkt2->buf.ptr[4]=pkt1->id[0];pkt2->buf.ptr[5]=pkt1->id[1];
	pkt2->buf.ptr[6]=pkt1->num[0];pkt2->buf.ptr[7]=pkt1->num[1];
	for(tmp=0;tmp < pkt1->buf.len;tmp++) pkt2->buf.ptr[8+tmp]=pkt1->buf.ptr[tmp];
	pkt2->buf.len= 8 + pkt1->buf.len;
	send_ip(pkt2);
}
Ejemplo n.º 7
0
static void select_handler(ClickRecognizerRef crr, void *context) {
    s_current_field++;
    if (s_current_field > 3) {
        s_ip_set = true;

        persist_write_data(IP_PERSIST_KEY, s_ip, 4);
        send_ip(s_ip);

        click_down_handler = click_handler;
        click_up_handler = click_handler;
        click_select_handler = click_handler;
        window_set_click_config_provider(s_window, (ClickConfigProvider) config_provider); 
    }
    update_ui();
}
Ejemplo n.º 8
0
Archivo: ike.cpp Proyecto: 12019/shrew
long _IKED::packet_ike_xmit( IDB_PH1 * ph1, IDB_XCH * xch, PACKET_IKE & packet, bool retry )
{
	//
	// prepare for log output
	//

	char txtaddr_l[ LIBIKE_MAX_TEXTADDR ];
	char txtaddr_r[ LIBIKE_MAX_TEXTADDR ];

	text_addr( txtaddr_l, &ph1->tunnel->saddr_l, true );
	text_addr( txtaddr_r, &ph1->tunnel->saddr_r, true );

	char * encap_mode = encap_ike;
	if( ph1->tunnel->natt_version != IPSEC_NATT_NONE )
		encap_mode = encap_nat;

	//
	// encapsulate ike packet into UDP/IP packet
	//

	PACKET_IP packet_ip;
	packet_ike_encap(
		packet,
		packet_ip,
		ph1->tunnel->saddr_l,
		ph1->tunnel->saddr_r,
		ph1->tunnel->natt_version );

	//
	// log the result
	//

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		packet_ip.buff(),
		packet_ip.size(),
		"-> : send %s packet %s -> %s",
		encap_mode,
		txtaddr_l,
		txtaddr_r );

	//
	// send ike packet
	//

	ETH_HEADER header;

	long result = send_ip(
					packet_ip,
					&header );

	if( result != LIBIKE_OK )
	{
		ph1->status( XCH_STATUS_DEAD, XCH_FAILED_NETWORK, 0 );
		xch->status( XCH_STATUS_DEAD, XCH_FAILED_NETWORK, 0 );
		return LIBIKE_FAILED;
	}

	//
	// queue packet for resend
	//

	xch->resend_queue( packet_ip );

	//
	// dump for encoded packets
	//

	if( dump_encrypt )
		pcap_encrypt.dump( header, packet_ip );

	return LIBIKE_OK;
}
Ejemplo n.º 9
0
Archivo: v_api.c Proyecto: pqhwan/TCP
/**
* TODO : take the pseudo header function out. NOTE : make sure it is generic
* enough to be called by handshake funcs AND send data funcs.
* TODO : 3rd shake might have data
* TODO : RST
*/
void tcp_send_handshake(int gripnum, socket_t *socket){

	tcphdr *header = NULL;

	switch(gripnum) {

		case 0:
			printf("\t TODO : RST NOT IMPLEMENTED YET\n");

		case SYN_SENT://1'st shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, 0,0,1,0,0,0, WINSIZE); //half the max sequence number
			
			break;
		case SYN_RCVD://2'nd shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									(socket->myseq)++, socket->ackseq,
									0,1,0,0,1, WINSIZE);

			break;

		case ESTABLISHED://3'rd shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									++(socket->myseq), socket->ackseq, 
									0,0,0,0,1, WINSIZE);
			break;

		case FIN_WAIT_1:// from ESTABLISHED --> FIN_WAIT_1 state (FIN SEGMENT)
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		case CLOSE_WAIT: //regular ACK
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									0,0,0,0,1,MAXSEQ);
			break;

		case LAST_ACK: // moving from CLOSE_WAIT --> LAST_ACK (FIN SEGMENT)
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		case CLOSING: // moving from FIN_WAIT_1 --> CLOSING
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;
		case ACKNOWLEDGE:
			printf("RST, ACK\n");
			header = tcp_mastercrafter(socket->myport, socket->urport,
					socket->myseq, socket->ackseq,
					0,0,0,0,1,MAXSEQ);

		case RST: // RST packet
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		default:
			printf("\t WARNING : Unknown shake!\n");
			return;
	}

	//0. make sure TCP header is not NULL
	if (header == NULL) {
		printf("\tWARNING : Could not make TCP header\n");
		return;
	}

	struct pseudo_tcpp *tcp_packet = (uint16_t *)malloc(sizeof(struct pseudo_tcpp));
	memset(tcp_packet, 0x0, sizeof(struct pseudo_tcpp));

	//1. fill the pseudiheader part
	((uint32_t *)tcp_packet)[0] = socket->myaddr;
	((uint32_t *)tcp_packet)[1] = socket->uraddr;
	((uint8_t *)tcp_packet)[9] = (uint8_t)TCP;
	((uint16_t *)tcp_packet)[5] = ntohs((uint16_t)TCPHDRSIZE);


	//2. fill the header 
	tcp_hton(header);
	memcpy(&tcp_packet->tcp, header, TCPHDRSIZE);

	//3. data (NONE)
	//TODO : 3rd handshake could have data. 
	memset(tcp_packet->payload, 0, 1024);

	//4. checksum
	uint16_t checksum = tcp_checksum(tcp_packet, TCPHDRSIZE+12);
	

	//5. set the checksum in the TCP header
	header->check = checksum;
	if (header->check == 0) {
		printf("\t ERROR : something went wrong with checksum\n");
		header->check = 0xffffff;
	}

	//6. TODO : error checking
	interface_t *nexthop = get_nexthop(socket->uraddr);

	//TODO : packet top pass to ip
	char *packet = (char *)malloc(TCPHDRSIZE+IPHDRSIZE);

	if (packet == NULL) {
		printf("\t ERROR : Malloc failed\n");
		return;
	}

	//7. copy the TCP header to ip packet
	memset(packet, 0, TCPHDRSIZE+IPHDRSIZE);
	memcpy(packet, header, TCPHDRSIZE);

	//8. NO data, so you are done : pass to ip
	encapsulate_inip(socket->myaddr,socket->uraddr,(uint8_t)TCP,header, TCPHDRSIZE, &packet);

	//9. TCP/IP packet all set, sending time
	int ret = send_ip(nexthop, packet, TCPHDRSIZE+IPHDRSIZE);

	free(tcp_packet);
	free(packet);
	free(header);

	return;
}
Ejemplo n.º 10
0
void handler_sigalarm(int signo)
{
	send_ip();
	alarm(2);
}