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 inode *inode;
 235   struct socket *peersock, *nextsock;
 236 
 237   DPRINTF((net_debug, "NET: sock_release: socket 0x%x, inode 0x%x\n",
 238                                                 sock, SOCK_INODE(sock)));
 239   if ((oldstate = sock->state) != SS_UNCONNECTED)
 240                         sock->state = SS_DISCONNECTING;
 241 
 242   /* Wake up anyone waiting for connections. */
 243   for (peersock = sock->iconn; peersock; peersock = nextsock) {
 244         nextsock = peersock->next;
 245         sock_release_peer(peersock);
 246   }
 247 
 248   /*
 249    * Wake up anyone we're connected to. First, we release the
 250    * protocol, to give it a chance to flush data, etc.
 251    */
 252   peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
 253   if (sock->ops) sock->ops->release(sock, peersock);
 254   if (peersock) sock_release_peer(peersock);
 255   inode = SOCK_INODE(sock);
 256   sock->state = SS_FREE;                /* this really releases us */
 257   wake_up(&socket_wait_free);
 258 
 259   /* We need to do this. If sock alloc was called we already have an inode. */
 260   iput(inode);
 261 }
 262 
 263 
 264 static int
 265 sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267   DPRINTF((net_debug, "NET: sock_lseek: huh?\n"));
 268   return(-ESPIPE);
 269 }
 270 
 271 
 272 static int
 273 sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 274 {
 275   struct socket *sock;
 276 
 277   DPRINTF((net_debug, "NET: sock_read: buf=0x%x, size=%d\n", ubuf, size));
 278   if (!(sock = socki_lookup(inode))) {
 279         printk("NET: sock_read: can't find socket for inode!\n");
 280         return(-EBADF);
 281   }
 282   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 283   return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
 284 }
 285 
 286 
 287 static int
 288 sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 289 {
 290   struct socket *sock;
 291 
 292   DPRINTF((net_debug, "NET: sock_write: buf=0x%x, size=%d\n", ubuf, size));
 293   if (!(sock = socki_lookup(inode))) {
 294         printk("NET: sock_write: can't find socket for inode!\n");
 295         return(-EBADF);
 296   }
 297   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 298   return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
 299 }
 300 
 301 
 302 static int
 303 sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
     /* [previous][next][first][last][top][bottom][index][help] */
 304              int count)
 305 {
 306   DPRINTF((net_debug, "NET: sock_readdir: huh?\n"));
 307   return(-EBADF);
 308 }
 309 
 310 
 311 int
 312 sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 313            unsigned long arg)
 314 {
 315   struct socket *sock;
 316 
 317   DPRINTF((net_debug, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
 318                                                         inode, cmd, arg));
 319   if (!(sock = socki_lookup(inode))) {
 320         printk("NET: sock_ioctl: can't find socket for inode!\n");
 321         return(-EBADF);
 322   }
 323   return(sock->ops->ioctl(sock, cmd, arg));
 324 }
 325 
 326 
 327 static int
 328 sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 329 {
 330   struct socket *sock;
 331 
 332   DPRINTF((net_debug, "NET: sock_select: inode = 0x%x, kind = %s\n", inode,
 333        (sel_type == SEL_IN) ? "in" :
 334        (sel_type == SEL_OUT) ? "out" : "ex"));
 335   if (!(sock = socki_lookup(inode))) {
 336         printk("NET: sock_select: can't find socket for inode!\n");
 337         return(0);
 338   }
 339 
 340   /* We can't return errors to select, so its either yes or no. */
 341   if (sock->ops && sock->ops->select)
 342         return(sock->ops->select(sock, sel_type, wait));
 343   return(0);
 344 }
 345 
 346 
 347 void
 348 sock_close(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 349 {
 350   struct socket *sock;
 351 
 352   DPRINTF((net_debug, "NET: sock_close: inode=0x%x (cnt=%d)\n",
 353                                                 inode, inode->i_count));
 354 
 355   /* It's possible the inode is NULL if we're closing an unfinished socket. */
 356   if (!inode) return;
 357   if (!(sock = socki_lookup(inode))) {
 358         printk("NET: sock_close: can't find socket for inode!\n");
 359         return;
 360   }
 361   sock_release(sock);
 362 }
 363 
 364 
 365 int
 366 sock_awaitconn(struct socket *mysock, struct socket *servsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 367 {
 368   struct socket *last;
 369 
 370   DPRINTF((net_debug,
 371         "NET: sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
 372                                                         mysock, servsock));
 373   if (!(servsock->flags & SO_ACCEPTCON)) {
 374         DPRINTF((net_debug,
 375                 "NET: sock_awaitconn: server not accepting connections\n"));
 376         return(-EINVAL);
 377   }
 378 
 379   /* Put ourselves on the server's incomplete connection queue. */
 380   mysock->next = NULL;
 381   cli();
 382   if (!(last = servsock->iconn)) servsock->iconn = mysock;
 383     else {
 384         while (last->next) last = last->next;
 385         last->next = mysock;
 386   }
 387   mysock->state = SS_CONNECTING;
 388   mysock->conn = servsock;
 389   sti();
 390 
 391   /*
 392    * Wake up server, then await connection. server will set state to
 393    * SS_CONNECTED if we're connected.
 394    */
 395   wake_up(servsock->wait);
 396   if (mysock->state != SS_CONNECTED) {
 397         interruptible_sleep_on(mysock->wait);
 398         if (mysock->state != SS_CONNECTED &&
 399             mysock->state != SS_DISCONNECTING) {
 400                 /*
 401                  * if we're not connected we could have been
 402                  * 1) interrupted, so we need to remove ourselves
 403                  *    from the server list
 404                  * 2) rejected (mysock->conn == NULL), and have
 405                  *    already been removed from the list
 406                  */
 407                 if (mysock->conn == servsock) {
 408                         cli();
 409                         if ((last = servsock->iconn) == mysock)
 410                                         servsock->iconn = mysock->next;
 411                         else {
 412                                 while (last->next != mysock) last = last->next;
 413                                 last->next = mysock->next;
 414                         }
 415                         sti();
 416                 }
 417                 return(mysock->conn ? -EINTR : -EACCES);
 418         }
 419   }
 420   return(0);
 421 }
 422 
 423 
 424 /*
 425  * Perform the socket system call. we locate the appropriate
 426  * family, then create a fresh socket.
 427  */
 428 static int
 429 sock_socket(int family, int type, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 430 {
 431   int i, fd;
 432   struct socket *sock;
 433   struct proto_ops *ops;
 434 
 435   DPRINTF((net_debug,
 436         "NET: sock_socket: family = %d, type = %d, protocol = %d\n",
 437                                                 family, type, protocol));
 438 
 439   /* Locate the correct protocol family. */
 440   for (i = 0; i < NPROTO; ++i) {
 441         if (pops[i] == NULL) continue;
 442         if (pops[i]->family == family) break;
 443   }
 444   if (i == NPROTO) {
 445         DPRINTF((net_debug, "NET: sock_socket: family not found\n"));
 446         return(-EINVAL);
 447   }
 448   ops = pops[i];
 449 
 450   /*
 451    * Check that this is a type that we know how to manipulate and
 452    * the protocol makes sense here. The family can still reject the
 453    * protocol later.
 454    */
 455   if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
 456        type != SOCK_SEQPACKET && type != SOCK_RAW &&
 457        type != SOCK_PACKET) || protocol < 0)
 458                                                         return(-EINVAL);
 459 
 460   /*
 461    * allocate the socket and allow the family to set things up. if
 462    * the protocol is 0, the family is instructed to select an appropriate
 463    * default.
 464    */
 465   if (!(sock = sock_alloc(1))) {
 466         printk("sock_socket: no more sockets\n");
 467         return(-EAGAIN);
 468   }
 469   sock->type = type;
 470   sock->ops = ops;
 471   if ((i = sock->ops->create(sock, protocol)) < 0) {
 472         sock_release(sock);
 473         return(i);
 474   }
 475 
 476   if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
 477         sock_release(sock);
 478         return(-EINVAL);
 479   }
 480 
 481   return(fd);
 482 }
 483 
 484 
 485 static int
 486 sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
     /* [previous][next][first][last][top][bottom][index][help] */
 487 {
 488   int fd1, fd2, i;
 489   struct socket *sock1, *sock2;
 490   int er;
 491 
 492   DPRINTF((net_debug,
 493         "NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
 494                                                         family, type, protocol));
 495 
 496   /*
 497    * Obtain the first socket and check if the underlying protocol
 498    * supports the socketpair call.
 499    */
 500   if ((fd1 = sock_socket(family, type, protocol)) < 0) return(fd1);
 501   sock1 = sockfd_lookup(fd1, NULL);
 502   if (!sock1->ops->socketpair) {
 503         sys_close(fd1);
 504         return(-EINVAL);
 505   }
 506 
 507   /* Now grab another socket and try to connect the two together. */
 508   if ((fd2 = sock_socket(family, type, protocol)) < 0) {
 509         sys_close(fd1);
 510         return(-EINVAL);
 511   }
 512   sock2 = sockfd_lookup(fd2, NULL);
 513   if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
 514         sys_close(fd1);
 515         sys_close(fd2);
 516         return(i);
 517   }
 518   sock1->conn = sock2;
 519   sock2->conn = sock1;
 520   sock1->state = SS_CONNECTED;
 521   sock2->state = SS_CONNECTED;
 522 
 523   er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
 524   if(er)
 525         return er;
 526   put_fs_long(fd1, &usockvec[0]);
 527   put_fs_long(fd2, &usockvec[1]);
 528 
 529   return(0);
 530 }
 531 
 532 
 533 /*
 534  * Bind a name to a socket. Nothing much to do here since its
 535  * the protocol's responsibility to handle the local address.
 536  */
 537 static int
 538 sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 539 {
 540   struct socket *sock;
 541   int i;
 542 
 543   DPRINTF((net_debug, "NET: sock_bind: fd = %d\n", fd));
 544   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 545                                                                 return(-EBADF);
 546   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 547   if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
 548         DPRINTF((net_debug, "NET: sock_bind: bind failed\n"));
 549         return(i);
 550   }
 551   return(0);
 552 }
 553 
 554 
 555 /*
 556  * Perform a listen. Basically, we allow the protocol to do anything
 557  * necessary for a listen, and if that works, we mark the socket as
 558  * ready for listening.
 559  */
 560 static int
 561 sock_listen(int fd, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 562 {
 563   struct socket *sock;
 564 
 565   DPRINTF((net_debug, "NET: sock_listen: fd = %d\n", fd));
 566   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 567                                                                 return(-EBADF);
 568   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 569   if (sock->state != SS_UNCONNECTED) {
 570         DPRINTF((net_debug, "NET: sock_listen: socket isn't unconnected\n"));
 571         return(-EINVAL);
 572   }
 573   if (sock->ops && sock->ops->listen) sock->ops->listen(sock, backlog);
 574   sock->flags |= SO_ACCEPTCON;
 575   return(0);
 576 }
 577 
 578 
 579 /*
 580  * For accept, we attempt to create a new socket, set up the link
 581  * with the client, wake up the client, then return the new
 582  * connected fd.
 583  */
 584 static int
 585 sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 586 {
 587   struct file *file;
 588   struct socket *sock, *newsock;
 589   int i;
 590 
 591   DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
 592   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 593                                                                 return(-EBADF);
 594   
 595   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
 596   if (sock->state != SS_UNCONNECTED) {
 597         DPRINTF((net_debug, "NET: sock_accept: socket isn't unconnected\n"));
 598         return(-EINVAL);
 599   }
 600   if (!(sock->flags & SO_ACCEPTCON)) {
 601         DPRINTF((net_debug,
 602                 "NET: sock_accept: socket not accepting connections!\n"));
 603         return(-EINVAL);
 604   }
 605 
 606   if (!(newsock = sock_alloc(0))) {
 607         printk("NET: sock_accept: no more sockets\n");
 608         return(-EAGAIN);
 609   }
 610   newsock->type = sock->type;
 611   newsock->ops = sock->ops;
 612   if ((i = sock->ops->dup(newsock, sock)) < 0) {
 613         sock_release(newsock);
 614         return(i);
 615   }
 616 
 617   i = newsock->ops->accept(sock, newsock, file->f_flags);
 618   if ( i < 0) {
 619         sock_release(newsock);
 620         return(i);
 621   }
 622 
 623   if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
 624         sock_release(newsock);
 625         return(-EINVAL);
 626   }
 627 
 628   DPRINTF((net_debug, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
 629                                                         sock, newsock));
 630 
 631   if (upeer_sockaddr)
 632         newsock->ops->getname(newsock, upeer_sockaddr, upeer_addrlen, 1);
 633 
 634   return(fd);
 635 }
 636 
 637 
 638 /* Attempt to connect to a socket with the server address. */
 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   struct file *file;
 644   int i;
 645 
 646   DPRINTF((net_debug, "NET: sock_connect: fd = %d\n", fd));
 647   if (fd < 0 || fd >= NR_OPEN || (file=current->filp[fd]) == NULL)
 648                                                                 return(-EBADF);
 649   
 650   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
 651   switch(sock->state) {
 652         case SS_UNCONNECTED:
 653                 /* This is ok... continue with connect */
 654                 break;
 655         case SS_CONNECTED:
 656                 /* Socket is already connected */
 657                 return -EISCONN;
 658         case SS_CONNECTING:
 659                 /* Not yet connected... we will check this. */
 660                 return(sock->ops->connect(sock, uservaddr,
 661                                           addrlen, file->f_flags));
 662         default:
 663                 DPRINTF((net_debug,
 664                         "NET: sock_connect: socket not unconnected\n"));
 665                 return(-EINVAL);
 666   }
 667   i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
 668   if (i < 0) {
 669         DPRINTF((net_debug, "NET: sock_connect: connect failed\n"));
 670         return(i);
 671   }
 672   return(0);
 673 }
 674 
 675 
 676 static int
 677 sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 678 {
 679   struct socket *sock;
 680 
 681   DPRINTF((net_debug, "NET: sock_getsockname: fd = %d\n", fd));
 682   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 683                                                                 return(-EBADF);
 684   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 685   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 0));
 686 }
 687 
 688 
 689 static int
 690 sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 691 {
 692   struct socket *sock;
 693 
 694   DPRINTF((net_debug, "NET: sock_getpeername: fd = %d\n", fd));
 695   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
 696                         return(-EBADF);
 697   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 698   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 1));
 699 }
 700 
 701 
 702 static int
 703 sock_send(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 704 {
 705   struct socket *sock;
 706   struct file *file;
 707 
 708   DPRINTF((net_debug,
 709         "NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
 710                                                         fd, buff, len, flags));
 711 
 712   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 713                                                                 return(-EBADF);
 714   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 715 
 716   return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
 717 }
 718 
 719 
 720 static int
 721 sock_sendto(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 722            struct sockaddr *addr, int addr_len)
 723 {
 724   struct socket *sock;
 725   struct file *file;
 726 
 727   DPRINTF((net_debug,
 728         "NET: sock_sendto(fd = %d, buff = %X, len = %d, flags = %X,"
 729          " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len));
 730 
 731   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 732                                                                 return(-EBADF);
 733   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 734 
 735   return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
 736                            flags, addr, addr_len));
 737 }
 738 
 739 
 740 static int
 741 sock_recv(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 742 {
 743   struct socket *sock;
 744   struct file *file;
 745 
 746   DPRINTF((net_debug,
 747         "NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
 748                                                         fd, buff, len, flags));
 749 
 750   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 751                                                                 return(-EBADF);
 752   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 753 
 754   return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
 755 }
 756 
 757 
 758 static int
 759 sock_recvfrom(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 760              struct sockaddr *addr, int *addr_len)
 761 {
 762   struct socket *sock;
 763   struct file *file;
 764 
 765   DPRINTF((net_debug,
 766         "NET: sock_recvfrom(fd = %d, buff = %X, len = %d, flags = %X,"
 767         " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
 768 
 769   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 770                                                                 return(-EBADF);
 771   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 772 
 773   return(sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
 774                              flags, addr, addr_len));
 775 }
 776 
 777 
 778 static int
 779 sock_setsockopt(int fd, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 780 {
 781   struct socket *sock;
 782   struct file *file;
 783         
 784   DPRINTF((net_debug, "NET: sock_setsockopt(fd=%d, level=%d, optname=%d,\n",
 785                                                         fd, level, optname));
 786   DPRINTF((net_debug, "                     optval = %X, optlen = %d)\n",
 787                                                         optval, optlen));
 788 
 789   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 790                                                                 return(-EBADF);
 791   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 792 
 793   return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
 794 }
 795 
 796 
 797 static int
 798 sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 799 {
 800   struct socket *sock;
 801   struct file *file;
 802 
 803   DPRINTF((net_debug, "NET: sock_getsockopt(fd=%d, level=%d, optname=%d,\n",
 804                                                 fd, level, optname));
 805   DPRINTF((net_debug, "                     optval = %X, optlen = %X)\n",
 806                                                 optval, optlen));
 807 
 808   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 809                                                                 return(-EBADF);
 810   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 811             
 812   if (!sock->ops || !sock->ops->getsockopt) return(0);
 813   return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
 814 }
 815 
 816 
 817 static int
 818 sock_shutdown(int fd, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 819 {
 820   struct socket *sock;
 821   struct file *file;
 822 
 823   DPRINTF((net_debug, "NET: sock_shutdown(fd = %d, how = %d)\n", fd, how));
 824 
 825   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
 826                                                                 return(-EBADF);
 827 
 828   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
 829 
 830   return(sock->ops->shutdown(sock, how));
 831 }
 832 
 833 
 834 int
 835 sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 836 {
 837   struct socket *sock;
 838 
 839   sock = socki_lookup (filp->f_inode);
 840   if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
 841                                 return(sock->ops->fcntl(sock, cmd, arg));
 842   return(-EINVAL);
 843 }
 844 
 845 
 846 /*
 847  * System call vectors. Since I (RIB) want to rewrite sockets as streams,
 848  * we have this level of indirection. Not a lot of overhead, since more of
 849  * the work is done via read/write/select directly.
 850  */
 851 asmlinkage int
 852 sys_socketcall(int call, unsigned long *args)
     /* [previous][next][first][last][top][bottom][index][help] */
 853 {
 854   int er;
 855   switch(call) {
 856         case SYS_SOCKET:
 857                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 858                 if(er)
 859                         return er;
 860                 return(sock_socket(get_fs_long(args+0),
 861                                    get_fs_long(args+1),
 862                                    get_fs_long(args+2)));
 863         case SYS_BIND:
 864                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 865                 if(er)
 866                         return er;
 867                 return(sock_bind(get_fs_long(args+0),
 868                                  (struct sockaddr *)get_fs_long(args+1),
 869                                  get_fs_long(args+2)));
 870         case SYS_CONNECT:
 871                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 872                 if(er)
 873                         return er;
 874                 return(sock_connect(get_fs_long(args+0),
 875                                     (struct sockaddr *)get_fs_long(args+1),
 876                                     get_fs_long(args+2)));
 877         case SYS_LISTEN:
 878                 er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
 879                 if(er)
 880                         return er;
 881                 return(sock_listen(get_fs_long(args+0),
 882                                    get_fs_long(args+1)));
 883         case SYS_ACCEPT:
 884                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 885                 if(er)
 886                         return er;
 887                 return(sock_accept(get_fs_long(args+0),
 888                                    (struct sockaddr *)get_fs_long(args+1),
 889                                    (int *)get_fs_long(args+2)));
 890         case SYS_GETSOCKNAME:
 891                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 892                 if(er)
 893                         return er;
 894                 return(sock_getsockname(get_fs_long(args+0),
 895                                         (struct sockaddr *)get_fs_long(args+1),
 896                                         (int *)get_fs_long(args+2)));
 897         case SYS_GETPEERNAME:
 898                 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
 899                 if(er)
 900                         return er;
 901                 return(sock_getpeername(get_fs_long(args+0),
 902                                         (struct sockaddr *)get_fs_long(args+1),
 903                                         (int *)get_fs_long(args+2)));
 904         case SYS_SOCKETPAIR:
 905                 er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
 906                 if(er)
 907                         return er;
 908                 return(sock_socketpair(get_fs_long(args+0),
 909                                        get_fs_long(args+1),
 910                                        get_fs_long(args+2),
 911                                        (unsigned long *)get_fs_long(args+3)));
 912         case SYS_SEND:
 913                 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
 914                 if(er)
 915                         return er;
 916                 return(sock_send(get_fs_long(args+0),
 917                                  (void *)get_fs_long(args+1),
 918                                  get_fs_long(args+2),
 919                                  get_fs_long(args+3)));
 920         case SYS_SENDTO:
 921                 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
 922                 if(er)
 923                         return er;
 924                 return(sock_sendto(get_fs_long(args+0),
 925                                    (void *)get_fs_long(args+1),
 926                                    get_fs_long(args+2),
 927                                    get_fs_long(args+3),
 928                                    (struct sockaddr *)get_fs_long(args+4),
 929                                    get_fs_long(args+5)));
 930         case SYS_RECV:
 931                 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
 932                 if(er)
 933                         return er;
 934                 return(sock_recv(get_fs_long(args+0),
 935                                  (void *)get_fs_long(args+1),
 936                                  get_fs_long(args+2),
 937                                  get_fs_long(args+3)));
 938         case SYS_RECVFROM:
 939                 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
 940                 if(er)
 941                         return er;
 942                 return(sock_recvfrom(get_fs_long(args+0),
 943                                      (void *)get_fs_long(args+1),
 944                                      get_fs_long(args+2),
 945                                      get_fs_long(args+3),
 946                                      (struct sockaddr *)get_fs_long(args+4),
 947                                      (int *)get_fs_long(args+5)));
 948         case SYS_SHUTDOWN:
 949                 er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
 950                 if(er)
 951                         return er;
 952                 return(sock_shutdown(get_fs_long(args+0),
 953                                      get_fs_long(args+1)));
 954         case SYS_SETSOCKOPT:
 955                 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
 956                 if(er)
 957                         return er;
 958                 return(sock_setsockopt(get_fs_long(args+0),
 959                                        get_fs_long(args+1),
 960                                        get_fs_long(args+2),
 961                                        (char *)get_fs_long(args+3),
 962                                        get_fs_long(args+4)));
 963         case SYS_GETSOCKOPT:
 964                 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
 965                 if(er)
 966                         return er;
 967                 return(sock_getsockopt(get_fs_long(args+0),
 968                                        get_fs_long(args+1),
 969                                        get_fs_long(args+2),
 970                                        (char *)get_fs_long(args+3),
 971                                        (int *)get_fs_long(args+4)));
 972         default:
 973                 return(-EINVAL);
 974   }
 975 }
 976 
 977 
 978 static int
 979 net_ioctl(unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 980 {
 981   int er;
 982   switch(cmd) {
 983         case DDIOCSDBG:
 984                 er=verify_area(VERIFY_READ, (void *)arg, sizeof(long));
 985                 if(er)
 986                         return er;
 987                 net_debug = get_fs_long((long *)arg);
 988                 if (net_debug != 0 && net_debug != 1) {
 989                         net_debug = 0;
 990                         return(-EINVAL);
 991                 }
 992                 return(0);
 993         default:
 994                 return(-EINVAL);
 995   }
 996   /*NOTREACHED*/
 997   return(0);
 998 }
 999 
1000 
1001 /*
1002  * Handle the IOCTL system call for the NET devices.  This basically
1003  * means I/O control for the SOCKET layer (future expansions could be
1004  * a variable number of socket table entries, et al), and for the more
1005  * general protocols like ARP.  The latter currently lives in the INET
1006  * module, so we have to get ugly a tiny little bit.  Later... -FvK
1007  */
1008 static int
1009 net_fioctl(struct inode *inode, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
1010            unsigned int cmd, unsigned long arg)
1011 {
1012   extern int arp_ioctl(unsigned int, void *);
1013 
1014   /* Dispatch on the minor device. */
1015   switch(MINOR(inode->i_rdev)) {
1016         case 0:         /* NET (SOCKET) */
1017                 DPRINTF((net_debug, "NET: SOCKET level I/O control request.\n"));
1018                 return(net_ioctl(cmd, arg));
1019 #ifdef CONFIG_INET
1020         case 1:         /* ARP */
1021                 DPRINTF((net_debug, "NET: ARP level I/O control request.\n"));
1022                 return(arp_ioctl(cmd, (void *) arg));
1023 #endif
1024         default:
1025                 return(-ENODEV);
1026   }
1027   /*NOTREACHED*/
1028   return(-EINVAL);
1029 }
1030 
1031 
1032 static struct file_operations net_fops = {
1033   NULL,         /* LSEEK        */
1034   NULL,         /* READ         */
1035   NULL,         /* WRITE        */
1036   NULL,         /* READDIR      */
1037   NULL,         /* SELECT       */
1038   net_fioctl,   /* IOCTL        */
1039   NULL,         /* MMAP         */
1040   NULL,         /* OPEN         */
1041   NULL          /* CLOSE        */
1042 };
1043 
1044 
1045 /*
1046  * This function is called by a protocol handler that wants to
1047  * advertise its address family, and have it linked into the
1048  * SOCKET module.
1049  */
1050 int
1051 sock_register(int family, struct proto_ops *ops)
     /* [previous][next][first][last][top][bottom][index][help] */
1052 {
1053   int i;
1054 
1055   cli();
1056   for(i = 0; i < NPROTO; i++) {
1057         if (pops[i] != NULL) continue;
1058         pops[i] = ops;
1059         pops[i]->family = family;
1060         sti();
1061         DPRINTF((net_debug, "NET: Installed protocol %d in slot %d (0x%X)\n",
1062                                                 family, i, (long)ops));
1063         return(i);
1064   }
1065   sti();
1066   return(-ENOMEM);
1067 }
1068 
1069 
1070 void
1071 sock_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1072 {
1073   struct socket *sock;
1074   int i;
1075 
1076   /* Set up our SOCKET VFS major device. */
1077   if (register_chrdev(SOCKET_MAJOR, "socket", &net_fops) < 0) {
1078         printk("NET: cannot register major device %d!\n", SOCKET_MAJOR);
1079         return;
1080   }
1081 
1082   /* Release all sockets. */
1083   for (sock = sockets; sock <= last_socket; ++sock) sock->state = SS_FREE;
1084 
1085   /* Initialize all address (protocol) families. */
1086   for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1087 
1088   /* Initialize the DDI module. */
1089   ddi_init();
1090 
1091   /* Initialize the ARP module. */
1092 #if 0
1093   arp_init();
1094 #endif
1095 }

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