1e68ff398SKip Macy /*
2e68ff398SKip Macy * This code lifted from:
3e68ff398SKip Macy * Simple `echo' pseudo-device KLD
4e68ff398SKip Macy * Murray Stokely
5e68ff398SKip Macy * Converted to 5.X by Søren (Xride) Straarup
6e68ff398SKip Macy */
7e68ff398SKip Macy
8e68ff398SKip Macy /*
9e68ff398SKip Macy * /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
10e68ff398SKip Macy * /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
11e68ff398SKip Macy */
12e68ff398SKip Macy
13e68ff398SKip Macy #include <sys/cdefs.h>
14e68ff398SKip Macy __FBSDID("$FreeBSD$");
15e68ff398SKip Macy
16e68ff398SKip Macy #include <sys/types.h>
17*df38ada2SBjoern A. Zeeb #include <sys/param.h> /* defines used in kernel.h and module.h */
180082e6a5SNavdeep Parhar #include <sys/module.h>
19e68ff398SKip Macy #include <sys/systm.h> /* uprintf */
20e68ff398SKip Macy #include <sys/errno.h>
21e68ff398SKip Macy #include <sys/kernel.h> /* types used in module initialization */
22e68ff398SKip Macy #include <sys/conf.h> /* cdevsw struct */
23e68ff398SKip Macy #include <sys/uio.h> /* uio struct */
24e68ff398SKip Macy #include <sys/malloc.h>
250082e6a5SNavdeep Parhar #include <sys/proc.h>
260082e6a5SNavdeep Parhar #include <sys/sysctl.h>
270082e6a5SNavdeep Parhar #include <machine/stdarg.h>
28e68ff398SKip Macy
29e68ff398SKip Macy #include "krping.h"
30e68ff398SKip Macy
31e68ff398SKip Macy #define BUFFERSIZE 512
32e68ff398SKip Macy
337029da5cSPawel Biernacki SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
347029da5cSPawel Biernacki "kernel rping module");
350082e6a5SNavdeep Parhar
360082e6a5SNavdeep Parhar int krping_debug = 0;
370082e6a5SNavdeep Parhar SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");
380082e6a5SNavdeep Parhar
39e68ff398SKip Macy /* Function prototypes */
40e68ff398SKip Macy static d_open_t krping_open;
41e68ff398SKip Macy static d_close_t krping_close;
42e68ff398SKip Macy static d_read_t krping_read;
43e68ff398SKip Macy static d_write_t krping_write;
44e8f206ccSHans Petter Selasky static d_purge_t krping_purge;
45e68ff398SKip Macy
46e68ff398SKip Macy /* Character device entry points */
47e68ff398SKip Macy static struct cdevsw krping_cdevsw = {
48e68ff398SKip Macy .d_version = D_VERSION,
49e68ff398SKip Macy .d_open = krping_open,
50e68ff398SKip Macy .d_close = krping_close,
51e68ff398SKip Macy .d_read = krping_read,
52e68ff398SKip Macy .d_write = krping_write,
53e8f206ccSHans Petter Selasky .d_purge = krping_purge,
54e68ff398SKip Macy .d_name = "krping",
55e68ff398SKip Macy };
56e68ff398SKip Macy
57e68ff398SKip Macy typedef struct s_krping {
58e68ff398SKip Macy char msg[BUFFERSIZE];
59e68ff398SKip Macy int len;
60e68ff398SKip Macy } krping_t;
61e68ff398SKip Macy
620082e6a5SNavdeep Parhar struct stats_list_entry {
630082e6a5SNavdeep Parhar STAILQ_ENTRY(stats_list_entry) link;
640082e6a5SNavdeep Parhar struct krping_stats *stats;
650082e6a5SNavdeep Parhar };
660082e6a5SNavdeep Parhar STAILQ_HEAD(stats_list, stats_list_entry);
670082e6a5SNavdeep Parhar
68e68ff398SKip Macy /* vars */
69e68ff398SKip Macy static struct cdev *krping_dev;
70e68ff398SKip Macy
71e68ff398SKip Macy static int
krping_loader(struct module * m,int what,void * arg)72e68ff398SKip Macy krping_loader(struct module *m, int what, void *arg)
73e68ff398SKip Macy {
74e68ff398SKip Macy int err = 0;
75e68ff398SKip Macy
76e68ff398SKip Macy switch (what) {
77e68ff398SKip Macy case MOD_LOAD: /* kldload */
78e68ff398SKip Macy krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
79e68ff398SKip Macy 0600, "krping");
80e68ff398SKip Macy printf("Krping device loaded.\n");
81e68ff398SKip Macy break;
82e68ff398SKip Macy case MOD_UNLOAD:
83e68ff398SKip Macy destroy_dev(krping_dev);
84e68ff398SKip Macy printf("Krping device unloaded.\n");
85e68ff398SKip Macy break;
86e68ff398SKip Macy default:
87e68ff398SKip Macy err = EOPNOTSUPP;
88e68ff398SKip Macy break;
89e68ff398SKip Macy }
900082e6a5SNavdeep Parhar
910082e6a5SNavdeep Parhar return (err);
92e68ff398SKip Macy }
93e68ff398SKip Macy
94e68ff398SKip Macy static int
krping_open(struct cdev * dev,int oflags,int devtype,struct thread * p)95e68ff398SKip Macy krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
96e68ff398SKip Macy {
970082e6a5SNavdeep Parhar
980082e6a5SNavdeep Parhar return (0);
99e68ff398SKip Macy }
100e68ff398SKip Macy
101e68ff398SKip Macy static int
krping_close(struct cdev * dev,int fflag,int devtype,struct thread * p)102e68ff398SKip Macy krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
103e68ff398SKip Macy {
1040082e6a5SNavdeep Parhar
105e68ff398SKip Macy return 0;
106e68ff398SKip Macy }
107e68ff398SKip Macy
1080082e6a5SNavdeep Parhar static void
krping_copy_stats(struct krping_stats * stats,void * arg)1090082e6a5SNavdeep Parhar krping_copy_stats(struct krping_stats *stats, void *arg)
1100082e6a5SNavdeep Parhar {
1110082e6a5SNavdeep Parhar struct stats_list_entry *s;
1120082e6a5SNavdeep Parhar struct stats_list *list = arg;
1130082e6a5SNavdeep Parhar
1140082e6a5SNavdeep Parhar s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);
1150082e6a5SNavdeep Parhar if (s == NULL)
1160082e6a5SNavdeep Parhar return;
1170082e6a5SNavdeep Parhar if (stats != NULL) {
1180082e6a5SNavdeep Parhar s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);
1190082e6a5SNavdeep Parhar if (s->stats == NULL) {
1200082e6a5SNavdeep Parhar free(s, M_DEVBUF);
1210082e6a5SNavdeep Parhar return;
1220082e6a5SNavdeep Parhar }
1230082e6a5SNavdeep Parhar *s->stats = *stats;
1240082e6a5SNavdeep Parhar }
1250082e6a5SNavdeep Parhar STAILQ_INSERT_TAIL(list, s, link);
1260082e6a5SNavdeep Parhar }
1270082e6a5SNavdeep Parhar
128e68ff398SKip Macy static int
krping_read(struct cdev * dev,struct uio * uio,int ioflag)129e68ff398SKip Macy krping_read(struct cdev *dev, struct uio *uio, int ioflag)
130e68ff398SKip Macy {
131e68ff398SKip Macy int num = 1;
1320082e6a5SNavdeep Parhar struct stats_list list;
1330082e6a5SNavdeep Parhar struct stats_list_entry *e;
1340082e6a5SNavdeep Parhar
1350082e6a5SNavdeep Parhar STAILQ_INIT(&list);
1360082e6a5SNavdeep Parhar krping_walk_cb_list(krping_copy_stats, &list);
1370082e6a5SNavdeep Parhar
1380082e6a5SNavdeep Parhar if (STAILQ_EMPTY(&list))
1390082e6a5SNavdeep Parhar return (0);
140e68ff398SKip Macy
141e68ff398SKip Macy uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
1420082e6a5SNavdeep Parhar "num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",
1430082e6a5SNavdeep Parhar "wr bytes", "wr msgs", "rd bytes", "rd msgs");
144e68ff398SKip Macy
1450082e6a5SNavdeep Parhar while (!STAILQ_EMPTY(&list)) {
1460082e6a5SNavdeep Parhar e = STAILQ_FIRST(&list);
1470082e6a5SNavdeep Parhar STAILQ_REMOVE_HEAD(&list, link);
1480082e6a5SNavdeep Parhar if (e->stats == NULL)
1490082e6a5SNavdeep Parhar uprintf("krping: %d listen\n", num);
1500082e6a5SNavdeep Parhar else {
1510082e6a5SNavdeep Parhar struct krping_stats *stats = e->stats;
152e68ff398SKip Macy
1530082e6a5SNavdeep Parhar uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "
1540082e6a5SNavdeep Parhar "%10llu %10llu %10llu %10llu\n", num, stats->name,
1550082e6a5SNavdeep Parhar stats->send_bytes, stats->send_msgs,
1560082e6a5SNavdeep Parhar stats->recv_bytes, stats->recv_msgs,
1570082e6a5SNavdeep Parhar stats->write_bytes, stats->write_msgs,
1580082e6a5SNavdeep Parhar stats->read_bytes, stats->read_msgs);
1590082e6a5SNavdeep Parhar free(stats, M_DEVBUF);
160e68ff398SKip Macy }
1610082e6a5SNavdeep Parhar num++;
1620082e6a5SNavdeep Parhar free(e, M_DEVBUF);
163e68ff398SKip Macy }
1640082e6a5SNavdeep Parhar
1650082e6a5SNavdeep Parhar return (0);
166e68ff398SKip Macy }
167e68ff398SKip Macy
168e68ff398SKip Macy static int
krping_write(struct cdev * dev,struct uio * uio,int ioflag)169e68ff398SKip Macy krping_write(struct cdev *dev, struct uio *uio, int ioflag)
170e68ff398SKip Macy {
171e68ff398SKip Macy int err = 0;
172e68ff398SKip Macy int amt;
173e68ff398SKip Macy int remain = BUFFERSIZE;
174e68ff398SKip Macy char *cp;
175e68ff398SKip Macy krping_t *krpingmsg;
176e68ff398SKip Macy
177e68ff398SKip Macy krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK | M_ZERO);
178e68ff398SKip Macy cp = krpingmsg->msg;
179e68ff398SKip Macy while (uio->uio_resid) {
180e68ff398SKip Macy amt = MIN(uio->uio_resid, remain);
181e68ff398SKip Macy if (amt == 0)
182e68ff398SKip Macy break;
183e68ff398SKip Macy
184e68ff398SKip Macy /* Copy the string in from user memory to kernel memory */
185e68ff398SKip Macy err = uiomove(cp, amt, uio);
186e68ff398SKip Macy if (err) {
187e68ff398SKip Macy uprintf("Write failed: bad address!\n");
18830061808SSlava Shwartsman goto done;
189e68ff398SKip Macy }
190e68ff398SKip Macy cp += amt;
191e68ff398SKip Macy remain -= amt;
192e68ff398SKip Macy }
193e68ff398SKip Macy
194e68ff398SKip Macy if (uio->uio_resid != 0) {
195e68ff398SKip Macy uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
19630061808SSlava Shwartsman err = EMSGSIZE;
19730061808SSlava Shwartsman goto done;
198e68ff398SKip Macy }
199e68ff398SKip Macy
200e68ff398SKip Macy /* null terminate and remove the \n */
201e68ff398SKip Macy cp--;
202e68ff398SKip Macy *cp = 0;
203e68ff398SKip Macy krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
204e68ff398SKip Macy uprintf("krping: write string = |%s|\n", krpingmsg->msg);
205478d3005SHans Petter Selasky err = krping_doit(krpingmsg->msg);
20630061808SSlava Shwartsman done:
207e68ff398SKip Macy free(krpingmsg, M_DEVBUF);
208e68ff398SKip Macy return(err);
209e68ff398SKip Macy }
210e68ff398SKip Macy
211e8f206ccSHans Petter Selasky static void
krping_purge(struct cdev * dev __unused)212e8f206ccSHans Petter Selasky krping_purge(struct cdev *dev __unused)
213e8f206ccSHans Petter Selasky {
214e8f206ccSHans Petter Selasky
215e8f206ccSHans Petter Selasky krping_cancel_all();
216e8f206ccSHans Petter Selasky }
217e8f206ccSHans Petter Selasky
2180082e6a5SNavdeep Parhar int
krping_sigpending(void)2190082e6a5SNavdeep Parhar krping_sigpending(void)
2200082e6a5SNavdeep Parhar {
2210082e6a5SNavdeep Parhar
2220082e6a5SNavdeep Parhar return (SIGPENDING(curthread));
2230082e6a5SNavdeep Parhar }
2240082e6a5SNavdeep Parhar
225e68ff398SKip Macy DEV_MODULE(krping, krping_loader, NULL);
2260082e6a5SNavdeep Parhar MODULE_DEPEND(krping, ibcore, 1, 1, 1);
227