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_socketcall
  26. sock_init

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

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