root/net/socket.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. family_name
  2. get_fd
  3. toss_fd
  4. socki_lookup
  5. sockfd_lookup
  6. sock_alloc
  7. sock_release_peer
  8. sock_release
  9. sock_lseek
  10. sock_read
  11. sock_write
  12. sock_readdir
  13. sock_ioctl
  14. sock_select
  15. sock_close
  16. sock_awaitconn
  17. sock_socket
  18. sock_socketpair
  19. sock_bind
  20. sock_listen
  21. sock_accept
  22. sock_connect
  23. sock_getsockname
  24. sock_getpeername
  25. sys_send
  26. sys_sendto
  27. sys_recv
  28. sys_recvfrom
  29. sys_setsockopt
  30. sys_getsockopt
  31. sys_shutdown
  32. sock_fcntl
  33. sys_socketcall
  34. sock_init

   1 /* modified by Ross Biro to help support inet sockets. */
   2 #include <linux/signal.h>
   3 #include <linux/errno.h>
   4 #include <linux/sched.h>
   5 #include <linux/kernel.h>
   6 #include <linux/stat.h>
   7 #include <linux/socket.h>
   8 #include <linux/fcntl.h>
   9 #include <linux/termios.h>
  10 #include <linux/config.h>
  11 
  12 #include <asm/system.h>
  13 #include <asm/segment.h>
  14 
  15 #include "kern_sock.h"
  16 #include "socketcall.h"
  17 
  18 extern int sys_close(int fd);
  19 
  20 extern struct proto_ops unix_proto_ops;
  21 #ifdef CONFIG_TCPIP
  22 extern struct proto_ops inet_proto_ops;
  23 #endif
  24 
  25 static struct {
  26         short family;
  27         char *name;
  28         struct proto_ops *ops;
  29 } proto_table[] = {
  30         {AF_UNIX,       "AF_UNIX",      &unix_proto_ops},
  31 #ifdef CONFIG_TCPIP
  32         {AF_INET,       "AF_INET",      &inet_proto_ops},
  33 #endif
  34 };
  35 #define NPROTO (sizeof(proto_table) / sizeof(proto_table[0]))
  36 
  37 static char *
  38 family_name(int family)
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40         int i;
  41 
  42         for (i = 0; i < NPROTO; ++i)
  43                 if (proto_table[i].family == family)
  44                         return proto_table[i].name;
  45         return "UNKNOWN";
  46 }
  47 
  48 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
  49                       int whence);
  50 static int sock_read(struct inode *inode, struct file *file, char *buf,
  51                      int size);
  52 static int sock_write(struct inode *inode, struct file *file, char *buf,
  53                       int size);
  54 static int sock_readdir(struct inode *inode, struct file *file,
  55                         struct dirent *dirent, int count);
  56 static void sock_close(struct inode *inode, struct file *file);
  57 static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
  58 static int sock_ioctl(struct inode *inode, struct file *file,
  59                       unsigned int cmd, unsigned int arg);
  60 
  61 static struct file_operations socket_file_ops = {
  62         sock_lseek,
  63         sock_read,
  64         sock_write,
  65         sock_readdir,
  66         sock_select,
  67         sock_ioctl,
  68         NULL,           /* mmap */
  69         NULL,           /* no special open code... */
  70         sock_close
  71 };
  72 
  73 #define SOCK_INODE(S) ((struct inode *)(S)->dummy)
  74 
  75 static struct socket sockets[NSOCKETS];
  76 #define last_socket (sockets + NSOCKETS - 1)
  77 static struct wait_queue *socket_wait_free = NULL;
  78 
  79 /*
  80  * obtains the first available file descriptor and sets it up for use
  81  */
  82 static int
  83 get_fd(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         int fd;
  86         struct file *file;
  87 
  88         /*
  89          * find a file descriptor suitable for return to the user.
  90          */
  91         file = get_empty_filp();
  92         if (!file)
  93                 return -1;
  94         for (fd = 0; fd < NR_OPEN; ++fd)
  95                 if (!current->filp[fd])
  96                         break;
  97         if (fd == NR_OPEN) {
  98                 file->f_count = 0;
  99                 return -1;
 100         }
 101         FD_CLR(fd, &current->close_on_exec);
 102         current->filp[fd] = file;
 103         file->f_op = &socket_file_ops;
 104         file->f_mode = 3;
 105         file->f_flags = 0;
 106         file->f_count = 1;
 107         file->f_inode = inode;
 108         if (inode)
 109                 inode->i_count++;
 110         file->f_pos = 0;
 111         return fd;
 112 }
 113 
 114 /*
 115  * reverses the action of get_fd() by releasing the file. it closes the
 116  * descriptor, but makes sure it does nothing more. called when an incomplete
 117  * socket must be closed, along with sock_release().
 118  */
 119 static inline void
 120 toss_fd(int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122   /* the count protects us from iput. */
 123         sys_close(fd);
 124 }
 125 
 126 struct socket *
 127 socki_lookup(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         struct socket *sock;
 130 
 131         for (sock = sockets; sock <= last_socket; ++sock)
 132                 if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
 133                         return sock;
 134         return NULL;
 135 }
 136 
 137 static inline struct socket *
 138 sockfd_lookup(int fd, struct file **pfile)
     /* [previous][next][first][last][top][bottom][index][help] */
 139 {
 140         struct file *file;
 141 
 142         if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd]))
 143                 return NULL;
 144         if (pfile)
 145                 *pfile = file;
 146         return socki_lookup(file->f_inode);
 147 }
 148 
 149 static struct socket *
 150 sock_alloc(int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152         struct socket *sock;
 153 
 154         while (1) {
 155                 cli();
 156                 for (sock = sockets; sock <= last_socket; ++sock)
 157                         if (sock->state == SS_FREE) {
 158                                 sock->state = SS_UNCONNECTED;
 159                                 sti();
 160                                 sock->flags = 0;
 161                                 sock->ops = NULL;
 162                                 sock->data = NULL;
 163                                 sock->conn = NULL;
 164                                 sock->iconn = NULL;
 165                                 /*
 166                                  * this really shouldn't be necessary, but
 167                                  * everything else depends on inodes, so we
 168                                  * grab it.
 169                                  * sleeps are also done on the i_wait member
 170                                  * of this inode.
 171                                  * the close system call will iput this inode
 172                                  * for us.
 173                                  */
 174                                 if (!(SOCK_INODE(sock) = get_empty_inode())) {
 175                                         printk("sock_alloc: no more inodes\n");
 176                                         sock->state = SS_FREE;
 177                                         return NULL;
 178                                 }
 179                                 SOCK_INODE(sock)->i_mode = S_IFSOCK;
 180                                 sock->wait = &SOCK_INODE(sock)->i_wait;
 181                                 PRINTK(("sock_alloc: socket 0x%x, inode 0x%x\n",
 182                                        sock, SOCK_INODE(sock)));
 183                                 return sock;
 184                         }
 185                 sti();
 186                 if (!wait)
 187                         return NULL;
 188                 PRINTK(("sock_alloc: no free sockets, sleeping...\n"));
 189                 interruptible_sleep_on(&socket_wait_free);
 190                 if (current->signal & ~current->blocked) {
 191                         PRINTK(("sock_alloc: sleep was interrupted\n"));
 192                         return NULL;
 193                 }
 194                 PRINTK(("sock_alloc: wakeup... trying again...\n"));
 195         }
 196 }
 197 
 198 static inline void
 199 sock_release_peer(struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 200 {
 201         peer->state = SS_DISCONNECTING;
 202         wake_up(peer->wait);
 203 }
 204 
 205 static void
 206 sock_release(struct socket *sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         int oldstate;
 209         struct socket *peersock, *nextsock;
 210 
 211         PRINTK(("sock_release: socket 0x%x, inode 0x%x\n", sock,
 212                SOCK_INODE(sock)));
 213         if ((oldstate = sock->state) != SS_UNCONNECTED)
 214                 sock->state = SS_DISCONNECTING;
 215         /*
 216          * wake up anyone waiting for connections
 217          */
 218         for (peersock = sock->iconn; peersock; peersock = nextsock) {
 219                 nextsock = peersock->next;
 220                 sock_release_peer(peersock);
 221         }
 222         /*
 223          * wake up anyone we're connected to. first, we release the
 224          * protocol, to give it a chance to flush data, etc.
 225          */
 226         peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
 227         if (sock->ops)
 228                 sock->ops->release(sock, peersock);
 229         if (peersock)
 230                 sock_release_peer(peersock);
 231         sock->state = SS_FREE;          /* this really releases us */
 232         wake_up(&socket_wait_free);
 233         iput(SOCK_INODE(sock)); /* we need to do this.  If sock alloc was
 234                                    called we already have an inode. */
 235 }
 236 
 237 static int
 238 sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240         PRINTK(("sock_lseek: huh?\n"));
 241         return -ESPIPE;
 242 }
 243 
 244 static int
 245 sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247         struct socket *sock;
 248 
 249         PRINTK(("sock_read: buf=0x%x, size=%d\n", ubuf, size));
 250         if (!(sock = socki_lookup(inode))) {
 251                 printk("sock_read: can't find socket for inode!\n");
 252                 return -EBADF;
 253         }
 254         if (sock->flags & SO_ACCEPTCON)
 255                 return -EINVAL;
 256         return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK));
 257 }
 258 
 259 static int
 260 sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         struct socket *sock;
 263 
 264         PRINTK(("sock_write: buf=0x%x, size=%d\n", ubuf, size));
 265         if (!(sock = socki_lookup(inode))) {
 266                 printk("sock_write: can't find socket for inode!\n");
 267                 return -EBADF;
 268         }
 269         if (sock->flags & SO_ACCEPTCON)
 270                 return -EINVAL;
 271         return sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK));
 272 }
 273 
 274 static int
 275 sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
     /* [previous][next][first][last][top][bottom][index][help] */
 276              int count)
 277 {
 278         PRINTK(("sock_readdir: huh?\n"));
 279         return -EBADF;
 280 }
 281 
 282 int
 283 sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 284            unsigned int arg)
 285 {
 286         struct socket *sock;
 287 
 288         PRINTK(("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg));
 289         if (!(sock = socki_lookup(inode))) {
 290                 printk("sock_ioctl: can't find socket for inode!\n");
 291                 return -EBADF;
 292         }
 293         return sock->ops->ioctl(sock, cmd, arg);
 294 }
 295 
 296 static int
 297 sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299         struct socket *sock;
 300 
 301         PRINTK(("sock_select: inode = 0x%x, kind = %s\n", inode,
 302                (sel_type == SEL_IN) ? "in" :
 303                (sel_type == SEL_OUT) ? "out" : "ex"));
 304         if (!(sock = socki_lookup(inode))) {
 305                 printk("sock_select: can't find socket for inode!\n");
 306                 return 0;
 307         }
 308         /*
 309          * we can't return errors to select, so its either yes or no.
 310          */
 311         if (sock->ops && sock->ops->select)
 312                 return sock->ops->select(sock, sel_type, wait);
 313         return 0;
 314 }
 315 
 316 void
 317 sock_close(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 318 {
 319         struct socket *sock;
 320 
 321         PRINTK(("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count));
 322         /*
 323          * it's possible the inode is NULL if we're closing an unfinished
 324          * socket.
 325          */
 326         if (!inode)
 327                 return;
 328         if (!(sock = socki_lookup(inode))) {
 329                 printk("sock_close: can't find socket for inode!\n");
 330                 return;
 331         }
 332         sock_release(sock);
 333 }
 334 
 335 int
 336 sock_awaitconn(struct socket *mysock, struct socket *servsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 337 {
 338         struct socket *last;
 339 
 340         PRINTK(("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
 341                mysock, servsock));
 342         if (!(servsock->flags & SO_ACCEPTCON)) {
 343                 PRINTK(("sock_awaitconn: server not accepting connections\n"));
 344                 return -EINVAL;
 345         }
 346 
 347         /*
 348          * put ourselves on the server's incomplete connection queue.
 349          */
 350         mysock->next = NULL;
 351         cli();
 352         if (!(last = servsock->iconn))
 353                 servsock->iconn = mysock;
 354         else {
 355                 while (last->next)
 356                         last = last->next;
 357                 last->next = mysock;
 358         }
 359         mysock->state = SS_CONNECTING;
 360         mysock->conn = servsock;
 361         sti();
 362 
 363         /*
 364          * wake up server, then await connection. server will set state to
 365          * SS_CONNECTED if we're connected.
 366          */
 367         wake_up(servsock->wait);
 368         if (mysock->state != SS_CONNECTED) {
 369                 interruptible_sleep_on(mysock->wait);
 370                 if (mysock->state != SS_CONNECTED) {
 371                         /*
 372                          * if we're not connected we could have been
 373                          * 1) interrupted, so we need to remove ourselves
 374                          *    from the server list
 375                          * 2) rejected (mysock->conn == NULL), and have
 376                          *    already been removed from the list
 377                          */
 378                         if (mysock->conn == servsock) {
 379                                 cli();
 380                                 if ((last = servsock->iconn) == mysock)
 381                                         servsock->iconn = mysock->next;
 382                                 else {
 383                                         while (last->next != mysock)
 384                                                 last = last->next;
 385                                         last->next = mysock->next;
 386                                 }
 387                                 sti();
 388                         }
 389                         return mysock->conn ? -EINTR : -EACCES;
 390                 }
 391         }
 392         return 0;
 393 }
 394 
 395 /*
 396  * perform the socket system call. we locate the appropriate family, then
 397  * create a fresh socket.
 398  */
 399 static int
 400 sock_socket(int family, int type, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 401 {
 402         int i, fd;
 403         struct socket *sock;
 404         struct proto_ops *ops;
 405 
 406         PRINTK(("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
 407                family, family_name(family), type, protocol));
 408 
 409         /*
 410          * locate the correct protocol family
 411          */
 412         for (i = 0; i < NPROTO; ++i)
 413                 if (proto_table[i].family == family)
 414                         break;
 415         if (i == NPROTO) {
 416                 PRINTK(("sys_socket: family not found\n"));
 417                 return -EINVAL;
 418         }
 419         ops = proto_table[i].ops;
 420 
 421         /*
 422          * check that this is a type that we know how to manipulate and
 423          * the protocol makes sense here. the family can still reject the
 424          * protocol later.
 425          */
 426         if ((type != SOCK_STREAM &&
 427              type != SOCK_DGRAM &&
 428              type != SOCK_SEQPACKET &&
 429              type != SOCK_RAW) ||
 430             protocol < 0)
 431                 return -EINVAL;
 432 
 433         /*
 434          * allocate the socket and allow the family to set things up. if
 435          * the protocol is 0, the family is instructed to select an appropriate
 436          * default.
 437          */
 438         if (!(sock = sock_alloc(1))) {
 439                 printk("sys_socket: no more sockets\n");
 440                 return -EAGAIN;
 441         }
 442         sock->type = type;
 443         sock->ops = ops;
 444         if ((i = sock->ops->create(sock, protocol)) < 0) {
 445                 sock_release(sock);
 446                 return i;
 447         }
 448 
 449         if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
 450                 sock_release(sock);
 451                 return -EINVAL;
 452         }
 453 
 454         return fd;
 455 }
 456 
 457 static int
 458 sock_socketpair(int family, int type, int protocol, int usockvec[2])
     /* [previous][next][first][last][top][bottom][index][help] */
 459 {
 460         int fd1, fd2, i;
 461         struct socket *sock1, *sock2;
 462 
 463         PRINTK(("sys_socketpair: family = %d, type = %d, protocol = %d\n",
 464                family, type, protocol));
 465 
 466         /*
 467          * obtain the first socket and check if the underlying protocol
 468          * supports the socketpair call
 469          */
 470         if ((fd1 = sock_socket(family, type, protocol)) < 0)
 471                 return fd1;
 472         sock1 = sockfd_lookup(fd1, NULL);
 473         if (!sock1->ops->socketpair) {
 474                 sys_close(fd1);
 475                 return -EINVAL;
 476         }
 477 
 478         /*
 479          * now grab another socket and try to connect the two together
 480          */
 481         if ((fd2 = sock_socket(family, type, protocol)) < 0) {
 482                 sys_close(fd1);
 483                 return -EINVAL;
 484         }
 485         sock2 = sockfd_lookup(fd2, NULL);
 486         if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
 487                 sys_close(fd1);
 488                 sys_close(fd2);
 489                 return i;
 490         }
 491         sock1->conn = sock2;
 492         sock2->conn = sock1;
 493         sock1->state = SS_CONNECTED;
 494         sock2->state = SS_CONNECTED;
 495 
 496         verify_area(usockvec, 2 * sizeof(int));
 497         put_fs_long(fd1, &usockvec[0]);
 498         put_fs_long(fd2, &usockvec[1]);
 499 
 500         return 0;
 501 }
 502 
 503 /*
 504  * binds a name to a socket. nothing much to do here since its the
 505  * protocol's responsibility to handle the local address
 506  */
 507 static int
 508 sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510         struct socket *sock;
 511         int i;
 512 
 513         PRINTK(("sys_bind: fd = %d\n", fd));
 514         if (!(sock = sockfd_lookup(fd, NULL)))
 515                 return -EBADF;
 516         if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
 517                 PRINTK(("sys_bind: bind failed\n"));
 518                 return i;
 519         }
 520         return 0;
 521 }
 522 
 523 /*
 524  * perform a listen. basically, we allow the protocol to do anything
 525  * necessary for a listen, and if that works, we mark the socket as
 526  * ready for listening.
 527  */
 528 static int
 529 sock_listen(int fd, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531         struct socket *sock;
 532 
 533         PRINTK(("sys_listen: fd = %d\n", fd));
 534         if (!(sock = sockfd_lookup(fd, NULL)))
 535                 return -EBADF;
 536         if (sock->state != SS_UNCONNECTED) {
 537                 PRINTK(("sys_listen: socket isn't unconnected\n"));
 538                 return -EINVAL;
 539         }
 540         if (sock->flags & SO_ACCEPTCON) {
 541                 PRINTK(("sys_listen: socket already accepting connections!\n"));
 542                 return -EINVAL;
 543         }
 544         if (sock->ops && sock->ops->listen)
 545           sock->ops->listen (sock, backlog);
 546         sock->flags |= SO_ACCEPTCON;
 547         return 0;
 548 }
 549 
 550 /*
 551  * for accept, we attempt to create a new socket, set up the link with the
 552  * client, wake up the client, then return the new connected fd.
 553  */
 554 static int
 555 sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 556 {
 557         struct file *file;
 558         struct socket *sock, *newsock;
 559         int i;
 560 
 561         PRINTK(("sys_accept: fd = %d\n", fd));
 562         if (!(sock = sockfd_lookup(fd, &file)))
 563                 return -EBADF;
 564         if (sock->state != SS_UNCONNECTED) {
 565                 PRINTK(("sys_accept: socket isn't unconnected\n"));
 566                 return -EINVAL;
 567         }
 568         if (!(sock->flags & SO_ACCEPTCON)) {
 569                 PRINTK(("sys_accept: socket not accepting connections!\n"));
 570                 return -EINVAL;
 571         }
 572 
 573         if (!(newsock = sock_alloc(0))) {
 574                 printk("sys_accept: no more sockets\n");
 575                 return -EAGAIN;
 576         }
 577         newsock->type = sock->type;
 578         newsock->ops = sock->ops;
 579         if ((i = sock->ops->dup(newsock, sock)) < 0) {
 580                 sock_release(newsock);
 581                 return i;
 582         }
 583 
 584         i = newsock->ops->accept(sock, newsock, file->f_flags);
 585 
 586         if ( i < 0)
 587           {
 588             sock_release(newsock);
 589             return (i);
 590           }
 591 
 592         if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
 593                 sock_release(newsock);
 594                 return -EINVAL;
 595         }
 596 
 597         PRINTK(("sys_accept: connected socket 0x%x via 0x%x\n",
 598                sock, newsock));
 599 
 600         if (upeer_sockaddr)
 601                 newsock->ops->getname(newsock, upeer_sockaddr,
 602                                       upeer_addrlen, 1);
 603 
 604         return fd;
 605 }
 606 
 607 /*
 608  * attempt to connect to a socket with the server address.
 609  */
 610 static int
 611 sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 612 {
 613         struct socket *sock;
 614         struct file *file;
 615         int i;
 616 
 617         PRINTK(("sys_connect: fd = %d\n", fd));
 618         if (!(sock = sockfd_lookup(fd, &file)))
 619                 return -EBADF;
 620         switch (sock->state) {
 621                 case SS_UNCONNECTED:
 622                         /* This is ok... continue with connect */
 623                         break;
 624                 case SS_CONNECTED:
 625                         /* Socket is already connected */
 626                         return -EISCONN;
 627                 case SS_CONNECTING:
 628                         /* Not yet connected... */
 629                         /* we will check this. */
 630                         return (sock->ops->connect(sock, uservaddr, addrlen, file->f_flags));
 631                 default:
 632                         PRINTK(("sys_connect: socket not unconnected\n"));
 633                         return -EINVAL;
 634         }
 635         i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
 636         if (i < 0) {
 637                 PRINTK(("sys_connect: connect failed\n"));
 638                 return i;
 639         }
 640         return 0;
 641 }
 642 
 643 static int
 644 sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 645 {
 646         struct socket *sock;
 647 
 648         PRINTK(("sys_getsockname: fd = %d\n", fd));
 649         if (!(sock = sockfd_lookup(fd, NULL)))
 650                 return -EBADF;
 651         return sock->ops->getname(sock, usockaddr, usockaddr_len, 0);
 652 }
 653 
 654 static int
 655 sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 656 {
 657         struct socket *sock;
 658 
 659         PRINTK(("sys_getpeername: fd = %d\n", fd));
 660         if (!(sock = sockfd_lookup(fd, NULL)))
 661                 return -EBADF;
 662         return sock->ops->getname(sock, usockaddr, usockaddr_len, 1);
 663 }
 664 
 665 
 666 /* send - shutdown added by bir7@leland.stanford.edu */
 667 
 668 static int
 669 sys_send( int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 670 {
 671         struct socket *sock;
 672         struct file *file;
 673 
 674         PRINTK(("sys_send (fd = %d, buff = %X, len = %d, flags = %X)\n",
 675                fd, buff, len, flags));
 676 
 677         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 678           return (-EBADF);
 679 
 680         if (!(sock = sockfd_lookup(fd, NULL)))
 681                 return (-ENOTSOCK);
 682 
 683         return (sock->ops->send (sock, buff, len, (file->f_flags & O_NONBLOCK),
 684                                  flags));
 685 
 686 }
 687 
 688 static int
 689 sys_sendto( int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 690            struct sockaddr *addr, int addr_len)
 691 {
 692         struct socket *sock;
 693         struct file *file;
 694 
 695         PRINTK(("sys_sendto (fd = %d, buff = %X, len = %d, flags = %X,"
 696                " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len));
 697 
 698         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 699           return (-EBADF);
 700 
 701         if (!(sock = sockfd_lookup(fd, NULL)))
 702                 return (-ENOTSOCK);
 703 
 704         return (sock->ops->sendto (sock, buff, len,
 705                                    (file->f_flags & O_NONBLOCK),
 706                                    flags, addr, addr_len));
 707 
 708 }
 709 
 710 
 711 static int
 712 sys_recv( int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 713 {
 714         struct socket *sock;
 715         struct file *file;
 716 
 717         PRINTK(("sys_recv (fd = %d, buff = %X, len = %d, flags = %X)\n",
 718                fd, buff, len, flags));
 719 
 720         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 721           return (-EBADF);
 722 
 723         if (!(sock = sockfd_lookup(fd, NULL)))
 724                 return (-ENOTSOCK);
 725 
 726         return (sock->ops->recv (sock, buff, len,(file->f_flags & O_NONBLOCK),
 727                                  flags));
 728 
 729 }
 730 
 731 static int
 732 sys_recvfrom( int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 733              struct sockaddr *addr, int *addr_len)
 734 {
 735         struct socket *sock;
 736         struct file *file;
 737 
 738         PRINTK(("sys_recvfrom (fd = %d, buff = %X, len = %d, flags = %X,"
 739                " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
 740 
 741         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 742           return (-EBADF);
 743 
 744         if (!(sock = sockfd_lookup(fd, NULL)))
 745                 return (-ENOTSOCK);
 746 
 747         return (sock->ops->recvfrom (sock, buff, len,
 748                                      (file->f_flags & O_NONBLOCK),
 749                                      flags, addr, addr_len));
 750 
 751 }
 752 
 753 
 754 static int
 755 sys_setsockopt (int fd, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 756 {
 757         struct socket *sock;
 758         struct file *file;
 759         
 760         PRINTK (("sys_setsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
 761                 optname));
 762         PRINTK (("               optval = %X, optlen = %d)\n", optval, optlen));
 763 
 764         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 765           return (-EBADF);
 766 
 767         if (!(sock = sockfd_lookup(fd, NULL)))
 768                 return (-ENOTSOCK);
 769 
 770         return (sock->ops->setsockopt (sock, level, optname, optval, optlen));
 771 
 772 }
 773 
 774 static int
 775 sys_getsockopt (int fd, int level, int optname, char *optval, int *optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 776 {
 777         struct socket *sock;
 778         struct file *file;
 779         PRINTK (("sys_getsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
 780                 optname));
 781         PRINTK (("               optval = %X, optlen = %X)\n", optval, optlen));
 782 
 783         if (fd < 0 || fd >= NR_OPEN ||  ((file = current->filp[fd]) == NULL))
 784           return (-EBADF);
 785 
 786         if (!(sock = sockfd_lookup(fd, NULL)))
 787             return (-ENOTSOCK);
 788             
 789         if (!sock->ops || !sock->ops->getsockopt)
 790                 return 0;
 791         return sock->ops->getsockopt(sock, level, optname, optval, optlen);
 792 
 793 }
 794 
 795 
 796 static int
 797 sys_shutdown( int fd, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 798 {
 799         struct socket *sock;
 800         struct file *file;
 801 
 802         PRINTK(("sys_shutdown (fd = %d, how = %d)\n",fd, how));
 803 
 804         file = current->filp[fd];
 805         if (fd < 0 || fd >= NR_OPEN || file == NULL)
 806           return (-EBADF);
 807 
 808         if (!(sock = sockfd_lookup(fd, NULL)))
 809                 return (-ENOTSOCK);
 810 
 811         return (sock->ops->shutdown (sock, how));
 812 
 813 }
 814 
 815 int
 816 sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 817 {
 818    struct socket *sock;
 819    sock = socki_lookup (filp->f_inode);
 820    
 821    if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
 822      return (sock->ops->fcntl (sock, cmd, arg));
 823 
 824    return (-EINVAL);
 825 }
 826 
 827 
 828 /*
 829  * system call vectors. since i want to rewrite sockets as streams, we have
 830  * this level of indirection. not a lot of overhead, since more of the work is
 831  * done via read/write/select directly
 832  */
 833 int
 834 sys_socketcall(int call, unsigned long *args)
     /* [previous][next][first][last][top][bottom][index][help] */
 835 {
 836         switch (call) {
 837         case SYS_SOCKET:
 838                 verify_area(args, 3 * sizeof(long));
 839                 return sock_socket(get_fs_long(args+0),
 840                                    get_fs_long(args+1),
 841                                    get_fs_long(args+2));
 842 
 843         case SYS_BIND:
 844                 verify_area(args, 3 * sizeof(long));
 845                 return sock_bind(get_fs_long(args+0),
 846                                  (struct sockaddr *)get_fs_long(args+1),
 847                                  get_fs_long(args+2));
 848 
 849         case SYS_CONNECT:
 850                 verify_area(args, 3 * sizeof(long));
 851                 return sock_connect(get_fs_long(args+0),
 852                                     (struct sockaddr *)get_fs_long(args+1),
 853                                     get_fs_long(args+2));
 854 
 855         case SYS_LISTEN:
 856                 verify_area(args, 2 * sizeof(long));
 857                 return sock_listen(get_fs_long(args+0),
 858                                    get_fs_long(args+1));
 859 
 860         case SYS_ACCEPT:
 861                 verify_area(args, 3 * sizeof(long));
 862                 return sock_accept(get_fs_long(args+0),
 863                                    (struct sockaddr *)get_fs_long(args+1),
 864                                    (int *)get_fs_long(args+2));
 865 
 866         case SYS_GETSOCKNAME:
 867                 verify_area(args, 3 * sizeof(long));
 868                 return sock_getsockname(get_fs_long(args+0),
 869                                         (struct sockaddr *)get_fs_long(args+1),
 870                                         (int *)get_fs_long(args+2));
 871 
 872         case SYS_GETPEERNAME:
 873                 verify_area(args, 3 * sizeof(long));
 874                 return sock_getpeername(get_fs_long(args+0),
 875                                         (struct sockaddr *)get_fs_long(args+1),
 876                                         (int *)get_fs_long(args+2));
 877 
 878         case SYS_SOCKETPAIR:
 879                 verify_area(args, 4 * sizeof(long));
 880                 return sock_socketpair(get_fs_long(args+0),
 881                                        get_fs_long(args+1),
 882                                        get_fs_long(args+2),
 883                                        (int *)get_fs_long(args+3));
 884 
 885       case SYS_SEND:
 886           verify_area(args, 4 * sizeof (unsigned long));
 887           return ( sys_send (get_fs_long(args+0),
 888                              (void *)get_fs_long(args+1),
 889                              get_fs_long(args+2),
 890                              get_fs_long(args+3)));
 891                              
 892       case SYS_SENDTO:
 893           verify_area(args, 6 * sizeof (unsigned long));
 894           return ( sys_sendto (get_fs_long(args+0),
 895                              (void *)get_fs_long(args+1),
 896                              get_fs_long(args+2),
 897                              get_fs_long(args+3),
 898                              (struct sockaddr *)get_fs_long(args+4),
 899                              get_fs_long(args+5)));
 900 
 901     
 902       case SYS_RECV:
 903           verify_area(args, 4 * sizeof (unsigned long));
 904           return ( sys_recv (get_fs_long(args+0),
 905                              (void *)get_fs_long(args+1),
 906                              get_fs_long(args+2),
 907                              get_fs_long(args+3)));
 908                              
 909       case SYS_RECVFROM:
 910           verify_area(args, 6 * sizeof (unsigned long));
 911           return ( sys_recvfrom (get_fs_long(args+0),
 912                                  (void *)get_fs_long(args+1),
 913                                  get_fs_long(args+2),
 914                                  get_fs_long(args+3),
 915                                  (struct sockaddr *)get_fs_long(args+4),
 916                                  (int *)get_fs_long(args+5)));
 917 
 918       case SYS_SHUTDOWN:
 919           verify_area (args, 2* sizeof (unsigned long));
 920           return ( sys_shutdown (get_fs_long (args+0),
 921                                  get_fs_long (args+1)));
 922 
 923       case SYS_SETSOCKOPT:
 924           verify_area (args, 5*sizeof (unsigned long));
 925           return (sys_setsockopt (get_fs_long (args+0),
 926                                   get_fs_long (args+1),
 927                                   get_fs_long (args+2),
 928                                   (char *)get_fs_long (args+3),
 929                                   get_fs_long (args+4)));
 930 
 931 
 932       case SYS_GETSOCKOPT:
 933           verify_area (args, 5*sizeof (unsigned long));
 934           return (sys_getsockopt (get_fs_long (args+0),
 935                                   get_fs_long (args+1),
 936                                   get_fs_long (args+2),
 937                                   (char *)get_fs_long (args+3),
 938                                   (int *)get_fs_long (args+4)));
 939 
 940         default:
 941                 return -EINVAL;
 942         }
 943 }
 944 
 945 void
 946 sock_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 947 {
 948         struct socket *sock;
 949         int i, ok;
 950 
 951         for (sock = sockets; sock <= last_socket; ++sock)
 952                 sock->state = SS_FREE;
 953         for (i = ok = 0; i < NPROTO; ++i) {
 954                 printk("sock_init: initializing family %d (%s)\n",
 955                        proto_table[i].family, proto_table[i].name);
 956                 if ((*proto_table[i].ops->init)() < 0) {
 957                         printk("sock_init: init failed.\n",
 958                                proto_table[i].family);
 959                         proto_table[i].family = -1;
 960                 }
 961                 else
 962                         ++ok;
 963         }
 964         if (!ok)
 965                 printk("sock_init: warning: no protocols initialized\n");
 966         return;
 967 }
 968 

/* [previous][next][first][last][top][bottom][index][help] */