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

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