static void rtl_netd(void * data, char * name) { fs_node_t * tty = data; { fprintf(tty, "Sending DNS query...\n"); uint8_t queries[] = { 3,'i','r','c', 8,'f','r','e','e','n','o','d','e', 3,'n','e','t', 0, 0x00, 0x01, /* A */ 0x00, 0x01, /* IN */ }; int my_tx = next_tx_buf(); size_t packet_size = write_dns_packet(rtl_tx_buffer[my_tx], sizeof(queries), queries); outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]); outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size); } sleep_on(rx_wait); parse_dns_response(tty, last_packet); { fprintf(tty, "Sending DNS query...\n"); uint8_t queries[] = { 7,'n','y','a','n','c','a','t', 5,'d','a','k','k','o', 2,'u','s', 0, 0x00, 0x01, /* A */ 0x00, 0x01, /* IN */ }; int my_tx = next_tx_buf(); size_t packet_size = write_dns_packet(rtl_tx_buffer[my_tx], sizeof(queries), queries); outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]); outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size); } sleep_on(rx_wait); parse_dns_response(tty, last_packet); seq_no = krand(); { fprintf(tty, "Sending TCP syn\n"); int my_tx = next_tx_buf(); uint8_t payload[] = { 0 }; size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], payload, 0, (TCP_FLAGS_SYN | DATA_OFFSET_5)); outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]); outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size); seq_no += 1; ack_no = 0; } { struct ethernet_packet * eth = net_receive(); uint16_t eth_type = ntohs(eth->type); fprintf(tty, "Ethernet II, Src: (%2x:%2x:%2x:%2x:%2x:%2x), Dst: (%2x:%2x:%2x:%2x:%2x:%2x) [type=%4x)\n", eth->source[0], eth->source[1], eth->source[2], eth->source[3], eth->source[4], eth->source[5], eth->destination[0], eth->destination[1], eth->destination[2], eth->destination[3], eth->destination[4], eth->destination[5], eth_type); struct ipv4_packet * ipv4 = (struct ipv4_packet *)eth->payload; uint32_t src_addr = ntohl(ipv4->source); uint32_t dst_addr = ntohl(ipv4->destination); uint16_t length = ntohs(ipv4->length); char src_ip[16]; char dst_ip[16]; ip_ntoa(src_addr, src_ip); ip_ntoa(dst_addr, dst_ip); fprintf(tty, "IP packet [%s → %s] length=%d bytes\n", src_ip, dst_ip, length); struct tcp_header * tcp = (struct tcp_header *)ipv4->payload; if (seq_no != ntohl(tcp->ack_number)) { fprintf(tty, "[eth] Expected ack number of 0x%x, got 0x%x\n", seq_no, ntohl(tcp->ack_number)); fprintf(tty, "[eth] Bailing...\n"); return; } ack_no = ntohl(tcp->seq_number) + 1; free(eth); } { fprintf(tty, "Sending TCP ack\n"); int my_tx = next_tx_buf(); uint8_t payload[] = { 0 }; size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], payload, 0, (TCP_FLAGS_ACK | DATA_OFFSET_5)); outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]); outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size); } fprintf(tty, "[eth] s-next=0x%x, r-next=0x%x\n", seq_no, ack_no); }
/* Does DNS lookup for addr and puts resulting tox id in id_bin. */ void *dns3_lookup_thread(void *data) { ToxWindow *self = t_data.self; char inputdomain[MAX_STR_SIZE]; char name[MAX_STR_SIZE]; int namelen = parse_addr(t_data.addr, name, inputdomain); if (namelen == -1) { dns_error(self, "Must be a Tox ID or an address in the form username@domain"); killdns_thread(NULL); } char DNS_pubkey[DNS3_KEY_SIZE]; char domain[MAX_DOMAIN_SIZE]; int match = get_domain_match(DNS_pubkey, domain, inputdomain); if (match == -1) { dns_error(self, "Domain not found."); killdns_thread(NULL); } void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey); if (dns_obj == NULL) { dns_error(self, "Core failed to create DNS object."); killdns_thread(NULL); } char string[MAX_DNS_REQST_SIZE + 1]; uint32_t request_id; int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id, (uint8_t *) name, namelen); if (str_len == -1) { dns_error(self, "Core failed to generate DNS3 string."); killdns_thread(dns_obj); } string[str_len] = '\0'; u_char answer[PACKETSZ]; char d_string[MAX_DOMAIN_SIZE + MAX_DNS_REQST_SIZE + 10]; /* format string and create dns query */ snprintf(d_string, sizeof(d_string), "_%s._tox.%s", string, domain); int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer)); if (ans_len <= 0) { dns_error(self, "DNS query failed."); killdns_thread(dns_obj); } char ans_id[MAX_DNS_REQST_SIZE + 1]; /* extract TXT from DNS response */ if (parse_dns_response(self, answer, ans_len, ans_id) == -1) killdns_thread(dns_obj); char encrypted_id[MAX_DNS_REQST_SIZE + 1]; int prfx_len = strlen(TOX_DNS3_TXT_PREFIX); /* extract the encrypted ID from TXT response */ if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) { dns_error(self, "Bad DNS3 TXT response."); killdns_thread(dns_obj); } memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len); if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id, strlen(encrypted_id), request_id) == -1) { dns_error(self, "Core failed to decrypt DNS response."); killdns_thread(dns_obj); } pthread_mutex_lock(&Winthread.lock); cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg); pthread_mutex_unlock(&Winthread.lock); killdns_thread(dns_obj); return 0; }