ddp_usrreq.c revision 128943
1184610Salfred/*
2184610Salfred * Copyright (c) 1990,1994 Regents of The University of Michigan.
3184610Salfred * All Rights Reserved.  See COPYRIGHT.
4184610Salfred *
5184610Salfred * $FreeBSD: head/sys/netatalk/ddp_usrreq.c 128943 2004-05-05 03:34:37Z rwatson $
6184610Salfred */
7184610Salfred
8184610Salfred#include <sys/param.h>
9184610Salfred#include <sys/systm.h>
10184610Salfred#include <sys/malloc.h>
11184610Salfred#include <sys/mbuf.h>
12184610Salfred#include <sys/socket.h>
13184610Salfred#include <sys/socketvar.h>
14184610Salfred#include <sys/protosw.h>
15184610Salfred#include <net/if.h>
16184610Salfred#include <net/route.h>
17184610Salfred#include <net/netisr.h>
18184610Salfred
19184610Salfred#include <netatalk/at.h>
20184610Salfred#include <netatalk/at_var.h>
21184610Salfred#include <netatalk/ddp_var.h>
22184610Salfred#include <netatalk/ddp_pcb.h>
23184610Salfred#include <netatalk/at_extern.h>
24184610Salfred
25184610Salfredstatic u_long	ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
26184610Salfredstatic u_long	ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at));
27184610Salfred
28184610Salfredstatic struct ifqueue atintrq1, atintrq2, aarpintrq;
29184610Salfred
30184610Salfredstatic int
31184610Salfredddp_attach(struct socket *so, int proto, struct thread *td)
32184610Salfred{
33184610Salfred	struct ddpcb	*ddp;
34184610Salfred	int		error = 0;
35190754Sthompsa	int		s;
36184610Salfred
37184610Salfred
38188942Sthompsa	ddp = sotoddpcb(so);
39188942Sthompsa	if (ddp != NULL) {
40188942Sthompsa	    return (EINVAL);
41184610Salfred	}
42184610Salfred
43184610Salfred	s = splnet();
44188942Sthompsa	error = at_pcballoc(so);
45188942Sthompsa	splx(s);
46188942Sthompsa	if (error) {
47188942Sthompsa	    return (error);
48188942Sthompsa	}
49188942Sthompsa	return (soreserve(so, ddp_sendspace, ddp_recvspace));
50188942Sthompsa}
51188942Sthompsa
52184610Salfredstatic int
53188942Sthompsaddp_detach(struct socket *so)
54188942Sthompsa{
55188942Sthompsa	struct ddpcb	*ddp;
56184610Salfred	int		s;
57190181Sthompsa
58190181Sthompsa	ddp = sotoddpcb(so);
59190181Sthompsa	if (ddp == NULL) {
60184610Salfred	    return (EINVAL);
61184610Salfred	}
62184610Salfred	s = splnet();
63184610Salfred	at_pcbdetach(so, ddp);
64184610Salfred	splx(s);
65184610Salfred	return (0);
66184610Salfred}
67184610Salfred
68184610Salfredstatic int
69184610Salfredddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
70184610Salfred{
71184610Salfred	struct ddpcb	*ddp;
72184610Salfred	int		error = 0;
73184610Salfred	int		s;
74184610Salfred
75184610Salfred	ddp = sotoddpcb(so);
76184610Salfred	if (ddp == NULL) {
77184610Salfred	    return (EINVAL);
78184610Salfred	}
79184610Salfred	s = splnet();
80184610Salfred	error = at_pcbsetaddr(ddp, nam, td);
81184610Salfred	splx(s);
82184610Salfred	return (error);
83184610Salfred}
84184610Salfred
85184610Salfredstatic int
86184610Salfredddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
87184610Salfred{
88184610Salfred	struct ddpcb	*ddp;
89184610Salfred	int		error = 0;
90184610Salfred	int		s;
91184610Salfred
92184610Salfred	ddp = sotoddpcb(so);
93184610Salfred	if (ddp == NULL) {
94184610Salfred	    return (EINVAL);
95184610Salfred	}
96184610Salfred
97184610Salfred	if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
98184610Salfred	    return (EISCONN);
99184610Salfred	}
100190735Sthompsa
101184610Salfred	s = splnet();
102184610Salfred	error = at_pcbconnect(ddp, nam, td);
103184610Salfred	splx(s);
104184610Salfred	if (error == 0)
105184610Salfred	    soisconnected(so);
106184610Salfred	return (error);
107184610Salfred}
108184610Salfred
109184610Salfredstatic int
110184610Salfredddp_disconnect(struct socket *so)
111184610Salfred{
112190183Sthompsa
113184610Salfred	struct ddpcb	*ddp;
114184610Salfred	int		s;
115184610Salfred
116184610Salfred	ddp = sotoddpcb(so);
117184610Salfred	if (ddp == NULL) {
118184610Salfred	    return (EINVAL);
119184610Salfred	}
120184610Salfred	if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
121184610Salfred	    return (ENOTCONN);
122184610Salfred	}
123184610Salfred
124184610Salfred	s = splnet();
125184610Salfred	at_pcbdisconnect(ddp);
126184610Salfred	ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
127184610Salfred	splx(s);
128184610Salfred	soisdisconnected(so);
129184610Salfred	return (0);
130184610Salfred}
131184610Salfred
132184610Salfredstatic int
133184610Salfredddp_shutdown(struct socket *so)
134184610Salfred{
135184610Salfred	struct ddpcb	*ddp;
136184610Salfred
137184610Salfred	ddp = sotoddpcb(so);
138184610Salfred	if (ddp == NULL) {
139184610Salfred		return (EINVAL);
140184610Salfred	}
141184610Salfred	socantsendmore(so);
142184610Salfred	return (0);
143184610Salfred}
144184610Salfred
145184610Salfredstatic int
146184610Salfredddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
147184610Salfred            struct mbuf *control, struct thread *td)
148184610Salfred{
149184610Salfred	struct ddpcb	*ddp;
150184610Salfred	int		error = 0;
151184610Salfred	int		s;
152184610Salfred
153184610Salfred	ddp = sotoddpcb(so);
154184610Salfred	if (ddp == NULL) {
155184610Salfred		return (EINVAL);
156184610Salfred	}
157184610Salfred
158184610Salfred    	if (control && control->m_len) {
159184610Salfred		return (EINVAL);
160184610Salfred    	}
161184610Salfred
162184610Salfred	if (addr != NULL) {
163184610Salfred		if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
164184610Salfred			return (EISCONN);
165188409Sthompsa		}
166184610Salfred
167184610Salfred		s = splnet();
168184610Salfred		error = at_pcbconnect(ddp, addr, td);
169184610Salfred		splx(s);
170184610Salfred		if (error) {
171184610Salfred			return (error);
172184610Salfred		}
173184610Salfred	} else {
174184610Salfred		if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) {
175184610Salfred			return (ENOTCONN);
176184610Salfred		}
177184610Salfred	}
178188409Sthompsa
179188409Sthompsa	s = splnet();
180184610Salfred	error = ddp_output(m, so);
181184610Salfred	if (addr != NULL) {
182184610Salfred	    at_pcbdisconnect(ddp);
183184610Salfred	}
184184610Salfred	splx(s);
185184610Salfred	return (error);
186184610Salfred}
187184610Salfred
188184610Salfredstatic int
189188409Sthompsaddp_abort(struct socket *so)
190188409Sthompsa{
191184610Salfred	struct ddpcb	*ddp;
192184610Salfred	int		s;
193184610Salfred
194184610Salfred	ddp = sotoddpcb(so);
195184610Salfred	if (ddp == NULL) {
196184610Salfred		return (EINVAL);
197184610Salfred	}
198184610Salfred	s = splnet();
199184610Salfred	at_pcbdetach(so, ddp);
200184610Salfred	splx(s);
201184610Salfred	return (0);
202184610Salfred}
203184610Salfred
204184610Salfredvoid
205184610Salfredddp_init(void)
206184610Salfred{
207184610Salfred
208184610Salfred	atintrq1.ifq_maxlen = IFQ_MAXLEN;
209184610Salfred	atintrq2.ifq_maxlen = IFQ_MAXLEN;
210184610Salfred	aarpintrq.ifq_maxlen = IFQ_MAXLEN;
211184610Salfred	mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
212184610Salfred	mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
213184610Salfred	mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
214184610Salfred	netisr_register(NETISR_ATALK1, at1intr, &atintrq1, 0);
215184610Salfred	netisr_register(NETISR_ATALK2, at2intr, &atintrq2, 0);
216184610Salfred	netisr_register(NETISR_AARP, aarpintr, &aarpintrq, 0);
217184610Salfred}
218184610Salfred
219184610Salfred#if 0
220184610Salfredstatic void
221184610Salfredddp_clean(void)
222184610Salfred{
223184610Salfred    struct ddpcb	*ddp;
224184610Salfred
225184610Salfred    for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next) {
226184610Salfred	at_pcbdetach(ddp->ddp_socket, ddp);
227184610Salfred    }
228184610Salfred}
229184610Salfred#endif
230184610Salfred
231184610Salfredstatic int
232184610Salfredat_setpeeraddr(struct socket *so, struct sockaddr **nam)
233184610Salfred{
234184610Salfred	return (EOPNOTSUPP);
235184610Salfred}
236184610Salfred
237184610Salfredstatic int
238184610Salfredat_setsockaddr(struct socket *so, struct sockaddr **nam)
239184610Salfred{
240184610Salfred	struct ddpcb	*ddp;
241184610Salfred
242184610Salfred	ddp = sotoddpcb(so);
243184610Salfred	if (ddp == NULL) {
244184610Salfred	    return (EINVAL);
245184610Salfred	}
246184610Salfred	at_sockaddr(ddp, nam);
247184610Salfred	return (0);
248184610Salfred}
249184610Salfred
250184610Salfredstruct pr_usrreqs ddp_usrreqs = {
251184610Salfred	ddp_abort,
252188409Sthompsa	pru_accept_notsupp,
253188409Sthompsa	ddp_attach,
254184610Salfred	ddp_bind,
255184610Salfred	ddp_connect,
256184610Salfred	pru_connect2_notsupp,
257184610Salfred	at_control,
258184610Salfred	ddp_detach,
259184610Salfred	ddp_disconnect,
260184610Salfred	pru_listen_notsupp,
261184610Salfred	at_setpeeraddr,
262188409Sthompsa	pru_rcvd_notsupp,
263188409Sthompsa	pru_rcvoob_notsupp,
264184610Salfred	ddp_send,
265184610Salfred	pru_sense_null,
266184610Salfred	ddp_shutdown,
267184610Salfred	at_setsockaddr,
268184610Salfred	sosend,
269184610Salfred	soreceive,
270184610Salfred	sopoll,
271184610Salfred	pru_sosetlabel_null
272184610Salfred};
273184610Salfred