ANSIfy syscall args
[unix-history] / usr / src / sys / kern / uipc_syscalls.c
CommitLineData
da7c5cc6 1/*
da7c5cc6 2 *
dbf0c423 3 * %sccs.include.redist.c%
96e6449f 4 *
1d123e2b 5 * @(#)uipc_syscalls.c 7.26 (Berkeley) %G%
da7c5cc6 6 */
c8c7dd0e 7
94368568 8#include "param.h"
5e00df3b 9#include "filedesc.h"
6d47a3da 10#include "proc.h"
94368568 11#include "file.h"
94368568 12#include "buf.h"
6d47a3da 13#include "malloc.h"
94368568
JB
14#include "mbuf.h"
15#include "protosw.h"
16#include "socket.h"
17#include "socketvar.h"
813b7cd1
MT
18#ifdef KTRACE
19#include "ktrace.h"
20#endif
4147b3f6 21
c8c7dd0e 22/*
cf012934 23 * System call interface to the socket abstraction.
c8c7dd0e 24 */
8ffc8876
CT
25#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
26#define COMPAT_OLDSOCK
27#endif
c8c7dd0e 28
88a7a62a
SL
29extern struct fileops socketops;
30
85843d69
KM
31socket(p, uap, retval)
32 struct proc *p;
33 register struct args {
cf012934 34 int domain;
cc15ab5d 35 int type;
cf012934 36 int protocol;
85843d69
KM
37 } *uap;
38 int *retval;
39{
5e00df3b 40 struct filedesc *fdp = p->p_fd;
2b4b57cd 41 struct socket *so;
0c9a45f0 42 struct file *fp;
76ffad7c 43 int fd, error;
c8c7dd0e 44
5e00df3b 45 if (error = falloc(p, &fp, &fd))
d9c2f47f 46 return (error);
4147b3f6
BJ
47 fp->f_flag = FREAD|FWRITE;
48 fp->f_type = DTYPE_SOCKET;
88a7a62a 49 fp->f_ops = &socketops;
76ffad7c 50 if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {
994fd74e 51 fdp->fd_ofiles[fd] = 0;
336f999d 52 ffree(fp);
76ffad7c
MK
53 } else {
54 fp->f_data = (caddr_t)so;
85843d69 55 *retval = fd;
76ffad7c 56 }
d9c2f47f 57 return (error);
c8c7dd0e 58}
ae921915 59
85843d69
KM
60/* ARGSUSED */
61bind(p, uap, retval)
62 struct proc *p;
63 register struct args {
cf012934
BJ
64 int s;
65 caddr_t name;
66 int namelen;
85843d69
KM
67 } *uap;
68 int *retval;
69{
5e00df3b 70 struct file *fp;
cf012934 71 struct mbuf *nam;
76ffad7c 72 int error;
ae921915 73
5e00df3b 74 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 75 return (error);
76ffad7c 76 if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
d9c2f47f 77 return (error);
76ffad7c 78 error = sobind((struct socket *)fp->f_data, nam);
cf012934 79 m_freem(nam);
d9c2f47f 80 return (error);
cf012934
BJ
81}
82
85843d69
KM
83/* ARGSUSED */
84listen(p, uap, retval)
85 struct proc *p;
86 register struct args {
cf012934
BJ
87 int s;
88 int backlog;
85843d69
KM
89 } *uap;
90 int *retval;
91{
5e00df3b 92 struct file *fp;
76ffad7c 93 int error;
cf012934 94
5e00df3b 95 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f
MK
96 return (error);
97 return (solisten((struct socket *)fp->f_data, uap->backlog));
cf012934
BJ
98}
99
8ffc8876 100#ifdef COMPAT_OLDSOCK
85843d69
KM
101accept(p, uap, retval)
102 struct proc *p;
103 struct args {
76ffad7c
MK
104 int s;
105 caddr_t name;
106 int *anamelen;
107 int compat_43;
85843d69
KM
108 } *uap;
109 int *retval;
110{
76ffad7c 111
85843d69 112 uap->compat_43 = 0;
d9c2f47f 113 return (accept1(p, uap, retval));
f4d2893a
MK
114}
115
85843d69
KM
116oaccept(p, uap, retval)
117 struct proc *p;
118 struct args {
76ffad7c
MK
119 int s;
120 caddr_t name;
121 int *anamelen;
122 int compat_43;
85843d69
KM
123 } *uap;
124 int *retval;
125{
76ffad7c 126
85843d69 127 uap->compat_43 = 1;
d9c2f47f 128 return (accept1(p, uap, retval));
f4d2893a 129}
8ffc8876 130#else /* COMPAT_OLDSOCK */
f4d2893a 131
76ffad7c 132#define accept1 accept
f4d2893a 133#endif
76ffad7c 134
85843d69
KM
135accept1(p, uap, retval)
136 struct proc *p;
137 register struct args {
cf012934
BJ
138 int s;
139 caddr_t name;
140 int *anamelen;
8ffc8876 141#ifdef COMPAT_OLDSOCK
76ffad7c
MK
142 int compat_43;
143#endif
85843d69
KM
144 } *uap;
145 int *retval;
146{
0c9a45f0 147 struct file *fp;
cf012934 148 struct mbuf *nam;
27f43765 149 int namelen, error, s;
cf012934
BJ
150 register struct socket *so;
151
7a22a33c
MK
152 if (uap->name && (error = copyin((caddr_t)uap->anamelen,
153 (caddr_t)&namelen, sizeof (namelen))))
d9c2f47f 154 return (error);
5e00df3b 155 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 156 return (error);
2b4b57cd 157 s = splnet();
88a7a62a 158 so = (struct socket *)fp->f_data;
4147b3f6 159 if ((so->so_options & SO_ACCEPTCONN) == 0) {
4147b3f6 160 splx(s);
d9c2f47f 161 return (EINVAL);
4147b3f6
BJ
162 }
163 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
2b4b57cd 164 splx(s);
d9c2f47f 165 return (EWOULDBLOCK);
2b4b57cd 166 }
4147b3f6 167 while (so->so_qlen == 0 && so->so_error == 0) {
62229532
BJ
168 if (so->so_state & SS_CANTRCVMORE) {
169 so->so_error = ECONNABORTED;
170 break;
171 }
27f43765
MK
172 if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
173 netcon, 0)) {
174 splx(s);
d9c2f47f 175 return (error);
27f43765 176 }
62229532 177 }
f269ef23 178 if (so->so_error) {
27f43765 179 error = so->so_error;
f4ed5810 180 so->so_error = 0;
f269ef23 181 splx(s);
d9c2f47f 182 return (error);
f269ef23 183 }
5e00df3b 184 if (error = falloc(p, &fp, retval)) {
2b4b57cd 185 splx(s);
d9c2f47f 186 return (error);
cf012934
BJ
187 }
188 { struct socket *aso = so->so_q;
189 if (soqremque(aso, 1) == 0)
190 panic("accept");
191 so = aso;
2b4b57cd 192 }
4147b3f6
BJ
193 fp->f_type = DTYPE_SOCKET;
194 fp->f_flag = FREAD|FWRITE;
88a7a62a
SL
195 fp->f_ops = &socketops;
196 fp->f_data = (caddr_t)so;
cce93e4b 197 nam = m_get(M_WAIT, MT_SONAME);
66f52238 198 (void) soaccept(so, nam);
cf012934 199 if (uap->name) {
8ffc8876 200#ifdef COMPAT_OLDSOCK
76ffad7c 201 if (uap->compat_43)
f4d2893a
MK
202 mtod(nam, struct osockaddr *)->sa_family =
203 mtod(nam, struct sockaddr *)->sa_family;
204#endif
cf012934
BJ
205 if (namelen > nam->m_len)
206 namelen = nam->m_len;
207 /* SHOULD COPY OUT A CHAIN HERE */
7a22a33c
MK
208 if ((error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
209 (u_int)namelen)) == 0)
210 error = copyout((caddr_t)&namelen,
211 (caddr_t)uap->anamelen, sizeof (*uap->anamelen));
cf012934
BJ
212 }
213 m_freem(nam);
2b4b57cd 214 splx(s);
d9c2f47f 215 return (error);
ae921915
BJ
216}
217
85843d69
KM
218/* ARGSUSED */
219connect(p, uap, retval)
220 struct proc *p;
221 register struct args {
cf012934
BJ
222 int s;
223 caddr_t name;
224 int namelen;
85843d69
KM
225 } *uap;
226 int *retval;
227{
5e00df3b 228 struct file *fp;
c8c7dd0e 229 register struct socket *so;
cf012934 230 struct mbuf *nam;
27f43765 231 int error, s;
c8c7dd0e 232
5e00df3b 233 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 234 return (error);
88a7a62a 235 so = (struct socket *)fp->f_data;
27f43765 236 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
d9c2f47f 237 return (EALREADY);
27f43765 238 if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
d9c2f47f 239 return (error);
27f43765
MK
240 error = soconnect(so, nam);
241 if (error)
cf012934 242 goto bad;
27f43765 243 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
6222acc3 244 m_freem(nam);
d9c2f47f 245 return (EINPROGRESS);
6222acc3 246 }
c8c7dd0e 247 s = splnet();
cc15ab5d 248 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
27f43765
MK
249 if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
250 netcon, 0))
251 break;
252 if (error == 0) {
253 error = so->so_error;
254 so->so_error = 0;
255 }
cc15ab5d 256 splx(s);
cf012934 257bad:
6750daae 258 so->so_state &= ~SS_ISCONNECTING;
cf012934 259 m_freem(nam);
27f43765
MK
260 if (error == ERESTART)
261 error = EINTR;
d9c2f47f 262 return (error);
c8c7dd0e
BJ
263}
264
85843d69
KM
265socketpair(p, uap, retval)
266 struct proc *p;
267 register struct args {
5a48956d
SL
268 int domain;
269 int type;
270 int protocol;
271 int *rsv;
85843d69
KM
272 } *uap;
273 int retval[];
274{
5e00df3b 275 register struct filedesc *fdp = p->p_fd;
0c9a45f0 276 struct file *fp1, *fp2;
5a48956d 277 struct socket *so1, *so2;
76ffad7c 278 int fd, error, sv[2];
cf012934 279
76ffad7c 280 if (error = socreate(uap->domain, &so1, uap->type, uap->protocol))
d9c2f47f 281 return (error);
76ffad7c 282 if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))
b242cf10 283 goto free1;
5e00df3b 284 if (error = falloc(p, &fp1, &fd))
5a48956d 285 goto free2;
0c9a45f0 286 sv[0] = fd;
5a48956d
SL
287 fp1->f_flag = FREAD|FWRITE;
288 fp1->f_type = DTYPE_SOCKET;
289 fp1->f_ops = &socketops;
290 fp1->f_data = (caddr_t)so1;
5e00df3b 291 if (error = falloc(p, &fp2, &fd))
5a48956d
SL
292 goto free3;
293 fp2->f_flag = FREAD|FWRITE;
294 fp2->f_type = DTYPE_SOCKET;
295 fp2->f_ops = &socketops;
296 fp2->f_data = (caddr_t)so2;
0c9a45f0 297 sv[1] = fd;
76ffad7c 298 if (error = soconnect2(so1, so2))
5a48956d 299 goto free4;
33446404
MK
300 if (uap->type == SOCK_DGRAM) {
301 /*
302 * Datagram socket connection is asymmetric.
303 */
76ffad7c 304 if (error = soconnect2(so2, so1))
33446404
MK
305 goto free4;
306 }
76ffad7c 307 error = copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
85843d69
KM
308 retval[0] = sv[0]; /* XXX ??? */
309 retval[1] = sv[1]; /* XXX ??? */
d9c2f47f 310 return (error);
5a48956d 311free4:
336f999d 312 ffree(fp2);
994fd74e 313 fdp->fd_ofiles[sv[1]] = 0;
5a48956d 314free3:
336f999d 315 ffree(fp1);
994fd74e 316 fdp->fd_ofiles[sv[0]] = 0;
5a48956d 317free2:
8011f5df 318 (void)soclose(so2);
b242cf10 319free1:
8011f5df 320 (void)soclose(so1);
d9c2f47f 321 return (error);
cf012934
BJ
322}
323
85843d69
KM
324sendto(p, uap, retval)
325 struct proc *p;
326 register struct args {
cf012934
BJ
327 int s;
328 caddr_t buf;
329 int len;
330 int flags;
331 caddr_t to;
332 int tolen;
85843d69
KM
333 } *uap;
334 int *retval;
335{
88a7a62a 336 struct msghdr msg;
d3d550b5 337 struct iovec aiov;
5e00df3b 338 int error;
c8c7dd0e 339
88a7a62a
SL
340 msg.msg_name = uap->to;
341 msg.msg_namelen = uap->tolen;
342 msg.msg_iov = &aiov;
343 msg.msg_iovlen = 1;
27f43765 344 msg.msg_control = 0;
8ffc8876 345#ifdef COMPAT_OLDSOCK
27f43765
MK
346 msg.msg_flags = 0;
347#endif
cf012934
BJ
348 aiov.iov_base = uap->buf;
349 aiov.iov_len = uap->len;
5e00df3b 350 return (sendit(p, uap->s, &msg, uap->flags, retval));
c8c7dd0e
BJ
351}
352
8ffc8876 353#ifdef COMPAT_OLDSOCK
85843d69
KM
354osend(p, uap, retval)
355 struct proc *p;
356 register struct args {
cf012934
BJ
357 int s;
358 caddr_t buf;
359 int len;
360 int flags;
85843d69
KM
361 } *uap;
362 int *retval;
363{
88a7a62a 364 struct msghdr msg;
a6b6f679 365 struct iovec aiov;
cc15ab5d 366
88a7a62a
SL
367 msg.msg_name = 0;
368 msg.msg_namelen = 0;
369 msg.msg_iov = &aiov;
370 msg.msg_iovlen = 1;
cf012934
BJ
371 aiov.iov_base = uap->buf;
372 aiov.iov_len = uap->len;
6d47a3da 373 msg.msg_control = 0;
27f43765 374 msg.msg_flags = 0;
5e00df3b 375 return (sendit(p, uap->s, &msg, uap->flags, retval));
88a7a62a
SL
376}
377
7a22a33c 378#define MSG_COMPAT 0x8000
85843d69
KM
379osendmsg(p, uap, retval)
380 struct proc *p;
381 register struct args {
6d47a3da
MK
382 int s;
383 caddr_t msg;
384 int flags;
85843d69
KM
385 } *uap;
386 int *retval;
387{
6d47a3da 388 struct msghdr msg;
813b7cd1 389 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 390 int error;
6d47a3da 391
76ffad7c 392 if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (struct omsghdr)))
d9c2f47f 393 return (error);
813b7cd1
MT
394 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
395 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 396 return (EMSGSIZE);
813b7cd1
MT
397 MALLOC(iov, struct iovec *,
398 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
399 M_WAITOK);
400 } else
401 iov = aiov;
402 if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
403 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
404 goto done;
7a22a33c 405 msg.msg_flags = MSG_COMPAT;
813b7cd1 406 msg.msg_iov = iov;
5e00df3b 407 error = sendit(p, uap->s, &msg, uap->flags, retval);
813b7cd1
MT
408done:
409 if (iov != aiov)
410 FREE(iov, M_IOV);
d9c2f47f 411 return (error);
6d47a3da
MK
412}
413#endif
414
85843d69
KM
415sendmsg(p, uap, retval)
416 struct proc *p;
417 register struct args {
88a7a62a
SL
418 int s;
419 caddr_t msg;
420 int flags;
85843d69
KM
421 } *uap;
422 int *retval;
423{
88a7a62a 424 struct msghdr msg;
813b7cd1 425 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 426 int error;
88a7a62a 427
76ffad7c 428 if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)))
d9c2f47f 429 return (error);
813b7cd1
MT
430 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
431 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 432 return (EMSGSIZE);
813b7cd1
MT
433 MALLOC(iov, struct iovec *,
434 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
435 M_WAITOK);
436 } else
437 iov = aiov;
3eb6310a 438 if (msg.msg_iovlen &&
813b7cd1
MT
439 (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
440 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
441 goto done;
442 msg.msg_iov = iov;
8ffc8876 443#ifdef COMPAT_OLDSOCK
27f43765
MK
444 msg.msg_flags = 0;
445#endif
5e00df3b 446 error = sendit(p, uap->s, &msg, uap->flags, retval);
813b7cd1
MT
447done:
448 if (iov != aiov)
449 FREE(iov, M_IOV);
d9c2f47f 450 return (error);
88a7a62a
SL
451}
452
5e00df3b
KM
453sendit(p, s, mp, flags, retsize)
454 register struct proc *p;
88a7a62a
SL
455 int s;
456 register struct msghdr *mp;
85843d69 457 int flags, *retsize;
88a7a62a 458{
5e00df3b 459 struct file *fp;
88a7a62a
SL
460 struct uio auio;
461 register struct iovec *iov;
462 register int i;
27f43765 463 struct mbuf *to, *control;
76ffad7c 464 int len, error;
813b7cd1
MT
465#ifdef KTRACE
466 struct iovec *ktriov = NULL;
467#endif
88a7a62a 468
5e00df3b 469 if (error = getsock(p->p_fd, s, &fp))
76ffad7c 470 return (error);
88a7a62a
SL
471 auio.uio_iov = mp->msg_iov;
472 auio.uio_iovcnt = mp->msg_iovlen;
c41770c0 473 auio.uio_segflg = UIO_USERSPACE;
c4ec2128 474 auio.uio_rw = UIO_WRITE;
994fd74e 475 auio.uio_procp = p;
88a7a62a
SL
476 auio.uio_offset = 0; /* XXX */
477 auio.uio_resid = 0;
478 iov = mp->msg_iov;
125c8f95 479 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
76ffad7c
MK
480 if (iov->iov_len < 0)
481 return (EINVAL);
7a22a33c
MK
482 if ((auio.uio_resid += iov->iov_len) < 0)
483 return (EINVAL);
88a7a62a
SL
484 }
485 if (mp->msg_name) {
76ffad7c
MK
486 if (error = sockargs(&to, mp->msg_name, mp->msg_namelen,
487 MT_SONAME))
488 return (error);
88a7a62a
SL
489 } else
490 to = 0;
6d47a3da 491 if (mp->msg_control) {
7a22a33c 492 if (mp->msg_controllen < sizeof(struct cmsghdr)
8ffc8876 493#ifdef COMPAT_OLDSOCK
a7a4c7b9 494 && mp->msg_flags != MSG_COMPAT
7a22a33c 495#endif
a7a4c7b9 496 ) {
7a22a33c
MK
497 error = EINVAL;
498 goto bad;
499 }
76ffad7c
MK
500 if (error = sockargs(&control, mp->msg_control,
501 mp->msg_controllen, MT_CONTROL))
6d47a3da 502 goto bad;
8ffc8876 503#ifdef COMPAT_OLDSOCK
7a22a33c 504 if (mp->msg_flags == MSG_COMPAT) {
27f43765 505 register struct cmsghdr *cm;
76ffad7c 506
27f43765 507 M_PREPEND(control, sizeof(*cm), M_WAIT);
76ffad7c
MK
508 if (control == 0) {
509 error = ENOBUFS;
510 goto bad;
511 } else {
27f43765
MK
512 cm = mtod(control, struct cmsghdr *);
513 cm->cmsg_len = control->m_len;
514 cm->cmsg_level = SOL_SOCKET;
515 cm->cmsg_type = SCM_RIGHTS;
516 }
517 }
518#endif
6d47a3da
MK
519 } else
520 control = 0;
813b7cd1 521#ifdef KTRACE
5e00df3b 522 if (KTRPOINT(p, KTR_GENIO)) {
813b7cd1
MT
523 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
524
525 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
526 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
527 }
528#endif
88a7a62a 529 len = auio.uio_resid;
76ffad7c 530 if (error = sosend((struct socket *)fp->f_data, to, &auio,
7a22a33c 531 (struct mbuf *)0, control, flags)) {
76ffad7c
MK
532 if (auio.uio_resid != len && (error == ERESTART ||
533 error == EINTR || error == EWOULDBLOCK))
534 error = 0;
535 if (error == EPIPE)
5e00df3b 536 psignal(p, SIGPIPE);
813b7cd1
MT
537 }
538 if (error == 0)
85843d69 539 *retsize = len - auio.uio_resid;
813b7cd1
MT
540#ifdef KTRACE
541 if (ktriov != NULL) {
542 if (error == 0)
5e00df3b 543 ktrgenio(p->p_tracep, s, UIO_WRITE,
81ba99b6 544 ktriov, *retsize, error);
813b7cd1
MT
545 FREE(ktriov, M_TEMP);
546 }
547#endif
6d47a3da 548bad:
88a7a62a
SL
549 if (to)
550 m_freem(to);
76ffad7c 551 return (error);
cf012934
BJ
552}
553
8ffc8876 554#ifdef COMPAT_OLDSOCK
85843d69
KM
555orecvfrom(p, uap, retval)
556 struct proc *p;
557 struct args {
76ffad7c
MK
558 int s;
559 caddr_t buf;
560 int len;
561 int flags;
562 caddr_t from;
563 int *fromlenaddr;
85843d69
KM
564 } *uap;
565 int *retval;
566{
76ffad7c 567
85843d69 568 uap->flags |= MSG_COMPAT;
d9c2f47f 569 return (recvfrom(p, uap, retval));
f4d2893a 570}
f4d2893a 571#endif
76ffad7c 572
85843d69
KM
573recvfrom(p, uap, retval)
574 struct proc *p;
575 register struct args {
cf012934
BJ
576 int s;
577 caddr_t buf;
578 int len;
579 int flags;
580 caddr_t from;
581 int *fromlenaddr;
85843d69
KM
582 } *uap;
583 int *retval;
584{
88a7a62a 585 struct msghdr msg;
cf012934 586 struct iovec aiov;
7a22a33c 587 int error;
cf012934 588
6d47a3da 589 if (uap->fromlenaddr) {
7a22a33c
MK
590 if (error = copyin((caddr_t)uap->fromlenaddr,
591 (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen)))
d9c2f47f 592 return (error);
6d47a3da 593 } else
7a22a33c 594 msg.msg_namelen = 0;
88a7a62a 595 msg.msg_name = uap->from;
88a7a62a
SL
596 msg.msg_iov = &aiov;
597 msg.msg_iovlen = 1;
cf012934
BJ
598 aiov.iov_base = uap->buf;
599 aiov.iov_len = uap->len;
6d47a3da 600 msg.msg_control = 0;
813b7cd1 601 msg.msg_flags = uap->flags;
5e00df3b 602 return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
cf012934 603}
76ffad7c 604
8ffc8876 605#ifdef COMPAT_OLDSOCK
85843d69
KM
606orecv(p, uap, retval)
607 struct proc *p;
608 register struct args {
cf012934
BJ
609 int s;
610 caddr_t buf;
611 int len;
612 int flags;
85843d69
KM
613 } *uap;
614 int *retval;
615{
88a7a62a 616 struct msghdr msg;
cf012934
BJ
617 struct iovec aiov;
618
88a7a62a
SL
619 msg.msg_name = 0;
620 msg.msg_namelen = 0;
621 msg.msg_iov = &aiov;
622 msg.msg_iovlen = 1;
cf012934
BJ
623 aiov.iov_base = uap->buf;
624 aiov.iov_len = uap->len;
6d47a3da
MK
625 msg.msg_control = 0;
626 msg.msg_flags = uap->flags;
5e00df3b 627 return (recvit(p, uap->s, &msg, (caddr_t)0, retval));
6d47a3da
MK
628}
629
7a22a33c
MK
630/*
631 * Old recvmsg. This code takes advantage of the fact that the old msghdr
632 * overlays the new one, missing only the flags, and with the (old) access
633 * rights where the control fields are now.
634 */
85843d69
KM
635orecvmsg(p, uap, retval)
636 struct proc *p;
637 register struct args {
6d47a3da
MK
638 int s;
639 struct omsghdr *msg;
640 int flags;
85843d69
KM
641 } *uap;
642 int *retval;
643{
6d47a3da 644 struct msghdr msg;
813b7cd1 645 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 646 int error;
6d47a3da 647
76ffad7c
MK
648 if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg,
649 sizeof (struct omsghdr)))
d9c2f47f 650 return (error);
813b7cd1
MT
651 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
652 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 653 return (EMSGSIZE);
813b7cd1
MT
654 MALLOC(iov, struct iovec *,
655 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
656 M_WAITOK);
657 } else
658 iov = aiov;
7a22a33c 659 msg.msg_flags = uap->flags | MSG_COMPAT;
813b7cd1
MT
660 if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
661 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
662 goto done;
663 msg.msg_iov = iov;
5e00df3b 664 error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
7a22a33c
MK
665
666 if (msg.msg_controllen && error == 0)
667 error = copyout((caddr_t)&msg.msg_controllen,
668 (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));
813b7cd1
MT
669done:
670 if (iov != aiov)
671 FREE(iov, M_IOV);
d9c2f47f 672 return (error);
cf012934 673}
6d47a3da 674#endif
cf012934 675
85843d69
KM
676recvmsg(p, uap, retval)
677 struct proc *p;
678 register struct args {
88a7a62a
SL
679 int s;
680 struct msghdr *msg;
681 int flags;
85843d69
KM
682 } *uap;
683 int *retval;
684{
88a7a62a 685 struct msghdr msg;
813b7cd1 686 struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
76ffad7c
MK
687 register int error;
688
689 if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg)))
d9c2f47f 690 return (error);
813b7cd1
MT
691 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
692 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 693 return (EMSGSIZE);
813b7cd1
MT
694 MALLOC(iov, struct iovec *,
695 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
696 M_WAITOK);
697 } else
698 iov = aiov;
8ffc8876 699#ifdef COMPAT_OLDSOCK
7a22a33c
MK
700 msg.msg_flags = uap->flags &~ MSG_COMPAT;
701#else
6d47a3da 702 msg.msg_flags = uap->flags;
7a22a33c 703#endif
27f43765 704 uiov = msg.msg_iov;
813b7cd1
MT
705 msg.msg_iov = iov;
706 if (error = copyin((caddr_t)uiov, (caddr_t)iov,
707 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
708 goto done;
5e00df3b 709 if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {
76ffad7c
MK
710 msg.msg_iov = uiov;
711 error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));
712 }
813b7cd1
MT
713done:
714 if (iov != aiov)
715 FREE(iov, M_IOV);
d9c2f47f 716 return (error);
cf012934
BJ
717}
718
5e00df3b
KM
719recvit(p, s, mp, namelenp, retsize)
720 register struct proc *p;
7a22a33c 721 int s;
88a7a62a 722 register struct msghdr *mp;
7a22a33c 723 caddr_t namelenp;
85843d69 724 int *retsize;
cf012934 725{
5e00df3b 726 struct file *fp;
88a7a62a
SL
727 struct uio auio;
728 register struct iovec *iov;
729 register int i;
76ffad7c 730 int len, error;
7a22a33c 731 struct mbuf *from = 0, *control = 0;
813b7cd1
MT
732#ifdef KTRACE
733 struct iovec *ktriov = NULL;
734#endif
88a7a62a 735
5e00df3b 736 if (error = getsock(p->p_fd, s, &fp))
76ffad7c 737 return (error);
88a7a62a
SL
738 auio.uio_iov = mp->msg_iov;
739 auio.uio_iovcnt = mp->msg_iovlen;
c41770c0 740 auio.uio_segflg = UIO_USERSPACE;
c4ec2128 741 auio.uio_rw = UIO_READ;
994fd74e 742 auio.uio_procp = p;
88a7a62a
SL
743 auio.uio_offset = 0; /* XXX */
744 auio.uio_resid = 0;
745 iov = mp->msg_iov;
125c8f95 746 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
76ffad7c
MK
747 if (iov->iov_len < 0)
748 return (EINVAL);
7a22a33c
MK
749 if ((auio.uio_resid += iov->iov_len) < 0)
750 return (EINVAL);
88a7a62a 751 }
813b7cd1 752#ifdef KTRACE
5e00df3b 753 if (KTRPOINT(p, KTR_GENIO)) {
813b7cd1
MT
754 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
755
756 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
757 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
758 }
759#endif
88a7a62a 760 len = auio.uio_resid;
76ffad7c 761 if (error = soreceive((struct socket *)fp->f_data, &from, &auio,
7a22a33c 762 (struct mbuf **)0, &control, &mp->msg_flags)) {
76ffad7c
MK
763 if (auio.uio_resid != len && (error == ERESTART ||
764 error == EINTR || error == EWOULDBLOCK))
765 error = 0;
766 }
813b7cd1
MT
767#ifdef KTRACE
768 if (ktriov != NULL) {
769 if (error == 0)
5e00df3b 770 ktrgenio(p->p_tracep, s, UIO_READ,
81ba99b6 771 ktriov, len - auio.uio_resid, error);
813b7cd1
MT
772 FREE(ktriov, M_TEMP);
773 }
774#endif
76ffad7c
MK
775 if (error)
776 goto out;
85843d69 777 *retsize = len - auio.uio_resid;
88a7a62a
SL
778 if (mp->msg_name) {
779 len = mp->msg_namelen;
780 if (len <= 0 || from == 0)
781 len = 0;
782 else {
8ffc8876 783#ifdef COMPAT_OLDSOCK
7a22a33c 784 if (mp->msg_flags & MSG_COMPAT)
f4d2893a
MK
785 mtod(from, struct osockaddr *)->sa_family =
786 mtod(from, struct sockaddr *)->sa_family;
787#endif
7a22a33c 788 if (len > from->m_len)
88a7a62a 789 len = from->m_len;
7a22a33c
MK
790 /* else if len < from->m_len ??? */
791 if (error = copyout(mtod(from, caddr_t),
792 (caddr_t)mp->msg_name, (unsigned)len))
793 goto out;
88a7a62a 794 }
a2aebb63 795 mp->msg_namelen = len;
7a22a33c
MK
796 if (namelenp &&
797 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
8ffc8876 798#ifdef COMPAT_OLDSOCK
7a22a33c
MK
799 if (mp->msg_flags & MSG_COMPAT)
800 error = 0; /* old recvfrom didn't check */
801 else
802#endif
803 goto out;
88a7a62a 804 }
6d47a3da
MK
805 }
806 if (mp->msg_control) {
8ffc8876 807#ifdef COMPAT_OLDSOCK
7a22a33c
MK
808 /*
809 * We assume that old recvmsg calls won't receive access
810 * rights and other control info, esp. as control info
811 * is always optional and those options didn't exist in 4.3.
812 * If we receive rights, trim the cmsghdr; anything else
813 * is tossed.
814 */
815 if (control && mp->msg_flags & MSG_COMPAT) {
816 if (mtod(control, struct cmsghdr *)->cmsg_level !=
817 SOL_SOCKET ||
818 mtod(control, struct cmsghdr *)->cmsg_type !=
819 SCM_RIGHTS) {
820 mp->msg_controllen = 0;
821 goto out;
27f43765 822 }
7a22a33c
MK
823 control->m_len -= sizeof (struct cmsghdr);
824 control->m_data += sizeof (struct cmsghdr);
27f43765 825 }
7a22a33c 826#endif
6d47a3da
MK
827 len = mp->msg_controllen;
828 if (len <= 0 || control == 0)
829 len = 0;
830 else {
831 if (len >= control->m_len)
832 len = control->m_len;
833 else
834 mp->msg_flags |= MSG_CTRUNC;
7a22a33c 835 error = copyout((caddr_t)mtod(control, caddr_t),
6d47a3da
MK
836 (caddr_t)mp->msg_control, (unsigned)len);
837 }
a2aebb63 838 mp->msg_controllen = len;
88a7a62a 839 }
76ffad7c 840out:
88a7a62a
SL
841 if (from)
842 m_freem(from);
6d47a3da
MK
843 if (control)
844 m_freem(control);
76ffad7c 845 return (error);
cf012934
BJ
846}
847
85843d69
KM
848/* ARGSUSED */
849shutdown(p, uap, retval)
850 struct proc *p;
851 register struct args {
6ef233bf
SL
852 int s;
853 int how;
85843d69
KM
854 } *uap;
855 int *retval;
856{
6ef233bf 857 struct file *fp;
76ffad7c 858 int error;
cf012934 859
5e00df3b 860 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f
MK
861 return (error);
862 return (soshutdown((struct socket *)fp->f_data, uap->how));
cf012934
BJ
863}
864
85843d69
KM
865/* ARGSUSED */
866setsockopt(p, uap, retval)
867 struct proc *p;
868 register struct args {
66f52238
SL
869 int s;
870 int level;
871 int name;
872 caddr_t val;
873 int valsize;
85843d69
KM
874 } *uap;
875 int *retval;
876{
66f52238 877 struct file *fp;
d2cba8de 878 struct mbuf *m = NULL;
76ffad7c 879 int error;
66f52238 880
5e00df3b 881 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 882 return (error);
76ffad7c 883 if (uap->valsize > MLEN)
d9c2f47f 884 return (EINVAL);
d2cba8de
SL
885 if (uap->val) {
886 m = m_get(M_WAIT, MT_SOOPTS);
76ffad7c 887 if (m == NULL)
d9c2f47f 888 return (ENOBUFS);
76ffad7c
MK
889 if (error = copyin(uap->val, mtod(m, caddr_t),
890 (u_int)uap->valsize)) {
61ec2127 891 (void) m_free(m);
d9c2f47f 892 return (error);
61ec2127 893 }
d2cba8de 894 m->m_len = uap->valsize;
66f52238 895 }
d9c2f47f 896 return (sosetopt((struct socket *)fp->f_data, uap->level,
76ffad7c 897 uap->name, m));
66f52238
SL
898}
899
85843d69
KM
900/* ARGSUSED */
901getsockopt(p, uap, retval)
902 struct proc *p;
903 register struct args {
66f52238
SL
904 int s;
905 int level;
906 int name;
907 caddr_t val;
908 int *avalsize;
85843d69
KM
909 } *uap;
910 int *retval;
911{
66f52238 912 struct file *fp;
d2cba8de 913 struct mbuf *m = NULL;
76ffad7c 914 int valsize, error;
66f52238 915
5e00df3b 916 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 917 return (error);
d2cba8de 918 if (uap->val) {
76ffad7c
MK
919 if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
920 sizeof (valsize)))
d9c2f47f 921 return (error);
61ec2127
SL
922 } else
923 valsize = 0;
76ffad7c
MK
924 if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
925 uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
d2cba8de
SL
926 if (valsize > m->m_len)
927 valsize = m->m_len;
76ffad7c
MK
928 error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
929 if (error == 0)
930 error = copyout((caddr_t)&valsize,
931 (caddr_t)uap->avalsize, sizeof (valsize));
d2cba8de 932 }
d2cba8de
SL
933 if (m != NULL)
934 (void) m_free(m);
d9c2f47f 935 return (error);
66f52238
SL
936}
937
85843d69
KM
938/* ARGSUSED */
939pipe(p, uap, retval)
940 struct proc *p;
941 struct args *uap;
942 int retval[];
cf012934 943{
5e00df3b 944 register struct filedesc *fdp = p->p_fd;
0c9a45f0 945 struct file *rf, *wf;
cf012934 946 struct socket *rso, *wso;
76ffad7c 947 int fd, error;
cf012934 948
76ffad7c 949 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0))
d9c2f47f 950 return (error);
76ffad7c 951 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0))
b242cf10 952 goto free1;
5e00df3b 953 if (error = falloc(p, &rf, &fd))
cf012934 954 goto free2;
85843d69 955 retval[0] = fd;
cf012934
BJ
956 rf->f_flag = FREAD;
957 rf->f_type = DTYPE_SOCKET;
88a7a62a
SL
958 rf->f_ops = &socketops;
959 rf->f_data = (caddr_t)rso;
5e00df3b 960 if (error = falloc(p, &wf, &fd))
cf012934
BJ
961 goto free3;
962 wf->f_flag = FWRITE;
963 wf->f_type = DTYPE_SOCKET;
88a7a62a
SL
964 wf->f_ops = &socketops;
965 wf->f_data = (caddr_t)wso;
85843d69 966 retval[1] = fd;
76ffad7c 967 if (error = unp_connect2(wso, rso))
cf012934 968 goto free4;
d9c2f47f 969 return (0);
cf012934 970free4:
336f999d 971 ffree(wf);
994fd74e 972 fdp->fd_ofiles[retval[1]] = 0;
cf012934 973free3:
336f999d 974 ffree(rf);
994fd74e 975 fdp->fd_ofiles[retval[0]] = 0;
cf012934 976free2:
8011f5df 977 (void)soclose(wso);
b242cf10 978free1:
8011f5df 979 (void)soclose(rso);
d9c2f47f 980 return (error);
cc15ab5d 981}
a3076b07
BJ
982
983/*
70f2eac5 984 * Get socket name.
a3076b07 985 */
8ffc8876 986#ifdef COMPAT_OLDSOCK
85843d69
KM
987getsockname(p, uap, retval)
988 struct proc *p;
989 struct args {
76ffad7c
MK
990 int fdes;
991 caddr_t asa;
992 int *alen;
993 int compat_43;
85843d69
KM
994 } *uap;
995 int *retval;
996{
76ffad7c 997
85843d69 998 uap->compat_43 = 0;
d9c2f47f 999 return (getsockname1(p, uap, retval));
f4d2893a
MK
1000}
1001
85843d69
KM
1002ogetsockname(p, uap, retval)
1003 struct proc *p;
1004 struct args {
76ffad7c
MK
1005 int fdes;
1006 caddr_t asa;
1007 int *alen;
1008 int compat_43;
85843d69
KM
1009 } *uap;
1010 int *retval;
1011{
76ffad7c 1012
85843d69 1013 uap->compat_43 = 1;
d9c2f47f 1014 return (getsockname1(p, uap, retval));
f4d2893a 1015}
8ffc8876 1016#else /* COMPAT_OLDSOCK */
f4d2893a 1017
76ffad7c 1018#define getsockname1 getsockname
f4d2893a 1019#endif
76ffad7c 1020
85843d69
KM
1021/* ARGSUSED */
1022getsockname1(p, uap, retval)
1023 struct proc *p;
1024 register struct args {
a3076b07 1025 int fdes;
70f2eac5
SL
1026 caddr_t asa;
1027 int *alen;
8ffc8876 1028#ifdef COMPAT_OLDSOCK
76ffad7c
MK
1029 int compat_43;
1030#endif
85843d69
KM
1031 } *uap;
1032 int *retval;
1033{
5e00df3b 1034 struct file *fp;
05d69517 1035 register struct socket *so;
cf012934 1036 struct mbuf *m;
76ffad7c 1037 int len, error;
a3076b07 1038
5e00df3b 1039 if (error = getsock(p->p_fd, uap->fdes, &fp))
d9c2f47f 1040 return (error);
76ffad7c 1041 if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
d9c2f47f 1042 return (error);
88a7a62a 1043 so = (struct socket *)fp->f_data;
cce93e4b 1044 m = m_getclr(M_WAIT, MT_SONAME);
76ffad7c 1045 if (m == NULL)
d9c2f47f 1046 return (ENOBUFS);
76ffad7c 1047 if (error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0))
70f2eac5
SL
1048 goto bad;
1049 if (len > m->m_len)
1050 len = m->m_len;
8ffc8876 1051#ifdef COMPAT_OLDSOCK
76ffad7c 1052 if (uap->compat_43)
f4d2893a
MK
1053 mtod(m, struct osockaddr *)->sa_family =
1054 mtod(m, struct sockaddr *)->sa_family;
1055#endif
76ffad7c
MK
1056 error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
1057 if (error == 0)
1058 error = copyout((caddr_t)&len, (caddr_t)uap->alen,
f4d2893a 1059 sizeof (len));
cf012934
BJ
1060bad:
1061 m_freem(m);
d9c2f47f 1062 return (error);
cf012934
BJ
1063}
1064
f4d2893a
MK
1065/*
1066 * Get name of peer for connected socket.
1067 */
8ffc8876 1068#ifdef COMPAT_OLDSOCK
85843d69
KM
1069getpeername(p, uap, retval)
1070 struct proc *p;
1071 struct args {
76ffad7c
MK
1072 int fdes;
1073 caddr_t asa;
1074 int *alen;
1075 int compat_43;
85843d69
KM
1076 } *uap;
1077 int *retval;
1078{
76ffad7c 1079
85843d69 1080 uap->compat_43 = 0;
d9c2f47f 1081 return (getpeername1(p, uap, retval));
6d47a3da 1082}
6d47a3da 1083
85843d69
KM
1084ogetpeername(p, uap, retval)
1085 struct proc *p;
1086 struct args {
76ffad7c
MK
1087 int fdes;
1088 caddr_t asa;
1089 int *alen;
1090 int compat_43;
85843d69
KM
1091 } *uap;
1092 int *retval;
1093{
76ffad7c 1094
85843d69 1095 uap->compat_43 = 1;
d9c2f47f 1096 return (getpeername1(p, uap, retval));
f4d2893a 1097}
8ffc8876 1098#else /* COMPAT_OLDSOCK */
f4d2893a 1099
76ffad7c 1100#define getpeername1 getpeername
f4d2893a 1101#endif
76ffad7c 1102
85843d69
KM
1103/* ARGSUSED */
1104getpeername1(p, uap, retval)
1105 struct proc *p;
1106 register struct args {
a7343092
SL
1107 int fdes;
1108 caddr_t asa;
1109 int *alen;
8ffc8876 1110#ifdef COMPAT_OLDSOCK
76ffad7c
MK
1111 int compat_43;
1112#endif
85843d69
KM
1113 } *uap;
1114 int *retval;
1115{
5e00df3b 1116 struct file *fp;
a7343092
SL
1117 register struct socket *so;
1118 struct mbuf *m;
76ffad7c 1119 int len, error;
a7343092 1120
5e00df3b 1121 if (error = getsock(p->p_fd, uap->fdes, &fp))
d9c2f47f 1122 return (error);
a7343092 1123 so = (struct socket *)fp->f_data;
76ffad7c 1124 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
d9c2f47f 1125 return (ENOTCONN);
a7343092 1126 m = m_getclr(M_WAIT, MT_SONAME);
76ffad7c 1127 if (m == NULL)
d9c2f47f 1128 return (ENOBUFS);
76ffad7c 1129 if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
d9c2f47f 1130 return (error);
76ffad7c 1131 if (error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0))
a7343092
SL
1132 goto bad;
1133 if (len > m->m_len)
1134 len = m->m_len;
8ffc8876 1135#ifdef COMPAT_OLDSOCK
76ffad7c 1136 if (uap->compat_43)
f4d2893a
MK
1137 mtod(m, struct osockaddr *)->sa_family =
1138 mtod(m, struct sockaddr *)->sa_family;
1139#endif
76ffad7c 1140 if (error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len))
a7343092 1141 goto bad;
76ffad7c 1142 error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
a7343092
SL
1143bad:
1144 m_freem(m);
d9c2f47f 1145 return (error);
a7343092
SL
1146}
1147
7a22a33c
MK
1148sockargs(mp, buf, buflen, type)
1149 struct mbuf **mp;
1150 caddr_t buf;
1151 int buflen, type;
cf012934 1152{
1d123e2b 1153 register struct sockaddr *sa;
cf012934 1154 register struct mbuf *m;
127f7d76 1155 int error;
cf012934 1156
7a22a33c 1157 if ((u_int)buflen > MLEN) {
8ffc8876 1158#ifdef COMPAT_OLDSOCK
7a22a33c
MK
1159 if (type == MT_SONAME && (u_int)buflen <= 112)
1160 buflen = MLEN; /* unix domain compat. hack */
3eb6310a
MK
1161 else
1162#endif
cf012934 1163 return (EINVAL);
3eb6310a 1164 }
98447d3f 1165 m = m_get(M_WAIT, type);
7c52d753
SL
1166 if (m == NULL)
1167 return (ENOBUFS);
7a22a33c
MK
1168 m->m_len = buflen;
1169 error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
127f7d76 1170 if (error)
cf012934 1171 (void) m_free(m);
1d123e2b 1172 else {
7a22a33c 1173 *mp = m;
1d123e2b
KB
1174 if (type == MT_SONAME) {
1175 sa = mtod(m, struct sockaddr *);
76ffad7c 1176
8ffc8876 1177#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1d123e2b
KB
1178 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1179 sa->sa_family = sa->sa_len;
f4d2893a 1180#endif
1d123e2b
KB
1181 sa->sa_len = buflen;
1182 }
a2aebb63 1183 }
127f7d76 1184 return (error);
cf012934 1185}
88a7a62a 1186
5e00df3b
KM
1187getsock(fdp, fdes, fpp)
1188 struct filedesc *fdp;
1189 int fdes;
1190 struct file **fpp;
88a7a62a
SL
1191{
1192 register struct file *fp;
1193
8429d022 1194 if ((unsigned)fdes >= fdp->fd_nfiles ||
994fd74e 1195 (fp = fdp->fd_ofiles[fdes]) == NULL)
5e00df3b
KM
1196 return (EBADF);
1197 if (fp->f_type != DTYPE_SOCKET)
1198 return (ENOTSOCK);
1199 *fpp = fp;
1200 return (0);
88a7a62a 1201}