date and time created 82/08/01 12:33:31 by root
[unix-history] / usr / src / sys / kern / uipc_socket.c
CommitLineData
90aaea96 1/* socket.c 4.43 82/07/21 */
ce9d8eb4
BJ
2
3#include "../h/param.h"
92a533e6 4#include "../h/systm.h"
ce9d8eb4
BJ
5#include "../h/dir.h"
6#include "../h/user.h"
92a533e6
BJ
7#include "../h/proc.h"
8#include "../h/file.h"
ce9d8eb4 9#include "../h/inode.h"
92a533e6 10#include "../h/buf.h"
ce9d8eb4 11#include "../h/mbuf.h"
92a533e6
BJ
12#include "../h/protosw.h"
13#include "../h/socket.h"
14#include "../h/socketvar.h"
ae921915 15#include "../h/stat.h"
b8acc34d 16#include "../h/ioctl.h"
c5ff2e32
BJ
17#include "../net/in.h"
18#include "../net/in_systm.h"
2a4251c4 19#include "../net/route.h"
ce9d8eb4 20
ce9d8eb4 21/*
cc15ab5d
BJ
22 * Socket support routines.
23 *
24 * DEAL WITH INTERRUPT NOTIFICATION.
ce9d8eb4 25 */
ce9d8eb4
BJ
26
27/*
28 * Create a socket.
29 */
2b4b57cd 30socreate(aso, type, asp, asa, options)
ce9d8eb4
BJ
31 struct socket **aso;
32 int type;
2b4b57cd
BJ
33 struct sockproto *asp;
34 struct sockaddr *asa;
92a533e6 35 int options;
ce9d8eb4
BJ
36{
37 register struct protosw *prp;
38 register struct socket *so;
39 struct mbuf *m;
cc15ab5d 40 int pf, proto, error;
ce9d8eb4
BJ
41
42 /*
cc15ab5d
BJ
43 * Use process standard protocol/protocol family if none
44 * specified by address argument.
ce9d8eb4 45 */
2b4b57cd 46 if (asp == 0) {
cc15ab5d 47 pf = PF_INET; /* should be u.u_protof */
ce9d8eb4
BJ
48 proto = 0;
49 } else {
2b4b57cd
BJ
50 pf = asp->sp_family;
51 proto = asp->sp_protocol;
ce9d8eb4 52 }
cc15ab5d
BJ
53
54 /*
55 * If protocol specified, look for it, otherwise
56 * for a protocol of the correct type in the right family.
57 */
58 if (proto)
59 prp = pffindproto(pf, proto);
60 else
61 prp = pffindtype(pf, type);
62 if (prp == 0)
63 return (EPROTONOSUPPORT);
ce9d8eb4
BJ
64
65 /*
66 * Get a socket structure.
67 */
cc15ab5d 68 m = m_getclr(M_WAIT);
ce9d8eb4
BJ
69 if (m == 0)
70 return (ENOBUFS);
ce9d8eb4 71 so = mtod(m, struct socket *);
92a533e6 72 so->so_options = options;
90aaea96
BJ
73 if (options & SO_ACCEPTCONN) {
74 so->so_q = so;
75 so->so_q0 = so;
76 so->so_qlimit = (so->so_options & SO_NEWFDONCONN) ? 5 : 1;
77 }
62364f0e
BJ
78 so->so_state = 0;
79 if (u.u_uid == 0)
80 so->so_state = SS_PRIV;
ce9d8eb4
BJ
81
82 /*
cc15ab5d
BJ
83 * Attach protocol to socket, initializing
84 * and reserving resources.
ce9d8eb4
BJ
85 */
86 so->so_proto = prp;
b91acce4
BJ
87 error = (*prp->pr_usrreq)(so, PRU_ATTACH, 0, asa);
88 if (error) {
90aaea96 89 so->so_state |= SS_NOFDREF;
de48daf3 90 sofree(so);
cc15ab5d 91 return (error);
ce9d8eb4
BJ
92 }
93 *aso = so;
94 return (0);
95}
96
ae921915
BJ
97sofree(so)
98 struct socket *so;
99{
100
90aaea96
BJ
101 if (so->so_head) {
102 if (!soqremque(so, 0) && !soqremque(so, 1))
103 panic("sofree dq");
104 so->so_head = 0;
105 }
106 if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
4ad99bae
BJ
107 return;
108 sbrelease(&so->so_snd);
109 sbrelease(&so->so_rcv);
2752c877 110 (void) m_free(dtom(so));
ae921915
BJ
111}
112
92a533e6 113/*
cc15ab5d
BJ
114 * Close a socket on last file table reference removal.
115 * Initiate disconnect if connected.
116 * Free socket when disconnect complete.
92a533e6 117 */
89900a09 118soclose(so, exiting)
92a533e6 119 register struct socket *so;
89900a09 120 int exiting;
92a533e6 121{
cc15ab5d 122 int s = splnet(); /* conservative */
90aaea96 123 register struct socket *so2;
cc15ab5d 124
90aaea96
BJ
125 if (so->so_options & SO_ACCEPTCONN) {
126 while (so->so_q0 != so)
127 soclose(so->so_q0, 1);
128 while (so->so_q != so)
129 soclose(so->so_q, 1);
130 }
cc15ab5d
BJ
131 if (so->so_pcb == 0)
132 goto discard;
1ee9e088
BJ
133 if (exiting)
134 so->so_options |= SO_KEEPALIVE;
cc15ab5d
BJ
135 if (so->so_state & SS_ISCONNECTED) {
136 if ((so->so_state & SS_ISDISCONNECTING) == 0) {
2b4b57cd 137 u.u_error = sodisconnect(so, (struct sockaddr *)0);
cc15ab5d 138 if (u.u_error) {
89900a09
BJ
139 if (exiting)
140 goto drop;
cc15ab5d
BJ
141 splx(s);
142 return;
143 }
144 }
30b84e26 145 if ((so->so_options & SO_DONTLINGER) == 0) {
b8acc34d 146 if ((so->so_state & SS_ISDISCONNECTING) &&
62364f0e 147 (so->so_state & SS_NBIO) &&
89900a09 148 exiting == 0) {
b8acc34d
BJ
149 u.u_error = EINPROGRESS;
150 splx(s);
151 return;
152 }
89900a09 153 /* should use tsleep here, for at most linger */
b8acc34d
BJ
154 while (so->so_state & SS_ISCONNECTED)
155 sleep((caddr_t)&so->so_timeo, PZERO+1);
72857acf 156 }
cc15ab5d 157 }
89900a09 158drop:
37c0974a
SL
159 if (so->so_pcb) {
160 u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, 0, 0);
161 if (exiting == 0 && u.u_error) {
162 splx(s);
163 return;
164 }
165 }
cc15ab5d 166discard:
90aaea96 167 so->so_state |= SS_NOFDREF;
4ad99bae 168 sofree(so);
cc15ab5d 169 splx(s);
92a533e6
BJ
170}
171
ae921915 172/*ARGSUSED*/
cc15ab5d 173sostat(so, sb)
92a533e6 174 struct socket *so;
cc15ab5d 175 struct stat *sb;
92a533e6
BJ
176{
177
5e35cca3
BJ
178 bzero((caddr_t)sb, sizeof (*sb)); /* XXX */
179 return (0); /* XXX */
92a533e6
BJ
180}
181
2b4b57cd
BJ
182/*
183 * Accept connection on a socket.
184 */
185soaccept(so, asa)
186 struct socket *so;
187 struct sockaddr *asa;
188{
189 int s = splnet();
190 int error;
191
2b4b57cd 192 error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, 0, (caddr_t)asa);
2b4b57cd
BJ
193 splx(s);
194 return (error);
195}
196
ce9d8eb4 197/*
cc15ab5d
BJ
198 * Connect socket to a specified address.
199 * If already connected or connecting, then avoid
200 * the protocol entry, to keep its job simpler.
ce9d8eb4 201 */
2b4b57cd 202soconnect(so, asa)
ce9d8eb4 203 struct socket *so;
2b4b57cd 204 struct sockaddr *asa;
ce9d8eb4 205{
cc15ab5d
BJ
206 int s = splnet();
207 int error;
ce9d8eb4 208
cc15ab5d
BJ
209 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) {
210 error = EISCONN;
211 goto bad;
212 }
2b4b57cd 213 error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, 0, (caddr_t)asa);
cc15ab5d
BJ
214bad:
215 splx(s);
216 return (error);
ce9d8eb4
BJ
217}
218
219/*
cc15ab5d
BJ
220 * Disconnect from a socket.
221 * Address parameter is from system call for later multicast
222 * protocols. Check to make sure that connected and no disconnect
223 * in progress (for protocol's sake), and then invoke protocol.
ce9d8eb4 224 */
2b4b57cd 225sodisconnect(so, asa)
ce9d8eb4 226 struct socket *so;
2b4b57cd 227 struct sockaddr *asa;
ce9d8eb4 228{
cc15ab5d
BJ
229 int s = splnet();
230 int error;
ce9d8eb4 231
cc15ab5d
BJ
232 if ((so->so_state & SS_ISCONNECTED) == 0) {
233 error = ENOTCONN;
234 goto bad;
ce9d8eb4 235 }
cc15ab5d
BJ
236 if (so->so_state & SS_ISDISCONNECTING) {
237 error = EALREADY;
238 goto bad;
ce9d8eb4 239 }
2b4b57cd 240 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, 0, asa);
cc15ab5d
BJ
241bad:
242 splx(s);
243 return (error);
ce9d8eb4
BJ
244}
245
cc15ab5d
BJ
246/*
247 * Send on a socket.
248 * If send must go all at once and message is larger than
249 * send buffering, then hard error.
250 * Lock against other senders.
251 * If must go all at once and not enough room now, then
252 * inform user that this would block and do nothing.
253 */
2b4b57cd 254sosend(so, asa)
ce9d8eb4 255 register struct socket *so;
2b4b57cd 256 struct sockaddr *asa;
ce9d8eb4 257{
cc15ab5d
BJ
258 struct mbuf *top = 0;
259 register struct mbuf *m, **mp = ⊤
ae921915
BJ
260 register u_int len;
261 int error = 0, space, s;
ce9d8eb4 262
cc15ab5d
BJ
263 if (sosendallatonce(so) && u.u_count > so->so_snd.sb_hiwat)
264 return (EMSGSIZE);
0f90f987
BJ
265#ifdef notdef
266 /* NEED TO PREVENT BUSY WAITING IN SELECT FOR WRITING */
62364f0e 267 if ((so->so_snd.sb_flags & SB_LOCK) && (so->so_state & SS_NBIO))
cc15ab5d 268 return (EWOULDBLOCK);
0f90f987
BJ
269#endif
270restart:
cc15ab5d
BJ
271 sblock(&so->so_snd);
272#define snderr(errno) { error = errno; splx(s); goto release; }
273
cc15ab5d 274again:
0f90f987
BJ
275 s = splnet();
276 if (so->so_state & SS_CANTSENDMORE) {
277 psignal(u.u_procp, SIGPIPE);
278 snderr(EPIPE);
279 }
4c078bb2
BJ
280 if (so->so_error) {
281 error = so->so_error;
0f90f987 282 so->so_error = 0; /* ??? */
4c078bb2
BJ
283 splx(s);
284 goto release;
285 }
cc15ab5d
BJ
286 if ((so->so_state & SS_ISCONNECTED) == 0) {
287 if (so->so_proto->pr_flags & PR_CONNREQUIRED)
288 snderr(ENOTCONN);
2b4b57cd 289 if (asa == 0)
cc15ab5d
BJ
290 snderr(EDESTADDRREQ);
291 }
cc15ab5d 292 if (top) {
2b4b57cd 293 error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, asa);
0f90f987 294 top = 0;
cc15ab5d
BJ
295 if (error) {
296 splx(s);
ce9d8eb4
BJ
297 goto release;
298 }
cc15ab5d 299 mp = ⊤
ce9d8eb4 300 }
b91acce4
BJ
301 if (u.u_count == 0) {
302 splx(s);
303 goto release;
304 }
50fc8df6 305 space = sbspace(&so->so_snd);
6fa47729 306 if (space <= 0 || sosendallatonce(so) && space < u.u_count) {
62364f0e 307 if (so->so_state & SS_NBIO)
cc15ab5d
BJ
308 snderr(EWOULDBLOCK);
309 sbunlock(&so->so_snd);
310 sbwait(&so->so_snd);
311 splx(s);
0f90f987 312 goto restart;
ce9d8eb4 313 }
cc15ab5d 314 splx(s);
50fc8df6 315 while (u.u_count && space > 0) {
cc15ab5d
BJ
316 MGET(m, 1);
317 if (m == NULL) {
0f90f987 318 error = ENOBUFS; /* SIGPIPE? */
cc15ab5d 319 goto release;
ce9d8eb4 320 }
c5ff2e32 321 if (u.u_count >= CLBYTES && space >= CLBYTES) {
cc15ab5d 322 register struct mbuf *p;
c5ff2e32 323 MCLGET(p, 1);
cc15ab5d
BJ
324 if (p == 0)
325 goto nopages;
326 m->m_off = (int)p - (int)m;
c5ff2e32 327 len = CLBYTES;
cc15ab5d 328 } else {
ce9d8eb4 329nopages:
cc15ab5d
BJ
330 m->m_off = MMINOFF;
331 len = MIN(MLEN, u.u_count);
ce9d8eb4 332 }
cc15ab5d
BJ
333 iomove(mtod(m, caddr_t), len, B_WRITE);
334 m->m_len = len;
335 *mp = m;
336 mp = &m->m_next;
50fc8df6 337 space = sbspace(&so->so_snd);
ce9d8eb4 338 }
cc15ab5d
BJ
339 goto again;
340
ce9d8eb4 341release:
cc15ab5d 342 sbunlock(&so->so_snd);
0f90f987
BJ
343 if (top)
344 m_freem(top);
ce9d8eb4
BJ
345 return (error);
346}
347
2b4b57cd 348soreceive(so, asa)
ce9d8eb4 349 register struct socket *so;
2b4b57cd 350 struct sockaddr *asa;
ce9d8eb4
BJ
351{
352 register struct mbuf *m, *n;
ae921915 353 u_int len;
edebca28
BJ
354 int eor, s, error = 0, cnt = u.u_count;
355 caddr_t base = u.u_base;
ce9d8eb4 356
cc15ab5d
BJ
357restart:
358 sblock(&so->so_rcv);
359 s = splnet();
360
361#define rcverr(errno) { error = errno; splx(s); goto release; }
ce9d8eb4 362 if (so->so_rcv.sb_cc == 0) {
4c078bb2
BJ
363 if (so->so_error) {
364 error = so->so_error;
365 so->so_error = 0;
366 splx(s);
367 goto release;
368 }
cc15ab5d
BJ
369 if (so->so_state & SS_CANTRCVMORE) {
370 splx(s);
371 goto release;
372 }
196d84fd
BJ
373 if ((so->so_state & SS_ISCONNECTED) == 0 &&
374 (so->so_proto->pr_flags & PR_CONNREQUIRED))
375 rcverr(ENOTCONN);
62364f0e 376 if (so->so_state & SS_NBIO)
4c078bb2 377 rcverr(EWOULDBLOCK);
cc15ab5d 378 sbunlock(&so->so_rcv);
2752c877 379 sbwait(&so->so_rcv);
a4f6d93d 380 splx(s);
cc15ab5d 381 goto restart;
ce9d8eb4 382 }
92a533e6 383 m = so->so_rcv.sb_mb;
ce9d8eb4
BJ
384 if (m == 0)
385 panic("receive");
b031e888 386 if (so->so_proto->pr_flags & PR_ADDR) {
b031e888
BJ
387 if (m->m_len != sizeof (struct sockaddr))
388 panic("soreceive addr");
389 if (asa)
390 bcopy(mtod(m, caddr_t), (caddr_t)asa, sizeof (*asa));
b031e888
BJ
391 so->so_rcv.sb_cc -= m->m_len;
392 so->so_rcv.sb_mbcnt -= MSIZE;
50fc8df6 393 m = m_free(m);
cc15ab5d
BJ
394 if (m == 0)
395 panic("receive 2");
50fc8df6 396 so->so_rcv.sb_mb = m;
cc15ab5d 397 }
edebca28
BJ
398 so->so_state &= ~SS_RCVATMARK;
399 if (so->so_oobmark && cnt > so->so_oobmark)
400 cnt = so->so_oobmark;
ce9d8eb4
BJ
401 eor = 0;
402 do {
edebca28 403 len = MIN(m->m_len, cnt);
ce9d8eb4
BJ
404 splx(s);
405 iomove(mtod(m, caddr_t), len, B_READ);
edebca28 406 cnt -= len;
ce9d8eb4
BJ
407 s = splnet();
408 if (len == m->m_len) {
e495e1cc
BJ
409 eor = (int)m->m_act;
410 sbfree(&so->so_rcv, m);
411 so->so_rcv.sb_mb = m->m_next;
ce9d8eb4
BJ
412 MFREE(m, n);
413 } else {
414 m->m_off += len;
415 m->m_len -= len;
92a533e6 416 so->so_rcv.sb_cc -= len;
ce9d8eb4 417 }
edebca28 418 } while ((m = so->so_rcv.sb_mb) && cnt && !eor);
ce9d8eb4
BJ
419 if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0)
420 do {
ce9d8eb4 421 if (m == 0)
cc15ab5d
BJ
422 panic("receive 3");
423 sbfree(&so->so_rcv, m);
ce9d8eb4
BJ
424 eor = (int)m->m_act;
425 so->so_rcv.sb_mb = m->m_next;
426 MFREE(m, n);
cc15ab5d 427 m = n;
ce9d8eb4 428 } while (eor == 0);
cc15ab5d
BJ
429 if ((so->so_proto->pr_flags & PR_WANTRCVD) && so->so_pcb)
430 (*so->so_proto->pr_usrreq)(so, PRU_RCVD, 0, 0);
edebca28
BJ
431 if (so->so_oobmark) {
432 so->so_oobmark -= u.u_base - base;
433 if (so->so_oobmark == 0)
434 so->so_state |= SS_RCVATMARK;
435 }
cc15ab5d 436release:
ae921915 437 sbunlock(&so->so_rcv);
cc15ab5d 438 splx(s);
ae921915 439 return (error);
92a533e6
BJ
440}
441
edebca28
BJ
442sohasoutofband(so)
443 struct socket *so;
444{
445
446 if (so->so_pgrp == 0)
447 return;
448 if (so->so_pgrp > 0)
449 gsignal(so->so_pgrp, SIGURG);
0a0f7cbb
BJ
450 else {
451 struct proc *p = pfind(-so->so_pgrp);
452
453 if (p)
454 psignal(p, SIGURG);
455 }
edebca28
BJ
456}
457
ae921915
BJ
458/*ARGSUSED*/
459soioctl(so, cmd, cmdp)
92a533e6
BJ
460 register struct socket *so;
461 int cmd;
462 register caddr_t cmdp;
463{
464
2156d53c 465 switch (cmd) {
92a533e6 466
30b84e26
BJ
467 case FIONBIO: {
468 int nbio;
469 if (copyin(cmdp, (caddr_t)&nbio, sizeof (nbio))) {
470 u.u_error = EFAULT;
471 return;
472 }
473 if (nbio)
62364f0e 474 so->so_state |= SS_NBIO;
30b84e26 475 else
62364f0e 476 so->so_state &= ~SS_NBIO;
30b84e26
BJ
477 return;
478 }
479
480 case FIOASYNC: {
481 int async;
482 if (copyin(cmdp, (caddr_t)&async, sizeof (async))) {
483 u.u_error = EFAULT;
484 return;
485 }
486 if (async)
62364f0e 487 so->so_state |= SS_ASYNC;
30b84e26 488 else
62364f0e 489 so->so_state &= ~SS_ASYNC;
30b84e26
BJ
490 return;
491 }
492
493 case SIOCSKEEP: {
494 int keep;
495 if (copyin(cmdp, (caddr_t)&keep, sizeof (keep))) {
496 u.u_error = EFAULT;
497 return;
498 }
499 if (keep)
9d2f171f 500 so->so_options &= ~SO_KEEPALIVE;
90aaea96
BJ
501 else
502 so->so_options |= SO_KEEPALIVE;
30b84e26
BJ
503 return;
504 }
505
506 case SIOCGKEEP: {
62364f0e 507 int keep = (so->so_options & SO_KEEPALIVE) != 0;
30b84e26
BJ
508 if (copyout((caddr_t)&keep, cmdp, sizeof (keep)))
509 u.u_error = EFAULT;
510 return;
511 }
512
513 case SIOCSLINGER: {
514 int linger;
515 if (copyin(cmdp, (caddr_t)&linger, sizeof (linger))) {
516 u.u_error = EFAULT;
517 return;
518 }
519 so->so_linger = linger;
520 if (so->so_linger)
521 so->so_options &= ~SO_DONTLINGER;
522 else
523 so->so_options |= SO_DONTLINGER;
524 return;
525 }
526
527 case SIOCGLINGER: {
528 int linger = so->so_linger;
529 if (copyout((caddr_t)&linger, cmdp, sizeof (linger))) {
530 u.u_error = EFAULT;
531 return;
532 }
533 }
edebca28
BJ
534 case SIOCSPGRP: {
535 int pgrp;
536 if (copyin(cmdp, (caddr_t)&pgrp, sizeof (pgrp))) {
537 u.u_error = EFAULT;
538 return;
539 }
540 so->so_pgrp = pgrp;
541 return;
542 }
543
544 case SIOCGPGRP: {
545 int pgrp = so->so_pgrp;
546 if (copyout((caddr_t)&pgrp, cmdp, sizeof (pgrp))) {
547 u.u_error = EFAULT;
548 return;
549 }
550 }
30b84e26 551
b8acc34d
BJ
552 case SIOCDONE: {
553 int flags;
554 if (copyin(cmdp, (caddr_t)&flags, sizeof (flags))) {
555 u.u_error = EFAULT;
556 return;
557 }
30b84e26 558 flags++;
b8acc34d
BJ
559 if (flags & FREAD) {
560 int s = splimp();
561 socantrcvmore(so);
562 sbflush(&so->so_rcv);
785e10b7 563 splx(s);
b8acc34d
BJ
564 }
565 if (flags & FWRITE)
c30cd845 566 u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_SHUTDOWN, (struct mbuf *)0, 0);
b8acc34d
BJ
567 return;
568 }
569
edebca28
BJ
570 case SIOCSENDOOB: {
571 char oob;
572 struct mbuf *m;
573 if (copyin(cmdp, (caddr_t)&oob, sizeof (oob))) {
574 u.u_error = EFAULT;
575 return;
576 }
577 m = m_get(M_DONTWAIT);
578 if (m == 0) {
579 u.u_error = ENOBUFS;
580 return;
581 }
582 m->m_off = MMINOFF;
583 m->m_len = 1;
584 *mtod(m, caddr_t) = oob;
585 (*so->so_proto->pr_usrreq)(so, PRU_SENDOOB, m, 0);
586 return;
587 }
588
589 case SIOCRCVOOB: {
590 struct mbuf *m = m_get(M_DONTWAIT);
591 if (m == 0) {
592 u.u_error = ENOBUFS;
593 return;
594 }
595 m->m_off = MMINOFF; *mtod(m, caddr_t) = 0;
596 (*so->so_proto->pr_usrreq)(so, PRU_RCVOOB, m, 0);
597 if (copyout(mtod(m, caddr_t), cmdp, sizeof (char))) {
598 u.u_error = EFAULT;
599 return;
600 }
601 m_free(m);
602 return;
603 }
604
605 case SIOCATMARK: {
606 int atmark = (so->so_state&SS_RCVATMARK) != 0;
607 if (copyout((caddr_t)&atmark, cmdp, sizeof (atmark))) {
608 u.u_error = EFAULT;
609 return;
610 }
611 return;
612 }
2a4251c4
SL
613
614 /* routing table update calls */
615 case SIOCADDRT:
616 case SIOCDELRT:
617 case SIOCCHGRT: {
618 struct rtentry route;
2a4251c4
SL
619 if (!suser())
620 return;
2a4251c4
SL
621 if (copyin(cmdp, (caddr_t)&route, sizeof (route))) {
622 u.u_error = EFAULT;
623 return;
624 }
625 u.u_error = rtrequest(cmd, &route);
626 return;
627 }
628
5e1eeba0 629 /* type/protocol specific ioctls */
92a533e6 630 }
5e1eeba0 631 u.u_error = EOPNOTSUPP;
ce9d8eb4 632}