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

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