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

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