1178784Skmacy/* 2256829Snp * This code lifted from: 3178784Skmacy * Simple `echo' pseudo-device KLD 4178784Skmacy * Murray Stokely 5178784Skmacy * Converted to 5.X by S��ren (Xride) Straarup 6178784Skmacy */ 7178784Skmacy 8178784Skmacy/* 9256829Snp * /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping 10256829Snp * /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping 11178784Skmacy */ 12178784Skmacy 13178784Skmacy#include <sys/cdefs.h> 14178784Skmacy__FBSDID("$FreeBSD$"); 15178784Skmacy 16178784Skmacy#include <sys/types.h> 17256829Snp#include <sys/module.h> 18178784Skmacy#include <sys/systm.h> /* uprintf */ 19178784Skmacy#include <sys/errno.h> 20178784Skmacy#include <sys/param.h> /* defines used in kernel.h */ 21178784Skmacy#include <sys/kernel.h> /* types used in module initialization */ 22178784Skmacy#include <sys/conf.h> /* cdevsw struct */ 23178784Skmacy#include <sys/uio.h> /* uio struct */ 24178784Skmacy#include <sys/malloc.h> 25256829Snp#include <sys/proc.h> 26256829Snp#include <sys/sysctl.h> 27256829Snp#include <machine/stdarg.h> 28178784Skmacy 29178784Skmacy#include "krping.h" 30178784Skmacy 31178784Skmacy#define BUFFERSIZE 512 32178784Skmacy 33256829SnpSYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW, 0, "kernel rping module"); 34256829Snp 35256829Snpint krping_debug = 0; 36256829SnpSYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , ""); 37256829Snp 38178784Skmacy/* Function prototypes */ 39178784Skmacystatic d_open_t krping_open; 40178784Skmacystatic d_close_t krping_close; 41178784Skmacystatic d_read_t krping_read; 42178784Skmacystatic d_write_t krping_write; 43178784Skmacy 44178784Skmacy/* Character device entry points */ 45178784Skmacystatic struct cdevsw krping_cdevsw = { 46178784Skmacy .d_version = D_VERSION, 47178784Skmacy .d_open = krping_open, 48178784Skmacy .d_close = krping_close, 49178784Skmacy .d_read = krping_read, 50178784Skmacy .d_write = krping_write, 51178784Skmacy .d_name = "krping", 52178784Skmacy}; 53178784Skmacy 54178784Skmacytypedef struct s_krping { 55178784Skmacy char msg[BUFFERSIZE]; 56178784Skmacy int len; 57178784Skmacy} krping_t; 58178784Skmacy 59256829Snpstruct stats_list_entry { 60256829Snp STAILQ_ENTRY(stats_list_entry) link; 61256829Snp struct krping_stats *stats; 62256829Snp}; 63256829SnpSTAILQ_HEAD(stats_list, stats_list_entry); 64256829Snp 65178784Skmacy/* vars */ 66178784Skmacystatic struct cdev *krping_dev; 67178784Skmacy 68178784Skmacystatic int 69178784Skmacykrping_loader(struct module *m, int what, void *arg) 70178784Skmacy{ 71178784Skmacy int err = 0; 72178784Skmacy 73178784Skmacy switch (what) { 74178784Skmacy case MOD_LOAD: /* kldload */ 75178784Skmacy krping_init(); 76256829Snp krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL, 77178784Skmacy 0600, "krping"); 78178784Skmacy printf("Krping device loaded.\n"); 79178784Skmacy break; 80178784Skmacy case MOD_UNLOAD: 81178784Skmacy destroy_dev(krping_dev); 82178784Skmacy printf("Krping device unloaded.\n"); 83178784Skmacy break; 84178784Skmacy default: 85178784Skmacy err = EOPNOTSUPP; 86178784Skmacy break; 87178784Skmacy } 88256829Snp 89256829Snp return (err); 90178784Skmacy} 91178784Skmacy 92178784Skmacystatic int 93178784Skmacykrping_open(struct cdev *dev, int oflags, int devtype, struct thread *p) 94178784Skmacy{ 95256829Snp 96256829Snp return (0); 97178784Skmacy} 98178784Skmacy 99178784Skmacystatic int 100178784Skmacykrping_close(struct cdev *dev, int fflag, int devtype, struct thread *p) 101178784Skmacy{ 102256829Snp 103178784Skmacy return 0; 104178784Skmacy} 105178784Skmacy 106256829Snpstatic void 107256829Snpkrping_copy_stats(struct krping_stats *stats, void *arg) 108256829Snp{ 109256829Snp struct stats_list_entry *s; 110256829Snp struct stats_list *list = arg; 111256829Snp 112256829Snp s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO); 113256829Snp if (s == NULL) 114256829Snp return; 115256829Snp if (stats != NULL) { 116256829Snp s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO); 117256829Snp if (s->stats == NULL) { 118256829Snp free(s, M_DEVBUF); 119256829Snp return; 120256829Snp } 121256829Snp *s->stats = *stats; 122256829Snp } 123256829Snp STAILQ_INSERT_TAIL(list, s, link); 124256829Snp} 125256829Snp 126178784Skmacystatic int 127178784Skmacykrping_read(struct cdev *dev, struct uio *uio, int ioflag) 128178784Skmacy{ 129256829Snp int num = 1; 130256829Snp struct stats_list list; 131256829Snp struct stats_list_entry *e; 132178784Skmacy 133256829Snp STAILQ_INIT(&list); 134256829Snp krping_walk_cb_list(krping_copy_stats, &list); 135256829Snp 136256829Snp if (STAILQ_EMPTY(&list)) 137256829Snp return (0); 138256829Snp 139178784Skmacy uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n", 140256829Snp "num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs", 141256829Snp "wr bytes", "wr msgs", "rd bytes", "rd msgs"); 142178784Skmacy 143256829Snp while (!STAILQ_EMPTY(&list)) { 144256829Snp e = STAILQ_FIRST(&list); 145256829Snp STAILQ_REMOVE_HEAD(&list, link); 146256829Snp if (e->stats == NULL) 147256829Snp uprintf("krping: %d listen\n", num); 148256829Snp else { 149256829Snp struct krping_stats *stats = e->stats; 150178784Skmacy 151256829Snp uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu " 152256829Snp "%10llu %10llu %10llu %10llu\n", num, stats->name, 153256829Snp stats->send_bytes, stats->send_msgs, 154256829Snp stats->recv_bytes, stats->recv_msgs, 155256829Snp stats->write_bytes, stats->write_msgs, 156256829Snp stats->read_bytes, stats->read_msgs); 157256829Snp free(stats, M_DEVBUF); 158178784Skmacy } 159256829Snp num++; 160256829Snp free(e, M_DEVBUF); 161178784Skmacy } 162256829Snp 163256829Snp return (0); 164178784Skmacy} 165178784Skmacy 166178784Skmacystatic int 167178784Skmacykrping_write(struct cdev *dev, struct uio *uio, int ioflag) 168178784Skmacy{ 169178784Skmacy int err = 0; 170178784Skmacy int amt; 171178784Skmacy int remain = BUFFERSIZE; 172178784Skmacy char *cp; 173178784Skmacy krping_t *krpingmsg; 174178784Skmacy 175178784Skmacy krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); 176178784Skmacy if (!krpingmsg) { 177178784Skmacy uprintf("Could not malloc mem!\n"); 178178784Skmacy return ENOMEM; 179178784Skmacy } 180178784Skmacy 181178784Skmacy cp = krpingmsg->msg; 182178784Skmacy while (uio->uio_resid) { 183178784Skmacy amt = MIN(uio->uio_resid, remain); 184178784Skmacy if (amt == 0) 185178784Skmacy break; 186178784Skmacy 187178784Skmacy /* Copy the string in from user memory to kernel memory */ 188178784Skmacy err = uiomove(cp, amt, uio); 189178784Skmacy if (err) { 190178784Skmacy uprintf("Write failed: bad address!\n"); 191178784Skmacy return err; 192178784Skmacy } 193178784Skmacy cp += amt; 194178784Skmacy remain -= amt; 195178784Skmacy } 196178784Skmacy 197178784Skmacy if (uio->uio_resid != 0) { 198178784Skmacy uprintf("Message too big. max size is %d!\n", BUFFERSIZE); 199178784Skmacy return EMSGSIZE; 200178784Skmacy } 201178784Skmacy 202178784Skmacy /* null terminate and remove the \n */ 203178784Skmacy cp--; 204178784Skmacy *cp = 0; 205178784Skmacy krpingmsg->len = (unsigned long)(cp - krpingmsg->msg); 206178784Skmacy uprintf("krping: write string = |%s|\n", krpingmsg->msg); 207256829Snp err = krping_doit(krpingmsg->msg, curproc); 208178784Skmacy free(krpingmsg, M_DEVBUF); 209178784Skmacy return(err); 210178784Skmacy} 211178784Skmacy 212256829Snpvoid 213256829Snpkrping_printf(void *cookie, const char *fmt, ...) 214256829Snp{ 215256829Snp va_list ap; 216256829Snp 217256829Snp va_start(ap, fmt); 218256829Snp vtprintf(cookie, -1, fmt, ap); 219256829Snp va_end(ap); 220256829Snp} 221256829Snp 222256829Snpint 223256829Snpkrping_sigpending(void) 224256829Snp{ 225256829Snp 226256829Snp return (SIGPENDING(curthread)); 227256829Snp} 228256829Snp 229256829SnpDEV_MODULE(krping, krping_loader, NULL); 230256829SnpMODULE_DEPEND(krping, ibcore, 1, 1, 1); 231