1/*-
2 * Copyright (c) 1999, 2000, 2001 Boris Popov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/errno.h>
33#include <sys/eventhandler.h>
34#include <sys/kernel.h>
35#include <sys/lock.h>
36#include <sys/malloc.h>
37#include <sys/proc.h>
38#include <sys/sysctl.h>
39#include <sys/time.h>
40
41#include <netncp/ncp.h>
42#include <netncp/ncp_conn.h>
43#include <netncp/ncp_sock.h>
44#include <netncp/ncp_subr.h>
45#include <netncp/ncp_rq.h>
46#include <netncp/ncp_ncp.h>
47#include <netncp/nwerror.h>
48
49int ncp_debuglevel = 0;
50
51struct callout_handle ncp_timer_handle;
52static eventhandler_tag ncp_exit_tag;
53
54static void ncp_at_exit(void *arg, struct proc *p);
55static void ncp_timer(void *arg);
56
57/*
58 * duplicate string from user space. It should be very-very slow.
59 */
60char *
61ncp_str_dup(char *s) {
62	char *p, bt;
63	int len = 0;
64
65	for (p = s;;p++) {
66		if (copyin(p, &bt, 1)) return NULL;
67		len++;
68		if (bt == 0) break;
69	}
70	p = malloc(len, M_NCPDATA, M_WAITOK);
71	copyin(s, p, len);
72	return p;
73}
74
75
76void
77ncp_at_exit(void *arg, struct proc *p)
78{
79	struct ncp_conn *ncp, *nncp;
80	struct thread *td;
81
82	mtx_lock(&Giant);
83	FOREACH_THREAD_IN_PROC(p, td) {
84		if (ncp_conn_putprochandles(td) == 0)
85			continue;
86
87		ncp_conn_locklist(LK_EXCLUSIVE, td);
88		for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
89			nncp = SLIST_NEXT(ncp, nc_next);
90			if (ncp_conn_lock(ncp, td, td->td_ucred,
91					  NCPM_READ | NCPM_EXECUTE | NCPM_WRITE))
92				continue;
93			if (ncp_conn_free(ncp) != 0)
94				ncp_conn_unlock(ncp, td);
95		}
96		ncp_conn_unlocklist(td);
97	}
98	mtx_unlock(&Giant);
99}
100
101int
102ncp_init(void)
103{
104	ncp_conn_init();
105	ncp_exit_tag = EVENTHANDLER_REGISTER(process_exit, ncp_at_exit, NULL,
106	    EVENTHANDLER_PRI_ANY);
107	ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
108	return 0;
109}
110
111int
112ncp_done(void)
113{
114	int error;
115
116	error = ncp_conn_destroy();
117	if (error)
118		return error;
119	untimeout(ncp_timer, NULL, ncp_timer_handle);
120	EVENTHANDLER_DEREGISTER(process_exit, ncp_exit_tag);
121	return 0;
122}
123
124
125/* tick every second and check for watch dog packets and lost connections */
126static void
127ncp_timer(void *arg)
128{
129	struct ncp_conn *conn;
130
131	if(ncp_conn_locklist(LK_SHARED | LK_NOWAIT, NULL) == 0) {
132		SLIST_FOREACH(conn, &conn_list, nc_next)
133			ncp_check_conn(conn);
134		ncp_conn_unlocklist(NULL);
135	}
136	ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
137}
138