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 cb = TAILQ_FIRST(©_cbs); 116 TAILQ_REMOVE(©_cbs, cb, list); 117 if (cb->pd) { 118 uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n", 119 num++, cb->name, cb->stats.send_bytes, 120 cb->stats.send_msgs, cb->stats.recv_bytes, 121 cb->stats.recv_msgs, cb->stats.write_bytes, 122 cb->stats.write_msgs, 123 cb->stats.read_bytes, 124 cb->stats.read_msgs); 125 } else { 126 uprintf("krping: %d listen\n", num++); 127 } 128 free(cb, M_DEVBUF); 129 } 130 return 0; 131 } 132 133 static int 134 krping_write(struct cdev *dev, struct uio *uio, int ioflag) 135 { 136 int err = 0; 137 int amt; 138 int remain = BUFFERSIZE; 139 char *cp; 140 krping_t *krpingmsg; 141 142 krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); 143 if (!krpingmsg) { 144 uprintf("Could not malloc mem!\n"); 145 return ENOMEM; 146 } 147 148 cp = krpingmsg->msg; 149 while (uio->uio_resid) { 150 amt = MIN(uio->uio_resid, remain); 151 if (amt == 0) 152 break; 153 154 /* Copy the string in from user memory to kernel memory */ 155 err = uiomove(cp, amt, uio); 156 if (err) { 157 uprintf("Write failed: bad address!\n"); 158 return err; 159 } 160 cp += amt; 161 remain -= amt; 162 } 163 164 if (uio->uio_resid != 0) { 165 uprintf("Message too big. max size is %d!\n", BUFFERSIZE); 166 return EMSGSIZE; 167 } 168 169 /* null terminate and remove the \n */ 170 cp--; 171 *cp = 0; 172 krpingmsg->len = (unsigned long)(cp - krpingmsg->msg); 173 uprintf("krping: write string = |%s|\n", krpingmsg->msg); 174 err = krping_doit(krpingmsg->msg); 175 free(krpingmsg, M_DEVBUF); 176 return(err); 177 } 178 179 DEV_MODULE(krping,krping_loader,NULL); 180