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/module.h> 18 #include <sys/systm.h> /* uprintf */ 19 #include <sys/errno.h> 20 #include <sys/param.h> /* defines used in kernel.h */ 21 #include <sys/kernel.h> /* types used in module initialization */ 22 #include <sys/conf.h> /* cdevsw struct */ 23 #include <sys/uio.h> /* uio struct */ 24 #include <sys/malloc.h> 25 26 #include "krping.h" 27 28 #define BUFFERSIZE 512 29 30 /* Function prototypes */ 31 static d_open_t krping_open; 32 static d_close_t krping_close; 33 static d_read_t krping_read; 34 static d_write_t krping_write; 35 36 /* Character device entry points */ 37 static struct cdevsw krping_cdevsw = { 38 .d_version = D_VERSION, 39 .d_open = krping_open, 40 .d_close = krping_close, 41 .d_read = krping_read, 42 .d_write = krping_write, 43 .d_name = "krping", 44 }; 45 46 typedef struct s_krping { 47 char msg[BUFFERSIZE]; 48 int len; 49 } krping_t; 50 51 /* vars */ 52 static struct cdev *krping_dev; 53 54 static int 55 krping_loader(struct module *m, int what, void *arg) 56 { 57 int err = 0; 58 59 switch (what) { 60 case MOD_LOAD: /* kldload */ 61 krping_init(); 62 krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL, 63 0600, "krping"); 64 printf("Krping device loaded.\n"); 65 break; 66 case MOD_UNLOAD: 67 destroy_dev(krping_dev); 68 printf("Krping device unloaded.\n"); 69 break; 70 default: 71 err = EOPNOTSUPP; 72 break; 73 } 74 return err; 75 } 76 77 static int 78 krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p) 79 { 80 int err = 0; 81 return err; 82 } 83 84 static int 85 krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p) 86 { 87 return 0; 88 } 89 90 static int 91 krping_read(struct cdev *dev, struct uio *uio, int ioflag) 92 { 93 struct krping_cb *cb, *cb2; 94 int num=1; 95 struct krping_cb_list copy_cbs; 96 97 uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n", 98 "num", "device", "snd bytes", "snd msgs", "rcv bytes", 99 "rcv msgs", "wr bytes", "wr msgs", "rd bytes", "rd msgs"); 100 TAILQ_INIT(©_cbs); 101 102 mtx_lock(&krping_mutex); 103 TAILQ_FOREACH(cb, &krping_cbs, list) { 104 cb2 = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT|M_ZERO); 105 if (!cb2) 106 break; 107 bcopy(cb, cb2, sizeof(*cb)); 108 TAILQ_INSERT_TAIL(©_cbs, cb2, list); 109 } 110 mtx_unlock(&krping_mutex); 111 112 while (!TAILQ_EMPTY(©_cbs)) { 113 114 cb = TAILQ_FIRST(©_cbs); 115 TAILQ_REMOVE(©_cbs, cb, list); 116 if (cb->pd) { 117 uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n", 118 num++, cb->pd->device->name, cb->stats.send_bytes, 119 cb->stats.send_msgs, cb->stats.recv_bytes, 120 cb->stats.recv_msgs, cb->stats.write_bytes, 121 cb->stats.write_msgs, 122 cb->stats.read_bytes, 123 cb->stats.read_msgs); 124 } else { 125 uprintf("krping: %d listen\n", num++); 126 } 127 free(cb, M_DEVBUF); 128 } 129 return 0; 130 } 131 132 static int 133 krping_write(struct cdev *dev, struct uio *uio, int ioflag) 134 { 135 int err = 0; 136 int amt; 137 int remain = BUFFERSIZE; 138 char *cp; 139 krping_t *krpingmsg; 140 141 krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); 142 if (!krpingmsg) { 143 uprintf("Could not malloc mem!\n"); 144 return ENOMEM; 145 } 146 147 cp = krpingmsg->msg; 148 while (uio->uio_resid) { 149 amt = MIN(uio->uio_resid, remain); 150 if (amt == 0) 151 break; 152 153 /* Copy the string in from user memory to kernel memory */ 154 err = uiomove(cp, amt, uio); 155 if (err) { 156 uprintf("Write failed: bad address!\n"); 157 return err; 158 } 159 cp += amt; 160 remain -= amt; 161 } 162 163 if (uio->uio_resid != 0) { 164 uprintf("Message too big. max size is %d!\n", BUFFERSIZE); 165 return EMSGSIZE; 166 } 167 168 /* null terminate and remove the \n */ 169 cp--; 170 *cp = 0; 171 krpingmsg->len = (unsigned long)(cp - krpingmsg->msg); 172 uprintf("krping: write string = |%s|\n", krpingmsg->msg); 173 err = krping_doit(krpingmsg->msg); 174 free(krpingmsg, M_DEVBUF); 175 return(err); 176 } 177 178 MODULE_DEPEND(krping, rdma_core, 1, 1, 1); 179 MODULE_DEPEND(krping, rdma_cma, 1, 1, 1); 180 DEV_MODULE(krping,krping_loader,NULL); 181