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$"); 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 */ 30 static d_open_t krping_open; 31 static d_close_t krping_close; 32 static d_read_t krping_read; 33 static d_write_t krping_write; 34 35 /* Character device entry points */ 36 static 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 45 typedef struct s_krping { 46 char msg[BUFFERSIZE]; 47 int len; 48 } krping_t; 49 50 /* vars */ 51 static struct cdev *krping_dev; 52 53 #undef MODULE_VERSION 54 #include <sys/module.h> 55 56 static int 57 krping_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 79 static int 80 krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p) 81 { 82 int err = 0; 83 return err; 84 } 85 86 static int 87 krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p) 88 { 89 return 0; 90 } 91 92 static int 93 krping_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(©_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(©_cbs, cb2, list); 111 } 112 mtx_unlock(&krping_mutex); 113 114 while (!TAILQ_EMPTY(©_cbs)) { 115 116 cb = TAILQ_FIRST(©_cbs); 117 TAILQ_REMOVE(©_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 134 static int 135 krping_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 180 DEV_MODULE(krping,krping_loader,NULL); 181