1 /* $NetBSD: idrp_usrreq.c,v 1.12 2003/08/07 16:33:35 agc Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)idrp_usrreq.c 8.1 (Berkeley) 6/10/93
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: idrp_usrreq.c,v 1.12 2003/08/07 16:33:35 agc Exp $");
36
37 #include <sys/param.h>
38 #include <sys/proc.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/protosw.h>
45 #include <sys/errno.h>
46
47 #include <net/raw_cb.h>
48 #include <net/route.h>
49 #include <net/if.h>
50
51 #include <netiso/argo_debug.h>
52 #include <netiso/iso.h>
53 #include <netiso/clnp.h>
54 #include <netiso/clnl.h>
55 #include <netiso/iso_pcb.h>
56 #include <netiso/iso_var.h>
57 #include <netiso/idrp_var.h>
58
59 #include <machine/stdarg.h>
60
61 LIST_HEAD(, rawcb) idrp_pcb;
62 struct isopcb idrp_isop;
63 static struct sockaddr_iso idrp_addrs[2] =
64 {{sizeof(idrp_addrs), AF_ISO,}, {sizeof(idrp_addrs[1]), AF_ISO,}};
65
66 /*
67 * IDRP initialization
68 */
69 void
70 idrp_init()
71 {
72 extern struct clnl_protosw clnl_protox[256];
73
74 LIST_INIT(&idrp_pcb);
75
76 idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
77 idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
78 idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
79 idrp_isop.isop_sladdr = idrp_addrs[1];
80 idrp_isop.isop_sfaddr = idrp_addrs[1];
81 clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
82 }
83
84 /*
85 * CALLED FROM:
86 * tpclnp_input().
87 * FUNCTION and ARGUMENTS:
88 * Take a packet (m) from clnp, strip off the clnp header
89 * and mke suitable for the idrp socket.
90 * No return value.
91 */
92 void
93 #if __STDC__
94 idrp_input(struct mbuf *m, ...)
95 #else
96 idrp_input(m, va_alist)
97 struct mbuf *m;
98 va_dcl
99 #endif
100 {
101 struct sockaddr_iso *src, *dst;
102 va_list ap;
103
104 va_start(ap, m);
105 src = va_arg(ap, struct sockaddr_iso *);
106 dst = va_arg(ap, struct sockaddr_iso *);
107 va_end(ap);
108
109 if (idrp_isop.isop_socket == 0) {
110 bad: m_freem(m);
111 return;
112 }
113 bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
114 bcopy((caddr_t) & (src->siso_addr), (caddr_t) & idrp_addrs[0].siso_addr,
115 1 + src->siso_nlen);
116 bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
117 bcopy((caddr_t) & (dst->siso_addr), (caddr_t) & idrp_addrs[1].siso_addr,
118 1 + dst->siso_nlen);
119 if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
120 sisotosa(idrp_addrs), m, (struct mbuf *) 0) == 0)
121 goto bad;
122 sorwakeup(idrp_isop.isop_socket);
123 }
124
125 int
126 #if __STDC__
127 idrp_output(struct mbuf *m, ...)
128 #else
129 idrp_output(m, va_alist)
130 struct mbuf *m;
131 va_dcl
132 #endif
133 {
134 struct sockaddr_iso *siso;
135 int s = splsoftnet(), i;
136 va_list ap;
137
138 va_start(ap, m);
139 siso = va_arg(ap, struct sockaddr_iso *);
140 va_end(ap);
141
142 bcopy((caddr_t) & (siso->siso_addr),
143 (caddr_t) & idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
144 siso++;
145 bcopy((caddr_t) & (siso->siso_addr),
146 (caddr_t) & idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
147 i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
148 splx(s);
149 return (i);
150 }
151
152 u_long idrp_sendspace = 3072; /* really max datagram size */
153 u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */
154
155 /* ARGSUSED */
156 int
157 idrp_usrreq(so, req, m, nam, control, p)
158 struct socket *so;
159 int req;
160 struct mbuf *m, *nam, *control;
161 struct proc *p;
162 {
163 struct rawcb *rp;
164 int error = 0;
165
166 if (req == PRU_CONTROL)
167 return (EOPNOTSUPP);
168
169 rp = sotorawcb(so);
170 #ifdef DIAGNOSTIC
171 if (req != PRU_SEND && req != PRU_SENDOOB && control)
172 panic("idrp_usrreq: unexpected control mbuf");
173 #endif
174 if (rp == 0 && req != PRU_ATTACH) {
175 error = EINVAL;
176 goto release;
177 }
178
179 /*
180 * Note: need to block idrp_input while changing the udp pcb queue
181 * and/or pcb addresses.
182 */
183 switch (req) {
184
185 case PRU_ATTACH:
186 if (rp != 0) {
187 error = EISCONN;
188 break;
189 }
190 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
191 error = soreserve(so, idrp_sendspace, idrp_recvspace);
192 if (error)
193 break;
194 }
195 MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
196 if (rp == 0) {
197 error = ENOBUFS;
198 break;
199 }
200 bzero(rp, sizeof(*rp));
201 rp->rcb_socket = so;
202 LIST_INSERT_HEAD(&idrp_pcb, rp, rcb_list);
203 so->so_pcb = rp;
204 break;
205
206 case PRU_SEND:
207 if (control && control->m_len) {
208 m_freem(control);
209 m_freem(m);
210 error = EINVAL;
211 break;
212 }
213 if (nam == NULL) {
214 m_freem(m);
215 error = EINVAL;
216 break;
217 }
218 /* error checking here */
219 error = idrp_output(m, mtod(nam, struct sockaddr_iso *));
220 break;
221
222 case PRU_SENDOOB:
223 m_freem(control);
224 m_freem(m);
225 error = EOPNOTSUPP;
226 break;
227
228 case PRU_DETACH:
229 raw_detach(rp);
230 break;
231
232 case PRU_SHUTDOWN:
233 socantsendmore(so);
234 break;
235
236 case PRU_SENSE:
237 /*
238 * stat: don't bother with a blocksize.
239 */
240 return (0);
241
242 default:
243 error = EOPNOTSUPP;
244 break;
245 }
246
247 release:
248 return (error);
249 }
Cache object: 3f9b2373ab558583a52500a6a915a8df
|