Example #1
0
int cpt_dump_link(struct cpt_context * ctx)
{
	struct net *net = get_exec_env()->ve_netns;
	struct net_device *dev;

	cpt_open_section(ctx, CPT_SECT_NET_DEVICE);
	for_each_netdev(net, dev) {
		struct cpt_netdev_image v;
		struct cpt_hwaddr_image hw;
		loff_t saved_obj;

		if (dev->netdev_ops->ndo_cpt == NULL) {
			eprintk_ctx("unsupported netdev %s\n", dev->name);
			cpt_close_section(ctx);
			return -EBUSY;
		}

		cpt_open_object(NULL, ctx);

		v.cpt_next = CPT_NULL;
		v.cpt_object = CPT_OBJ_NET_DEVICE;
		v.cpt_hdrlen = sizeof(v);
		v.cpt_content = CPT_CONTENT_ARRAY;

		v.cpt_index = dev->ifindex;
		v.cpt_flags = dev->flags;
		memcpy(v.cpt_name, dev->name, IFNAMSIZ);
		ctx->write(&v, sizeof(v), ctx);

		cpt_push_object(&saved_obj, ctx);

		cpt_open_object(NULL, ctx);
		dev->netdev_ops->ndo_cpt(dev, &cpt_ops, ctx);

		/* Dump hardware address */
		cpt_open_object(NULL, ctx);
		hw.cpt_next = CPT_NULL;
		hw.cpt_object = CPT_OBJ_NET_HWADDR;
		hw.cpt_hdrlen = sizeof(hw);
		hw.cpt_content = CPT_CONTENT_VOID;

		if (dev->dev_addrs.count != 1) {
			eprintk_ctx("multiple hwaddrs on %s\n", dev->name);
			return -EINVAL;
		}

		BUILD_BUG_ON(sizeof(hw.cpt_dev_addr) != MAX_ADDR_LEN);
		memcpy(hw.cpt_dev_addr, dev->dev_addr, sizeof(hw.cpt_dev_addr));
		ctx->write(&hw, sizeof(hw), ctx);
		cpt_close_object(ctx);
		
		cpt_dump_netstats(dev, ctx);

		cpt_pop_object(&saved_obj, ctx);

		cpt_close_object(ctx);
	}
	cpt_close_section(ctx);
	return 0;
}
Example #2
0
int cpt_open_object(cpt_object_t *obj, struct cpt_context *ctx)
{
	if (ctx->file == NULL)
		return 0;

	cpt_close_object(ctx);

	ctx->current_object = ctx->file->f_pos;
	if (obj)
		cpt_obj_setpos(obj, ctx->current_object, ctx);

	return 0;
}
Example #3
0
static void cpt_dump_netstats(struct net_device *dev, struct cpt_context * ctx)
{
	struct cpt_netstats_image *n;
	struct net_device_stats *stats;

	if (!dev->netdev_ops->ndo_get_stats)
		return;

	n = cpt_get_buf(ctx);
	stats = dev->netdev_ops->ndo_get_stats(dev);
	cpt_open_object(NULL, ctx);

	n->cpt_next = CPT_NULL;
	n->cpt_object = CPT_OBJ_NET_STATS;
	n->cpt_hdrlen = sizeof(*n);
	n->cpt_content = CPT_CONTENT_VOID;

	n->cpt_rx_packets = stats->rx_packets;
	n->cpt_tx_packets = stats->tx_packets;
	n->cpt_rx_bytes = stats->rx_bytes;
	n->cpt_tx_bytes = stats->tx_bytes;
	n->cpt_rx_errors = stats->rx_errors;
	n->cpt_tx_errors = stats->tx_errors;
	n->cpt_rx_dropped = stats->rx_dropped;
	n->cpt_tx_dropped = stats->tx_dropped;
	n->cpt_multicast = stats->multicast;
	n->cpt_collisions = stats->collisions;
	n->cpt_rx_length_errors = stats->rx_length_errors;
	n->cpt_rx_over_errors = stats->rx_over_errors;
	n->cpt_rx_crc_errors = stats->rx_crc_errors;
	n->cpt_rx_frame_errors = stats->rx_frame_errors;
	n->cpt_rx_fifo_errors = stats->rx_fifo_errors;
	n->cpt_rx_missed_errors = stats->rx_missed_errors;
	n->cpt_tx_aborted_errors = stats->tx_aborted_errors;
	n->cpt_tx_carrier_errors = stats->tx_carrier_errors;
	n->cpt_tx_fifo_errors = stats->tx_fifo_errors;
	n->cpt_tx_heartbeat_errors = stats->tx_heartbeat_errors;
	n->cpt_tx_window_errors = stats->tx_window_errors;
	n->cpt_rx_compressed = stats->rx_compressed;
	n->cpt_tx_compressed = stats->tx_compressed;

	ctx->write(n, sizeof(*n), ctx);
	cpt_close_object(ctx);
	cpt_release_buf(ctx);
	return;
}
Example #4
0
static void cpt_pop(loff_t *p, struct cpt_context *ctx)
{
	cpt_close_object(ctx);
	cpt_pop_object(p, ctx);
}
Example #5
0
static int cpt_dump_route(struct cpt_context * ctx)
{
	int err;
	struct socket *sock;
	struct msghdr msg;
	struct iovec iov;
	struct {
		struct nlmsghdr nlh;
		struct rtgenmsg g;
	} req;
	struct sockaddr_nl nladdr;
	struct cpt_object_hdr v;
	mm_segment_t oldfs;
	char *pg;

	err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock);
	if (err)
		return err;

	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;

	req.nlh.nlmsg_len = sizeof(req);
	req.nlh.nlmsg_type = RTM_GETROUTE;
	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
	req.nlh.nlmsg_pid = 0;
	req.g.rtgen_family = AF_INET;

	iov.iov_base=&req;
	iov.iov_len=sizeof(req);
	msg.msg_name=&nladdr;
	msg.msg_namelen=sizeof(nladdr);
	msg.msg_iov=&iov;
	msg.msg_iovlen=1;
	msg.msg_control=NULL;
	msg.msg_controllen=0;
	msg.msg_flags=MSG_DONTWAIT;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	err = sock_sendmsg(sock, &msg, sizeof(req));
	set_fs(oldfs);

	if (err < 0)
		goto out_sock;

	pg = (char*)__get_free_page(GFP_KERNEL);
	if (pg == NULL) {
		err = -ENOMEM;
		goto out_sock;
	}

	cpt_open_section(ctx, CPT_SECT_NET_ROUTE);
	cpt_open_object(NULL, ctx);
	v.cpt_next = CPT_NULL;
	v.cpt_object = CPT_OBJ_NET_ROUTE;
	v.cpt_hdrlen = sizeof(v);
	v.cpt_content = CPT_CONTENT_NLMARRAY;

	ctx->write(&v, sizeof(v), ctx);

#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
restart:
#endif
	for (;;) {
		struct nlmsghdr *h;

		iov.iov_base = pg;
		iov.iov_len = PAGE_SIZE;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT);
		set_fs(oldfs);

		if (err < 0)
			goto out_sock_pg;
		if (msg.msg_flags & MSG_TRUNC) {
			err = -ENOBUFS;
			goto out_sock_pg;
		}

		h = (struct nlmsghdr*)pg;
		while (NLMSG_OK(h, err)) {
			if (h->nlmsg_type == NLMSG_DONE) {
				err = 0;
				goto done;
			}
			if (h->nlmsg_type == NLMSG_ERROR) {
				struct nlmsgerr *errm = (struct nlmsgerr*)NLMSG_DATA(h);
				err = errm->error;
				eprintk_ctx("NLMSG error: %d\n", errm->error);
				goto done;
			}
			if (h->nlmsg_type != RTM_NEWROUTE) {
				eprintk_ctx("NLMSG: %d\n", h->nlmsg_type);
				err = -EINVAL;
				goto done;
			}
			ctx->write(h, NLMSG_ALIGN(h->nlmsg_len), ctx);
			h = NLMSG_NEXT(h, err);
		}
		if (err) {
			eprintk_ctx("!!!Remnant of size %d %d %d\n", err, h->nlmsg_len, h->nlmsg_type);
			err = -EINVAL;
			break;
		}
	}
done:
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
	if (!err && req.g.rtgen_family == AF_INET) {
		req.g.rtgen_family = AF_INET6;
		iov.iov_base=&req;
		iov.iov_len=sizeof(req);
		msg.msg_name=&nladdr;
		msg.msg_namelen=sizeof(nladdr);
		msg.msg_iov=&iov;
		msg.msg_iovlen=1;
		msg.msg_control=NULL;
		msg.msg_controllen=0;
		msg.msg_flags=MSG_DONTWAIT;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_sendmsg(sock, &msg, sizeof(req));
		set_fs(oldfs);

		if (err > 0)
			goto restart;
	}
#endif
	ctx->align(ctx);
	cpt_close_object(ctx);
	cpt_close_section(ctx);

out_sock_pg:
	free_page((unsigned long)pg);
out_sock:
	sock_release(sock);
	return err;
}
Example #6
0
int cpt_dump_ifaddr(struct cpt_context * ctx)
{
	struct net *net = get_exec_env()->ve_netns;
	struct net_device *dev;

	cpt_open_section(ctx, CPT_SECT_NET_IFADDR);
	for_each_netdev(net, dev) {
		struct in_device *idev = in_dev_get(dev);
		struct in_ifaddr *ifa;

		if (!idev)
			continue;

		for (ifa = idev->ifa_list; ifa; ifa = ifa->ifa_next) {
			struct cpt_ifaddr_image v;
			cpt_open_object(NULL, ctx);

			v.cpt_next = CPT_NULL;
			v.cpt_object = CPT_OBJ_NET_IFADDR;
			v.cpt_hdrlen = sizeof(v);
			v.cpt_content = CPT_CONTENT_VOID;

			v.cpt_index = dev->ifindex;
			v.cpt_family = AF_INET;
			v.cpt_masklen = ifa->ifa_prefixlen;
			v.cpt_flags = ifa->ifa_flags;
			v.cpt_scope = ifa->ifa_scope;
			memset(&v.cpt_address, 0, sizeof(v.cpt_address));
			memset(&v.cpt_peer, 0, sizeof(v.cpt_peer));
			memset(&v.cpt_broadcast, 0, sizeof(v.cpt_broadcast));
			v.cpt_address[0] = ifa->ifa_local;
			v.cpt_peer[0] = ifa->ifa_address;
			v.cpt_broadcast[0] = ifa->ifa_broadcast;
			memcpy(v.cpt_label, ifa->ifa_label, IFNAMSIZ);
			ctx->write(&v, sizeof(v), ctx);
			cpt_close_object(ctx);
		}
		in_dev_put(idev);
	}
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
	for_each_netdev(net, dev) {
		struct inet6_dev *idev = in6_dev_get(dev);
		struct inet6_ifaddr *ifa;

		if (!idev)
			continue;

		for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
			struct cpt_ifaddr_image v;

			if (dev == net->loopback_dev &&
			    ifa->prefix_len == 128 &&
			    ifa->addr.s6_addr32[0] == 0 &&
			    ifa->addr.s6_addr32[1] == 0 &&
			    ifa->addr.s6_addr32[2] == 0 &&
			    ifa->addr.s6_addr32[3] == htonl(1))
				continue;

			cpt_open_object(NULL, ctx);

			v.cpt_next = CPT_NULL;
			v.cpt_object = CPT_OBJ_NET_IFADDR;
			v.cpt_hdrlen = sizeof(v);
			v.cpt_content = CPT_CONTENT_VOID;

			v.cpt_index = dev->ifindex;
			v.cpt_family = AF_INET6;
			v.cpt_masklen = ifa->prefix_len;
			v.cpt_flags = ifa->flags;
			v.cpt_scope = ifa->scope;
			v.cpt_valid_lft = ifa->valid_lft;
			v.cpt_prefered_lft = ifa->prefered_lft;
			memcpy(&v.cpt_address, &ifa->addr, 16);
			memcpy(&v.cpt_peer, &ifa->addr, 16);
			memset(&v.cpt_broadcast, 0, sizeof(v.cpt_broadcast));
			memcpy(v.cpt_label, dev->name, IFNAMSIZ);
			ctx->write(&v, sizeof(v), ctx);
			cpt_close_object(ctx);
		}
		in6_dev_put(idev);
	}
#endif
	cpt_close_section(ctx);
	return 0;
}
Example #7
0
int cpt_dump_tty(cpt_object_t *obj, struct cpt_context *ctx)
{
	struct tty_struct *tty = obj->o_obj;
	struct cpt_tty_image *v;

	if (tty->link) {
		if (lookup_cpt_object(CPT_OBJ_TTY, tty->link, ctx) == NULL) {
			eprintk_ctx("orphan pty %s %d\n", tty->name, tty->driver->subtype == PTY_TYPE_SLAVE);
			return -EINVAL;
		}
		if (tty->link->link != tty) {
			eprintk_ctx("bad pty pair\n");
			return -EINVAL;
		}
		if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
		    tty->driver->subtype == PTY_TYPE_SLAVE &&
		    tty->link->count)
			obj->o_count++;
	}
	if (obj->o_count != tty->count) {
		eprintk_ctx("tty %s is referenced outside %d %d\n", tty->name, obj->o_count, tty->count);
		return -EBUSY;
	}

	cpt_open_object(obj, ctx);

	v = cpt_get_buf(ctx);
	v->cpt_next = -1;
	v->cpt_object = CPT_OBJ_TTY;
	v->cpt_hdrlen = sizeof(*v);
	v->cpt_content = CPT_CONTENT_ARRAY;

	v->cpt_index = tty->index;
	v->cpt_link = -1;
	if (tty->link)
		v->cpt_link = tty->link->index;
	v->cpt_drv_type = tty->driver->type;
	v->cpt_drv_subtype = tty->driver->subtype;
	v->cpt_drv_flags = tty->driver->flags;
	v->cpt_packet = tty->packet;
	v->cpt_stopped = tty->stopped;
	v->cpt_hw_stopped = tty->hw_stopped;
	v->cpt_flow_stopped = tty->flow_stopped;
	v->cpt_flags = tty->flags;
	v->cpt_ctrl_status = tty->ctrl_status;
	v->cpt_canon_data = tty->canon_data;
	v->cpt_canon_head = tty->canon_head - tty->read_tail;
	v->cpt_canon_column = tty->canon_column;
	v->cpt_column = tty->column;
	v->cpt_erasing = tty->erasing;
	v->cpt_lnext = tty->lnext;
	v->cpt_icanon = tty->icanon;
	v->cpt_raw = tty->raw;
	v->cpt_real_raw = tty->real_raw;
	v->cpt_closing = tty->closing;
	v->cpt_minimum_to_wake = tty->minimum_to_wake;
	v->cpt_pgrp = 0;
	if (tty->pgrp) {
		v->cpt_pgrp = pid_vnr(tty->pgrp);
		if ((int)v->cpt_pgrp < 0) {
			dprintk_ctx("cannot map tty->pgrp %d -> %d\n", pid_vnr(tty->pgrp), (int)v->cpt_pgrp);
			v->cpt_pgrp = -1;
		}
	}
	v->cpt_session = 0;
	if (tty->session) {
		v->cpt_session = pid_vnr(tty->session);
		if ((int)v->cpt_session < 0) {
			eprintk_ctx("cannot map tty->session %d -> %d\n", pid_nr(tty->session), (int)v->cpt_session);
			cpt_release_buf(ctx);
			return -EINVAL;
		}
	}
	memcpy(v->cpt_name, tty->name, 64);
	v->cpt_ws_row = tty->winsize.ws_row;
	v->cpt_ws_col = tty->winsize.ws_col;
	v->cpt_ws_prow = tty->winsize.ws_ypixel;
	v->cpt_ws_pcol = tty->winsize.ws_xpixel;
	if (tty->termios == NULL) {
		eprintk_ctx("NULL termios");
		cpt_release_buf(ctx);
		return -EINVAL;
	}
	v->cpt_c_line = tty->termios->c_line;
	v->cpt_c_iflag = tty->termios->c_iflag;
	v->cpt_c_oflag = tty->termios->c_oflag;
	v->cpt_c_cflag = tty->termios->c_cflag;
	v->cpt_c_lflag = tty->termios->c_lflag;
	memcpy(v->cpt_c_cc, tty->termios->c_cc, NCCS);
	if (NCCS < 32)
		memset(v->cpt_c_cc + NCCS, 255, 32 - NCCS);
	memcpy(v->cpt_read_flags, tty->read_flags, sizeof(v->cpt_read_flags));

	ctx->write(v, sizeof(*v), ctx);
	cpt_release_buf(ctx);

	if (tty->read_buf && tty->read_cnt) {
		struct cpt_obj_bits *v = cpt_get_buf(ctx);
		loff_t saved_pos;

		cpt_push_object(&saved_pos, ctx);
		cpt_open_object(NULL, ctx);
		v->cpt_next = CPT_NULL;
		v->cpt_object = CPT_OBJ_BITS;
		v->cpt_hdrlen = sizeof(*v);
		v->cpt_content = CPT_CONTENT_DATA;
		v->cpt_size = tty->read_cnt;
		ctx->write(v, sizeof(*v), ctx);
		cpt_release_buf(ctx);

		if (tty->read_cnt) {
			int n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail);
			ctx->write(tty->read_buf + tty->read_tail, n, ctx);
			if (tty->read_cnt > n)
				ctx->write(tty->read_buf, tty->read_cnt-n, ctx);
			ctx->align(ctx);
		}

		cpt_close_object(ctx);
		cpt_pop_object(&saved_pos, ctx);
	}

	cpt_close_object(ctx);

	return 0;
}