cregit-Linux how code gets into the kernel

Release 4.11 fs/ncpfs/sock.c

Directory: fs/ncpfs
/*
 *  linux/fs/ncpfs/sock.c
 *
 *  Copyright (C) 1992, 1993  Rick Sladkey
 *
 *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp
 *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
 *
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/time.h>
#include <linux/errno.h>
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
#include <linux/in.h>
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <net/scm.h>
#include <net/sock.h>
#include <linux/ipx.h>
#include <linux/poll.h>
#include <linux/file.h>

#include "ncp_fs.h"

#include "ncpsign_kernel.h"


static int _recv(struct socket *sock, void *buf, int size, unsigned flags) { struct msghdr msg = {NULL, }; struct kvec iov = {buf, size}; return kernel_recvmsg(sock, &msg, &iov, 1, size, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Al Viro3052.63%133.33%
Linus Torvalds (pre-git)2747.37%266.67%
Total57100.00%3100.00%


static int _send(struct socket *sock, const void *buff, int len) { struct msghdr msg = { .msg_flags = 0 }; struct kvec vec = {.iov_base = (void *)buff, .iov_len = len}; iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len); return sock_sendmsg(sock, &msg); }

Contributors

PersonTokensPropCommitsCommitProp
Al Viro5469.23%240.00%
Linus Torvalds (pre-git)2430.77%360.00%
Total78100.00%5100.00%

struct ncp_request_reply { struct list_head req; wait_queue_head_t wq; atomic_t refs; unsigned char* reply_buf; size_t datalen; int result; enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; struct iov_iter from; struct kvec tx_iov[3]; u_int16_t tx_type; u_int32_t sign[6]; };
static inline struct ncp_request_reply* ncp_alloc_req(void) { struct ncp_request_reply *req; req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL); if (!req) return NULL; init_waitqueue_head(&req->wq); atomic_set(&req->refs, (1)); req->status = RQ_IDLE; return req; }

Contributors

PersonTokensPropCommitsCommitProp
Pierre Ossman66100.00%1100.00%
Total66100.00%1100.00%


static void ncp_req_get(struct ncp_request_reply *req) { atomic_inc(&req->refs); }

Contributors

PersonTokensPropCommitsCommitProp
Pierre Ossman19100.00%1100.00%
Total19100.00%1100.00%


static void ncp_req_put(struct ncp_request_reply *req) { if (atomic_dec_and_test(&req->refs)) kfree(req); }

Contributors

PersonTokensPropCommitsCommitProp
Pierre Ossman26100.00%1100.00%
Total26100.00%1100.00%


void ncp_tcp_data_ready(struct sock *sk) { struct ncp_server *server = sk->sk_user_data; server->data_ready(sk); schedule_work(&server->rcv.tq); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec2158.33%120.00%
Linus Torvalds (pre-git)1130.56%120.00%
Al Viro25.56%120.00%
Arnaldo Carvalho de Melo12.78%120.00%
Ingo Molnar12.78%120.00%
Total36100.00%5100.00%


void ncp_tcp_error_report(struct sock *sk) { struct ncp_server *server = sk->sk_user_data; server->error_report(sk); schedule_work(&server->rcv.tq); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec2569.44%125.00%
Linus Torvalds (pre-git)925.00%125.00%
Arnaldo Carvalho de Melo12.78%125.00%
Ingo Molnar12.78%125.00%
Total36100.00%4100.00%


void ncp_tcp_write_space(struct sock *sk) { struct ncp_server *server = sk->sk_user_data; /* We do not need any locking: we first set tx.creq, and then we do sendmsg, not vice versa... */ server->write_space(sk); if (server->tx.creq) schedule_work(&server->tx.tq); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3373.33%125.00%
Linus Torvalds (pre-git)1022.22%125.00%
Ingo Molnar12.22%125.00%
Arnaldo Carvalho de Melo12.22%125.00%
Total45100.00%4100.00%


void ncpdgram_timeout_call(unsigned long v) { struct ncp_server *server = (void*)v; schedule_work(&server->timeout_tq); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec2382.14%120.00%
Linus Torvalds (pre-git)414.29%360.00%
Ingo Molnar13.57%120.00%
Total28100.00%5100.00%


static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result) { req->result = result; if (req->status != RQ_ABANDONED) memcpy(req->reply_buf, server->rxbuf, req->datalen); req->status = RQ_DONE; wake_up_all(&req->wq); ncp_req_put(req); }

Contributors

PersonTokensPropCommitsCommitProp
Pierre Ossman3348.53%125.00%
Petr Vandrovec3044.12%125.00%
Linus Torvalds (pre-git)57.35%250.00%
Total68100.00%4100.00%


static void __abort_ncp_connection(struct ncp_server *server) { struct ncp_request_reply *req; ncp_invalidate_conn(server); del_timer(&server->timeout_tm); while (!list_empty(&server->tx.requests)) { req = list_entry(server->tx.requests.next, struct ncp_request_reply, req); list_del_init(&req->req); ncp_finish_request(server, req, -EIO); } req = server->rcv.creq; if (req) { server->rcv.creq = NULL; ncp_finish_request(server, req, -EIO); server->rcv.ptr = NULL; server->rcv.state = 0; } req = server->tx.creq; if (req) { server->tx.creq = NULL; ncp_finish_request(server, req, -EIO); } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec11370.62%111.11%
Linus Torvalds (pre-git)4427.50%777.78%
Pierre Ossman31.88%111.11%
Total160100.00%9100.00%


static inline int get_conn_number(struct ncp_reply_header *rp) { return rp->conn_low | (rp->conn_high << 8); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec2288.00%150.00%
Linus Torvalds (pre-git)312.00%150.00%
Total25100.00%2100.00%


static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err) { /* If req is done, we got signal, but we also received answer... */ switch (req->status) { case RQ_IDLE: case RQ_DONE: break; case RQ_QUEUED: list_del_init(&req->req); ncp_finish_request(server, req, err); break; case RQ_INPROGRESS: req->status = RQ_ABANDONED; break; case RQ_ABANDONED: break; } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec4867.61%133.33%
Linus Torvalds (pre-git)1318.31%133.33%
Pierre Ossman1014.08%133.33%
Total71100.00%3100.00%


static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err) { mutex_lock(&server->rcv.creq_mutex); __ncp_abort_request(server, req, err); mutex_unlock(&server->rcv.creq_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3673.47%133.33%
Linus Torvalds (pre-git)918.37%133.33%
Ingo Molnar48.16%133.33%
Total49100.00%3100.00%


static inline void __ncptcp_abort(struct ncp_server *server) { __abort_ncp_connection(server); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec1588.24%150.00%
Linus Torvalds (pre-git)211.76%150.00%
Total17100.00%2100.00%


static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) { struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT }; return sock_sendmsg(sock, &msg); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec2353.49%250.00%
Al Viro1841.86%125.00%
Linus Torvalds (pre-git)24.65%125.00%
Total43100.00%4100.00%


static void __ncptcp_try_send(struct ncp_server *server) { struct ncp_request_reply *rq; struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT }; int result; rq = server->tx.creq; if (!rq) return; msg.msg_iter = rq->from; result = sock_sendmsg(server->ncp_sock, &msg); if (result == -EAGAIN) return; if (result < 0) { pr_err("tcp: Send failed: %d\n", result); __ncp_abort_request(server, rq, result); return; } if (!msg_data_left(&msg)) { server->rcv.creq = rq; server->tx.creq = NULL; return; } rq->from = msg.msg_iter; }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec7757.04%240.00%
Al Viro2921.48%120.00%
Linus Torvalds (pre-git)2720.00%120.00%
Joe Perches21.48%120.00%
Total135100.00%5100.00%


static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) { req->status = RQ_INPROGRESS; h->conn_low = server->connection; h->conn_high = server->connection >> 8; h->sequence = ++server->sequence; }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3360.00%125.00%
Linus Torvalds (pre-git)2240.00%375.00%
Total55100.00%4100.00%


static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) { size_t signlen, len = req->tx_iov[1].iov_len; struct ncp_request_header *h = req->tx_iov[1].iov_base; ncp_init_header(server, req, h); signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, len - sizeof(struct ncp_request_header) + 1, cpu_to_le32(len), req->sign); if (signlen) { /* NCP over UDP appends signature */ req->tx_iov[2].iov_base = req->sign; req->tx_iov[2].iov_len = signlen; } iov_iter_kvec(&req->from, WRITE | ITER_KVEC, req->tx_iov + 1, signlen ? 2 : 1, len + signlen); server->rcv.creq = req; server->timeout_last = server->m.time_out; server->timeout_retries = server->m.retry_count; ncpdgram_send(server->ncp_sock, req); mod_timer(&server->timeout_tm, jiffies + server->m.time_out); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec13363.94%133.33%
Al Viro4320.67%133.33%
Linus Torvalds (pre-git)3215.38%133.33%
Total208100.00%3100.00%

#define NCP_TCP_XMIT_MAGIC (0x446D6454) #define NCP_TCP_XMIT_VERSION (1) #define NCP_TCP_RCVD_MAGIC (0x744E6350)
static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) { size_t signlen, len = req->tx_iov[1].iov_len; struct ncp_request_header *h = req->tx_iov[1].iov_base; ncp_init_header(server, req, h); signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, len - sizeof(struct ncp_request_header) + 1, cpu_to_be32(len + 24), req->sign + 4) + 16; req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); req->sign[1] = htonl(len + signlen); req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); req->sign[3] = htonl(req->datalen + 8); /* NCP over TCP prepends signature */ req->tx_iov[0].iov_base = req->sign; req->tx_iov[0].iov_len = signlen; iov_iter_kvec(&req->from, WRITE | ITER_KVEC, req->tx_iov, 2, len + signlen); server->tx.creq = req; __ncptcp_try_send(server); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec10146.76%125.00%
Linus Torvalds (pre-git)8037.04%125.00%
Al Viro3516.20%250.00%
Total216100.00%4100.00%


static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req) { /* we copy the data so that we do not depend on the caller staying alive */ memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len); req->tx_iov[1].iov_base = server->txbuf; if (server->ncp_sock->type == SOCK_STREAM) ncptcp_start_request(server, req); else ncpdgram_start_request(server, req); }

Contributors

PersonTokensPropCommitsCommitProp
Pierre Ossman3948.15%133.33%
Petr Vandrovec2935.80%133.33%
Linus Torvalds (pre-git)1316.05%133.33%
Total81100.00%3100.00%


static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req) { mutex_lock(&server->rcv.creq_mutex); if (!ncp_conn_valid(server)) { mutex_unlock(&server->rcv.creq_mutex); pr_err("tcp: Server died\n"); return -EIO; } ncp_req_get(req); if (server->tx.creq || server->rcv.creq) { req->status = RQ_QUEUED; list_add_tail(&req->req, &server->tx.requests); mutex_unlock(&server->rcv.creq_mutex); return 0; } __ncp_start_request(server, req); mutex_unlock(&server->rcv.creq_mutex); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec7456.92%120.00%
Linus Torvalds (pre-git)4131.54%120.00%
Ingo Molnar86.15%120.00%
Pierre Ossman53.85%120.00%
Joe Perches21.54%120.00%
Total130100.00%5100.00%


static void __ncp_next_request(struct ncp_server *server) { struct ncp_request_reply *req; server->rcv.creq = NULL; if (list_empty(&server->tx.requests)) { return; } req = list_entry(server->tx.requests.next, struct ncp_request_reply, req); list_del_init(&req->req); __ncp_start_request(server, req); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec6488.89%150.00%
Linus Torvalds (pre-git)811.11%150.00%
Total72100.00%2100.00%


static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len) { if (server->info_sock) { struct msghdr msg = { .msg_flags = MSG_NOSIGNAL }; __be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)}; struct kvec iov[2] = { {.iov_base = hdr, .iov_len = 8}, {.iov_base = (void *)data, .iov_len = len}, }; iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE, iov, 2, len + 8); sock_sendmsg(server->info_sock, &msg); } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec7759.69%125.00%
Al Viro5240.31%375.00%
Total129100.00%4100.00%


void ncpdgram_rcv_proc(struct work_struct *work) { struct ncp_server *server = container_of(work, struct ncp_server, rcv.tq); struct socket* sock; sock = server->ncp_sock; while (1) { struct ncp_reply_header reply; int result; result = _recv(sock, &reply, sizeof(reply), MSG_PEEK | MSG_DONTWAIT); if (result < 0) { break; } if (result >= sizeof(reply)) { struct ncp_request_reply *req; if (reply.type == NCP_WATCHDOG) { unsigned char buf[10]; if (server->connection != get_conn_number(&reply)) { goto drop; } result = _recv(sock, buf, sizeof(buf), MSG_DONTWAIT); if (result < 0) { ncp_dbg(1, "recv failed with %d\n", result); continue; } if (result < 10) { ncp_dbg(1, "too short (%u) watchdog packet\n", result); continue; } if (buf[9] != '?') { ncp_dbg(1, "bad signature (%02X) in watchdog packet\n", buf[9]); continue; } buf[9] = 'Y'; _send(sock, buf, sizeof(buf)); continue; } if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) { result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT); if (result < 0) { continue; } info_server(server, 0, server->unexpected_packet.data, result); continue; } mutex_lock(&server->rcv.creq_mutex); req = server->rcv.creq; if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence && server->connection == get_conn_number(&reply)))) { if (reply.type == NCP_POSITIVE_ACK) { server->timeout_retries = server->m.retry_count; server->timeout_last = NCP_MAX_RPC_TIMEOUT; mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT); } else if (reply.type == NCP_REPLY) { result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT); #ifdef CONFIG_NCPFS_PACKET_SIGNING if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { if (result < 8 + 8) { result = -EIO; } else { unsigned int hdrl; result -= 8; hdrl = sock->sk->sk_family == AF_INET ? 8 : 6; if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) { pr_info("Signature violation\n"); result = -EIO; } } } #endif del_timer(&server->timeout_tm); server->rcv.creq = NULL; ncp_finish_request(server, req, result); __ncp_next_request(server); mutex_unlock(&server->rcv.creq_mutex); continue; } } mutex_unlock(&server->rcv.creq_mutex); } drop:; _recv(sock, &reply, sizeof(reply), MSG_DONTWAIT); } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec53492.07%327.27%
David Howells142.41%19.09%
Joe Perches111.90%218.18%
Pierre Ossman81.38%19.09%
Ingo Molnar61.03%19.09%
Linus Torvalds (pre-git)50.86%19.09%
Al Viro10.17%19.09%
Arnaldo Carvalho de Melo10.17%19.09%
Total580100.00%11100.00%


static void __ncpdgram_timeout_proc(struct ncp_server *server) { /* If timer is pending, we are processing another request... */ if (!timer_pending(&server->timeout_tm)) { struct ncp_request_reply* req; req = server->rcv.creq; if (req) { int timeout; if (server->m.flags & NCP_MOUNT_SOFT) { if (server->timeout_retries-- == 0) { __ncp_abort_request(server, req, -ETIMEDOUT); return; } } /* Ignore errors */ ncpdgram_send(server->ncp_sock, req); timeout = server->timeout_last << 1; if (timeout > NCP_MAX_RPC_TIMEOUT) { timeout = NCP_MAX_RPC_TIMEOUT; } server->timeout_last = timeout; mod_timer(&server->timeout_tm, jiffies + timeout); } } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec129100.00%1100.00%
Total129100.00%1100.00%


void ncpdgram_timeout_proc(struct work_struct *work) { struct ncp_server *server = container_of(work, struct ncp_server, timeout_tq); mutex_lock(&server->rcv.creq_mutex); __ncpdgram_timeout_proc(server); mutex_unlock(&server->rcv.creq_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3468.00%133.33%
David Howells1224.00%133.33%
Ingo Molnar48.00%133.33%
Total50100.00%3100.00%


static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) { int result; if (buffer) { result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT); } else { static unsigned char dummy[1024]; if (len > sizeof(dummy)) { len = sizeof(dummy); } result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT); } if (result < 0) { return result; } if (result > len) { pr_err("tcp: bug in recvmsg (%u > %zu)\n", result, len); return -EIO; } return result; }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec11998.35%133.33%
Joe Perches10.83%133.33%
Alexey Dobriyan10.83%133.33%
Total121100.00%3100.00%


static int __ncptcp_rcv_proc(struct ncp_server *server) { /* We have to check the result, so store the complete header */ while (1) { int result; struct ncp_request_reply *req; int datalen; int type; while (server->rcv.len) { result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len); if (result == -EAGAIN) { return 0; } if (result <= 0) { req = server->rcv.creq; if (req) { __ncp_abort_request(server, req, -EIO); } else { __ncptcp_abort(server); } if (result < 0) { pr_err("tcp: error in recvmsg: %d\n", result); } else { ncp_dbg(1, "tcp: EOF\n"); } return -EIO; } if (server->rcv.ptr) { server->rcv.ptr += result; } server->rcv.len -= result; } switch (server->rcv.state) { case 0: if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) { pr_err("tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic)); __ncptcp_abort(server); return -EIO; } datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF; if (datalen < 10) { pr_err("tcp: Unexpected reply len %d\n", datalen); __ncptcp_abort(server); return -EIO; } #ifdef CONFIG_NCPFS_PACKET_SIGNING if (server->sign_active) { if (datalen < 18) { pr_err("tcp: Unexpected reply len %d\n", datalen); __ncptcp_abort(server); return -EIO; } server->rcv.buf.len = datalen - 8; server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1; server->rcv.len = 8; server->rcv.state = 4; break; } #endif type = ntohs(server->rcv.buf.type); #ifdef CONFIG_NCPFS_PACKET_SIGNING cont:; #endif if (type != NCP_REPLY) { if (datalen - 8 <= sizeof(server->unexpected_packet.data)) { *(__u16*)(server->unexpected_packet.data) = htons(type); server->unexpected_packet.len = datalen - 8; server->rcv.state = 5; server->rcv.ptr = server->unexpected_packet.data + 2; server->rcv.len = datalen - 10; break; } ncp_dbg(1, "tcp: Unexpected NCP type %02X\n", type); skipdata2:; server->rcv.state = 2; skipdata:; server->rcv.ptr = NULL; server->rcv.len = datalen - 10; break; } req = server->rcv.creq; if (!req) { ncp_dbg(1, "Reply without appropriate request\n"); goto skipdata2; } if (datalen > req->datalen + 8) { pr_err("tcp: Unexpected reply len %d (expected at most %zd)\n", datalen, req->datalen + 8); server->rcv.state = 3; goto skipdata; } req->datalen = datalen - 8; ((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY; server->rcv.ptr = server->rxbuf + 2; server->rcv.len = datalen - 10; server->rcv.state = 1; break; #ifdef CONFIG_NCPFS_PACKET_SIGNING case 4: datalen = server->rcv.buf.len; type = ntohs(server->rcv.buf.type2); goto cont; #endif case 1: req = server->rcv.creq; if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) { if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) { pr_err("tcp: Bad sequence number\n"); __ncp_abort_request(server, req, -EIO); return -EIO; } if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) { pr_err("tcp: Connection number mismatch\n"); __ncp_abort_request(server, req, -EIO); return -EIO; } } #ifdef CONFIG_NCPFS_PACKET_SIGNING if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) { pr_err("tcp: Signature violation\n"); __ncp_abort_request(server, req, -EIO); return -EIO; } } #endif ncp_finish_request(server, req, req->datalen); nextreq:; __ncp_next_request(server); case 2: next:; server->rcv.ptr = (unsigned char*)&server->rcv.buf; server->rcv.len = 10; server->rcv.state = 0; break; case 3: ncp_finish_request(server, server->rcv.creq, -EIO); goto nextreq; case 5: info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len); goto next; } } }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec87191.88%337.50%
Pierre Ossman444.64%112.50%
Joe Perches272.85%225.00%
Bob Miller50.53%112.50%
Alexey Dobriyan10.11%112.50%
Total948100.00%8100.00%


void ncp_tcp_rcv_proc(struct work_struct *work) { struct ncp_server *server = container_of(work, struct ncp_server, rcv.tq); mutex_lock(&server->rcv.creq_mutex); __ncptcp_rcv_proc(server); mutex_unlock(&server->rcv.creq_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3465.38%133.33%
David Howells1426.92%133.33%
Ingo Molnar47.69%133.33%
Total52100.00%3100.00%


void ncp_tcp_tx_proc(struct work_struct *work) { struct ncp_server *server = container_of(work, struct ncp_server, tx.tq); mutex_lock(&server->rcv.creq_mutex); __ncptcp_try_send(server); mutex_unlock(&server->rcv.creq_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec3465.38%133.33%
David Howells1426.92%133.33%
Ingo Molnar47.69%133.33%
Total52100.00%3100.00%


static int do_ncp_rpc_call(struct ncp_server *server, int size, unsigned char* reply_buf, int max_reply_size) { int result; struct ncp_request_reply *req; req = ncp_alloc_req(); if (!req) return -ENOMEM; req->reply_buf = reply_buf; req->datalen = max_reply_size; req->tx_iov[1].iov_base = server->packet; req->tx_iov[1].iov_len = size; req->tx_type = *(u_int16_t*)server->packet; result = ncp_add_request(server, req); if (result < 0) goto out; if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) { ncp_abort_request(server, req, -EINTR); result = -EINTR; goto out; } result = req->result; out: ncp_req_put(req); return result; }

Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec10866.67%133.33%
Pierre Ossman4729.01%133.33%
Linus Torvalds (pre-git)74.32%133.33%
Total162100.00%3100.00%

/* * We need the server to be locked here, so check! */
static int ncp_do_request(struct ncp_server *server, int size, void* reply, int max_reply_size) { int result; if (server->lock == 0) { pr_err("Server not locked!\n"); return -EIO; } if (!ncp_conn_valid(server)) { return -EIO; } { sigset_t old_set; unsigned long mask, flags; spin_lock_irqsave(&current->sighand->siglock, flags); old_set = current->blocked; if (current->flags & PF_EXITING) mask = 0; else mask = sigmask(SIGKILL); if (server->m.flags & NCP_MOUNT_INTR) { /* FIXME: This doesn't seem right at all. So, like, we can't handle SIGINT and get whatever to stop? What if we've blocked it ourselves? What about alarms? Why, in fact, are we mucking with the sigmask at all? -- r~ */ if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGINT); if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGQUIT); } siginitsetinv(&current->blocked, mask); recalc_sigpending(); spin_unlock_irqrestore(&current->sighand->siglock, flags); result = do_ncp_rpc_call(server, size, reply, max_reply_size); spin_lock_irqsave(&current->sighand->siglock, flags); current->blocked = old_set; recalc_sigpending(); spin_unlock_irqrestore(&current->sighand->siglock, flags); } ncp_dbg(2, "do_ncp_rpc_call returned %d\n", result); return result; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)21785.43%433.33%
Linus Torvalds135.12%18.33%
Ingo Molnar83.15%18.33%
Joe Perches51.97%216.67%
Chris Wedgwood41.57%18.33%
Petr Vandrovec31.18%18.33%
Andrew Morton20.79%18.33%
David S. Miller20.79%18.33%
Total254100.00%12100.00%

/* ncp_do_request assures that at least a complete reply header is * received. It assumes that server->current_size contains the ncp * request size */
int ncp_request2(struct ncp_server *server, int function, void* rpl, int size) { struct ncp_request_header *h; struct ncp_reply_header* reply = rpl; int result; h = (struct ncp_request_header *) (server->packet); if (server->has_subfunction != 0) { *(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2); } h->type = NCP_REQUEST; /* * The server shouldn't know or care what task is making a * request, so we always use the same task number. */ h->task = 2; /* (current->pid) & 0xff; */ h->function = function; result = ncp_do_request(server, server->current_size, reply, size); if (result < 0) { ncp_dbg(1, "ncp_request_error: %d\n", result); goto out; } server->completion = reply->completion_code; server->conn_status = reply->connection_state; server->reply_size = result; server->ncp_reply_size = result - sizeof(struct ncp_reply_header); result = reply->completion_code; if (result != 0) ncp_vdbg("completion code=%x\n", result); out: return result; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)18491.54%562.50%
Petr Vandrovec125.97%112.50%
Joe Perches52.49%225.00%
Total201100.00%8100.00%


int ncp_connect(struct ncp_server *server) { struct ncp_request_header *h; int result; server->connection = 0xFFFF; server->sequence = 255; h = (struct ncp_request_header *) (server->packet); h->type = NCP_ALLOC_SLOT_REQUEST; h->task = 2; /* see above */ h->function = 0; result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size); if (result < 0) goto out; server->connection = h->conn_low + (h->conn_high * 256); result = 0; out: return result; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)10589.74%480.00%
Petr Vandrovec1210.26%120.00%
Total117100.00%5100.00%


int ncp_disconnect(struct ncp_server *server) { struct ncp_request_header *h; h = (struct ncp_request_header *) (server->packet); h->type = NCP_DEALLOC_SLOT_REQUEST; h->task = 2; /* see above */ h->function = 0; return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)67100.00%4100.00%
Total67100.00%4100.00%


void ncp_lock_server(struct ncp_server *server) { mutex_lock(&server->mutex); if (server->lock) pr_warn("%s: was locked!\n", __func__); server->lock = 1; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3183.78%360.00%
Joe Perches410.81%120.00%
Ingo Molnar25.41%120.00%
Total37100.00%5100.00%


void ncp_unlock_server(struct ncp_server *server) { if (!server->lock) { pr_warn("%s: was not locked!\n", __func__); return; } server->lock = 0; mutex_unlock(&server->mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3585.37%360.00%
Joe Perches49.76%120.00%
Ingo Molnar24.88%120.00%
Total41100.00%5100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Petr Vandrovec290560.45%510.87%
Linus Torvalds (pre-git)111523.20%1634.78%
Pierre Ossman3106.45%12.17%
Al Viro2685.58%613.04%
Joe Perches681.41%36.52%
David Howells541.12%12.17%
Ingo Molnar491.02%48.70%
Linus Torvalds140.29%24.35%
Bob Miller50.10%12.17%
Chris Wedgwood40.08%12.17%
Arnaldo Carvalho de Melo40.08%12.17%
Tejun Heo30.06%12.17%
David S. Miller20.04%12.17%
Andrew Morton20.04%12.17%
Alexey Dobriyan20.04%12.17%
Dave Jones10.02%12.17%
Total4806100.00%46100.00%
Directory: fs/ncpfs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.