/* Receive data over TCP/IP. */ int usbip_recv(struct socket *sock, void *buf, int size) { int result; struct msghdr msg; struct kvec iov; int total = 0; /* for blocks of if (usbip_dbg_flag_xmit) */ char *bp = buf; int osize = size; usbip_dbg_xmit("enter\n"); if (!sock || !buf || !size) { pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, size); return -EINVAL; } do { sock->sk->sk_allocation = GFP_NOIO; iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; msg.msg_flags = MSG_NOSIGNAL; result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); if (result <= 0) { pr_debug("receive sock %p buf %p size %u ret %d total %d\n", sock, buf, size, result, total); goto err; } size -= result; buf += result; total += result; } while (size > 0); if (usbip_dbg_flag_xmit) { if (!in_interrupt()) pr_debug("%-10s:", current->comm); else pr_debug("interrupt :"); pr_debug("receiving....\n"); usbip_dump_buffer(bp, osize); pr_debug("received, osize %d ret %d size %d total %d\n", osize, result, size, total); } return total; err: return result; }
/* Receive data over TCP/IP. */ int usbip_recv(struct socket *sock, void *buf, int size) { int result; struct kvec iov = {.iov_base = buf, .iov_len = size}; struct msghdr msg = {.msg_flags = MSG_NOSIGNAL}; int total = 0; iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size); usbip_dbg_xmit("enter\n"); if (!sock || !buf || !size) { pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, size); return -EINVAL; } do { int sz = msg_data_left(&msg); sock->sk->sk_allocation = GFP_NOIO; result = sock_recvmsg(sock, &msg, MSG_WAITALL); if (result <= 0) { pr_debug("receive sock %p buf %p size %u ret %d total %d\n", sock, buf + total, sz, result, total); goto err; } total += result; } while (msg_data_left(&msg)); if (usbip_dbg_flag_xmit) { if (!in_interrupt()) pr_debug("%-10s:", current->comm); else pr_debug("interrupt :"); pr_debug("receiving....\n"); usbip_dump_buffer(buf, size); pr_debug("received, osize %d ret %d size %zd total %d\n", size, result, msg_data_left(&msg), total); } return total; err: return result; }
static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending) { ssize_t total = 0; #ifdef DEBUG void * orgbuf=buff; #endif if (!bufflen) return 0; // dbg_file("do %d: len:%d\n", sending, bufflen); do { ssize_t nbytes; if (sending) { nbytes = send(sockfd, buff, bufflen, 0); } else { nbytes = recv(sockfd, buff, bufflen, 0); dbg_file("Number of bytes received from socket synchronously: %d\n",nbytes); } if (nbytes <= 0) return -1; buff = (void *)((char *)buff + nbytes); bufflen -= nbytes; total += nbytes; } while (bufflen > 0); #ifdef DEBUG usbip_dump_buffer(orgbuf,total); #endif // dbg_file("do %d: len:%d finish\n", sending, bufflen); return total; }
/* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */ int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags) { int result; struct msghdr msg; struct kvec iov; int total = 0; /* for blocks of if (usbip_dbg_flag_xmit) */ char *bp = buf; int osize = size; usbip_dbg_xmit("enter\n"); if (!sock || !buf || !size) { printk(KERN_ERR "%s: invalid arg, sock %p buff %p size %d\n", __func__, sock, buf, size); return -EINVAL; } if (usbip_dbg_flag_xmit) { if (send) { if (!in_interrupt()) printk(KERN_DEBUG "%-10s:", current->comm); else printk(KERN_DEBUG "interrupt :"); printk(KERN_DEBUG "%s: sending... , sock %p, buf %p, " "size %d, msg_flags %d\n", __func__, sock, buf, size, msg_flags); usbip_dump_buffer(buf, size); } } do { sock->sk->sk_allocation = GFP_NOIO; iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) result = kernel_sendmsg(sock, &msg, &iov, 1, size); else result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); if (result <= 0) { usbip_udbg("usbip_xmit: %s sock %p buf %p size %u ret " "%d total %d\n", send ? "send" : "receive", sock, buf, size, result, total); goto err; } size -= result; buf += result; total += result; } while (size > 0); if (usbip_dbg_flag_xmit) { if (!send) { if (!in_interrupt()) printk(KERN_DEBUG "%-10s:", current->comm); else printk(KERN_DEBUG "interrupt :"); printk(KERN_DEBUG "usbip_xmit: receiving....\n"); usbip_dump_buffer(bp, osize); printk(KERN_DEBUG "usbip_xmit: received, osize %d ret " "%d size %d total %d\n", osize, result, size, total); } if (send) printk(KERN_DEBUG "usbip_xmit: send, total %d\n", total); } return total; err: return result; }
int write_to_dev(char * buf, int buf_len, int len, SOCKET sockfd, HANDLE devfd, OVERLAPPED *ov) { int ret; unsigned long out=0, in_len, iso_len; struct usbip_header * u = (struct usbip_header *)buf; if(len!=sizeof(*u)){ err("read from sock ret %d not equal a usbip_header", len); #ifdef DEBUG usbip_dump_buffer(buf,len); #endif return -1; } if(usbip_header_correct_endian(u, 0)<0) return -1; dbg_file("recv seq %d\n", u->base.seqnum); if ((u->base.seqnum%100)==0) fprintf(stderr,"Receive sequence: %d\r", u->base.seqnum); #ifdef DEBUG usbip_dump_header(u); #endif if(check_out(htonl(u->base.seqnum))) in_len=0; else in_len=u->u.ret_submit.actual_length; iso_len = u->u.ret_submit.number_of_packets * sizeof(struct usbip_iso_packet_descriptor); if(in_len==0&&iso_len==0){ ret=WriteFile(devfd, (char *)u, sizeof(*u), &out, ov); if(!ret||out!=sizeof(*u)){ err("last error:%ld",GetLastError()); err("out:%ld ret:%d",out,ret); err("write dev failed"); return -1; } return 0; } len = sizeof(*u) + in_len + iso_len; if(len>buf_len){ err("too big len %d %ld %ld", len, in_len,iso_len); return -1; } ret=usbip_recv(sockfd, buf+sizeof(*u), in_len+iso_len); if(ret != in_len + iso_len){ err("recv from sock failed %d %ld", ret, in_len + iso_len); return -1; } if(iso_len) fix_iso_desc_endian(sock_read_buf+sizeof(*u)+in_len, u->u.ret_submit.number_of_packets); ret=WriteFile(devfd, buf, len, &out, ov); if(!ret||out!=len){ err("last error:%ld\n",GetLastError()); err("out:%ld ret:%d len:%d\n",out,ret,len); err("write dev failed"); return -1; } return 0; }