Beispiel #1
0
static err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	struct socket * sock = (struct socket *) arg;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	assert(err == ERR_OK && newpcb);
	assert(sock->flags & SOCK_FLG_OP_LISTENING);

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		int ret;

		ret = tcp_do_accept(sock, &sock->mess, newpcb);
		sock_revive(sock, ret);
		sock->flags &= ~SOCK_FLG_OP_PENDING;
		if (ret == OK) {
			return ERR_OK;
		}
		/* in case of an error fall through */
	}

	/* If we cannot accept rightaway we enqueue the connection for later */

	debug_tcp_print("Enqueue connection sock %ld pcb %p\n",
			get_sock_num(sock), newpcb);
	if (sock_enqueue_data(sock, newpcb, 1) != OK) {
		tcp_abort(newpcb);
		return ERR_ABRT;
	}
	if (sock_select_read_set(sock))
		sock_select_notify(sock);

	return ERR_OK;
}
Beispiel #2
0
static void tcp_op_listen(struct socket * sock, message * m)
{
	int backlog, err;
	struct tcp_pcb * new_pcb;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	err = copy_from_user(m->m_source, &backlog, sizeof(backlog),
				(cp_grant_id_t) m->IO_GRANT, 0);

	new_pcb = tcp_listen_with_backlog((struct tcp_pcb *) sock->pcb,
							(u8_t) backlog);
	debug_tcp_print("listening pcb %p", new_pcb);

	if (!new_pcb) {
		debug_tcp_print("Cannot listen on socket %ld", get_sock_num(sock));
		sock_reply(sock, EGENERIC);
		return;
	}

	/* advertise that this socket is willing to accept connections */
	tcp_accept(new_pcb, tcp_accept_callback);
	sock->flags |= SOCK_FLG_OP_LISTENING;

	sock->pcb = new_pcb;
	sock_reply(sock, OK);
}
Beispiel #3
0
static void tcp_op_accept(struct socket * sock, message * m)
{
	debug_tcp_print("socket num %ld", get_sock_num(sock));

	if (!(sock->flags & SOCK_FLG_OP_LISTENING)) {
		debug_tcp_print("socket %ld does not listen\n", get_sock_num(sock));
		sock_reply(sock, EINVAL);
		return;
	}

	/* there is a connection ready to be accepted */
	if (sock->recv_head) {
		int ret;
		struct tcp_pcb * pcb;
		
		pcb = (struct tcp_pcb *) sock->recv_head->data;
		assert(pcb);

		ret = tcp_do_accept(sock, m, pcb);
		sock_reply(sock, ret);
		if (ret == OK)
			sock_dequeue_data(sock);
		return;
	}

	debug_tcp_print("no ready connection, suspending\n");

	sock_reply(sock, SUSPEND);
	sock->flags |= SOCK_FLG_OP_PENDING;
}
Beispiel #4
0
static void tcp_op_read(struct socket * sock, message * m)
{
	debug_tcp_print("socket num %ld", get_sock_num(sock));

	if (!sock->pcb || ((struct tcp_pcb *) sock->pcb)->state !=
							ESTABLISHED) {
		debug_tcp_print("Connection not established\n");
		sock_reply(sock, ENOTCONN);
		return;
	}
	if (sock->recv_head) {
		/* data available receive immeditely */
		int ret = read_from_tcp(sock,  m);
		debug_tcp_print("read op finished");
		sock_reply(sock, ret);
	} else {
		if (sock->flags & SOCK_FLG_CLOSED) {
			printf("socket %ld already closed!!! call from %d\n",
					get_sock_num(sock), m->USER_ENDPT);
			do_tcp_debug = 1;
			sock_reply(sock, 0);
			return;
		}
		/* operation is being processed */
		debug_tcp_print("no data to read, suspending");
		sock_reply(sock, SUSPEND);
		sock->flags |= SOCK_FLG_OP_PENDING | SOCK_FLG_OP_READING;
	}
}
Beispiel #5
0
void socket_open(message * m)
{
        struct sock_ops * ops;
        struct socket * sock;
        int ret = OK;

        switch (m->DEVICE) {
        case SOCK_TYPE_TCP:
                ops = &sock_tcp_ops;
                break;
        case SOCK_TYPE_UDP:
                ops = &sock_udp_ops;
                break;
        case SOCK_TYPE_IP:
                ops = &sock_raw_ip_ops;
                break;
        default:
                if (m->DEVICE - SOCK_TYPES  < MAX_DEVS) {
                        m->DEVICE -= SOCK_TYPES;
                        nic_open(m);
                        return;
                }
                printf("LWIP unknown socket type %d\n", m->DEVICE);
                send_reply_open(m, EINVAL);
                return;
        }

        sock = get_unused_sock();
        if (!sock) {
                printf("LWIP : no free socket\n");
                send_reply_open(m, EAGAIN);
                return;
        }

        sock->ops = ops;
        sock->select_ep = NONE;
        sock->recv_data_size = 0;

        if (sock->ops && sock->ops->open)
                ret = sock->ops->open(sock, m);

        if (ret == OK) {
                debug_print("new socket %ld", get_sock_num(sock));
                send_reply_open(m, get_sock_num(sock));
        } else {
                debug_print("failed %d", ret);
                send_reply_open(m, ret);
        }
}
Beispiel #6
0
static void udp_op_write(struct socket * sock, message * m, __unused int blk)
{
	int ret;
	struct pbuf * pbuf;

	debug_udp_print("socket num %ld data size %d",
			get_sock_num(sock), m->COUNT);

	pbuf = pbuf_alloc(PBUF_TRANSPORT, m->COUNT, PBUF_POOL);
	if (!pbuf) {
		ret = ENOMEM;
		goto write_err;
	}

	if ((ret = copy_from_user(m->m_source, pbuf->payload, m->COUNT,
				(cp_grant_id_t) m->IO_GRANT, 0)) != OK) {
		pbuf_free(pbuf);
		goto write_err;
	}

	if (sock->usr_flags & NWUO_RWDATONLY)
		ret = udp_op_send(sock, pbuf, m);
	else
		ret = udp_op_sendto(sock, pbuf, m);

	if (pbuf_free(pbuf) == 0) {
		panic("We cannot buffer udp packets yet!");
	}
	
write_err:
	sock_reply(sock, ret);
}
Beispiel #7
0
static void udp_op_read(struct socket * sock, message * m, int blk)
{
	debug_udp_print("socket num %ld", get_sock_num(sock));

	if (sock->recv_head) {
		/* data available receive immeditely */

		struct udp_recv_data * data;
		int ret;

		data = (struct udp_recv_data *) sock->recv_head->data;

		ret = udp_do_receive(sock, m, (struct udp_pcb *) sock->pcb,
					data->pbuf, &data->ip, data->port);

		if (ret > 0) {
			sock_dequeue_data(sock);
			sock->recv_data_size -= data->pbuf->tot_len;
			udp_recv_free(data);
		}
		sock_reply(sock, ret);
	} else if (!blk)
		sock_reply(sock, EAGAIN);
	else {
		/* store the message so we know how to reply */
		sock->mess = *m;
		/* operation is being processes */
		sock->flags |= SOCK_FLG_OP_PENDING;

		debug_udp_print("no data to read, suspending\n");
	}
}
Beispiel #8
0
static int udp_op_write(struct socket * sock, struct sock_req * req,
	__unused int blk)
{
	int ret;
	struct pbuf * pbuf;

	debug_udp_print("socket num %ld data size %u",
			get_sock_num(sock), req->size);

	pbuf = pbuf_alloc(PBUF_TRANSPORT, req->size, PBUF_POOL);
	if (!pbuf)
		return ENOMEM;

	if ((ret = copy_from_user(req->endpt, pbuf->payload, req->size,
				req->grant, 0)) != OK) {
		pbuf_free(pbuf);
		return ret;
	}

	if (sock->usr_flags & NWUO_RWDATONLY)
		ret = udp_op_send(sock, pbuf, req->size);
	else
		ret = udp_op_sendto(sock, pbuf, req->size);

	if (pbuf_free(pbuf) == 0) {
		panic("We cannot buffer udp packets yet!");
	}

	return ret;
}
Beispiel #9
0
static void tcp_op_select_reply(struct socket * sock, message * m)
{
	assert(sock->select_ep != NONE);
	debug_tcp_print("socket num %ld", get_sock_num(sock));


	if (sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_REVIVING)) {
		debug_tcp_print("WARNING socket still blocking!");
		return;
	}

	if (sock->flags & SOCK_FLG_SEL_READ) {
		if (sock->pcb == NULL || (sock->recv_head &&
				!(sock->flags & SOCK_FLG_OP_WRITING)) ||
			 (!(sock->flags & SOCK_FLG_OP_LISTENING) && 
			 ((struct tcp_pcb *) sock->pcb)->state !=
			 ESTABLISHED)) {
			m->DEV_SEL_OPS |= SEL_RD;
			debug_tcp_print("read won't block");
		}
	}

	if (sock->flags & SOCK_FLG_SEL_WRITE  &&
			(sock->pcb == NULL ||
			 ((struct tcp_pcb *) sock->pcb)->state ==
			 ESTABLISHED)) {
		m->DEV_SEL_OPS |= SEL_WR;
		debug_tcp_print("write won't block");
	}

	if (m->DEV_SEL_OPS) 
		sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ |
							SOCK_FLG_SEL_ERROR);
}
Beispiel #10
0
static void tcp_error_callback(void *arg, err_t err)
{
	int perr;
	struct socket * sock = (struct socket *) arg;

	debug_tcp_print("socket num %ld err %d", get_sock_num(sock), err);

	switch (err) {
	case ERR_RST:
		perr = ECONNREFUSED;
		break;
	case ERR_CLSD:
		perr = EPIPE;
		break;
	case ERR_CONN:
		perr = ENOTCONN;
		break;
	default:
		perr = EIO;
	}
	
	if (sock->flags & SOCK_FLG_OP_PENDING) {
		sock_revive(sock, perr);
		sock->flags &= ~SOCK_FLG_OP_PENDING;
	} else if (sock_select_set(sock))
		sock_select_notify(sock);
	/*
	 * When error callback is called the tcb either does not exist anymore
	 * or is going to be deallocated soon after. We must not use the pcb
	 * anymore
	 */
	sock->pcb = NULL;
}
Beispiel #11
0
static int tcp_do_accept(struct socket * listen_sock,
			message * m,
			struct tcp_pcb * newpcb)
{
	struct socket * newsock;
	unsigned sock_num;
	int ret;

	debug_tcp_print("socket num %ld", get_sock_num(listen_sock));

	if ((ret = copy_from_user(m->m_source, &sock_num, sizeof(sock_num),
				(cp_grant_id_t) m->IO_GRANT, 0)) != OK)
		return EFAULT;
	if (!is_valid_sock_num(sock_num))
		return EBADF;

	newsock = get_sock(sock_num);
	assert(newsock->pcb); /* because of previous open() */
	
	/* we really want to forget about this socket */
	tcp_err((struct tcp_pcb *)newsock->pcb, NULL);
	tcp_abandon((struct tcp_pcb *)newsock->pcb, 0);
	
	tcp_arg(newpcb, newsock);
	tcp_err(newpcb, tcp_error_callback);
	tcp_sent(newpcb, tcp_sent_callback);
	tcp_recv(newpcb, tcp_recv_callback);
	tcp_nagle_disable(newpcb);
	tcp_accepted(((struct tcp_pcb *)(listen_sock->pcb)));
	newsock->pcb = newpcb;

	debug_tcp_print("Accepted new connection using socket %d\n", sock_num);

	return OK;
}
Beispiel #12
0
static void tcp_get_opt(struct socket * sock, message * m)
{
	int err;
	nwio_tcpopt_t tcpopt;
	struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	assert(pcb);

	if ((unsigned) m->COUNT < sizeof(tcpopt)) {
		sock_reply(sock, EINVAL);
		return;
	}

	/* FIXME : not used by the userspace library */
	tcpopt.nwto_flags = 0;
	
	err = copy_to_user(m->m_source, &tcpopt, sizeof(tcpopt),
				(cp_grant_id_t) m->IO_GRANT, 0);

	if (err != OK)
		sock_reply(sock, err);

	sock_reply(sock, OK);
}
Beispiel #13
0
static err_t tcp_connected_callback(void *arg,
				struct tcp_pcb *tpcb,
				__unused err_t err)
{
	struct socket * sock = (struct socket *) arg;

	debug_tcp_print("socket num %ld err %d", get_sock_num(sock), err);

	if (sock->pcb == NULL) {
		if (sock_select_set(sock))
			sock_select_notify(sock);
		return ERR_OK;
	}

	assert((struct tcp_pcb *)sock->pcb == tpcb);

	tcp_sent(tpcb, tcp_sent_callback);
	tcp_recv(tpcb, tcp_recv_callback);
	sock_revive(sock, OK);
	sock->flags &= ~(SOCK_FLG_OP_PENDING | SOCK_FLG_OP_CONNECTING);

	/* revive does the sock_select_notify() for us */

	return ERR_OK;
}
Beispiel #14
0
static void udp_recv_callback(void *arg,
			struct udp_pcb *pcb,
			struct pbuf *pbuf,
			ip_addr_t *addr,
			u16_t port)
{
	struct socket * sock = (struct socket *) arg;
	struct udp_recv_data * data;

	debug_udp_print("socket num : %ld addr : %x port : %d\n",
			get_sock_num(sock), (unsigned int) addr->addr, port);

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		/* we are resuming a suspended operation */
		int ret;

		ret = udp_do_receive(sock, &sock->req, pcb, pbuf, addr, port);

		send_req_reply(&sock->req, ret);
		sock->flags &= ~SOCK_FLG_OP_PENDING;

		if (ret > 0) {
			pbuf_free(pbuf);
			return;
		}
	}

	/* Do not enqueue more data than allowed */
	if (sock->recv_data_size > UDP_BUF_SIZE) {
		pbuf_free(pbuf);
		return;
	}

	/*
	 * nobody is waiting for the data or an error occured above, we enqueue
	 * the packet
	 */
	if (!(data = udp_recv_alloc())) {
		pbuf_free(pbuf);
		return;
	}

	data->ip = *addr;
	data->port = port;
	data->pbuf = pbuf;

	if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) {
		udp_recv_free(data);
		return;
	}
	
	/*
	 * We don't need to notify when somebody is already waiting, reviving
	 * read operation will do the trick for us. But we must announce new
	 * data available here.
	 */
	if (sock_select_read_set(sock))
		sock_select_notify(sock);
}
Beispiel #15
0
int socket_open(devminor_t minor)
{
        struct sock_ops * ops;
        struct socket * sock;
        int ret = OK;

        switch (minor) {
        case SOCK_TYPE_TCP:
                ops = &sock_tcp_ops;
                break;
        case SOCK_TYPE_UDP:
                ops = &sock_udp_ops;
                break;
        case SOCK_TYPE_IP:
                ops = &sock_raw_ip_ops;
                break;
        default:
                if (minor - SOCK_TYPES  < MAX_DEVS)
			return nic_open(minor - SOCK_TYPES);

                printf("LWIP unknown socket type %d\n", minor);
                return EINVAL;
        }

        sock = get_unused_sock();
        if (!sock) {
                printf("LWIP : no free socket\n");
                return EAGAIN;
        }

        sock->ops = ops;
        sock->select_ep = NONE;
        sock->recv_data_size = 0;

        if (sock->ops && sock->ops->open)
                ret = sock->ops->open(sock);

        if (ret == OK) {
                debug_print("new socket %ld", get_sock_num(sock));
                ret = get_sock_num(sock);
        } else {
                debug_print("failed %d", ret);
		/* FIXME: shouldn't sock be freed now? */
        }
	return ret;
}
Beispiel #16
0
static void raw_ip_op_close(struct socket * sock, __unused message * m)
{
	debug_print("socket num %ld", get_sock_num(sock));

	raw_ip_close(sock);

	sock_reply_close(sock, OK);
}
Beispiel #17
0
int raw_socket_input(struct pbuf * pbuf, struct nic * nic)
{
	struct socket * sock;
	struct pbuf * pbuf_new;

	if ((sock = nic->raw_socket) == NULL)
		return 0;

	debug_print("socket num : %ld", get_sock_num(sock));

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		int ret;
		/* we are resuming a suspended operation */
		ret = raw_receive(&sock->mess, pbuf);

		if (ret > 0) {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
			return 0;
		} else {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
		}
	}

	/* Do not enqueue more data than allowed */
	if (sock->recv_data_size > RAW_BUF_SIZE) {
		return 0;
	}

	/*
	 * nobody is waiting for the data or an error occured above, we enqueue
	 * the packet. We store a copy of this packet
	 */
	pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM);
	if (pbuf_new == NULL) {
		debug_print("LWIP : cannot allocated new pbuf\n");
		return 0;
	}

	if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) {
		debug_print("LWIP : cannot copy pbuf\n");
		return 0;
	}

	/*
	 * If we didn't managed to enqueue the packet we report it as not
	 * consumed
	 */
	if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) {
		pbuf_free(pbuf_new);
	}

	return 0;
}
Beispiel #18
0
static int raw_ip_op_open(struct socket * sock, __unused message * m)
{
	debug_print("socket num %ld", get_sock_num(sock));

	if (!(sock->buf = sock_alloc_buf(RAW_IP_BUF_SIZE))) {
		return ENOMEM;
	}
	sock->buf_size = RAW_IP_BUF_SIZE;

	return OK;
}
Beispiel #19
0
static void raw_ip_op_write(struct socket * sock, message * m, __unused int blk)
{
	int ret;
	struct pbuf * pbuf;
	struct ip_hdr * ip_hdr;

	debug_print("socket num %ld data size %d",
			get_sock_num(sock), m->COUNT);

	if (sock->pcb == NULL) {
		ret = EIO;
		goto write_err;
	}

	if ((size_t) m->COUNT > sock->buf_size) {
		ret = ENOMEM;
		goto write_err;
	}

	pbuf = pbuf_alloc(PBUF_LINK, m->COUNT, PBUF_RAM);
	if (!pbuf) {
		ret = ENOMEM;
		goto write_err;
	}

	if ((ret = copy_from_user(m->m_source, pbuf->payload, m->COUNT,
				(cp_grant_id_t) m->IO_GRANT, 0)) != OK) {
		pbuf_free(pbuf);
		goto write_err;
	}

	ip_hdr = (struct ip_hdr *) pbuf->payload;
	if (pbuf_header(pbuf, -IP_HLEN)) {
		pbuf_free(pbuf);
		ret = EIO;
		goto write_err;
	}

	if ((ret = raw_sendto((struct raw_pcb *)sock->pcb, pbuf,
				(ip_addr_t *) &ip_hdr->dest)) != OK) {
		debug_print("raw_sendto failed %d", ret);
		ret = EIO;
	} else
		ret = m->COUNT;
	

	pbuf_free(pbuf);
	
write_err:
	sock_reply(sock, ret);
}
Beispiel #20
0
static void tcp_op_get_cookie(struct socket * sock, message * m)
{
	tcp_cookie_t cookie;
	unsigned sock_num;

	assert(sizeof(cookie) >= sizeof(sock));

	sock_num = get_sock_num(sock);
	memcpy(&cookie, &sock_num, sizeof(sock_num));

	if (copy_to_user(m->m_source, &cookie, sizeof(sock),
			(cp_grant_id_t) m->IO_GRANT, 0) == OK)
		sock_reply(sock, OK);
	else
		sock_reply(sock, EFAULT);
}
Beispiel #21
0
static int tcp_op_open(struct socket * sock, __unused message * m)
{
	struct tcp_pcb * pcb;
	int ret;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	if (!(pcb = tcp_new()))
		return ENOMEM;
	debug_tcp_print("new tcp pcb %p\n", pcb);
	
	if ((ret = tcp_fill_new_socket(sock, pcb) != OK))
		tcp_abandon(pcb, 0);
	
	return ret;
}
Beispiel #22
0
static int udp_op_open(struct socket * sock, __unused message * m)
{
	struct udp_pcb * pcb;

	debug_udp_print("socket num %ld", get_sock_num(sock));

	if (!(pcb = udp_new()))
		return ENOMEM;

	sock->buf = NULL;
	sock->buf_size = 0;
	
	sock->pcb = pcb;
	
	return OK;
}
Beispiel #23
0
static int udp_op_close(struct socket * sock)
{
	debug_udp_print("socket num %ld", get_sock_num(sock));

	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, udp_recv_free);

	if (sock->pcb)
		udp_remove(sock->pcb);
	assert(sock->buf == NULL);

	/* mark it as unused */
	sock->ops = NULL;

	return OK;
}
Beispiel #24
0
static void nic_op_close(struct socket * sock, __unused message * m)
{
	struct nic * nic = (struct nic *)sock->data;

	debug_drv_print("socket %d", get_sock_num(sock));
	
	sock_dequeue_data_all(sock, raw_recv_free);
	sock->ops = NULL;

	if (nic->raw_socket == sock) {
		nic->raw_socket = NULL;
		debug_drv_print("no active raw sock at %s", nic->name);
	}

	sock_reply_close(sock, OK);
}
Beispiel #25
0
static void udp_op_close(struct socket * sock, __unused message * m)
{
	debug_udp_print("socket num %ld", get_sock_num(sock));

	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, udp_recv_free);

	if (sock->pcb)
		udp_remove(sock->pcb);
	assert(sock->buf == NULL);

	/* mark it as unused */
	sock->ops = NULL;

	sock_reply_close(sock, OK);
}
Beispiel #26
0
static void tcp_op_ioctl(struct socket * sock, message * m)
{
	if (!sock->pcb) {
		sock_reply(sock, ENOTCONN);
		return;
	}

	debug_tcp_print("socket num %ld req %c %d %d",
			get_sock_num(sock),
			(m->REQUEST >> 8) & 0xff,
			m->REQUEST & 0xff,
			(m->REQUEST >> 16) & _IOCPARM_MASK);
	
	switch (m->REQUEST) {
	case NWIOGTCPCONF:
		tcp_get_conf(sock, m);
		break;
	case NWIOSTCPCONF:
		tcp_set_conf(sock, m);
		break;
	case NWIOTCPCONN:
		tcp_op_connect(sock);
		break;
	case NWIOTCPLISTENQ:
		tcp_op_listen(sock, m);
		break;
	case NWIOGTCPCOOKIE:
		tcp_op_get_cookie(sock, m);
		break;
	case NWIOTCPACCEPTTO:
		tcp_op_accept(sock, m);
		break;
	case NWIOTCPSHUTDOWN:
		tcp_op_shutdown_tx(sock);
		break;
	case NWIOGTCPOPT:
		tcp_get_opt(sock, m);
		break;
	case NWIOSTCPOPT:
		tcp_set_opt(sock, m);
		break;
	default:
		sock_reply(sock, EBADIOCTL);
		return;
	}
}
Beispiel #27
0
static void nic_ioctl_set_ethopt(struct socket * sock,
				struct nic * nic,
				message * m)
{
	int err;
	nwio_ethopt_t ethopt;

	assert(nic);

	if (!sock) {
		send_reply(m, EINVAL);
		return;
	}

	debug_drv_print("device /dev/%s", nic->name);
	/*
	 * The device is not up yet, there is nothing to report or it is not
	 * an ethernet device
	 */
	if (!nic->netif.flags & NETIF_FLAG_UP ||
			!(nic->netif.flags & (NETIF_FLAG_ETHERNET |
				NETIF_FLAG_ETHARP))) {
		send_reply(m, ENODEV);
		return;
	}

	err = copy_from_user(m->m_source, &ethopt, sizeof(ethopt),
				(cp_grant_id_t) m->IO_GRANT, 0);
	if (err != OK)
		send_reply(m, err);

	/* we want to get data from this sock */
	if (ethopt.nweo_flags & NWEO_COPY) {
		if (nic->raw_socket) {
			send_reply(m, EBUSY);
			return;
		}

		nic->raw_socket = sock;
		debug_drv_print("active raw sock %d at %s",
				get_sock_num(sock), nic->name);
	}

	send_reply(m, OK);
}
Beispiel #28
0
static void tcp_op_shutdown_tx(struct socket * sock)
{
	err_t err;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	err = tcp_shutdown((struct tcp_pcb *) sock->pcb, 0, 1);

	switch (err) {
	case ERR_OK:
		sock_reply(sock, OK);
		break;
	case ERR_CONN:
		sock_reply(sock, ENOTCONN);
		break;
	default:
		sock_reply(sock, EGENERIC);
	}
}
Beispiel #29
0
static void tcp_set_opt(struct socket * sock, message * m)
{
	int err;
	nwio_tcpopt_t tcpopt;
	struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	assert(pcb);

	err = copy_from_user(m->m_source, &tcpopt, sizeof(tcpopt),
				(cp_grant_id_t) m->IO_GRANT, 0);

	if (err != OK)
		sock_reply(sock, err);

	/* FIXME : The userspace library does not use this */

	sock_reply(sock, OK);
}
Beispiel #30
0
static void tcp_set_conf(struct socket * sock, message * m)
{
	int err;
	nwio_tcpconf_t tconf;
	struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	assert(pcb);

	err = copy_from_user(m->m_source, &tconf, sizeof(tconf),
				(cp_grant_id_t) m->IO_GRANT, 0);

	if (err != OK)
		sock_reply(sock, err);

	debug_tcp_print("tconf.nwtc_flags = 0x%lx", tconf.nwtc_flags);
	debug_tcp_print("tconf.nwtc_remaddr = 0x%x",
				(unsigned int) tconf.nwtc_remaddr);
	debug_tcp_print("tconf.nwtc_remport = 0x%x", ntohs(tconf.nwtc_remport));
	debug_tcp_print("tconf.nwtc_locaddr = 0x%x",
				(unsigned int) tconf.nwtc_locaddr);
	debug_tcp_print("tconf.nwtc_locport = 0x%x", ntohs(tconf.nwtc_locport));

	sock->usr_flags = tconf.nwtc_flags;

	if (sock->usr_flags & NWTC_SET_RA)
		pcb->remote_ip.addr = tconf.nwtc_remaddr;
	if (sock->usr_flags & NWTC_SET_RP)
		pcb->remote_port = ntohs(tconf.nwtc_remport);

	if (sock->usr_flags & NWTC_LP_SET) {
		/* FIXME the user library can only bind to ANY anyway */
		if (tcp_bind(pcb, IP_ADDR_ANY, ntohs(tconf.nwtc_locport)) == ERR_USE) {
			sock_reply(sock, EADDRINUSE);
			return;
		}
	}
	
	sock_reply(sock, OK);
}