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*0082e6a5SNavdeep Parhar #include <sys/module.h> 18e68ff398SKip Macy #include <sys/systm.h> /* uprintf */ 19e68ff398SKip Macy #include <sys/errno.h> 20e68ff398SKip Macy #include <sys/param.h> /* defines used in kernel.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> 25*0082e6a5SNavdeep Parhar #include <sys/proc.h> 26*0082e6a5SNavdeep Parhar #include <sys/sysctl.h> 27*0082e6a5SNavdeep Parhar #include <machine/stdarg.h> 28e68ff398SKip Macy 29e68ff398SKip Macy #include "krping.h" 30e68ff398SKip Macy 31e68ff398SKip Macy #define BUFFERSIZE 512 32e68ff398SKip Macy 33*0082e6a5SNavdeep Parhar SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW, 0, "kernel rping module"); 34*0082e6a5SNavdeep Parhar 35*0082e6a5SNavdeep Parhar int krping_debug = 0; 36*0082e6a5SNavdeep Parhar SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , ""); 37*0082e6a5SNavdeep Parhar 38e68ff398SKip Macy /* Function prototypes */ 39e68ff398SKip Macy static d_open_t krping_open; 40e68ff398SKip Macy static d_close_t krping_close; 41e68ff398SKip Macy static d_read_t krping_read; 42e68ff398SKip Macy static d_write_t krping_write; 43e68ff398SKip Macy 44e68ff398SKip Macy /* Character device entry points */ 45e68ff398SKip Macy static struct cdevsw krping_cdevsw = { 46e68ff398SKip Macy .d_version = D_VERSION, 47e68ff398SKip Macy .d_open = krping_open, 48e68ff398SKip Macy .d_close = krping_close, 49e68ff398SKip Macy .d_read = krping_read, 50e68ff398SKip Macy .d_write = krping_write, 51e68ff398SKip Macy .d_name = "krping", 52e68ff398SKip Macy }; 53e68ff398SKip Macy 54e68ff398SKip Macy typedef struct s_krping { 55e68ff398SKip Macy char msg[BUFFERSIZE]; 56e68ff398SKip Macy int len; 57e68ff398SKip Macy } krping_t; 58e68ff398SKip Macy 59*0082e6a5SNavdeep Parhar struct stats_list_entry { 60*0082e6a5SNavdeep Parhar STAILQ_ENTRY(stats_list_entry) link; 61*0082e6a5SNavdeep Parhar struct krping_stats *stats; 62*0082e6a5SNavdeep Parhar }; 63*0082e6a5SNavdeep Parhar STAILQ_HEAD(stats_list, stats_list_entry); 64*0082e6a5SNavdeep Parhar 65e68ff398SKip Macy /* vars */ 66e68ff398SKip Macy static struct cdev *krping_dev; 67e68ff398SKip Macy 68e68ff398SKip Macy static int 69e68ff398SKip Macy krping_loader(struct module *m, int what, void *arg) 70e68ff398SKip Macy { 71e68ff398SKip Macy int err = 0; 72e68ff398SKip Macy 73e68ff398SKip Macy switch (what) { 74e68ff398SKip Macy case MOD_LOAD: /* kldload */ 75e68ff398SKip Macy krping_init(); 76e68ff398SKip Macy krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL, 77e68ff398SKip Macy 0600, "krping"); 78e68ff398SKip Macy printf("Krping device loaded.\n"); 79e68ff398SKip Macy break; 80e68ff398SKip Macy case MOD_UNLOAD: 81e68ff398SKip Macy destroy_dev(krping_dev); 82e68ff398SKip Macy printf("Krping device unloaded.\n"); 83e68ff398SKip Macy break; 84e68ff398SKip Macy default: 85e68ff398SKip Macy err = EOPNOTSUPP; 86e68ff398SKip Macy break; 87e68ff398SKip Macy } 88*0082e6a5SNavdeep Parhar 89*0082e6a5SNavdeep Parhar return (err); 90e68ff398SKip Macy } 91e68ff398SKip Macy 92e68ff398SKip Macy static int 93e68ff398SKip Macy krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p) 94e68ff398SKip Macy { 95*0082e6a5SNavdeep Parhar 96*0082e6a5SNavdeep Parhar return (0); 97e68ff398SKip Macy } 98e68ff398SKip Macy 99e68ff398SKip Macy static int 100e68ff398SKip Macy krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p) 101e68ff398SKip Macy { 102*0082e6a5SNavdeep Parhar 103e68ff398SKip Macy return 0; 104e68ff398SKip Macy } 105e68ff398SKip Macy 106*0082e6a5SNavdeep Parhar static void 107*0082e6a5SNavdeep Parhar krping_copy_stats(struct krping_stats *stats, void *arg) 108*0082e6a5SNavdeep Parhar { 109*0082e6a5SNavdeep Parhar struct stats_list_entry *s; 110*0082e6a5SNavdeep Parhar struct stats_list *list = arg; 111*0082e6a5SNavdeep Parhar 112*0082e6a5SNavdeep Parhar s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO); 113*0082e6a5SNavdeep Parhar if (s == NULL) 114*0082e6a5SNavdeep Parhar return; 115*0082e6a5SNavdeep Parhar if (stats != NULL) { 116*0082e6a5SNavdeep Parhar s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO); 117*0082e6a5SNavdeep Parhar if (s->stats == NULL) { 118*0082e6a5SNavdeep Parhar free(s, M_DEVBUF); 119*0082e6a5SNavdeep Parhar return; 120*0082e6a5SNavdeep Parhar } 121*0082e6a5SNavdeep Parhar *s->stats = *stats; 122*0082e6a5SNavdeep Parhar } 123*0082e6a5SNavdeep Parhar STAILQ_INSERT_TAIL(list, s, link); 124*0082e6a5SNavdeep Parhar } 125*0082e6a5SNavdeep Parhar 126e68ff398SKip Macy static int 127e68ff398SKip Macy krping_read(struct cdev *dev, struct uio *uio, int ioflag) 128e68ff398SKip Macy { 129e68ff398SKip Macy int num = 1; 130*0082e6a5SNavdeep Parhar struct stats_list list; 131*0082e6a5SNavdeep Parhar struct stats_list_entry *e; 132*0082e6a5SNavdeep Parhar 133*0082e6a5SNavdeep Parhar STAILQ_INIT(&list); 134*0082e6a5SNavdeep Parhar krping_walk_cb_list(krping_copy_stats, &list); 135*0082e6a5SNavdeep Parhar 136*0082e6a5SNavdeep Parhar if (STAILQ_EMPTY(&list)) 137*0082e6a5SNavdeep Parhar return (0); 138e68ff398SKip Macy 139e68ff398SKip Macy uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n", 140*0082e6a5SNavdeep Parhar "num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs", 141*0082e6a5SNavdeep Parhar "wr bytes", "wr msgs", "rd bytes", "rd msgs"); 142e68ff398SKip Macy 143*0082e6a5SNavdeep Parhar while (!STAILQ_EMPTY(&list)) { 144*0082e6a5SNavdeep Parhar e = STAILQ_FIRST(&list); 145*0082e6a5SNavdeep Parhar STAILQ_REMOVE_HEAD(&list, link); 146*0082e6a5SNavdeep Parhar if (e->stats == NULL) 147*0082e6a5SNavdeep Parhar uprintf("krping: %d listen\n", num); 148*0082e6a5SNavdeep Parhar else { 149*0082e6a5SNavdeep Parhar struct krping_stats *stats = e->stats; 150e68ff398SKip Macy 151*0082e6a5SNavdeep Parhar uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu " 152*0082e6a5SNavdeep Parhar "%10llu %10llu %10llu %10llu\n", num, stats->name, 153*0082e6a5SNavdeep Parhar stats->send_bytes, stats->send_msgs, 154*0082e6a5SNavdeep Parhar stats->recv_bytes, stats->recv_msgs, 155*0082e6a5SNavdeep Parhar stats->write_bytes, stats->write_msgs, 156*0082e6a5SNavdeep Parhar stats->read_bytes, stats->read_msgs); 157*0082e6a5SNavdeep Parhar free(stats, M_DEVBUF); 158e68ff398SKip Macy } 159*0082e6a5SNavdeep Parhar num++; 160*0082e6a5SNavdeep Parhar free(e, M_DEVBUF); 161e68ff398SKip Macy } 162*0082e6a5SNavdeep Parhar 163*0082e6a5SNavdeep Parhar return (0); 164e68ff398SKip Macy } 165e68ff398SKip Macy 166e68ff398SKip Macy static int 167e68ff398SKip Macy krping_write(struct cdev *dev, struct uio *uio, int ioflag) 168e68ff398SKip Macy { 169e68ff398SKip Macy int err = 0; 170e68ff398SKip Macy int amt; 171e68ff398SKip Macy int remain = BUFFERSIZE; 172e68ff398SKip Macy char *cp; 173e68ff398SKip Macy krping_t *krpingmsg; 174e68ff398SKip Macy 175e68ff398SKip Macy krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); 176e68ff398SKip Macy if (!krpingmsg) { 177e68ff398SKip Macy uprintf("Could not malloc mem!\n"); 178e68ff398SKip Macy return ENOMEM; 179e68ff398SKip Macy } 180e68ff398SKip Macy 181e68ff398SKip Macy cp = krpingmsg->msg; 182e68ff398SKip Macy while (uio->uio_resid) { 183e68ff398SKip Macy amt = MIN(uio->uio_resid, remain); 184e68ff398SKip Macy if (amt == 0) 185e68ff398SKip Macy break; 186e68ff398SKip Macy 187e68ff398SKip Macy /* Copy the string in from user memory to kernel memory */ 188e68ff398SKip Macy err = uiomove(cp, amt, uio); 189e68ff398SKip Macy if (err) { 190e68ff398SKip Macy uprintf("Write failed: bad address!\n"); 191e68ff398SKip Macy return err; 192e68ff398SKip Macy } 193e68ff398SKip Macy cp += amt; 194e68ff398SKip Macy remain -= amt; 195e68ff398SKip Macy } 196e68ff398SKip Macy 197e68ff398SKip Macy if (uio->uio_resid != 0) { 198e68ff398SKip Macy uprintf("Message too big. max size is %d!\n", BUFFERSIZE); 199e68ff398SKip Macy return EMSGSIZE; 200e68ff398SKip Macy } 201e68ff398SKip Macy 202e68ff398SKip Macy /* null terminate and remove the \n */ 203e68ff398SKip Macy cp--; 204e68ff398SKip Macy *cp = 0; 205e68ff398SKip Macy krpingmsg->len = (unsigned long)(cp - krpingmsg->msg); 206e68ff398SKip Macy uprintf("krping: write string = |%s|\n", krpingmsg->msg); 207*0082e6a5SNavdeep Parhar err = krping_doit(krpingmsg->msg, curproc); 208e68ff398SKip Macy free(krpingmsg, M_DEVBUF); 209e68ff398SKip Macy return(err); 210e68ff398SKip Macy } 211e68ff398SKip Macy 212*0082e6a5SNavdeep Parhar void 213*0082e6a5SNavdeep Parhar krping_printf(void *cookie, const char *fmt, ...) 214*0082e6a5SNavdeep Parhar { 215*0082e6a5SNavdeep Parhar va_list ap; 216*0082e6a5SNavdeep Parhar 217*0082e6a5SNavdeep Parhar va_start(ap, fmt); 218*0082e6a5SNavdeep Parhar vtprintf(cookie, -1, fmt, ap); 219*0082e6a5SNavdeep Parhar va_end(ap); 220*0082e6a5SNavdeep Parhar } 221*0082e6a5SNavdeep Parhar 222*0082e6a5SNavdeep Parhar int 223*0082e6a5SNavdeep Parhar krping_sigpending(void) 224*0082e6a5SNavdeep Parhar { 225*0082e6a5SNavdeep Parhar 226*0082e6a5SNavdeep Parhar return (SIGPENDING(curthread)); 227*0082e6a5SNavdeep Parhar } 228*0082e6a5SNavdeep Parhar 229e68ff398SKip Macy DEV_MODULE(krping, krping_loader, NULL); 230*0082e6a5SNavdeep Parhar MODULE_DEPEND(krping, ibcore, 1, 1, 1); 231