1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)uipc_syscalls.c	7.1.3 (2.11BSD) 1999/9/13
   7:  */
   8: 
   9: #include "param.h"
  10: 
  11: #include "../machine/seg.h"
  12: #include "../machine/psl.h"
  13: 
  14: #include "systm.h"
  15: #include "user.h"
  16: #include "proc.h"
  17: #include "file.h"
  18: #include "inode.h"
  19: #include "buf.h"
  20: #include "mbuf.h"
  21: #include "protosw.h"
  22: #include "socket.h"
  23: #include "socketvar.h"
  24: #include "uio.h"
  25: #include "domain.h"
  26: #include "pdpif/if_uba.h"
  27: #include "netinet/in.h"
  28: #include "netinet/in_systm.h"
  29: 
  30: static void
  31: MBZAP(m, len, type)
  32:     register struct mbuf *m;
  33:     int len, type;
  34:     {
  35:     m->m_next = 0;
  36:     m->m_off = MMINOFF;
  37:     m->m_len = len;
  38:     m->m_type = type;
  39:     m->m_act = 0;
  40:     }
  41: 
  42: /*
  43:  * System call interface to the socket abstraction.
  44:  */
  45: 
  46: extern int netoff;
  47: struct file *gtsockf();
  48: 
  49: socket()
  50: {
  51:     register struct a {
  52:         int domain;
  53:         int type;
  54:         int protocol;
  55:     } *uap = (struct a *)u.u_ap;
  56:     struct socket *so;
  57:     register struct file *fp;
  58: 
  59:     if (netoff)
  60:         return(u.u_error = ENETDOWN);
  61:     if ((fp = falloc()) == NULL)
  62:         return;
  63:     fp->f_flag = FREAD|FWRITE;
  64:     fp->f_type = DTYPE_SOCKET;
  65:     u.u_error = SOCREATE(uap->domain, &so, uap->type, uap->protocol);
  66:     if (u.u_error)
  67:         goto bad;
  68:     fp->f_socket = so;
  69:     return;
  70: bad:
  71:     u.u_ofile[u.u_r.r_val1] = 0;
  72:     fp->f_count = 0;
  73: }
  74: 
  75: bind()
  76: {
  77:     register struct a {
  78:         int s;
  79:         caddr_t name;
  80:         u_int   namelen;
  81:     } *uap = (struct a *)u.u_ap;
  82:     register struct file *fp;
  83:     register struct mbuf *nam;
  84:     char sabuf[MSIZE];
  85: 
  86:     if (netoff)
  87:         return(u.u_error = ENETDOWN);
  88:     fp = gtsockf(uap->s);
  89:     if (fp == 0)
  90:         return;
  91:     nam = (struct mbuf *)sabuf;
  92:     MBZAP(nam, uap->namelen, MT_SONAME);
  93:     if (uap->namelen > MLEN)
  94:         return (u.u_error = EINVAL);
  95:     u.u_error = copyin(uap->name, mtod(nam, caddr_t), uap->namelen);
  96:     if (u.u_error)
  97:         return;
  98:     u.u_error = SOBIND(fp->f_socket, nam);
  99: }
 100: 
 101: listen()
 102: {
 103:     register struct a {
 104:         int s;
 105:         int backlog;
 106:     } *uap = (struct a *)u.u_ap;
 107:     register struct file *fp;
 108: 
 109:     if (netoff)
 110:         return(u.u_error = ENETDOWN);
 111:     fp = gtsockf(uap->s);
 112:     if (fp == 0)
 113:         return;
 114:     u.u_error = SOLISTEN(fp->f_socket, uap->backlog);
 115: }
 116: 
 117: accept()
 118: {
 119:     register struct a {
 120:         int s;
 121:         caddr_t name;
 122:         int *anamelen;
 123:     } *uap = (struct a *)u.u_ap;
 124:     register struct file *fp;
 125:     struct mbuf *nam;
 126:     int namelen;
 127:     int s;
 128:     register struct socket *so;
 129:     char sabuf[MSIZE];
 130: 
 131:     if (netoff)
 132:         return(u.u_error = ENETDOWN);
 133:     if (uap->name == 0)
 134:         goto noname;
 135:     u.u_error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen,
 136:         sizeof (namelen));
 137:     if (u.u_error)
 138:         return;
 139: #ifndef pdp11
 140:     if (useracc((caddr_t)uap->name, (u_int)namelen, B_WRITE) == 0) {
 141:         u.u_error = EFAULT;
 142:         return;
 143:     }
 144: #endif
 145: noname:
 146:     fp = gtsockf(uap->s);
 147:     if (fp == 0)
 148:         return;
 149:     s = splnet();
 150:     so = fp->f_socket;
 151:     if (SOACC1(so)) {
 152:         splx(s);
 153:         return;
 154:     }
 155:     if (ufalloc(0) < 0) {
 156:         splx(s);
 157:         return;
 158:     }
 159:     fp = falloc();
 160:     if (fp == 0) {
 161:         u.u_ofile[u.u_r.r_val1] = 0;
 162:         splx(s);
 163:         return;
 164:     }
 165:     if (!(so = (struct socket *)ASOQREMQUE(so, 1))) /* deQ in super */
 166:         panic("accept");
 167:     fp->f_type = DTYPE_SOCKET;
 168:     fp->f_flag = FREAD|FWRITE;
 169:     fp->f_socket = so;
 170:     nam = (struct mbuf *)sabuf;
 171:     MBZAP(nam, 0, MT_SONAME);
 172:     u.u_error = SOACCEPT(so, nam);
 173:     if (uap->name) {
 174:         if (namelen > nam->m_len)
 175:             namelen = nam->m_len;
 176:         /* SHOULD COPY OUT A CHAIN HERE */
 177:         (void) copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
 178:             (u_int)namelen);
 179:         (void) copyout((caddr_t)&namelen, (caddr_t)uap->anamelen,
 180:             sizeof (*uap->anamelen));
 181:     }
 182:     splx(s);
 183: }
 184: 
 185: connect()
 186: {
 187:     register struct a {
 188:         int s;
 189:         caddr_t name;
 190:         u_int   namelen;
 191:     } *uap = (struct a *)u.u_ap;
 192:     register struct file *fp;
 193:     register struct socket *so;
 194:     struct mbuf *nam;
 195:     int s;
 196:     char sabuf[MSIZE];
 197:     struct  socket  kcopy;
 198: 
 199:     if (netoff)
 200:         return(u.u_error = ENETDOWN);
 201:     fp = gtsockf(uap->s);
 202:     if (fp == 0)
 203:         return;
 204:     if (uap->namelen > MLEN)
 205:         return (u.u_error = EINVAL);
 206:     nam = (struct mbuf *)sabuf;
 207:     MBZAP(nam, uap->namelen, MT_SONAME);
 208:     u.u_error = copyin(uap->name, mtod(nam, caddr_t), uap->namelen);
 209:     if (u.u_error)
 210:         return;
 211:     so = fp->f_socket;
 212:     /*
 213: 	 * soconnect was modified to clear the isconnecting bit on errors.
 214: 	 * also, it was changed to return the EINPROGRESS error if
 215: 	 * nonblocking, etc.
 216: 	 */
 217:     u.u_error = SOCON1(so, nam);
 218:     if (u.u_error)
 219:         return;
 220:     /*
 221: 	 * i don't think the setjmp stuff works too hot in supervisor mode,
 222: 	 * so what is done instead is do the setjmp here and then go back
 223: 	 * to supervisor mode to do the "while (isconnecting && !error)
 224: 	 * sleep()" loop.
 225: 	 */
 226:     s = splnet();
 227:     if (setjmp(&u.u_qsave))
 228:         {
 229:         u.u_error = EINTR;
 230:         goto bad2;
 231:         }
 232:     u.u_error = CONNWHILE(so);
 233: bad2:
 234:     splx(s);
 235: }
 236: 
 237: socketpair()
 238: {
 239:     register struct a {
 240:         int domain;
 241:         int type;
 242:         int protocol;
 243:         int *rsv;
 244:     } *uap = (struct a *)u.u_ap;
 245:     register struct file *fp1, *fp2;
 246:     struct socket *so1, *so2;
 247:     int sv[2];
 248: 
 249:     if  (netoff)
 250:         return(u.u_error = ENETDOWN);
 251:     u.u_error = SOCREATE(uap->domain, &so1, uap->type, uap->protocol);
 252:     if  (u.u_error)
 253:         return;
 254:     u.u_error = SOCREATE(uap->domain, &so2, uap->type, uap->protocol);
 255:     if  (u.u_error)
 256:         goto free;
 257:     fp1 = falloc();
 258:     if (fp1 == NULL)
 259:         goto free2;
 260:     sv[0] = u.u_r.r_val1;
 261:     fp1->f_flag = FREAD|FWRITE;
 262:     fp1->f_type = DTYPE_SOCKET;
 263:     fp1->f_socket = so1;
 264:     fp2 = falloc();
 265:     if (fp2 == NULL)
 266:         goto free3;
 267:     fp2->f_flag = FREAD|FWRITE;
 268:     fp2->f_type = DTYPE_SOCKET;
 269:     fp2->f_socket = so2;
 270:     sv[1] = u.u_r.r_val1;
 271:     u.u_error = SOCON2(so1, so2);
 272:     if (u.u_error)
 273:         goto free4;
 274:     if (uap->type == SOCK_DGRAM) {
 275:         /*
 276: 		 * Datagram socket connection is asymmetric.
 277: 		 */
 278:          u.u_error = SOCON2(so2, so1);
 279:          if (u.u_error)
 280:             goto free4;
 281:     }
 282:     u.u_r.r_val1 = 0;
 283:     (void) copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
 284:     return;
 285: free4:
 286:     fp2->f_count = 0;
 287:     u.u_ofile[sv[1]] = 0;
 288: free3:
 289:     fp1->f_count = 0;
 290:     u.u_ofile[sv[0]] = 0;
 291: free2:
 292:     (void)SOCLOSE(so2);
 293: free:
 294:     (void)SOCLOSE(so1);
 295: }
 296: 
 297: sendto()
 298: {
 299:     register struct a {
 300:         int s;
 301:         caddr_t buf;
 302:         int len;
 303:         int flags;
 304:         caddr_t to;
 305:         int tolen;
 306:     } *uap = (struct a *)u.u_ap;
 307:     struct msghdr msg;
 308:     struct iovec aiov;
 309: 
 310:     msg.msg_name = uap->to;
 311:     msg.msg_namelen = uap->tolen;
 312:     msg.msg_iov = &aiov;
 313:     msg.msg_iovlen = 1;
 314:     aiov.iov_base = uap->buf;
 315:     aiov.iov_len = uap->len;
 316:     msg.msg_accrights = 0;
 317:     msg.msg_accrightslen = 0;
 318:     sendit(uap->s, &msg, uap->flags);
 319: }
 320: 
 321: send()
 322: {
 323:     register struct a {
 324:         int s;
 325:         caddr_t buf;
 326:         int len;
 327:         int flags;
 328:     } *uap = (struct a *)u.u_ap;
 329:     struct msghdr msg;
 330:     struct iovec aiov;
 331: 
 332:     msg.msg_name = 0;
 333:     msg.msg_namelen = 0;
 334:     msg.msg_iov = &aiov;
 335:     msg.msg_iovlen = 1;
 336:     aiov.iov_base = uap->buf;
 337:     aiov.iov_len = uap->len;
 338:     msg.msg_accrights = 0;
 339:     msg.msg_accrightslen = 0;
 340:     sendit(uap->s, &msg, uap->flags);
 341: }
 342: 
 343: sendmsg()
 344: {
 345:     register struct a {
 346:         int s;
 347:         caddr_t msg;
 348:         int flags;
 349:     } *uap = (struct a *)u.u_ap;
 350:     struct msghdr msg;
 351:     struct iovec aiov[MSG_MAXIOVLEN];
 352: 
 353:     u.u_error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg));
 354:     if (u.u_error)
 355:         return;
 356:     if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
 357:         u.u_error = EMSGSIZE;
 358:         return;
 359:     }
 360:     u.u_error =
 361:         copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
 362:         (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
 363:     if (u.u_error)
 364:         return;
 365:     msg.msg_iov = aiov;
 366:     sendit(uap->s, &msg, uap->flags);
 367: }
 368: 
 369: sendit(s, mp, flags)
 370:     int s;
 371:     register struct msghdr *mp;
 372:     int flags;
 373: {
 374:     register struct file *fp;
 375:     struct uio auio;
 376:     register struct iovec *iov;
 377:     register int i;
 378:     struct mbuf *to, *rights;
 379:     int len;
 380:     char sabuf[MSIZE], ribuf[MSIZE];
 381: 
 382:     if (netoff)
 383:         return(u.u_error = ENETDOWN);
 384:     fp = gtsockf(s);
 385:     if (fp == 0)
 386:         return;
 387:     auio.uio_iov = mp->msg_iov;
 388:     auio.uio_iovcnt = mp->msg_iovlen;
 389:     auio.uio_segflg = UIO_USERSPACE;
 390:     auio.uio_offset = 0;                /* XXX */
 391:     auio.uio_resid = 0;
 392:     auio.uio_rw = UIO_WRITE;
 393:     iov = mp->msg_iov;
 394:     for (i = 0; i < mp->msg_iovlen; i++, iov++)
 395:         {
 396:         if  (iov->iov_len == 0)
 397:             continue;
 398:         auio.uio_resid += iov->iov_len;
 399:         }
 400:     if (mp->msg_name) {
 401:         to = (struct mbuf *)sabuf;
 402:         MBZAP(to, mp->msg_namelen, MT_SONAME);
 403:         u.u_error =
 404:             copyin(mp->msg_name, mtod(to, caddr_t), mp->msg_namelen);
 405:         if (u.u_error)
 406:             return;
 407:     } else
 408:         to = 0;
 409:     if (mp->msg_accrights) {
 410:         rights = (struct mbuf *)ribuf;
 411:         MBZAP(rights, mp->msg_accrightslen, MT_RIGHTS);
 412:         if (mp->msg_accrightslen > MLEN)
 413:             return(u.u_error = EINVAL);
 414:         u.u_error = copyin(mp->msg_accrights, mtod(rights, caddr_t),
 415:                 mp->msg_accrightslen);
 416:         if (u.u_error)
 417:             return;
 418:     } else
 419:         rights = 0;
 420:     len = auio.uio_resid;
 421:     if  (setjmp(&u.u_qsave))
 422:         {
 423:         if  (auio.uio_resid == len)
 424:             return;
 425:         else
 426:             u.u_error = 0;
 427:         }
 428:     else
 429:         u.u_error = SOSEND(fp->f_socket, to, &auio, flags, rights);
 430:     u.u_r.r_val1 = len - auio.uio_resid;
 431: }
 432: 
 433: recvfrom()
 434: {
 435:     register struct a {
 436:         int s;
 437:         caddr_t buf;
 438:         int len;
 439:         int flags;
 440:         caddr_t from;
 441:         int *fromlenaddr;
 442:     } *uap = (struct a *)u.u_ap;
 443:     struct msghdr msg;
 444:     struct iovec aiov;
 445:     int len;
 446: 
 447:     u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&len,
 448:        sizeof (len));
 449:     if (u.u_error)
 450:         return;
 451:     msg.msg_name = uap->from;
 452:     msg.msg_namelen = len;
 453:     msg.msg_iov = &aiov;
 454:     msg.msg_iovlen = 1;
 455:     aiov.iov_base = uap->buf;
 456:     aiov.iov_len = uap->len;
 457:     msg.msg_accrights = 0;
 458:     msg.msg_accrightslen = 0;
 459:     recvit(uap->s, &msg, uap->flags, (caddr_t)uap->fromlenaddr, (caddr_t)0);
 460: }
 461: 
 462: recv()
 463: {
 464:     register struct a {
 465:         int s;
 466:         caddr_t buf;
 467:         int len;
 468:         int flags;
 469:     } *uap = (struct a *)u.u_ap;
 470:     struct msghdr msg;
 471:     struct iovec aiov;
 472: 
 473:     msg.msg_name = 0;
 474:     msg.msg_namelen = 0;
 475:     msg.msg_iov = &aiov;
 476:     msg.msg_iovlen = 1;
 477:     aiov.iov_base = uap->buf;
 478:     aiov.iov_len = uap->len;
 479:     msg.msg_accrights = 0;
 480:     msg.msg_accrightslen = 0;
 481:     recvit(uap->s, &msg, uap->flags, (caddr_t)0, (caddr_t)0);
 482: }
 483: 
 484: recvmsg()
 485: {
 486:     register struct a {
 487:         int s;
 488:         struct  msghdr *msg;
 489:         int flags;
 490:     } *uap = (struct a *)u.u_ap;
 491:     struct msghdr msg;
 492:     struct iovec aiov[MSG_MAXIOVLEN];
 493: 
 494:     u.u_error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg));
 495:     if (u.u_error)
 496:         return;
 497:     if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
 498:         u.u_error = EMSGSIZE;
 499:         return;
 500:     }
 501:     u.u_error =
 502:         copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
 503:         (unsigned)(msg.msg_iovlen * sizeof(aiov[0])));
 504:     if (u.u_error)
 505:         return;
 506:     recvit(uap->s, &msg, uap->flags,
 507:         (caddr_t)&uap->msg->msg_namelen,
 508:         (caddr_t)&uap->msg->msg_accrightslen);
 509: }
 510: 
 511: recvit(s, mp, flags, namelenp, rightslenp)
 512:     int s;
 513:     register struct msghdr *mp;
 514:     int flags;
 515:     caddr_t namelenp, rightslenp;
 516: {
 517:     register struct file *fp;
 518:     struct uio auio;
 519:     register struct iovec *iov;
 520:     register int i;
 521:     struct mbuf *from, *rights;
 522:     int len, m_freem();
 523: 
 524:     if (netoff)
 525:         return(u.u_error = ENETDOWN);
 526:     fp = gtsockf(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:     auio.uio_rw = UIO_READ;
 535:     iov = mp->msg_iov;
 536:     for (i = 0; i < mp->msg_iovlen; i++, iov++)
 537:         {
 538:         if  (iov->iov_len == 0)
 539:             continue;
 540:         auio.uio_resid += iov->iov_len;
 541:         }
 542:     len = auio.uio_resid;
 543:     if  (setjmp(&u.u_qsave))
 544:         {
 545:         if  (auio.uio_resid == len)
 546:             return;
 547:         else
 548:             u.u_error = 0;
 549:         }
 550:     else
 551:         u.u_error = SORECEIVE((struct socket *)fp->f_data,
 552:                     &from, &auio,flags, &rights);
 553:     if  (u.u_error)
 554:         return;
 555:     u.u_r.r_val1 = len - auio.uio_resid;
 556:     if (mp->msg_name) {
 557:         len = mp->msg_namelen;
 558:         if (len <= 0 || from == 0)
 559:             len = 0;
 560:         else
 561:             (void) NETCOPYOUT(from, mp->msg_name, &len);
 562:         (void) copyout((caddr_t)&len, namelenp, sizeof(int));
 563:     }
 564:     if (mp->msg_accrights) {
 565:         len = mp->msg_accrightslen;
 566:         if (len <= 0 || rights == 0)
 567:             len = 0;
 568:         else
 569:             (void) NETCOPYOUT(rights, mp->msg_accrights, &len);
 570:         (void) copyout((caddr_t)&len, rightslenp, sizeof(int));
 571:     }
 572:     if (rights)
 573:         M_FREEM(rights);
 574:     if (from)
 575:         M_FREEM(from);
 576: }
 577: 
 578: shutdown()
 579: {
 580:     register struct a {
 581:         int s;
 582:         int how;
 583:     } *uap = (struct a *)u.u_ap;
 584:     register struct file *fp;
 585: 
 586:     if (netoff)
 587:         return(u.u_error = ENETDOWN);
 588:     fp = gtsockf(uap->s);
 589:     if (fp == 0)
 590:         return;
 591:     u.u_error = SOSHUTDOWN(fp->f_socket, uap->how);
 592: }
 593: 
 594: setsockopt()
 595: {
 596:     register struct a {
 597:         int s;
 598:         int level;
 599:         int name;
 600:         caddr_t val;
 601:         u_int   valsize;
 602:     } *uap = (struct a *)u.u_ap;
 603:     register struct file *fp;
 604:     register struct mbuf *m = NULL;
 605:     char optbuf[MSIZE];
 606: 
 607:     if (netoff)
 608:         return(u.u_error = ENETDOWN);
 609:     fp = gtsockf(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 = (struct mbuf *)optbuf;
 618:         MBZAP(m, uap->valsize, MT_SOOPTS);
 619:         u.u_error =
 620:             copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
 621:         if (u.u_error)
 622:             return;
 623:     }
 624:     u.u_error = SOSETOPT(fp->f_socket, uap->level, uap->name, m);
 625: }
 626: 
 627: getsockopt()
 628: {
 629:     register struct a {
 630:         int s;
 631:         int level;
 632:         int name;
 633:         caddr_t val;
 634:         int *avalsize;
 635:     } *uap = (struct a *)u.u_ap;
 636:     register struct file *fp;
 637:     struct mbuf *m = NULL, *m_free();
 638:     int valsize;
 639: 
 640:     if (netoff)
 641:         return(u.u_error = ENETDOWN);
 642:     fp = gtsockf(uap->s);
 643:     if (fp == 0)
 644:         return;
 645:     if (uap->val) {
 646:         u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
 647:             sizeof (valsize));
 648:         if (u.u_error)
 649:             return;
 650:     } else
 651:         valsize = 0;
 652:     u.u_error =
 653:         SOGETOPT(fp->f_socket, uap->level, uap->name, &m);
 654:     if (u.u_error)
 655:         goto bad;
 656:     if (uap->val && valsize && m != NULL) {
 657:         u.u_error = NETCOPYOUT(m, uap->val, &valsize);
 658:         if (u.u_error)
 659:             goto bad;
 660:         u.u_error = copyout((caddr_t)&valsize, (caddr_t)uap->avalsize,
 661:             sizeof (valsize));
 662:     }
 663: bad:
 664:     if (m != NULL)
 665:         M_FREE(m);
 666: }
 667: 
 668: /*
 669:  * Get socket name.
 670:  */
 671: getsockname()
 672: {
 673:     register struct a {
 674:         int fdes;
 675:         caddr_t asa;
 676:         int *alen;
 677:     } *uap = (struct a *)u.u_ap;
 678:     register struct file *fp;
 679:     struct mbuf *m;
 680:     int len;
 681:     char sabuf[MSIZE];
 682: 
 683:     if (netoff)
 684:         return(u.u_error = ENETDOWN);
 685:     fp = gtsockf(uap->fdes);
 686:     if (fp == 0)
 687:         return;
 688:     u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
 689:     if (u.u_error)
 690:         return;
 691:     m = (struct mbuf *)sabuf;
 692:     MBZAP(m, 0, MT_SONAME);
 693:     u.u_error = SOGETNAM(fp->f_socket, m);
 694:     if (u.u_error)
 695:         return;
 696:     if (len > m->m_len)
 697:         len = m->m_len;
 698:     u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
 699:     if (u.u_error)
 700:         return;
 701:     u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
 702: }
 703: 
 704: /*
 705:  * Get name of peer for connected socket.
 706:  */
 707: getpeername()
 708: {
 709:     register struct a {
 710:         int fdes;
 711:         caddr_t asa;
 712:         int *alen;
 713:     } *uap = (struct a *)u.u_ap;
 714:     register struct file *fp;
 715:     struct mbuf *m;
 716:     u_int len;
 717:     char sabuf[MSIZE];
 718: 
 719:     if (netoff)
 720:         return(u.u_error = ENETDOWN);
 721:     fp = gtsockf(uap->fdes);
 722:     if (fp == 0)
 723:         return;
 724:     m = (struct mbuf *)sabuf;
 725:     MBZAP(m, 0, MT_SONAME);
 726:     u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
 727:     if (u.u_error)
 728:         return;
 729:     u.u_error = SOGETPEER(fp->f_socket, m);
 730:     if (u.u_error)
 731:         return;
 732:     if (len > m->m_len)
 733:         len = m->m_len;
 734:     u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
 735:     if (u.u_error)
 736:         return;
 737:     u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
 738: }
 739: 
 740: #ifndef pdp11
 741: sockargs(aname, name, namelen, type)
 742:     struct mbuf **aname;
 743:     caddr_t name;
 744:     int namelen, type;
 745: {
 746:     register struct mbuf *m;
 747:     int error;
 748:     struct mbuf *m_free();
 749: 
 750:     if (namelen > MLEN)
 751:         return (EINVAL);
 752:     m = m_get(M_WAIT, type);
 753:     if (m == NULL)
 754:         return (ENOBUFS);
 755:     m->m_len = namelen;
 756:     error = copyin(name, mtod(m, caddr_t), (u_int)namelen);
 757:     if (error)
 758:         (void) m_free(m);
 759:     else
 760:         *aname = m;
 761:     return (error);
 762: }
 763: #endif
 764: 
 765: struct file *
 766: gtsockf(fdes)
 767:     int fdes;
 768: {
 769:     register struct file *fp;
 770: 
 771:     fp = getf(fdes);
 772:     if (fp == NULL)
 773:         return (0);
 774:     if (fp->f_type != DTYPE_SOCKET) {
 775:         u.u_error = ENOTSOCK;
 776:         return (0);
 777:     }
 778:     return (fp);
 779: }

Defined functions

MBZAP defined in line 30; used 8 times
accept defined in line 117; used 2 times
bind defined in line 75; used 2 times
connect defined in line 185; used 2 times
getpeername defined in line 707; used 2 times
getsockname defined in line 671; used 2 times
getsockopt defined in line 627; used 2 times
gtsockf defined in line 765; used 12 times
listen defined in line 101; used 2 times
recv defined in line 462; used 2 times
recvfrom defined in line 433; used 2 times
recvit defined in line 511; used 3 times
recvmsg defined in line 484; used 2 times
send defined in line 321; used 2 times
sendit defined in line 369; used 3 times
sendmsg defined in line 343; used 2 times
sendto defined in line 297; used 2 times
setsockopt defined in line 594; used 2 times
shutdown defined in line 578; used 2 times
sockargs defined in line 741; never used
socket defined in line 49; used 2 times
socketpair defined in line 237; used 2 times

Defined struct's

a defined in line 709; used 34 times
Last modified: 1999-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6545
Valid CSS Valid XHTML 1.0 Strict