1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)uipc_syscalls.c 7.5 (Berkeley) 06/29/88 18 */ 19 20 #include "param.h" 21 #include "dir.h" 22 #include "user.h" 23 #include "file.h" 24 #include "buf.h" 25 #include "mbuf.h" 26 #include "protosw.h" 27 #include "socket.h" 28 #include "socketvar.h" 29 30 /* 31 * System call interface to the socket abstraction. 32 */ 33 34 struct file *getsock(); 35 extern struct fileops socketops; 36 37 socket() 38 { 39 register struct a { 40 int domain; 41 int type; 42 int protocol; 43 } *uap = (struct a *)u.u_ap; 44 struct socket *so; 45 register struct file *fp; 46 47 if ((fp = falloc()) == NULL) 48 return; 49 fp->f_flag = FREAD|FWRITE; 50 fp->f_type = DTYPE_SOCKET; 51 fp->f_ops = &socketops; 52 u.u_error = socreate(uap->domain, &so, uap->type, uap->protocol); 53 if (u.u_error) 54 goto bad; 55 fp->f_data = (caddr_t)so; 56 return; 57 bad: 58 u.u_ofile[u.u_r.r_val1] = 0; 59 fp->f_count = 0; 60 } 61 62 bind() 63 { 64 register struct a { 65 int s; 66 caddr_t name; 67 int namelen; 68 } *uap = (struct a *)u.u_ap; 69 register struct file *fp; 70 struct mbuf *nam; 71 72 fp = getsock(uap->s); 73 if (fp == 0) 74 return; 75 u.u_error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); 76 if (u.u_error) 77 return; 78 u.u_error = sobind((struct socket *)fp->f_data, nam); 79 m_freem(nam); 80 } 81 82 listen() 83 { 84 register struct a { 85 int s; 86 int backlog; 87 } *uap = (struct a *)u.u_ap; 88 register struct file *fp; 89 90 fp = getsock(uap->s); 91 if (fp == 0) 92 return; 93 u.u_error = solisten((struct socket *)fp->f_data, uap->backlog); 94 } 95 96 accept() 97 { 98 register struct a { 99 int s; 100 caddr_t name; 101 int *anamelen; 102 } *uap = (struct a *)u.u_ap; 103 register struct file *fp; 104 struct mbuf *nam; 105 int namelen; 106 int s; 107 register struct socket *so; 108 109 if (uap->name == 0) 110 goto noname; 111 u.u_error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen, 112 sizeof (namelen)); 113 if (u.u_error) 114 return; 115 if (useracc((caddr_t)uap->name, (u_int)namelen, B_WRITE) == 0) { 116 u.u_error = EFAULT; 117 return; 118 } 119 noname: 120 fp = getsock(uap->s); 121 if (fp == 0) 122 return; 123 s = splnet(); 124 so = (struct socket *)fp->f_data; 125 if ((so->so_options & SO_ACCEPTCONN) == 0) { 126 u.u_error = EINVAL; 127 splx(s); 128 return; 129 } 130 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) { 131 u.u_error = EWOULDBLOCK; 132 splx(s); 133 return; 134 } 135 while (so->so_qlen == 0 && so->so_error == 0) { 136 if (so->so_state & SS_CANTRCVMORE) { 137 so->so_error = ECONNABORTED; 138 break; 139 } 140 sleep((caddr_t)&so->so_timeo, PZERO+1); 141 } 142 if (so->so_error) { 143 u.u_error = so->so_error; 144 so->so_error = 0; 145 splx(s); 146 return; 147 } 148 if (ufalloc(0) < 0) { 149 splx(s); 150 return; 151 } 152 fp = falloc(); 153 if (fp == 0) { 154 u.u_ofile[u.u_r.r_val1] = 0; 155 splx(s); 156 return; 157 } 158 { struct socket *aso = so->so_q; 159 if (soqremque(aso, 1) == 0) 160 panic("accept"); 161 so = aso; 162 } 163 fp->f_type = DTYPE_SOCKET; 164 fp->f_flag = FREAD|FWRITE; 165 fp->f_ops = &socketops; 166 fp->f_data = (caddr_t)so; 167 nam = m_get(M_WAIT, MT_SONAME); 168 (void) soaccept(so, nam); 169 if (uap->name) { 170 if (namelen > nam->m_len) 171 namelen = nam->m_len; 172 /* SHOULD COPY OUT A CHAIN HERE */ 173 (void) copyout(mtod(nam, caddr_t), (caddr_t)uap->name, 174 (u_int)namelen); 175 (void) copyout((caddr_t)&namelen, (caddr_t)uap->anamelen, 176 sizeof (*uap->anamelen)); 177 } 178 m_freem(nam); 179 splx(s); 180 } 181 182 connect() 183 { 184 register struct a { 185 int s; 186 caddr_t name; 187 int namelen; 188 } *uap = (struct a *)u.u_ap; 189 register struct file *fp; 190 register struct socket *so; 191 struct mbuf *nam; 192 int s; 193 194 fp = getsock(uap->s); 195 if (fp == 0) 196 return; 197 so = (struct socket *)fp->f_data; 198 if ((so->so_state & SS_NBIO) && 199 (so->so_state & SS_ISCONNECTING)) { 200 u.u_error = EALREADY; 201 return; 202 } 203 u.u_error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); 204 if (u.u_error) 205 return; 206 u.u_error = soconnect(so, nam); 207 if (u.u_error) 208 goto bad; 209 if ((so->so_state & SS_NBIO) && 210 (so->so_state & SS_ISCONNECTING)) { 211 u.u_error = EINPROGRESS; 212 m_freem(nam); 213 return; 214 } 215 s = splnet(); 216 if (setjmp(&u.u_qsave)) { 217 if (u.u_error == 0) 218 u.u_error = EINTR; 219 goto bad2; 220 } 221 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) 222 sleep((caddr_t)&so->so_timeo, PZERO+1); 223 u.u_error = so->so_error; 224 so->so_error = 0; 225 bad2: 226 splx(s); 227 bad: 228 so->so_state &= ~SS_ISCONNECTING; 229 m_freem(nam); 230 } 231 232 socketpair() 233 { 234 register struct a { 235 int domain; 236 int type; 237 int protocol; 238 int *rsv; 239 } *uap = (struct a *)u.u_ap; 240 register struct file *fp1, *fp2; 241 struct socket *so1, *so2; 242 int sv[2]; 243 244 if (useracc((caddr_t)uap->rsv, 2 * sizeof (int), B_WRITE) == 0) { 245 u.u_error = EFAULT; 246 return; 247 } 248 u.u_error = socreate(uap->domain, &so1, uap->type, uap->protocol); 249 if (u.u_error) 250 return; 251 u.u_error = socreate(uap->domain, &so2, uap->type, uap->protocol); 252 if (u.u_error) 253 goto free; 254 fp1 = falloc(); 255 if (fp1 == NULL) 256 goto free2; 257 sv[0] = u.u_r.r_val1; 258 fp1->f_flag = FREAD|FWRITE; 259 fp1->f_type = DTYPE_SOCKET; 260 fp1->f_ops = &socketops; 261 fp1->f_data = (caddr_t)so1; 262 fp2 = falloc(); 263 if (fp2 == NULL) 264 goto free3; 265 fp2->f_flag = FREAD|FWRITE; 266 fp2->f_type = DTYPE_SOCKET; 267 fp2->f_ops = &socketops; 268 fp2->f_data = (caddr_t)so2; 269 sv[1] = u.u_r.r_val1; 270 u.u_error = soconnect2(so1, so2); 271 if (u.u_error) 272 goto free4; 273 if (uap->type == SOCK_DGRAM) { 274 /* 275 * Datagram socket connection is asymmetric. 276 */ 277 u.u_error = soconnect2(so2, so1); 278 if (u.u_error) 279 goto free4; 280 } 281 u.u_r.r_val1 = 0; 282 (void) copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int)); 283 return; 284 free4: 285 fp2->f_count = 0; 286 u.u_ofile[sv[1]] = 0; 287 free3: 288 fp1->f_count = 0; 289 u.u_ofile[sv[0]] = 0; 290 free2: 291 (void)soclose(so2); 292 free: 293 (void)soclose(so1); 294 } 295 296 sendto() 297 { 298 register struct a { 299 int s; 300 caddr_t buf; 301 int len; 302 int flags; 303 caddr_t to; 304 int tolen; 305 } *uap = (struct a *)u.u_ap; 306 struct msghdr msg; 307 struct iovec aiov; 308 309 msg.msg_name = uap->to; 310 msg.msg_namelen = uap->tolen; 311 msg.msg_iov = &aiov; 312 msg.msg_iovlen = 1; 313 aiov.iov_base = uap->buf; 314 aiov.iov_len = uap->len; 315 msg.msg_accrights = 0; 316 msg.msg_accrightslen = 0; 317 sendit(uap->s, &msg, uap->flags); 318 } 319 320 send() 321 { 322 register struct a { 323 int s; 324 caddr_t buf; 325 int len; 326 int flags; 327 } *uap = (struct a *)u.u_ap; 328 struct msghdr msg; 329 struct iovec aiov; 330 331 msg.msg_name = 0; 332 msg.msg_namelen = 0; 333 msg.msg_iov = &aiov; 334 msg.msg_iovlen = 1; 335 aiov.iov_base = uap->buf; 336 aiov.iov_len = uap->len; 337 msg.msg_accrights = 0; 338 msg.msg_accrightslen = 0; 339 sendit(uap->s, &msg, uap->flags); 340 } 341 342 sendmsg() 343 { 344 register struct a { 345 int s; 346 caddr_t msg; 347 int flags; 348 } *uap = (struct a *)u.u_ap; 349 struct msghdr msg; 350 struct iovec aiov[MSG_MAXIOVLEN]; 351 352 u.u_error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)); 353 if (u.u_error) 354 return; 355 if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) { 356 u.u_error = EMSGSIZE; 357 return; 358 } 359 u.u_error = 360 copyin((caddr_t)msg.msg_iov, (caddr_t)aiov, 361 (unsigned)(msg.msg_iovlen * sizeof (aiov[0]))); 362 if (u.u_error) 363 return; 364 msg.msg_iov = aiov; 365 sendit(uap->s, &msg, uap->flags); 366 } 367 368 sendit(s, mp, flags) 369 int s; 370 register struct msghdr *mp; 371 int flags; 372 { 373 register struct file *fp; 374 struct uio auio; 375 register struct iovec *iov; 376 register int i; 377 struct mbuf *to, *rights; 378 int len; 379 380 fp = getsock(s); 381 if (fp == 0) 382 return; 383 auio.uio_iov = mp->msg_iov; 384 auio.uio_iovcnt = mp->msg_iovlen; 385 auio.uio_segflg = UIO_USERSPACE; 386 auio.uio_offset = 0; /* XXX */ 387 auio.uio_resid = 0; 388 iov = mp->msg_iov; 389 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 390 if (iov->iov_len < 0) { 391 u.u_error = EINVAL; 392 return; 393 } 394 if (iov->iov_len == 0) 395 continue; 396 if (useracc(iov->iov_base, (u_int)iov->iov_len, B_READ) == 0) { 397 u.u_error = EFAULT; 398 return; 399 } 400 auio.uio_resid += iov->iov_len; 401 } 402 if (mp->msg_name) { 403 u.u_error = 404 sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME); 405 if (u.u_error) 406 return; 407 } else 408 to = 0; 409 if (mp->msg_accrights) { 410 u.u_error = 411 sockargs(&rights, mp->msg_accrights, mp->msg_accrightslen, 412 MT_RIGHTS); 413 if (u.u_error) 414 goto bad; 415 } else 416 rights = 0; 417 len = auio.uio_resid; 418 u.u_error = 419 sosend((struct socket *)fp->f_data, to, &auio, flags, rights); 420 u.u_r.r_val1 = len - auio.uio_resid; 421 if (rights) 422 m_freem(rights); 423 bad: 424 if (to) 425 m_freem(to); 426 } 427 428 recvfrom() 429 { 430 register struct a { 431 int s; 432 caddr_t buf; 433 int len; 434 int flags; 435 caddr_t from; 436 int *fromlenaddr; 437 } *uap = (struct a *)u.u_ap; 438 struct msghdr msg; 439 struct iovec aiov; 440 int len; 441 442 u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&len, 443 sizeof (len)); 444 if (u.u_error) 445 return; 446 msg.msg_name = uap->from; 447 msg.msg_namelen = len; 448 msg.msg_iov = &aiov; 449 msg.msg_iovlen = 1; 450 aiov.iov_base = uap->buf; 451 aiov.iov_len = uap->len; 452 msg.msg_accrights = 0; 453 msg.msg_accrightslen = 0; 454 recvit(uap->s, &msg, uap->flags, (caddr_t)uap->fromlenaddr, (caddr_t)0); 455 } 456 457 recv() 458 { 459 register struct a { 460 int s; 461 caddr_t buf; 462 int len; 463 int flags; 464 } *uap = (struct a *)u.u_ap; 465 struct msghdr msg; 466 struct iovec aiov; 467 468 msg.msg_name = 0; 469 msg.msg_namelen = 0; 470 msg.msg_iov = &aiov; 471 msg.msg_iovlen = 1; 472 aiov.iov_base = uap->buf; 473 aiov.iov_len = uap->len; 474 msg.msg_accrights = 0; 475 msg.msg_accrightslen = 0; 476 recvit(uap->s, &msg, uap->flags, (caddr_t)0, (caddr_t)0); 477 } 478 479 recvmsg() 480 { 481 register struct a { 482 int s; 483 struct msghdr *msg; 484 int flags; 485 } *uap = (struct a *)u.u_ap; 486 struct msghdr msg; 487 struct iovec aiov[MSG_MAXIOVLEN]; 488 489 u.u_error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg)); 490 if (u.u_error) 491 return; 492 if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) { 493 u.u_error = EMSGSIZE; 494 return; 495 } 496 u.u_error = 497 copyin((caddr_t)msg.msg_iov, (caddr_t)aiov, 498 (unsigned)(msg.msg_iovlen * sizeof (aiov[0]))); 499 if (u.u_error) 500 return; 501 msg.msg_iov = aiov; 502 if (msg.msg_accrights) 503 if (useracc((caddr_t)msg.msg_accrights, 504 (unsigned)msg.msg_accrightslen, B_WRITE) == 0) { 505 u.u_error = EFAULT; 506 return; 507 } 508 recvit(uap->s, &msg, uap->flags, 509 (caddr_t)&uap->msg->msg_namelen, 510 (caddr_t)&uap->msg->msg_accrightslen); 511 } 512 513 recvit(s, mp, flags, namelenp, rightslenp) 514 int s; 515 register struct msghdr *mp; 516 int flags; 517 caddr_t namelenp, rightslenp; 518 { 519 register struct file *fp; 520 struct uio auio; 521 register struct iovec *iov; 522 register int i; 523 struct mbuf *from, *rights; 524 int len; 525 526 fp = getsock(s); 527 if (fp == 0) 528 return; 529 auio.uio_iov = mp->msg_iov; 530 auio.uio_iovcnt = mp->msg_iovlen; 531 auio.uio_segflg = UIO_USERSPACE; 532 auio.uio_offset = 0; /* XXX */ 533 auio.uio_resid = 0; 534 iov = mp->msg_iov; 535 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 536 if (iov->iov_len < 0) { 537 u.u_error = EINVAL; 538 return; 539 } 540 if (iov->iov_len == 0) 541 continue; 542 if (useracc(iov->iov_base, (u_int)iov->iov_len, B_WRITE) == 0) { 543 u.u_error = EFAULT; 544 return; 545 } 546 auio.uio_resid += iov->iov_len; 547 } 548 len = auio.uio_resid; 549 u.u_error = 550 soreceive((struct socket *)fp->f_data, &from, &auio, 551 flags, &rights); 552 u.u_r.r_val1 = len - auio.uio_resid; 553 if (mp->msg_name) { 554 len = mp->msg_namelen; 555 if (len <= 0 || from == 0) 556 len = 0; 557 else { 558 if (len > from->m_len) 559 len = from->m_len; 560 (void) copyout((caddr_t)mtod(from, caddr_t), 561 (caddr_t)mp->msg_name, (unsigned)len); 562 } 563 (void) copyout((caddr_t)&len, namelenp, sizeof (int)); 564 } 565 if (mp->msg_accrights) { 566 len = mp->msg_accrightslen; 567 if (len <= 0 || rights == 0) 568 len = 0; 569 else { 570 if (len > rights->m_len) 571 len = rights->m_len; 572 (void) copyout((caddr_t)mtod(rights, caddr_t), 573 (caddr_t)mp->msg_accrights, (unsigned)len); 574 } 575 (void) copyout((caddr_t)&len, rightslenp, sizeof (int)); 576 } 577 if (rights) 578 m_freem(rights); 579 if (from) 580 m_freem(from); 581 } 582 583 shutdown() 584 { 585 struct a { 586 int s; 587 int how; 588 } *uap = (struct a *)u.u_ap; 589 struct file *fp; 590 591 fp = getsock(uap->s); 592 if (fp == 0) 593 return; 594 u.u_error = soshutdown((struct socket *)fp->f_data, uap->how); 595 } 596 597 setsockopt() 598 { 599 struct a { 600 int s; 601 int level; 602 int name; 603 caddr_t val; 604 int valsize; 605 } *uap = (struct a *)u.u_ap; 606 struct file *fp; 607 struct mbuf *m = NULL; 608 609 fp = getsock(uap->s); 610 if (fp == 0) 611 return; 612 if (uap->valsize > MLEN) { 613 u.u_error = EINVAL; 614 return; 615 } 616 if (uap->val) { 617 m = m_get(M_WAIT, MT_SOOPTS); 618 if (m == NULL) { 619 u.u_error = ENOBUFS; 620 return; 621 } 622 u.u_error = 623 copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize); 624 if (u.u_error) { 625 (void) m_free(m); 626 return; 627 } 628 m->m_len = uap->valsize; 629 } 630 u.u_error = 631 sosetopt((struct socket *)fp->f_data, uap->level, uap->name, m); 632 } 633 634 getsockopt() 635 { 636 struct a { 637 int s; 638 int level; 639 int name; 640 caddr_t val; 641 int *avalsize; 642 } *uap = (struct a *)u.u_ap; 643 struct file *fp; 644 struct mbuf *m = NULL; 645 int valsize; 646 647 fp = getsock(uap->s); 648 if (fp == 0) 649 return; 650 if (uap->val) { 651 u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 652 sizeof (valsize)); 653 if (u.u_error) 654 return; 655 } else 656 valsize = 0; 657 u.u_error = 658 sogetopt((struct socket *)fp->f_data, uap->level, uap->name, &m); 659 if (u.u_error) 660 goto bad; 661 if (uap->val && valsize && m != NULL) { 662 if (valsize > m->m_len) 663 valsize = m->m_len; 664 u.u_error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 665 if (u.u_error) 666 goto bad; 667 u.u_error = copyout((caddr_t)&valsize, (caddr_t)uap->avalsize, 668 sizeof (valsize)); 669 } 670 bad: 671 if (m != NULL) 672 (void) m_free(m); 673 } 674 675 pipe() 676 { 677 register struct file *rf, *wf; 678 struct socket *rso, *wso; 679 int r; 680 681 u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0); 682 if (u.u_error) 683 return; 684 u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0); 685 if (u.u_error) 686 goto free; 687 rf = falloc(); 688 if (rf == NULL) 689 goto free2; 690 r = u.u_r.r_val1; 691 rf->f_flag = FREAD; 692 rf->f_type = DTYPE_SOCKET; 693 rf->f_ops = &socketops; 694 rf->f_data = (caddr_t)rso; 695 wf = falloc(); 696 if (wf == NULL) 697 goto free3; 698 wf->f_flag = FWRITE; 699 wf->f_type = DTYPE_SOCKET; 700 wf->f_ops = &socketops; 701 wf->f_data = (caddr_t)wso; 702 u.u_r.r_val2 = u.u_r.r_val1; 703 u.u_r.r_val1 = r; 704 if (u.u_error = unp_connect2(wso, rso)) 705 goto free4; 706 wso->so_state |= SS_CANTRCVMORE; 707 rso->so_state |= SS_CANTSENDMORE; 708 return; 709 free4: 710 wf->f_count = 0; 711 u.u_ofile[u.u_r.r_val2] = 0; 712 free3: 713 rf->f_count = 0; 714 u.u_ofile[r] = 0; 715 free2: 716 (void)soclose(wso); 717 free: 718 (void)soclose(rso); 719 } 720 721 /* 722 * Get socket name. 723 */ 724 getsockname() 725 { 726 register struct a { 727 int fdes; 728 caddr_t asa; 729 int *alen; 730 } *uap = (struct a *)u.u_ap; 731 register struct file *fp; 732 register struct socket *so; 733 struct mbuf *m; 734 int len; 735 736 fp = getsock(uap->fdes); 737 if (fp == 0) 738 return; 739 u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 740 if (u.u_error) 741 return; 742 so = (struct socket *)fp->f_data; 743 m = m_getclr(M_WAIT, MT_SONAME); 744 if (m == NULL) { 745 u.u_error = ENOBUFS; 746 return; 747 } 748 u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0); 749 if (u.u_error) 750 goto bad; 751 if (len > m->m_len) 752 len = m->m_len; 753 u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); 754 if (u.u_error) 755 goto bad; 756 u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); 757 bad: 758 m_freem(m); 759 } 760 761 /* 762 * Get name of peer for connected socket. 763 */ 764 getpeername() 765 { 766 register struct a { 767 int fdes; 768 caddr_t asa; 769 int *alen; 770 } *uap = (struct a *)u.u_ap; 771 register struct file *fp; 772 register struct socket *so; 773 struct mbuf *m; 774 int len; 775 776 fp = getsock(uap->fdes); 777 if (fp == 0) 778 return; 779 so = (struct socket *)fp->f_data; 780 if ((so->so_state & SS_ISCONNECTED) == 0) { 781 u.u_error = ENOTCONN; 782 return; 783 } 784 m = m_getclr(M_WAIT, MT_SONAME); 785 if (m == NULL) { 786 u.u_error = ENOBUFS; 787 return; 788 } 789 u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 790 if (u.u_error) 791 return; 792 u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0); 793 if (u.u_error) 794 goto bad; 795 if (len > m->m_len) 796 len = m->m_len; 797 u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); 798 if (u.u_error) 799 goto bad; 800 u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); 801 bad: 802 m_freem(m); 803 } 804 805 sockargs(aname, name, namelen, type) 806 struct mbuf **aname; 807 caddr_t name; 808 int namelen, type; 809 { 810 register struct mbuf *m; 811 int error; 812 813 if ((u_int)namelen > MLEN) 814 return (EINVAL); 815 m = m_get(M_WAIT, type); 816 if (m == NULL) 817 return (ENOBUFS); 818 m->m_len = namelen; 819 error = copyin(name, mtod(m, caddr_t), (u_int)namelen); 820 if (error) 821 (void) m_free(m); 822 else 823 *aname = m; 824 return (error); 825 } 826 827 struct file * 828 getsock(fdes) 829 int fdes; 830 { 831 register struct file *fp; 832 833 fp = getf(fdes); 834 if (fp == NULL) 835 return (0); 836 if (fp->f_type != DTYPE_SOCKET) { 837 u.u_error = ENOTSOCK; 838 return (0); 839 } 840 return (fp); 841 } 842