1 /* $NetBSD: idrp_usrreq.c,v 1.15 2004/04/25 21:13:13 matt 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.15 2004/04/25 21:13:13 matt 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(void)
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 idrp_input(struct mbuf *m, ...)
94 {
95 struct sockaddr_iso *src, *dst;
96 va_list ap;
97
98 va_start(ap, m);
99 src = va_arg(ap, struct sockaddr_iso *);
100 dst = va_arg(ap, struct sockaddr_iso *);
101 va_end(ap);
102
103 if (idrp_isop.isop_socket == 0) {
104 bad: m_freem(m);
105 return;
106 }
107 bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
108 bcopy((caddr_t) & (src->siso_addr), (caddr_t) & idrp_addrs[0].siso_addr,
109 1 + src->siso_nlen);
110 bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
111 bcopy((caddr_t) & (dst->siso_addr), (caddr_t) & idrp_addrs[1].siso_addr,
112 1 + dst->siso_nlen);
113 if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
114 sisotosa(idrp_addrs), m, (struct mbuf *) 0) == 0)
115 goto bad;
116 sorwakeup(idrp_isop.isop_socket);
117 }
118
119 int
120 idrp_output(struct mbuf *m, ...)
121 {
122 struct sockaddr_iso *siso;
123 int s = splsoftnet(), i;
124 va_list ap;
125
126 va_start(ap, m);
127 siso = va_arg(ap, struct sockaddr_iso *);
128 va_end(ap);
129
130 bcopy((caddr_t) & (siso->siso_addr),
131 (caddr_t) & idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
132 siso++;
133 bcopy((caddr_t) & (siso->siso_addr),
134 (caddr_t) & idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
135 i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
136 splx(s);
137 return (i);
138 }
139
140 u_long idrp_sendspace = 3072; /* really max datagram size */
141 u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */
142
143 /* ARGSUSED */
144 int
145 idrp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
146 struct mbuf *control, struct proc *p)
147 {
148 struct rawcb *rp;
149 int error = 0;
150
151 if (req == PRU_CONTROL)
152 return (EOPNOTSUPP);
153
154 rp = sotorawcb(so);
155 #ifdef DIAGNOSTIC
156 if (req != PRU_SEND && req != PRU_SENDOOB && control)
157 panic("idrp_usrreq: unexpected control mbuf");
158 #endif
159 if (rp == 0 && req != PRU_ATTACH) {
160 error = EINVAL;
161 goto release;
162 }
163
164 /*
165 * Note: need to block idrp_input while changing the udp pcb queue
166 * and/or pcb addresses.
167 */
168 switch (req) {
169
170 case PRU_ATTACH:
171 if (rp != 0) {
172 error = EISCONN;
173 break;
174 }
175 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
176 error = soreserve(so, idrp_sendspace, idrp_recvspace);
177 if (error)
178 break;
179 }
180 MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK|M_ZERO);
181 if (rp == 0) {
182 error = ENOBUFS;
183 break;
184 }
185 rp->rcb_socket = so;
186 LIST_INSERT_HEAD(&idrp_pcb, rp, rcb_list);
187 so->so_pcb = rp;
188 break;
189
190 case PRU_SEND:
191 if (control && control->m_len) {
192 m_freem(control);
193 m_freem(m);
194 error = EINVAL;
195 break;
196 }
197 if (nam == NULL) {
198 m_freem(m);
199 error = EINVAL;
200 break;
201 }
202 /* error checking here */
203 error = idrp_output(m, mtod(nam, struct sockaddr_iso *));
204 break;
205
206 case PRU_SENDOOB:
207 m_freem(control);
208 m_freem(m);
209 error = EOPNOTSUPP;
210 break;
211
212 case PRU_DETACH:
213 raw_detach(rp);
214 break;
215
216 case PRU_SHUTDOWN:
217 socantsendmore(so);
218 break;
219
220 case PRU_SENSE:
221 /*
222 * stat: don't bother with a blocksize.
223 */
224 return (0);
225
226 default:
227 error = EOPNOTSUPP;
228 break;
229 }
230
231 release:
232 return (error);
233 }
Cache object: 59faf74913ac7b487bc2c60df3df6437
|