krping_dev.c revision 237263
1/*
2 * This code lifted from:
3 * 	Simple `echo' pseudo-device KLD
4 * 	Murray Stokely
5 * 	Converted to 5.X by S��ren (Xride) Straarup
6 */
7
8/*
9 * /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
10 * /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
11 */
12
13#include <sys/cdefs.h>
14__FBSDID("$FreeBSD: head/sys/contrib/rdma/krping/krping_dev.c 237263 2012-06-19 07:34:13Z np $");
15
16#include <sys/types.h>
17#include <sys/systm.h>  /* uprintf */
18#include <sys/errno.h>
19#include <sys/param.h>  /* defines used in kernel.h */
20#include <sys/kernel.h> /* types used in module initialization */
21#include <sys/conf.h>   /* cdevsw struct */
22#include <sys/uio.h>    /* uio struct */
23#include <sys/malloc.h>
24
25#include "krping.h"
26
27#define BUFFERSIZE 512
28
29/* Function prototypes */
30static d_open_t      krping_open;
31static d_close_t     krping_close;
32static d_read_t      krping_read;
33static d_write_t     krping_write;
34
35/* Character device entry points */
36static struct cdevsw krping_cdevsw = {
37	.d_version = D_VERSION,
38	.d_open = krping_open,
39	.d_close = krping_close,
40	.d_read = krping_read,
41	.d_write = krping_write,
42	.d_name = "krping",
43};
44
45typedef struct s_krping {
46	char msg[BUFFERSIZE];
47	int len;
48} krping_t;
49
50/* vars */
51static struct cdev *krping_dev;
52
53#undef MODULE_VERSION
54#include <sys/module.h>
55
56static int
57krping_loader(struct module *m, int what, void *arg)
58{
59	int err = 0;
60
61	switch (what) {
62	case MOD_LOAD:                /* kldload */
63		krping_init();
64		krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
65					0600, "krping");
66		printf("Krping device loaded.\n");
67		break;
68	case MOD_UNLOAD:
69		destroy_dev(krping_dev);
70		printf("Krping device unloaded.\n");
71		break;
72	default:
73		err = EOPNOTSUPP;
74		break;
75	}
76	return err;
77}
78
79static int
80krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
81{
82	int err = 0;
83	return err;
84}
85
86static int
87krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
88{
89	return 0;
90}
91
92static int
93krping_read(struct cdev *dev, struct uio *uio, int ioflag)
94{
95	struct krping_cb *cb, *cb2;
96	int num=1;
97	struct krping_cb_list copy_cbs;
98
99	uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
100		"num", "device", "snd bytes", "snd msgs", "rcv bytes",
101		"rcv msgs", "wr bytes", "wr msgs", "rd bytes", "rd msgs");
102	TAILQ_INIT(&copy_cbs);
103
104	mtx_lock(&krping_mutex);
105	TAILQ_FOREACH(cb, &krping_cbs, list) {
106		cb2 = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT|M_ZERO);
107		if (!cb2)
108			break;
109		bcopy(cb, cb2, sizeof(*cb));
110		TAILQ_INSERT_TAIL(&copy_cbs, cb2, list);
111	}
112	mtx_unlock(&krping_mutex);
113
114	while (!TAILQ_EMPTY(&copy_cbs)) {
115
116		cb = TAILQ_FIRST(&copy_cbs);
117		TAILQ_REMOVE(&copy_cbs, cb, list);
118		if (cb->pd) {
119			uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n",
120			     num++, cb->pd->device->name, cb->stats.send_bytes,
121			     cb->stats.send_msgs, cb->stats.recv_bytes,
122			     cb->stats.recv_msgs, cb->stats.write_bytes,
123			     cb->stats.write_msgs,
124			     cb->stats.read_bytes,
125			     cb->stats.read_msgs);
126		} else {
127			uprintf("krping: %d listen\n", num++);
128		}
129		free(cb, M_DEVBUF);
130	}
131	return 0;
132}
133
134static int
135krping_write(struct cdev *dev, struct uio *uio, int ioflag)
136{
137	int err = 0;
138	int amt;
139	int remain = BUFFERSIZE;
140	char *cp;
141	krping_t *krpingmsg;
142
143	krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
144	if (!krpingmsg) {
145		uprintf("Could not malloc mem!\n");
146		return ENOMEM;
147	}
148
149	cp = krpingmsg->msg;
150	while (uio->uio_resid) {
151		amt = MIN(uio->uio_resid, remain);
152		if (amt == 0)
153			break;
154
155		/* Copy the string in from user memory to kernel memory */
156		err = uiomove(cp, amt, uio);
157		if (err) {
158			uprintf("Write failed: bad address!\n");
159			return err;
160		}
161		cp += amt;
162		remain -= amt;
163	}
164
165	if (uio->uio_resid != 0) {
166		uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
167		return EMSGSIZE;
168	}
169
170	/* null terminate and remove the \n */
171	cp--;
172	*cp = 0;
173	krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
174	uprintf("krping: write string = |%s|\n", krpingmsg->msg);
175	err = krping_doit(krpingmsg->msg);
176	free(krpingmsg, M_DEVBUF);
177	return(err);
178}
179
180DEV_MODULE(krping,krping_loader,NULL);
181