1139823Simp/*- 274060Sbp * Copyright (c) 1999, 2000, 2001 Boris Popov 351852Sbp * All rights reserved. 451852Sbp * 551852Sbp * Redistribution and use in source and binary forms, with or without 651852Sbp * modification, are permitted provided that the following conditions 751852Sbp * are met: 851852Sbp * 1. Redistributions of source code must retain the above copyright 951852Sbp * notice, this list of conditions and the following disclaimer. 1051852Sbp * 2. Redistributions in binary form must reproduce the above copyright 1151852Sbp * notice, this list of conditions and the following disclaimer in the 1251852Sbp * documentation and/or other materials provided with the distribution. 1351852Sbp * 1451852Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1551852Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1651852Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1751852Sbp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1851852Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1951852Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2051852Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2151852Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2251852Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2351852Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2451852Sbp * SUCH DAMAGE. 2551852Sbp */ 26116189Sobrien 27116189Sobrien#include <sys/cdefs.h> 28116189Sobrien__FBSDID("$FreeBSD$"); 29116189Sobrien 3051852Sbp#include <sys/param.h> 3176166Smarkm#include <sys/systm.h> 3251852Sbp#include <sys/errno.h> 33112564Sjhb#include <sys/eventhandler.h> 3476166Smarkm#include <sys/kernel.h> 3576166Smarkm#include <sys/lock.h> 3676166Smarkm#include <sys/malloc.h> 3751852Sbp#include <sys/proc.h> 3874060Sbp#include <sys/sysctl.h> 3951852Sbp#include <sys/time.h> 4051852Sbp 4151852Sbp#include <netncp/ncp.h> 4251852Sbp#include <netncp/ncp_conn.h> 4351852Sbp#include <netncp/ncp_sock.h> 4451852Sbp#include <netncp/ncp_subr.h> 4551852Sbp#include <netncp/ncp_rq.h> 4651852Sbp#include <netncp/ncp_ncp.h> 4751852Sbp#include <netncp/nwerror.h> 4851852Sbp 4951852Sbpint ncp_debuglevel = 0; 5051852Sbp 5151852Sbpstruct callout_handle ncp_timer_handle; 52112564Sjhbstatic eventhandler_tag ncp_exit_tag; 5351852Sbp 54112564Sjhbstatic void ncp_at_exit(void *arg, struct proc *p); 5551852Sbpstatic void ncp_timer(void *arg); 5651852Sbp 5751852Sbp/* 5851852Sbp * duplicate string from user space. It should be very-very slow. 5951852Sbp */ 6051852Sbpchar * 6151852Sbpncp_str_dup(char *s) { 6251852Sbp char *p, bt; 6351852Sbp int len = 0; 6451852Sbp 6551852Sbp for (p = s;;p++) { 6651852Sbp if (copyin(p, &bt, 1)) return NULL; 6751852Sbp len++; 6851852Sbp if (bt == 0) break; 6951852Sbp } 70184205Sdes p = malloc(len, M_NCPDATA, M_WAITOK); 7151852Sbp copyin(s, p, len); 7251852Sbp return p; 7351852Sbp} 7451852Sbp 7551852Sbp 7651852Sbpvoid 77112564Sjhbncp_at_exit(void *arg, struct proc *p) 7874060Sbp{ 7951852Sbp struct ncp_conn *ncp, *nncp; 80111577Sfjoe struct thread *td; 8151852Sbp 82126941Speter mtx_lock(&Giant); 83111577Sfjoe FOREACH_THREAD_IN_PROC(p, td) { 84111577Sfjoe if (ncp_conn_putprochandles(td) == 0) 85111577Sfjoe continue; 8651852Sbp 87111577Sfjoe ncp_conn_locklist(LK_EXCLUSIVE, td); 88111577Sfjoe for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) { 89111577Sfjoe nncp = SLIST_NEXT(ncp, nc_next); 90111577Sfjoe if (ncp_conn_lock(ncp, td, td->td_ucred, 91111577Sfjoe NCPM_READ | NCPM_EXECUTE | NCPM_WRITE)) 92111577Sfjoe continue; 93111577Sfjoe if (ncp_conn_free(ncp) != 0) 94111577Sfjoe ncp_conn_unlock(ncp, td); 95111577Sfjoe } 96111577Sfjoe ncp_conn_unlocklist(td); 9751852Sbp } 98126941Speter mtx_unlock(&Giant); 9951852Sbp} 10051852Sbp 10151852Sbpint 10274060Sbpncp_init(void) 10374060Sbp{ 10451852Sbp ncp_conn_init(); 105112564Sjhb ncp_exit_tag = EVENTHANDLER_REGISTER(process_exit, ncp_at_exit, NULL, 106112564Sjhb EVENTHANDLER_PRI_ANY); 107111577Sfjoe ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK); 10851852Sbp return 0; 10951852Sbp} 11051852Sbp 11174060Sbpint 11274060Sbpncp_done(void) 11374060Sbp{ 11474060Sbp int error; 11574060Sbp 11674060Sbp error = ncp_conn_destroy(); 11774060Sbp if (error) 11874060Sbp return error; 119111577Sfjoe untimeout(ncp_timer, NULL, ncp_timer_handle); 120112564Sjhb EVENTHANDLER_DEREGISTER(process_exit, ncp_exit_tag); 12174060Sbp return 0; 12251852Sbp} 12351852Sbp 12451852Sbp 12551852Sbp/* tick every second and check for watch dog packets and lost connections */ 12651852Sbpstatic void 12774060Sbpncp_timer(void *arg) 12874060Sbp{ 12951852Sbp struct ncp_conn *conn; 13051852Sbp 13151852Sbp if(ncp_conn_locklist(LK_SHARED | LK_NOWAIT, NULL) == 0) { 13251852Sbp SLIST_FOREACH(conn, &conn_list, nc_next) 13351852Sbp ncp_check_conn(conn); 13451852Sbp ncp_conn_unlocklist(NULL); 13551852Sbp } 136111577Sfjoe ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK); 13751852Sbp} 138