Beispiel #1
0
/**@brief this generates a Fins frame which is sent to the arp module so that the
 * (1) a host receives an ARP reply, OR (2) sends an ARP request to a network
 * @param fins_frame is the pointer to the received fins frame
 * @param task indicates whether the arp message is a request or a reply to or from network
 */
void fins_from_net(struct finsFrame *fins_frame, int task)
{
	uint32_t IP_addrs_read;
	uint64_t MAC_addrs;

	struct ARP_message *msg1 = (struct ARP_message*)malloc(sizeof(struct ARP_message));
	struct ARP_message *msg2 = (struct ARP_message*)malloc(sizeof(struct ARP_message));
	struct arp_hdr *arp_net = (struct arp_hdr*) malloc(sizeof(struct arp_hdr));

	PRINT_DEBUG("\nFins data frame which carries a request or reply ARP from a network\n");

	IP_addrs_read = read_IP_addrs();
	MAC_addrs = search_MAC_addrs(IP_addrs_read, ptr_neighbor_list);

	if (task==1){
		mimic_net_request(IP_addrs_read, MAC_addrs, msg1);
		arp_msg_to_hdr(msg1, arp_net);
		host_to_net(arp_net);
		arp_to_fins(arp_net, fins_frame);
	}
	else if (task==2){
		gen_requestARP(IP_addrs_read, msg1);
		mimic_net_reply(msg1, msg2);
		arp_msg_to_hdr(msg2, arp_net);
		host_to_net(arp_net);
		arp_to_fins(arp_net, fins_frame);
	}
	fins_frame->destinationID.id = ARPID;

	free(msg1);
	free(msg2);
}
Beispiel #2
0
/*************************************************************************
 * change packet's format from SOS message to MAC                        *
 *************************************************************************/
void sosmsg_to_mac(Message *msg, VMAC_PPDU *ppdu)
{
	ppdu->len = msg->len + PRE_PAYLOAD_LEN + POST_PAYLOAD_LEN;

	ppdu->mpdu.daddr = host_to_net(msg->daddr);
	ppdu->mpdu.saddr = host_to_net(msg->saddr);
	ppdu->mpdu.did = msg->did;
	ppdu->mpdu.sid = msg->sid;
	ppdu->mpdu.type = msg->type;

	ppdu->mpdu.data = msg->data;
}
/* Send the packets to tell our friends what our DHT public key is.
 *
 * if onion_dht_both is 0, use only the onion to send the packet.
 * if it is 1, use only the dht.
 * if it is something else, use both.
 *
 * return the number of packets sent on success
 * return -1 on failure.
 */
static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
{
    if (friend_num >= onion_c->num_friends)
        return -1;

    uint8_t data[FAKEID_DATA_MAX_LENGTH];
    data[0] = FAKEID_DATA_ID;
    uint64_t no_replay = unix_time();
    host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
    memcpy(data + 1, &no_replay, sizeof(no_replay));
    memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
    Node_format nodes[MAX_SENT_NODES];
    uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);
    uint32_t i;

    for (i = 0; i < num_nodes; ++i)
        to_net_family(&nodes[i].ip_port.ip);

    memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
    int num1 = -1, num2 = -1;

    if (onion_dht_both != 1)
        num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);

    if (onion_dht_both != 0)
        num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);

    if (num1 == -1)
        return num2;

    if (num2 == -1)
        return num1;

    return num1 + num2;
}
Beispiel #4
0
/**@brief This function sends out a fins frame that passes an arp request out to the network
 * @param sought_IP_addrs is the IP address whose associated MAC address is sought
 * @param fins_arp_out points to the fins frame which will be sent from the module
 * */
void arp_out_request(uint32_t sought_IP_addrs, struct finsFrame *fins_arp_out){

	gen_requestARP(sought_IP_addrs, &arp_msg);
	arp_msg_to_hdr(&arp_msg, packet);
	host_to_net(packet);
	print_arp_hdr(packet);
	arp_to_fins(packet, fins_arp_out); /**arp request to be sent to network*/
}
Beispiel #5
0
/**@brief This function sends out a fins frame with a reply arp in response to a request
 * from the network
 * @param fins_arp_out points to the fins frame which will be sent from the module
 * */
void arp_out_reply(struct finsFrame *fins_arp_out){

	struct ARP_message arp_msg_reply;

	gen_replyARP(&arp_msg, &arp_msg_reply);
	arp_msg_to_hdr(&arp_msg_reply, packet);
	host_to_net(packet);
	print_arp_hdr(packet);
	arp_to_fins(packet, fins_arp_out); /**arp reply to be sent to network */
}
Beispiel #6
0
static int save_blocklist(char *path)
{
    if (arg_opts.ignore_data_file)
        return 0;

    if (path == NULL)
        return -1;

    int len = sizeof(BlockedFriend) * Blocked_Contacts.num_blocked;
    char *data = malloc(len);

    if (data == NULL)
        exit_toxic_err("Failed in save_blocklist", FATALERR_MEMORY);

    int i;
    int count = 0;

    for (i = 0; i < Blocked_Contacts.max_index; ++i) {
        if (count > Blocked_Contacts.num_blocked)
            return -1;

        if (Blocked_Contacts.list[i].active) {
            BlockedFriend tmp;
            memset(&tmp, 0, sizeof(BlockedFriend));
            tmp.namelength = htons(Blocked_Contacts.list[i].namelength);
            memcpy(tmp.name, Blocked_Contacts.list[i].name, Blocked_Contacts.list[i].namelength + 1);
            memcpy(tmp.pub_key, Blocked_Contacts.list[i].pub_key, TOX_CLIENT_ID_SIZE);

            uint8_t lastonline[sizeof(uint64_t)];
            memcpy(lastonline, &Blocked_Contacts.list[i].last_on, sizeof(uint64_t));
            host_to_net(lastonline, sizeof(uint64_t));
            memcpy(&tmp.last_on, lastonline, sizeof(uint64_t));

            memcpy(data + count * sizeof(BlockedFriend), &tmp, sizeof(BlockedFriend));
            ++count;
        }
    }

    FILE *fp = fopen(path, "wb");

    if (fp == NULL) {
        free(data);
        return -1;
    }

    int ret = 0;

    if (fwrite(data, len, 1, fp) != 1)
        ret = -1;

    fclose(fp);
    free(data);
    return ret;
}
Beispiel #7
0
/**@brief this function receives an arp message from outside and processes it
 * @param fins_received is the pointer to the fins frame which has been received by the ARP module
 */
void arp_in(struct finsFrame *fins_received){

	struct ARP_message *arp_msg_ptr;

	fins_arp_in = fins_received;

	/**request or reply received from the network and as transmitted by the ethernet stub*/
	if (fins_arp_in->dataOrCtrl == DATA && (fins_arp_in->destinationID.id == (unsigned char) ARPID))
	{
		fins_to_arp(fins_arp_in, packet);  //extract arp hdr from the fins frame
		host_to_net(packet);               //convert it into the right format (e.g. htons issue etc.)
		arp_msg_ptr = &arp_msg;
		arp_hdr_to_msg(packet, arp_msg_ptr);  //convert the hdr into an internal ARP message (e.g. use uint64_t instead of unsigned char)

		print_msgARP(arp_msg_ptr);

		if (check_valid_arp(arp_msg_ptr)==1){

			update_cache(arp_msg_ptr);

			if ((arp_msg_ptr->target_IP_addrs==interface_IP_addrs) && (arp_msg_ptr->operation==ARPREQUESTOP))
				arp_out(REPLYDATA);//generate reply
			else if ((arp_msg_ptr->target_IP_addrs==interface_IP_addrs) && (arp_msg_ptr->operation==ARPREPLYOP))
			{	target_IP_addrs = arp_msg.sender_IP_addrs;
				arp_out(REPLYCONTROL);//generate fins control carrying neighbor's MAC address
			}
		}
	}
	else if ((fins_arp_in->dataOrCtrl == CONTROL) && (fins_arp_in->ctrlFrame.opcode == WRITEREQUEST)
			&& (fins_arp_in->destinationID.id == (unsigned char) ARPID))
	{/**as a request received from the ethernet stub-- IP address is provided in this fins control frame*/

		memcpy(fins_IP_address, fins_arp_in->ctrlFrame.paramterValue, PROTOCOLADDRSLEN);
		target_IP_addrs = gen_IP_addrs(fins_IP_address[0],fins_IP_address[1],fins_IP_address[2],fins_IP_address[3]);

		/**request initiated by the ethernet stub*/
		if (search_list(ptr_cacheHeader, target_IP_addrs)==0)//i.e. not found
			arp_out(REQUESTDATA); //generate arp request for MAC address and send out to the network
		else
			arp_out(REPLYCONTROL);//generate fins control carrying MAC address foe ethernet
	}

	print_cache();
}
Beispiel #8
0
/* Send the packets to tell our friends what our DHT public key is.
 *
 * if onion_dht_both is 0, use only the onion to send the packet.
 * if it is 1, use only the dht.
 * if it is something else, use both.
 *
 * return the number of packets sent on success
 * return -1 on failure.
 */
static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
{
    if (friend_num >= onion_c->num_friends)
        return -1;

    uint8_t data[FAKEID_DATA_MAX_LENGTH];
    data[0] = FAKEID_DATA_ID;
    uint64_t no_replay = unix_time();
    host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
    memcpy(data + 1, &no_replay, sizeof(no_replay));
    memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
    Node_format nodes[MAX_SENT_NODES];
    uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2));
    uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
    num_nodes += num_relays;
    int nodes_len = 0;

    if (num_nodes != 0) {
        nodes_len = pack_nodes(data + FAKEID_DATA_MIN_LENGTH, FAKEID_DATA_MAX_LENGTH - FAKEID_DATA_MIN_LENGTH, nodes,
                               num_nodes);

        if (nodes_len <= 0)
            return -1;
    }

    int num1 = -1, num2 = -1;

    if (onion_dht_both != 1)
        num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len);

    if (onion_dht_both != 0)
        num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len);

    if (num1 == -1)
        return num2;

    if (num2 == -1)
        return num1;

    return num1 + num2;
}