Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / netiso / idrp_usrreq.c
blob8df2506abb98422a94ede1ce0747ff2e2a1d456d
1 /* $NetBSD: idrp_usrreq.c,v 1.22 2009/03/18 17:06:52 cegger Exp $ */
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
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.
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.
31 * @(#)idrp_usrreq.c 8.1 (Berkeley) 6/10/93
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: idrp_usrreq.c,v 1.22 2009/03/18 17:06:52 cegger Exp $");
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>
47 #include <net/raw_cb.h>
48 #include <net/route.h>
49 #include <net/if.h>
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>
59 #include <machine/stdarg.h>
61 LIST_HEAD(, rawcb) idrp_pcb;
62 struct isopcb idrp_isop;
63 static struct sockaddr_iso idrp_addrs[2] =
66 .siso_len = sizeof(idrp_addrs[0]),
67 .siso_family = AF_ISO,
70 .siso_len = sizeof(idrp_addrs[1]),
71 .siso_family = AF_ISO,
76 * IDRP initialization
78 void
79 idrp_init(void)
81 extern struct clnl_protosw clnl_protox[256];
83 LIST_INIT(&idrp_pcb);
85 idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
86 idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
87 idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
88 idrp_isop.isop_sladdr = idrp_addrs[1];
89 idrp_isop.isop_sfaddr = idrp_addrs[1];
90 clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
94 * CALLED FROM:
95 * tpclnp_input().
96 * FUNCTION and ARGUMENTS:
97 * Take a packet (m) from clnp, strip off the clnp header
98 * and mke suitable for the idrp socket.
99 * No return value.
101 void
102 idrp_input(struct mbuf *m, ...)
104 struct sockaddr_iso *src, *dst;
105 va_list ap;
107 va_start(ap, m);
108 src = va_arg(ap, struct sockaddr_iso *);
109 dst = va_arg(ap, struct sockaddr_iso *);
110 va_end(ap);
112 if (idrp_isop.isop_socket == 0) {
113 bad: m_freem(m);
114 return;
116 memset(idrp_addrs[0].siso_data, 0, sizeof(idrp_addrs[0].siso_data));
117 memcpy((void *) & idrp_addrs[0].siso_addr, (void *) & (src->siso_addr),
118 1 + src->siso_nlen);
119 memset(idrp_addrs[1].siso_data, 0, sizeof(idrp_addrs[1].siso_data));
120 memcpy((void *) & idrp_addrs[1].siso_addr, (void *) & (dst->siso_addr),
121 1 + dst->siso_nlen);
122 if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
123 sisotosa(idrp_addrs), m, (struct mbuf *) 0) == 0)
124 goto bad;
125 sorwakeup(idrp_isop.isop_socket);
129 idrp_output(struct mbuf *m, ...)
131 struct sockaddr_iso *siso;
132 int s = splsoftnet(), i;
133 va_list ap;
135 va_start(ap, m);
136 siso = va_arg(ap, struct sockaddr_iso *);
137 va_end(ap);
139 bcopy((void *) & (siso->siso_addr),
140 (void *) & idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
141 siso++;
142 bcopy((void *) & (siso->siso_addr),
143 (void *) & idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
144 i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
145 splx(s);
146 return (i);
149 u_long idrp_sendspace = 3072; /* really max datagram size */
150 u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */
152 /* ARGSUSED */
154 idrp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
155 struct mbuf *control, struct lwp *l)
157 struct rawcb *rp;
158 struct proc *p;
159 int error = 0;
161 if (req == PRU_CONTROL)
162 return (EOPNOTSUPP);
164 p = l ? l->l_proc : NULL;
165 rp = sotorawcb(so);
166 #ifdef DIAGNOSTIC
167 if (req != PRU_SEND && req != PRU_SENDOOB && control)
168 panic("idrp_usrreq: unexpected control mbuf");
169 #endif
170 if (rp == 0 && req != PRU_ATTACH) {
171 error = EINVAL;
172 goto release;
176 * Note: need to block idrp_input while changing the udp pcb queue
177 * and/or pcb addresses.
179 switch (req) {
181 case PRU_ATTACH:
182 sosetlock(so);
183 if (rp != 0) {
184 error = EISCONN;
185 break;
187 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
188 error = soreserve(so, idrp_sendspace, idrp_recvspace);
189 if (error)
190 break;
192 rp = malloc(sizeof(*rp), M_PCB, M_WAITOK|M_ZERO);
193 if (rp == 0) {
194 error = ENOBUFS;
195 break;
197 rp->rcb_socket = so;
198 LIST_INSERT_HEAD(&idrp_pcb, rp, rcb_list);
199 so->so_pcb = rp;
200 break;
202 case PRU_SEND:
203 if (control && control->m_len) {
204 m_freem(control);
205 m_freem(m);
206 error = EINVAL;
207 break;
209 if (nam == NULL) {
210 m_freem(m);
211 error = EINVAL;
212 break;
214 /* error checking here */
215 error = idrp_output(m, mtod(nam, struct sockaddr_iso *));
216 break;
218 case PRU_SENDOOB:
219 m_freem(control);
220 m_freem(m);
221 error = EOPNOTSUPP;
222 break;
224 case PRU_DETACH:
225 raw_detach(rp);
226 break;
228 case PRU_SHUTDOWN:
229 socantsendmore(so);
230 break;
232 case PRU_SENSE:
234 * stat: don't bother with a blocksize.
236 return (0);
238 default:
239 error = EOPNOTSUPP;
240 break;
243 release:
244 return (error);