Esempio n. 1
0
/* there is input available from the other side.  read the input
 * (from link-level raw socket, or ip connection, or pipe depending on
 * how we were initialized.)
 * make sure the message is an ll_shell_ftp message (reject it and
 * return 0 otherwise).
 */
static int receive_message(message_t *msg)
{
    struct sockaddr_ll recv_arg;
    socklen_t recv_arg_len;
    int result;

    if (cooked_in_file == NULL) {
        memset(&recv_arg, 0, sizeof(recv_arg));
        recv_arg.sll_family = AF_PACKET;
        recv_arg.sll_ifindex = get_index.ifr_ifindex;
        recv_arg.sll_protocol = htons(ETH_P_ALL);

        recv_arg_len = sizeof(recv_arg);
        result = recvfrom(packet_socket, (void *) msg, sizeof(*msg),
                MSG_TRUNC, (struct sockaddr *) &recv_arg, &recv_arg_len);
    } else if (have_in_pio) {
        result = pio_read(&in_pio, (void *) msg, sizeof(*msg));
    } else {
        result = read(in_fd, (void *) msg, sizeof(*msg));
    }

    if (result == -1) {
        if (db[5].d) {
            fprintf(stderr,
                    "recvfrom errno %d (%s)\n", errno, strerror(errno));
        }
        result = -1;
        goto done;
    }

    if (((unsigned char *) msg)[0] == 0x41) {
        result = 0;
        goto done;
    }

    if (msg->eth_header.h_proto != htons(0x2985)) {
        result = 0;
        goto done;
    }

    if (0 != mac_cmp(my_mac_addr, msg->eth_header.h_dest)) {
        // fprintf(stderr, "rejecting msg not for me.\n");
        result = 0;
        goto done;
    }

    if (!server || receiving) {
        if (0 != mac_cmp(dest_mac_addr, msg->eth_header.h_source)) {
            // fprintf(stderr, "rejecting msg not for me.\n");
            result = 0;
            goto done;
        }
    }

    done:
    return result;
}
Esempio n. 2
0
wtp_handle_t* wtp_alloc(const char* device, wtp_aslan_msg_cb msg_cb)
{
    if ((!device) || (!msg_cb))
	{
        errno = EINVAL;
		return NULL;
    }

    int ret = -1;

    wtp_handle_t *handle = calloc(1, sizeof(wtp_handle_t));
    if (!handle)
	{
        errno = ENOMEM;
		return NULL;
    }

	handle->wtp_state = WTP_STATE_NONE;
    handle->msg_cb = msg_cb;

    //for testing purposes only
    char hds_ip[] = "192.168.1.10";
    handle->hds_port = ASLAN_PROTOCOL_PORT;
    handle->hello_interval_seconds = 5;

    /* UDP socket */
    int s = -1;
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
        free(handle);
		return NULL;
    }
    handle->udp_socket = s;

	if (pthread_mutex_init(&handle->hello_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    if (pthread_mutex_init(&handle->udp_mutex, NULL) != 0)
    {
		free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->ack_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->sta_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->monitor_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    handle->wtp_sta_hashmap = NULL;

    /* HDS parameters */
    handle->hds_inet_addr.sin_family = AF_INET;
    if (!inet_aton(hds_ip, (struct in_addr*) &(handle->hds_inet_addr.sin_addr.s_addr)))
	{
        errno = EINVAL;
		close_wtp(handle);
		return NULL;
    }
    handle->hds_ip = ntohl(handle->hds_inet_addr.sin_addr.s_addr);

    /* interface name */
    strncpy(handle->device, device, IFNAMSIZ - 1);

    /* interface IP */
    struct ifreq ifr;
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    if (ioctl(handle->udp_socket, SIOCGIFADDR, &ifr) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_ip = ntohl(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr);

    /* HDS sockaddr_in structure */
    handle->hds_inet_addr.sin_addr.s_addr = htonl(handle->hds_ip);
    handle->hds_inet_addr.sin_family  = AF_INET;
    handle->hds_inet_addr.sin_port = htons(handle->hds_port);

    /* UDP socket local port */
    struct sockaddr_in address;
    memset((char*) &address, 0, sizeof(address));
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = 0;
    address.sin_family = AF_INET;
    bind(handle->udp_socket, (struct sockaddr*) &address, sizeof(address));

    struct sockaddr_in sin = {0};
    socklen_t len = sizeof(sin);
    if (getsockname(handle->udp_socket, (struct sockaddr*)&sin, &len) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_port = ntohs(sin.sin_port);
	wpa_printf(MSG_INFO, "INFO: UDP socket for ASLAN messages created, listening on port: %d\n", handle->local_port);

	/* create FIFO pipe producers and consumers */
	pipe_t* recv_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_recv_producer = pipe_producer_new(recv_pipe);
	handle->msg_recv_consumer = pipe_consumer_new(recv_pipe);
	pipe_free(recv_pipe);

	pipe_t* send_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_send_producer = pipe_producer_new(send_pipe);
	handle->msg_send_consumer = pipe_consumer_new(send_pipe);
	pipe_free(send_pipe);

    /* start receiving thread for ASLAN messages */
    if (pthread_create(&(handle->receive_thread), NULL, receive_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: receiving thread for ASLAN messages created\n");

	/* start processing thread for ASLAN messages */
    if (pthread_create(&(handle->process_thread), NULL, process_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: processing thread for ASLAN messages created\n");

	/* start sending thread for ASLAN messages */
    if (pthread_create(&(handle->send_thread), NULL, send_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: sending thread for ASLAN messages created\n");

    /* obtain HDS MAC address by a Hello message */
    if (wtp_send_hello_msg(handle) == -1)
	{
		close_wtp(handle);
		return NULL;
    }

    /* Check ARP cache */
    if (handle->local_ip != handle->hds_ip)
    {
        struct arpreq areq;
        memset(&areq, 0, sizeof(areq));
        struct sockaddr_in* sockaddr = NULL;
        sockaddr = (struct sockaddr_in*) &(areq.arp_pa);
        sockaddr->sin_family = AF_INET;
        sockaddr->sin_addr.s_addr = htonl(handle->hds_ip);
        sockaddr = (struct sockaddr_in*) &(areq.arp_ha);
        sockaddr->sin_family = ARPHRD_ETHER;
        strncpy(areq.arp_dev, device, IFNAMSIZ - 1);

        int i = 0;
        unsigned char mac_loopback[] = {0, 0, 0, 0, 0, 0};

        ioctl(s, SIOCGARP, (caddr_t) &areq);
        while ((i < 5) && (mac_cmp(areq.arp_ha.sa_data, mac_loopback)))
		{
            i++;
            sleep(1);
            ioctl(s, SIOCGARP, (caddr_t) &areq);
        }

        memcpy(handle->hds_mac, areq.arp_ha.sa_data, 6);

        if (mac_cmp(areq.arp_ha.sa_data, mac_loopback)) wpa_printf(MSG_WARNING, "WARNING: HDS MAC address obtaining failed\n");
        else wpa_printf(MSG_INFO, "INFO: HDS MAC address found: "MACSTR"\n", MAC2STR(handle->hds_mac));
    }
    else wpa_printf(MSG_INFO, "INFO: WTP started at loopback\n");

    return handle;
}
Esempio n. 3
0
/* wait up to a tenth of a second to receive a sequence number back from the
 * other side.  we are expecting the sequence number to equal msg_seq.
 * and, we are sent back a message length, which we expect to be equal to
 * msg_len.
 * return 0 iff everything is happy.
 */
static int recv_seq_message(int msg_len, int msg_seq)
{
    int len, seq;
    message_t msg;
    int result;

    while (1) {
        if (have_in_pio) {
            result = pio_timed_read_ok(&in_pio, 1);
            if (result != 1) {
                if (db[5].d) {
                    fprintf(stderr, "timeout waiting for response.\n");
                }
                return 1;
            }
        } else {
            int result;
            struct timeval timer = {0, 100000};
            fd_set read_set;
            int fd;
            FD_ZERO(&read_set);
            if (cooked_in_file == NULL) {
                fd = packet_socket;
            } else {
                fd = in_fd;
            }
            FD_SET(fd, &read_set);
            result = select(fd + 1, &read_set, 0, 0, &timer);
            if (result == -1) {
                perror("select problem");
                return 1;
            }
            if (result != 1) {
                if (db[5].d) {
                    fprintf(stderr, "timeout waiting for response.\n");
                }
                return 1;
            }
            if (db[3].d) {
                fprintf(stderr, "recv_seq_message select returned %d:  ",
                        result);
                {
                    int i;
                    for (i = 0; i < fd + 1; i++) {
                        if (FD_ISSET(i, &read_set)) {
                            fprintf(stderr, "%d ", i);
                        }
                    }
                    fprintf(stderr, "\n");
                }
            }
        }

        result = receive_message(&msg);

        if (result == 0) { continue; }

        if (result == -1) { return -1; }

        if (0 != mac_cmp(my_mac_addr, msg.eth_header.h_dest)) {
            // fprintf(stderr, "rejecting msg not for me.\n");
            continue;
        }

        if (msg.msg_type != recv_ok_msg && msg.msg_type != recv_err_msg
            && msg.msg_type != recv_err_stop_msg)
        {
            continue;
        }

        if (msg.msg_body_len != 8) {
            return -1;
        }

        len = ntohl(* (unsigned long int *) &msg.msg_body[0]);
        seq = ntohl(* (unsigned long int *) &msg.msg_body[4]);

        if (len != msg_len || seq != msg_seq) {
            return -1;
        }

        if (msg.msg_type == recv_err_msg) {
            return -1;
        }

        if (msg.msg_type == recv_err_stop_msg) {
            fprintf(stderr, "got recv_err_stop_msg from server!\n");
            return(-1);
        }

        return 0;
    }
}