root/net/socket.c

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

DEFINITIONS

This source file includes following definitions.
  1. dprintf
  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. sock_send
  26. sock_sendto
  27. sock_recv
  28. sock_recvfrom
  29. sock_setsockopt
  30. sock_getsockopt
  31. sock_shutdown
  32. sock_fcntl
  33. sys_socketcall
  34. net_ioctl
  35. net_fioctl
  36. sock_register
  37. sock_init

   1 /*
   2  * NET          An implementation of the SOCKET network access protocol.
   3  *
   4  * Version:     @(#)socket.c    1.0.5   05/25/93
   5  *
   6  * Authors:     Orest Zborowski, <obz@Kodak.COM>
   7  *              Ross Biro, <bir7@leland.Stanford.Edu>
   8  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   9  *
  10  * Fixes:
  11  *              Anonymous       :       NOTSOCK/BADF cleanup. Error fix in
  12  *                                      shutdown()
  13  *              Alan Cox        :       verify_area() fixes
  14  *
  15  *
  16  *              This program is free software; you can redistribute it and/or
  17  *              modify it under the terms of the GNU General Public License
  18  *              as published by the Free Software Foundation; either version
  19  *              2 of the License, or (at your option) any later version.
  20  */
  21 
  22 #include <linux/config.h>
  23 #include <linux/signal.h>
  24 #include <linux/errno.h>
  25 #include <linux/sched.h>
  26 #include <linux/kernel.h>
  27 #include <linux/major.h>
  28 #include <linux/stat.h>
  29 #include <linux/socket.h>
  30 #include <linux/fcntl.h>
  31 #include <linux/termios.h>
  32 #include <linux/net.h>
  33 #include <linux/ddi.h>
  34 
  35 #include <asm/system.h>
  36 #include <asm/segment.h>
  37 
  38 #undef SOCK_DEBUG
  39 
  40 #ifdef SOCK_DEBUG
  41 #include <stdarg.h>
  42 #define DPRINTF(x) dprintf x
  43 #else
  44 #define DPRINTF(x) /**/
  45 #endif
  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 long arg);
  59 
  60 
  61 static struct file_operations socket_file_ops = {
  62   sock_lseek,
  63   sock_read,
  64   sock_write,
  65   sock_readdir,
  66   sock_select,
  67   sock_ioctl,
  68   NULL,                 /* mmap */
  69   NULL,                 /* no special open code... */
  70   sock_close
  71 };
  72 
  73 static struct socket sockets[NSOCKETS];
  74 static struct wait_queue *socket_wait_free = NULL;
  75 static struct proto_ops *pops[NPROTO];
  76 static int net_debug = 0;
  77 
  78 #define last_socket     (sockets + NSOCKETS - 1)
  79 
  80 #ifdef SOCK_DEBUG
  81 /* Module debugging. */
  82 static void
  83 dprintf(int level, char *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85   char buff[1024];
  86   va_list args;
  87   extern int vsprintf(char * buf, const char * fmt, va_list args);
  88 
  89   if (level == 0) return;
  90   va_start(args, fmt);
  91   vsprintf(buff, fmt, args);
  92   va_end(args);
  93   printk(buff);
  94 }
  95 #endif
  96 
  97 /* Obtains the first available file descriptor and sets it up for use. */
  98 static int
  99 get_fd(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101   int fd;
 102   struct file *file;
 103 
 104   /* Find a file descriptor suitable for return to the user. */
 105   file = get_empty_filp();
 106   if (!file) return(-1);
 107   for (fd = 0; fd < NR_OPEN; ++fd)
 108         if (!current->filp[fd]) break;
 109   if (fd == NR_OPEN) {
 110         file->f_count = 0;
 111         return(-1);
 112   }
 113   FD_CLR(fd, &current->close_on_exec);
 114   current->filp[fd] = file;
 115   file->f_op = &socket_file_ops;
 116   file->f_mode = 3;
 117   file->f_flags = 0;
 118   file->f_count = 1;
 119   file->f_inode = inode;
 120   if (inode) inode->i_count++;
 121   file->f_pos = 0;
 122   return(fd);
 123 }
 124 
 125 
 126 /*
 127  * Reverses the action of get_fd() by releasing the file. it closes
 128  * the descriptor, but makes sure it does nothing more. Called when
 129  * an incomplete socket must be closed, along with sock_release().
 130  */
 131 static inline void
 132 toss_fd(int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134   sys_close(fd);                /* the count protects us from iput */
 135 }
 136 
 137 
 138 struct socket *
 139 socki_lookup(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141   struct socket *sock;
 142 
 143   if ((sock = inode->i_socket) != NULL) {
 144         if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
 145                 return sock;
 146         printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
 147   }
 148   for (sock = sockets; sock <= last_socket; ++sock)
 149         if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) {
 150                 printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n");
 151                 return(sock);
 152         }
 153   return(NULL);
 154 }
 155 
 156 
 157 static inline struct socket *
 158 sockfd_lookup(int fd, struct file **pfile)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   struct file *file;
 161 
 162   if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd])) return(NULL);
 163   if (pfile) *pfile = file;
 164   return(socki_lookup(file->f_inode));
 165 }
 166 
 167 
 168 static struct socket *
 169 sock_alloc(int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171   struct socket *sock;
 172 
 173   while (1) {
 174         cli();
 175         for (sock = sockets; sock <= last_socket; ++sock) {
 176                 if (sock->state == SS_FREE) {
 177                         sock->state = SS_UNCONNECTED;
 178                         sti();
 179                         sock->flags = 0;
 180                         sock->ops = NULL;
 181                         sock->data = NULL;
 182                         sock->conn = NULL;
 183                         sock->iconn = NULL;
 184 
 185                         /*
 186                          * This really shouldn't be necessary, but everything
 187                          * else depends on inodes, so we grab it.
 188                          * Sleeps are also done on the i_wait member of this
 189                          * inode.  The close system call will iput this inode
 190                          * for us.
 191                          */
 192                         if (!(SOCK_INODE(sock) = get_empty_inode())) {
 193                                 printk("NET: sock_alloc: no more inodes\n");
 194                                 sock->state = SS_FREE;
 195                                 return(NULL);
 196                         }
 197                         SOCK_INODE(sock)->i_mode = S_IFSOCK;
 198                         SOCK_INODE(sock)->i_uid = current->euid;
 199                         SOCK_INODE(sock)->i_gid = current->egid;
 200                         SOCK_INODE(sock)->i_socket = sock;
 201 
 202                         sock->wait = &SOCK_INODE(sock)->i_wait;
 203                         DPRINTF((net_debug,
 204                                 "NET: sock_alloc: sk 0x%x, ino 0x%x\n",
 205                                                         sock, SOCK_INODE(sock)));
 206                         return(sock);
 207                 }
 208         }
 209         sti();
 210         if (!wait) return(NULL);
 211         DPRINTF((net_debug, "NET: sock_alloc: no free sockets, sleeping...\n"));
 212         interruptible_sleep_on(&socket_wait_free);
 213         if (current->signal & ~current->blocked) {
 214                 DPRINTF((net_debug, "NET: sock_alloc: sleep was interrupted\n"));
 215                 return(NULL);
 216         }
 217         DPRINTF((net_debug, "NET: sock_alloc: wakeup... trying again...\n"));
 218   }
 219 }
 220 
 221 
 222 static inline void
 223 sock_release_peer(struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225   peer->state = SS_DISCONNECTING;
 226   wake_up(peer->wait);
 227 }
 228 
 229 
 230 static void
 231 sock_release(struct socket *sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   int oldstate;
 234   struct socket *peersock, *nextsock;
 235 
 236   DPRINTF((net_debug, "NET: sock_release: socket 0x%x, inode 0x%x\n",
 237                                                 sock, SOCK_INODE(sock)));
 238   if ((oldstate = sock->state) != SS_UNCONNECTED)
 239                         sock->state = SS_DISCONNECTING;
 240 
 241   /* Wake up anyone waiting for connections. */
 242   for (peersock = sock->iconn; peersock; peersock = nextsock) {
 243         nextsock = peersock->next;
 244         sock_release_peer(peersock);
 245   }
 246 
 247   /*
 248    * Wake up anyone we're connected to. First, we release the
 249    * protocol, to give it a chance to flush data, etc.
 250    */
 251   peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
 252   if (sock->ops) sock->ops->release(sock, peersock);
 253   if (peersock) sock_release_peer(peersock);
 254   sock->state = SS_FREE;                /* this really releases us */
 255   wake_up(&socket_wait_free);
 256 
 257   /* We need to do this. If sock alloc was called we already have an inode. */
 258   iput(SOCK_INODE(sock));
 259 }
 260 
 261 
 262 static int
 263 sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265   DPRINTF((net_debug, "NET: sock_lseek: huh?\n"));
 266   return(-ESPIPE);
 267 }
 268 
 269 
 270 static int
 271 sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 272 {
 273   struct socket *sock;
 274 
 275   DPRINTF((net_debug, "NET: sock_read: buf=0x%x, size=%d\n", ubuf, size));
 276   if (!(sock = socki_lookup(inode))) {
 277         printk("NET: sock_read: can't find socket for inode!\n");
 278         return(-EBADF);
 279   }
 280   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 281   return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
 282 }
 283 
 284 
 285 static int
 286 sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288   struct socket *sock;
 289 
 290   DPRINTF((net_debug, "NET: sock_write: buf=0x%x, size=%d\n", ubuf, size));
 291   if (!(sock = socki_lookup(inode))) {
 292         printk("NET: sock_write: can't find socket for inode!\n");
 293         return(-EBADF);
 294   }
 295   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 296   return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
 297 }
 298 
 299 
 300 static int
 301 sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
     /* [previous][next][first][last][top][bottom][index][help] */
 302              int count)
 303 {
 304   DPRINTF((net_debug, "NET: sock_readdir: huh?\n"));
 305   return(-EBADF);
 306 }
 307 
 308 
 309 int
 310 sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 311            unsigned long arg)
 312 {
 313   struct socket *sock;
 314 
 315   DPRINTF((net_debug, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
 316                                                         inode, cmd, arg));
 317   if (!(sock = socki_lookup(inode))) {
 318         printk("NET: sock_ioctl: can't find socket for inode!\n");
 319         return(-EBADF);
 320   }
 321   return(sock->ops->ioctl(sock, cmd, arg));
 322 }
 323 
 324 
 325 static int
 326 sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328   struct socket *sock;
 329 
 330   DPRINTF((net_debug, "NET: sock_select: inode = 0x%x, kind = %s\n", inode,
 331        (sel_type == SEL_IN) ? "in" :
 332        (sel_type == SEL_OUT) ? "out" : "ex"));
 333   if (!(sock = socki_lookup(inode))) {
 334         printk("NET: sock_select: can't find socket for inode!\n");
 335         return(0);
 336   }
 337 
 338   /* We can't return errors to select, so its either yes or no. */
 339   if (sock->ops && sock->ops->select)
 340         return(sock->ops->select(sock, sel_type, wait));
 341   return(0);
 342 }
 343 
 344 
 345 void
 346 sock_close(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 347 {
 348   struct socket *sock;
 349 
 350   DPRINTF((net_debug, "NET: sock_close: inode=0x%x (cnt=%d)\n",
 351                                                 inode, inode->i_count));
 352 
 353   /* It's possible the inode is NULL if we're closing an unfinished socket. */
 354   if (!inode) return;
 355   if (!(sock = socki_lookup(inode))) {
 356         printk("NET: sock_close: can't find socket for inode!\n");
 357         return;
 358   }
 359   sock_release(sock);
 360 }
 361 
 362 
 363 int
 364 sock_awaitconn(struct socket *mysock, struct socket *servsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 365 {
 366   struct socket *last;
 367 
 368   DPRINTF((net_debug,
 369         "NET: sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
 370                                                         mysock, servsock));
 371   if (!(servsock->flags & SO_ACCEPTCON)) {
 372         DPRINTF((net_debug,
 373                 "NET: sock_awaitconn: server not accepting connections\n"));
 374         return(-EINVAL);
 375   }
 376 
 377   /* Put ourselves on the server's incomplete connection queue. */
 378   mysock->next = NULL;
 379   cli();
 380   if (!(last = servsock->iconn)) servsock->iconn = mysock;
 381     else {
 382         while (last->next) last = last->next;
 383         last->next = mysock;
 384   }
 385   mysock->state = SS_CONNECTING;
 386   mysock->conn = servsock;
 387   sti();
 388 
 389   /*
 390    * Wake up server, then await connection. server will set state to
 391    * SS_CONNECTED if we're connected.
 392    */
 393   wake_up(servsock->wait);
 394   if (mysock->state != SS_CONNECTED) {
 395         interruptible_sleep_on(mysock->wait);
 396         if (mysock->state != SS_CONNECTED &&
 397             mysock->state != SS_DISCONNECTING) {
 398                 /*
 399                  * if we're not connected we could have been
 400                  * 1) interrupted, so we need to remove ourselves
 401                  *    from the server list
 402                  * 2) rejected (mysock->conn == NULL), and have
 403                  *    already been removed from the list
 404                  */
 405                 if (mysock->conn == servsock) {
 406                         cli();
 407                         if ((last = servsock->iconn) == mysock)
 408                                         servsock->iconn = mysock->next;
 409                         else {
 410                                 while (last->next != mysock) last = last->next;
 411                                 last->next = mysock->next;
 412                         }
 413                         sti();
 414                 }
 415                 return(mysock->conn ? -EINTR : -EACCES);
 416         }
 417   }
 418   return(0);
 419 }
 420 
 421 
 422 /*
 423  * Perform the socket system call. we locate the appropriate
 424  * family, then create a fresh socket.
 425  */
 426 static int
 427 sock_socket(int family, int type, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 428 {
 429   int i, fd;
 430   struct socket *sock;
 431   struct proto_ops *ops;
 432 
 433   DPRINTF((net_debug,
 434         "NET: sock_socket: family = %d, type = %d, protocol = %d\n",
 435                                                 family, type, protocol));
 436 
 437   /* Locate the correct protocol family. */
 438   for (i = 0; i < NPROTO; ++i) {
 439         if (pops[i] == NULL) continue;
 440         if (pops[i]->family == family) break;
 441   }
 442   if (i == NPROTO) {
 443         DPRINTF((net_debug, "NET: sock_socket: family not found\n"));
 444         return(-EINVAL);
 445   }
 446   ops = pops[i];
 447 
 448   /*
 449    * Check that this is a type that we know how to manipulate and
 450    * the protocol makes sense here. The family can still reject the
 451    * protocol later.
 452    */
 453   if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
 454        type != SOCK_SEQPACKET && type != SOCK_RAW &&
 455        type != SOCK_PACKET) || protocol < 0)
 456                                                         return(-EINVAL);
 457 
 458   /*
 459    * allocate the socket and allow the family to set things up. if
 460    * the protocol is 0, the family is instructed to select an appropriate
 461    * default.
 462    */
 463   if (!(sock = sock_alloc(1))) {
 464         printk("sock_socket: no more sockets\n");
 465         return(-EAGAIN);
 466   }
 467   sock->type = type;
 468   sock->ops = ops;
 469   if ((i = sock->ops->create(sock, protocol)) < 0) {
 470         sock_release(sock);
 471         return(i);
 472   }
 473 
 474   if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
 475         sock_release(sock);
 476         return(-EINVAL);
 477   }
 478 
 479   return(fd);
 480 }
 481 
 482 
 483 static int
 484 sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486   int fd1, fd2, i;
 487   struct socket *sock1, *sock2;
 488   int er;
 489 
 490   DPRINTF((net_debug,
 491         "NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
 492                                                         family, type, protocol));
 493 
 494   /*
 495    * Obtain the first socket and check if the underlying protocol
 496    * supports the socketpair call.
 497    */
 498   if ((fd1 = sock_socket(family, type, protocol)) < 0) return(fd1);
 499   sock1 = sockfd_lookup(fd1, NULL);
 500   if (!sock1->ops->socketpair) {
 501         sys_close(fd1);
 502         return(-EINVAL);
 503   }
 504 
 505   /* Now grab another socket and try to connect the two together. */
 506   if ((fd2 = sock_socket(family, type, protocol)) < 0) {
 507         sys_close(fd1);
 508         return(-EINVAL);
 509   }
 510   sock2 = sockfd_lookup(fd2, NULL);
 511   if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
 512         sys_close(fd1);
 513         sys_close(fd2);
 514         return(i);
 515   }
 516   sock1->conn = sock2;
 517   sock2->conn = sock1;
 518   sock1->state = SS_CONNECTED;
 519   sock2->state = SS_CONNECTED;
 520 
 521   er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
 522   if(er)
 523         return er;
 524   put_fs_long(fd1, &usockvec[0]);
 525   put_fs_long(fd2, &usockvec[1]);
 526 
 527   return(0);
 528 }
 529 
 530 
 531 /*
 532  * Bind a name to a socket. Nothing much to do here since its
 533  * the protocol's responsibility to handle the local address.
 534  */
 535 static int
 536 sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538   struct socket *sock;
 539   int i;
 540 
 541   DPRINTF((net_debug, "NET: sock_bind: fd = %d\n", fd));
 542   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 543                                                                 return(-EBADF);
 544   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 545   if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
 546         DPRINTF((net_debug, "NET: sock_bind: bind failed\n"));
 547         return(i);
 548   }
 549   return(0);
 550 }
 551 
 552 
 553 /*
 554  * Perform a listen. Basically, we allow the protocol to do anything
 555  * necessary for a listen, and if that works, we mark the socket as
 556  * ready for listening.
 557  */
 558 static int
 559 sock_listen(int fd, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 560 {
 561   struct socket *sock;
 562 
 563   DPRINTF((net_debug, "NET: sock_listen: fd = %d\n", fd));
 564   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 565                                                                 return(-EBADF);
 566   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 567   if (sock->state != SS_UNCONNECTED) {
 568         DPRINTF((net_debug, "NET: sock_listen: socket isn't unconnected\n"));
 569         return(-EINVAL);
 570   }
 571   if (sock->ops && sock->ops->listen) sock->ops->listen(sock, backlog);
 572   sock->flags |= SO_ACCEPTCON;
 573   return(0);
 574 }
 575 
 576 
 577 /*
 578  * For accept, we attempt to create a new socket, set up the link
 579  * with the client, wake up the client, then return the new
 580  * connected fd.
 581  */
 582 static int
 583 sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 584 {
 585   struct file *file;
 586   struct socket *sock, *newsock;
 587   int i;
 588 
 589   DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
 590   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 591                                                                 return(-EBADF);
 592   
 593   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
 594   if (sock->state != SS_UNCONNECTED) {
 595         DPRINTF((net_debug, "NET: sock_accept: socket isn't unconnected\n"));
 596         return(-EINVAL);
 597   }
 598   if (!(sock->flags & SO_ACCEPTCON)) {
 599         DPRINTF((net_debug,
 600                 "NET: sock_accept: socket not accepting connections!\n"));
 601         return(-EINVAL);
 602   }
 603 
 604   if (!(newsock = sock_alloc(0))) {
 605         printk("NET: sock_accept: no more sockets\n");
 606         return(-EAGAIN);
 607   }
 608   newsock->type = sock->type;
 609   newsock->ops = sock->ops;
 610   if ((i = sock->ops->dup(newsock, sock)) < 0) {
 611         sock_release(newsock);
 612         return(i);
 613   }
 614 
 615   i = newsock->ops->accept(sock, newsock, file->f_flags);
 616   if ( i < 0) {
 617         sock_release(newsock);
 618         return(i);
 619   }
 620 
 621   if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
 622         sock_release(newsock);
 623         return(-EINVAL);
 624   }
 625 
 626   DPRINTF((net_debug, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
 627                                                         sock, newsock));
 628 
 629   if (upeer_sockaddr)
 630         newsock->ops->getname(newsock, upeer_sockaddr, upeer_addrlen, 1);
 631 
 632   return(fd);
 633 }
 634 
 635 
 636 /* Attempt to connect to a socket with the server address. */
 637 static int
 638 sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640   struct socket *sock;
 641   struct file *file;
 642   int i;
 643 
 644   DPRINTF((net_debug, "NET: sock_connect: fd = %d\n", fd));
 645   if (fd < 0 || fd >= NR_OPEN || (file=current->filp[fd]) == NULL)
 646                                                                 return(-EBADF);
 647   
 648   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
 649   switch(sock->state) {
 650         case SS_UNCONNECTED:
 651                 /* This is ok... continue with connect */
 652                 break;
 653         case SS_CONNECTED:
 654                 /* Socket is already connected */
 655                 return -EISCONN;
 656         case SS_CONNECTING:
 657                 /* Not yet connected... we will check this. */
 658                 return(sock->ops->connect(sock, uservaddr,
 659                                           addrlen, file->f_flags));
 660         default:
 661                 DPRINTF((net_debug,
 662                         "NET: sock_connect: socket not unconnected\n"));
 663                 return(-EINVAL);
 664   }
 665   i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
 666   if (i < 0) {
 667         DPRINTF((net_debug, "NET: sock_connect: connect failed\n"));
 668         return(i);
 669   }
 670   return(0);
 671 }
 672 
 673 
 674 static int
 675 sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 676 {
 677   struct socket *sock;
 678 
 679   DPRINTF((net_debug, "NET: sock_getsockname: fd = %d\n", fd));
 680   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 681                                                                 return(-EBADF);
 682   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 683   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 0));
 684 }
 685 
 686 
 687 static int
 688 sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 689 {
 690   struct socket *sock;
 691 
 692   DPRINTF((net_debug, "NET: sock_getpeername: fd = %d\n", fd));
 693   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 694                         return(-EBADF);
 695   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 696   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 1));
 697 }
 698 
 699 
 700 static int
 701 sock_send(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 702 {
 703   struct socket *sock;
 704   struct file *file;
 705 
 706   DPRINTF((net_debug,
 707         "NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
 708                                                         fd, buff, len, flags));
 709 
 710   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 711                                                                 return(-EBADF);
 712   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 713 
 714   return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
 715 }
 716 
 717 
 718 static int
 719 sock_sendto(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 720            struct sockaddr *addr, int addr_len)
 721 {
 722   struct socket *sock;
 723   struct file *file;
 724 
 725   DPRINTF((net_debug,
 726         "NET: sock_sendto(fd = %d, buff = %X, len = %d, flags = %X,"
 727          " addr=%X, alen = %d\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   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 732 
 733   return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
 734                            flags, addr, addr_len));
 735 }
 736 
 737 
 738 static int
 739 sock_recv(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 740 {
 741   struct socket *sock;
 742   struct file *file;
 743 
 744   DPRINTF((net_debug,
 745         "NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
 746                                                         fd, buff, len, flags));
 747 
 748   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 749                                                                 return(-EBADF);
 750   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 751 
 752   return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
 753 }
 754 
 755 
 756 static int
 757 sock_recvfrom(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 758              struct sockaddr *addr, int *addr_len)
 759 {
 760   struct socket *sock;
 761   struct file *file;
 762 
 763   DPRINTF((net_debug,
 764         "NET: sock_recvfrom(fd = %d, buff = %X, len = %d, flags = %X,"
 765         " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
 766 
 767   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 768                                                                 return(-EBADF);
 769   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 770 
 771   return(sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
 772                              flags, addr, addr_len));
 773 }
 774 
 775 
 776 static int
 777 sock_setsockopt(int fd, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 778 {
 779   struct socket *sock;
 780   struct file *file;
 781         
 782   DPRINTF((net_debug, "NET: sock_setsockopt(fd=%d, level=%d, optname=%d,\n",
 783                                                         fd, level, optname));
 784   DPRINTF((net_debug, "                     optval = %X, optlen = %d)\n",
 785                                                         optval, optlen));
 786 
 787   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 788                                                                 return(-EBADF);
 789   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 790 
 791   return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
 792 }
 793 
 794 
 795 static int
 796 sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 797 {
 798   struct socket *sock;
 799   struct file *file;
 800 
 801   DPRINTF((net_debug, "NET: sock_getsockopt(fd=%d, level=%d, optname=%d,\n",
 802                                                 fd, level, optname));
 803   DPRINTF((net_debug, "                     optval = %X, optlen = %X)\n",
 804                                                 optval, optlen));
 805 
 806   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 807                                                                 return(-EBADF);
 808   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 809             
 810   if (!sock->ops || !sock->ops->getsockopt) return(0);
 811   return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
 812 }
 813 
 814 
 815 static int
 816 sock_shutdown(int fd, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 817 {
 818   struct socket *sock;
 819   struct file *file;
 820 
 821   DPRINTF((net_debug, "NET: sock_shutdown(fd = %d, how = %d)\n", fd, how));
 822 
 823   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 824                                                                 return(-EBADF);
 825 
 826   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 827 
 828   return(sock->ops->shutdown(sock, how));
 829 }
 830 
 831 
 832 int
 833 sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 834 {
 835   struct socket *sock;
 836 
 837   sock = socki_lookup (filp->f_inode);
 838   if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
 839                                 return(sock->ops->fcntl(sock, cmd, arg));
 840   return(-EINVAL);
 841 }
 842 
 843 
 844 /*
 845  * System call vectors. Since I (RIB) want to rewrite sockets as streams,
 846  * we have this level of indirection. Not a lot of overhead, since more of
 847  * the work is done via read/write/select directly.
 848  */
 849 asmlinkage int
 850 sys_socketcall(int call, unsigned long *args)
     /* [previous][next][first][last][top][bottom][index][help] */
 851 {
 852   int er;
 853   switch(call) {
 854         case SYS_SOCKET:
 855                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 856                 if(er)
 857                         return er;
 858                 return(sock_socket(get_fs_long(args+0),
 859                                    get_fs_long(args+1),
 860                                    get_fs_long(args+2)));
 861         case SYS_BIND:
 862                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 863                 if(er)
 864                         return er;
 865                 return(sock_bind(get_fs_long(args+0),
 866                                  (struct sockaddr *)get_fs_long(args+1),
 867                                  get_fs_long(args+2)));
 868         case SYS_CONNECT:
 869                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 870                 if(er)
 871                         return er;
 872                 return(sock_connect(get_fs_long(args+0),
 873                                     (struct sockaddr *)get_fs_long(args+1),
 874                                     get_fs_long(args+2)));
 875         case SYS_LISTEN:
 876                 er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
 877                 if(er)
 878                         return er;
 879                 return(sock_listen(get_fs_long(args+0),
 880                                    get_fs_long(args+1)));
 881         case SYS_ACCEPT:
 882                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 883                 if(er)
 884                         return er;
 885                 return(sock_accept(get_fs_long(args+0),
 886                                    (struct sockaddr *)get_fs_long(args+1),
 887                                    (int *)get_fs_long(args+2)));
 888         case SYS_GETSOCKNAME:
 889                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 890                 if(er)
 891                         return er;
 892                 return(sock_getsockname(get_fs_long(args+0),
 893                                         (struct sockaddr *)get_fs_long(args+1),
 894                                         (int *)get_fs_long(args+2)));
 895         case SYS_GETPEERNAME:
 896                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 897                 if(er)
 898                         return er;
 899                 return(sock_getpeername(get_fs_long(args+0),
 900                                         (struct sockaddr *)get_fs_long(args+1),
 901                                         (int *)get_fs_long(args+2)));
 902         case SYS_SOCKETPAIR:
 903                 er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
 904                 if(er)
 905                         return er;
 906                 return(sock_socketpair(get_fs_long(args+0),
 907                                        get_fs_long(args+1),
 908                                        get_fs_long(args+2),
 909                                        (unsigned long *)get_fs_long(args+3)));
 910         case SYS_SEND:
 911                 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
 912                 if(er)
 913                         return er;
 914                 return(sock_send(get_fs_long(args+0),
 915                                  (void *)get_fs_long(args+1),
 916                                  get_fs_long(args+2),
 917                                  get_fs_long(args+3)));
 918         case SYS_SENDTO:
 919                 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
 920                 if(er)
 921                         return er;
 922                 return(sock_sendto(get_fs_long(args+0),
 923                                    (void *)get_fs_long(args+1),
 924                                    get_fs_long(args+2),
 925                                    get_fs_long(args+3),
 926                                    (struct sockaddr *)get_fs_long(args+4),
 927                                    get_fs_long(args+5)));
 928         case SYS_RECV:
 929                 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
 930                 if(er)
 931                         return er;
 932                 return(sock_recv(get_fs_long(args+0),
 933                                  (void *)get_fs_long(args+1),
 934                                  get_fs_long(args+2),
 935                                  get_fs_long(args+3)));
 936         case SYS_RECVFROM:
 937                 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
 938                 if(er)
 939                         return er;
 940                 return(sock_recvfrom(get_fs_long(args+0),
 941                                      (void *)get_fs_long(args+1),
 942                                      get_fs_long(args+2),
 943                                      get_fs_long(args+3),
 944                                      (struct sockaddr *)get_fs_long(args+4),
 945                                      (int *)get_fs_long(args+5)));
 946         case SYS_SHUTDOWN:
 947                 er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
 948                 if(er)
 949                         return er;
 950                 return(sock_shutdown(get_fs_long(args+0),
 951                                      get_fs_long(args+1)));
 952         case SYS_SETSOCKOPT:
 953                 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
 954                 if(er)
 955                         return er;
 956                 return(sock_setsockopt(get_fs_long(args+0),
 957                                        get_fs_long(args+1),
 958                                        get_fs_long(args+2),
 959                                        (char *)get_fs_long(args+3),
 960                                        get_fs_long(args+4)));
 961         case SYS_GETSOCKOPT:
 962                 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
 963                 if(er)
 964                         return er;
 965                 return(sock_getsockopt(get_fs_long(args+0),
 966                                        get_fs_long(args+1),
 967                                        get_fs_long(args+2),
 968                                        (char *)get_fs_long(args+3),
 969                                        (int *)get_fs_long(args+4)));
 970         default:
 971                 return(-EINVAL);
 972   }
 973 }
 974 
 975 
 976 static int
 977 net_ioctl(unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 978 {
 979   int er;
 980   switch(cmd) {
 981         case DDIOCSDBG:
 982                 er=verify_area(VERIFY_READ, (void *)arg, sizeof(long));
 983                 if(er)
 984                         return er;
 985                 net_debug = get_fs_long((long *)arg);
 986                 if (net_debug != 0 && net_debug != 1) {
 987                         net_debug = 0;
 988                         return(-EINVAL);
 989                 }
 990                 return(0);
 991         default:
 992                 return(-EINVAL);
 993   }
 994   /*NOTREACHED*/
 995   return(0);
 996 }
 997 
 998 
 999 /*
1000  * Handle the IOCTL system call for the NET devices.  This basically
1001  * means I/O control for the SOCKET layer (future expansions could be
1002  * a variable number of socket table entries, et al), and for the more
1003  * general protocols like ARP.  The latter currently lives in the INET
1004  * module, so we have to get ugly a tiny little bit.  Later... -FvK
1005  */
1006 static int
1007 net_fioctl(struct inode *inode, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
1008            unsigned int cmd, unsigned long arg)
1009 {
1010   extern int arp_ioctl(unsigned int, void *);
1011 
1012   /* Dispatch on the minor device. */
1013   switch(MINOR(inode->i_rdev)) {
1014         case 0:         /* NET (SOCKET) */
1015                 DPRINTF((net_debug, "NET: SOCKET level I/O control request.\n"));
1016                 return(net_ioctl(cmd, arg));
1017 #ifdef CONFIG_INET
1018         case 1:         /* ARP */
1019                 DPRINTF((net_debug, "NET: ARP level I/O control request.\n"));
1020                 return(arp_ioctl(cmd, (void *) arg));
1021 #endif
1022         default:
1023                 return(-ENODEV);
1024   }
1025   /*NOTREACHED*/
1026   return(-EINVAL);
1027 }
1028 
1029 
1030 static struct file_operations net_fops = {
1031   NULL,         /* LSEEK        */
1032   NULL,         /* READ         */
1033   NULL,         /* WRITE        */
1034   NULL,         /* READDIR      */
1035   NULL,         /* SELECT       */
1036   net_fioctl,   /* IOCTL        */
1037   NULL,         /* MMAP         */
1038   NULL,         /* OPEN         */
1039   NULL          /* CLOSE        */
1040 };
1041 
1042 
1043 /*
1044  * This function is called by a protocol handler that wants to
1045  * advertise its address family, and have it linked into the
1046  * SOCKET module.
1047  */
1048 int
1049 sock_register(int family, struct proto_ops *ops)
     /* [previous][next][first][last][top][bottom][index][help] */
1050 {
1051   int i;
1052 
1053   cli();
1054   for(i = 0; i < NPROTO; i++) {
1055         if (pops[i] != NULL) continue;
1056         pops[i] = ops;
1057         pops[i]->family = family;
1058         sti();
1059         DPRINTF((net_debug, "NET: Installed protocol %d in slot %d (0x%X)\n",
1060                                                 family, i, (long)ops));
1061         return(i);
1062   }
1063   sti();
1064   return(-ENOMEM);
1065 }
1066 
1067 
1068 void
1069 sock_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1070 {
1071   struct socket *sock;
1072   int i;
1073 
1074   /* Set up our SOCKET VFS major device. */
1075   if (register_chrdev(SOCKET_MAJOR, "socket", &net_fops) < 0) {
1076         printk("NET: cannot register major device %d!\n", SOCKET_MAJOR);
1077         return;
1078   }
1079 
1080   /* Release all sockets. */
1081   for (sock = sockets; sock <= last_socket; ++sock) sock->state = SS_FREE;
1082 
1083   /* Initialize all address (protocol) families. */
1084   for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1085 
1086   /* Initialize the DDI module. */
1087   ddi_init();
1088 
1089   /* Initialize the ARP module. */
1090 #if 0
1091   arp_init();
1092 #endif
1093 }

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