root/net/socket.c

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

DEFINITIONS

This source file includes following definitions.
  1. move_addr_to_kernel
  2. move_addr_to_user
  3. get_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_fasync
  17. sock_wake_async
  18. sock_awaitconn
  19. sock_socket
  20. sock_socketpair
  21. sock_bind
  22. sock_listen
  23. sock_accept
  24. sock_connect
  25. sock_getsockname
  26. sock_getpeername
  27. sock_send
  28. sock_sendto
  29. sock_recv
  30. sock_recvfrom
  31. sock_setsockopt
  32. sock_getsockopt
  33. sock_shutdown
  34. sock_fcntl
  35. sys_socketcall
  36. sock_register
  37. sock_unregister
  38. proto_init
  39. sock_init
  40. socket_get_info

   1 /*
   2  * NET          An implementation of the SOCKET network access protocol.
   3  *
   4  * Version:     @(#)socket.c    1.1.93  18/02/95
   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  *              Alan Cox        :       Removed DDI
  15  *              Jonathan Kamens :       SOCK_DGRAM reconnect bug
  16  *              Alan Cox        :       Moved a load of checks to the very
  17  *                                      top level.
  18  *              Alan Cox        :       Move address structures to/from user
  19  *                                      mode above the protocol layers.
  20  *              Rob Janssen     :       Allow 0 length sends.
  21  *              Alan Cox        :       Asynchronous I/O support (cribbed from the
  22  *                                      tty drivers).
  23  *              Niibe Yutaka    :       Asynchronous I/O for writes (4.4BSD style)
  24  *              Jeff Uphoff     :       Made max number of sockets command-line
  25  *                                      configurable.
  26  *              Matti Aarnio    :       Made the number of sockets dynamic,
  27  *                                      to be allocated when needed, and mr.
  28  *                                      Uphoff's max is used as max to be
  29  *                                      allowed to allocate.
  30  *              Linus           :       Argh. removed all the socket allocation
  31  *                                      altogether: it's in the inode now.
  32  *              Alan Cox        :       Made sock_alloc()/sock_release() public
  33  *                                      for NetROM and future kernel nfsd type
  34  *                                      stuff.
  35  *
  36  *
  37  *              This program is free software; you can redistribute it and/or
  38  *              modify it under the terms of the GNU General Public License
  39  *              as published by the Free Software Foundation; either version
  40  *              2 of the License, or (at your option) any later version.
  41  *
  42  *
  43  *      This module is effectively the top level interface to the BSD socket
  44  *      paradigm. Because it is very simple it works well for Unix domain sockets,
  45  *      but requires a whole layer of substructure for the other protocols.
  46  *
  47  *      In addition it lacks an effective kernel -> kernel interface to go with
  48  *      the user one.
  49  */
  50 
  51 #include <linux/config.h>
  52 #include <linux/signal.h>
  53 #include <linux/errno.h>
  54 #include <linux/sched.h>
  55 #include <linux/mm.h>
  56 #include <linux/kernel.h>
  57 #include <linux/major.h>
  58 #include <linux/stat.h>
  59 #include <linux/socket.h>
  60 #include <linux/fcntl.h>
  61 #include <linux/net.h>
  62 #include <linux/interrupt.h>
  63 #include <linux/netdevice.h>
  64 
  65 #include <asm/system.h>
  66 #include <asm/segment.h>
  67 
  68 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
  69                       int whence);
  70 static int sock_read(struct inode *inode, struct file *file, char *buf,
  71                      int size);
  72 static int sock_write(struct inode *inode, struct file *file, char *buf,
  73                       int size);
  74 static int sock_readdir(struct inode *inode, struct file *file,
  75                         struct dirent *dirent, int count);
  76 static void sock_close(struct inode *inode, struct file *file);
  77 static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
  78 static int sock_ioctl(struct inode *inode, struct file *file,
  79                       unsigned int cmd, unsigned long arg);
  80 static int sock_fasync(struct inode *inode, struct file *filp, int on);
  81                    
  82 
  83 
  84 /*
  85  *      Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
  86  *      in the operation structures but are done directly via the socketcall() multiplexor.
  87  */
  88 
  89 static struct file_operations socket_file_ops = {
  90         sock_lseek,
  91         sock_read,
  92         sock_write,
  93         sock_readdir,
  94         sock_select,
  95         sock_ioctl,
  96         NULL,                   /* mmap */
  97         NULL,                   /* no special open code... */
  98         sock_close,
  99         NULL,                   /* no fsync */
 100         sock_fasync
 101 };
 102 
 103 /*
 104  *      The protocol list. Each protocol is registered in here.
 105  */
 106 static struct proto_ops *pops[NPROTO];
 107 /*
 108  *      Statistics counters of the socket lists
 109  */
 110 static int sockets_in_use  = 0;
 111 
 112 /*
 113  *      Support routines. Move socket addresses back and forth across the kernel/user
 114  *      divide and look after the messy bits.
 115  */
 116 
 117 #define MAX_SOCK_ADDR   128             /* 108 for Unix domain - 16 for IP, 16 for IPX, about 80 for AX.25 */
 118  
 119 static int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121         int err;
 122         if(ulen<0||ulen>MAX_SOCK_ADDR)
 123                 return -EINVAL;
 124         if(ulen==0)
 125                 return 0;
 126         if((err=verify_area(VERIFY_READ,uaddr,ulen))<0)
 127                 return err;
 128         memcpy_fromfs(kaddr,uaddr,ulen);
 129         return 0;
 130 }
 131 
 132 static int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134         int err;
 135         int len;
 136 
 137                 
 138         if((err=verify_area(VERIFY_WRITE,ulen,sizeof(*ulen)))<0)
 139                 return err;
 140         len=get_fs_long(ulen);
 141         if(len>klen)
 142                 len=klen;
 143         if(len<0 || len> MAX_SOCK_ADDR)
 144                 return -EINVAL;
 145         if(len)
 146         {
 147                 if((err=verify_area(VERIFY_WRITE,uaddr,len))<0)
 148                         return err;
 149                 memcpy_tofs(uaddr,kaddr,len);
 150         }
 151         put_fs_long(len,ulen);
 152         return 0;
 153 }
 154 
 155 /*
 156  *      Obtains the first available file descriptor and sets it up for use. 
 157  */
 158 
 159 static int get_fd(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161         int fd;
 162         struct file *file;
 163 
 164         /*
 165          *      Find a file descriptor suitable for return to the user. 
 166          */
 167 
 168         file = get_empty_filp();
 169         if (!file) 
 170                 return(-1);
 171 
 172         for (fd = 0; fd < NR_OPEN; ++fd)
 173                 if (!current->files->fd[fd]) 
 174                         break;
 175         if (fd == NR_OPEN) 
 176         {
 177                 file->f_count = 0;
 178                 return(-1);
 179         }
 180 
 181         FD_CLR(fd, &current->files->close_on_exec);
 182                 current->files->fd[fd] = file;
 183         file->f_op = &socket_file_ops;
 184         file->f_mode = 3;
 185         file->f_flags = O_RDWR;
 186         file->f_count = 1;
 187         file->f_inode = inode;
 188         if (inode) 
 189                 inode->i_count++;
 190         file->f_pos = 0;
 191         return(fd);
 192 }
 193 
 194 
 195 /*
 196  *      Go from an inode to its socket slot.
 197  *
 198  * The original socket implementation wasn't very clever, which is
 199  * why this exists at all..
 200  */
 201 inline struct socket *socki_lookup(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203         return &inode->u.socket_i;
 204 }
 205 
 206 /*
 207  *      Go from a file number to its socket slot.
 208  */
 209 
 210 static inline struct socket *sockfd_lookup(int fd, struct file **pfile)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212         struct file *file;
 213         struct inode *inode;
 214 
 215         if (fd < 0 || fd >= NR_OPEN || !(file = current->files->fd[fd])) 
 216                 return NULL;
 217 
 218         inode = file->f_inode;
 219         if (!inode || !inode->i_sock)
 220                 return NULL;
 221 
 222         if (pfile) 
 223                 *pfile = file;
 224 
 225         return socki_lookup(inode);
 226 }
 227 
 228 /*
 229  *      Allocate a socket.
 230  */
 231 
 232 struct socket *sock_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 233 {
 234         struct inode * inode;
 235         struct socket * sock;
 236 
 237         inode = get_empty_inode();
 238         if (!inode)
 239                 return NULL;
 240 
 241         inode->i_mode = S_IFSOCK;
 242         inode->i_sock = 1;
 243         inode->i_uid = current->uid;
 244         inode->i_gid = current->gid;
 245 
 246         sock = &inode->u.socket_i;
 247         sock->state = SS_UNCONNECTED;
 248         sock->flags = 0;
 249         sock->ops = NULL;
 250         sock->data = NULL;
 251         sock->conn = NULL;
 252         sock->iconn = NULL;
 253         sock->next = NULL;
 254         sock->wait = &inode->i_wait;
 255         sock->inode = inode;            /* "backlink": we could use pointer arithmetic instead */
 256         sock->fasync_list = NULL;
 257         sockets_in_use++;
 258         return sock;
 259 }
 260 
 261 /*
 262  *      Release a socket.
 263  */
 264 
 265 static inline void sock_release_peer(struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267         peer->state = SS_DISCONNECTING;
 268         wake_up_interruptible(peer->wait);
 269         sock_wake_async(peer, 1);
 270 }
 271 
 272 void sock_release(struct socket *sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 273 {
 274         int oldstate;
 275         struct socket *peersock, *nextsock;
 276 
 277         if ((oldstate = sock->state) != SS_UNCONNECTED)
 278                 sock->state = SS_DISCONNECTING;
 279 
 280         /*
 281          *      Wake up anyone waiting for connections. 
 282          */
 283 
 284         for (peersock = sock->iconn; peersock; peersock = nextsock) 
 285         {
 286                 nextsock = peersock->next;
 287                 sock_release_peer(peersock);
 288         }
 289 
 290         /*
 291          * Wake up anyone we're connected to. First, we release the
 292          * protocol, to give it a chance to flush data, etc.
 293          */
 294 
 295         peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
 296         if (sock->ops) 
 297                 sock->ops->release(sock, peersock);
 298         if (peersock)
 299                 sock_release_peer(peersock);
 300         --sockets_in_use;       /* Bookkeeping.. */
 301         iput(SOCK_INODE(sock));
 302 }
 303 
 304 /*
 305  *      Sockets are not seekable.
 306  */
 307 
 308 static int sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310         return(-ESPIPE);
 311 }
 312 
 313 /*
 314  *      Read data from a socket. ubuf is a user mode pointer. We make sure the user
 315  *      area ubuf...ubuf+size-1 is writable before asking the protocol.
 316  */
 317 
 318 static int sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320         struct socket *sock;
 321         int err;
 322   
 323         if (!(sock = socki_lookup(inode))) 
 324         {
 325                 printk("NET: sock_read: can't find socket for inode!\n");
 326                 return(-EBADF);
 327         }
 328         if (sock->flags & SO_ACCEPTCON) 
 329                 return(-EINVAL);
 330 
 331         if(size<0)
 332                 return -EINVAL;
 333         if(size==0)
 334                 return 0;
 335         if ((err=verify_area(VERIFY_WRITE,ubuf,size))<0)
 336                 return err;
 337         return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
 338 }
 339 
 340 /*
 341  *      Write data to a socket. We verify that the user area ubuf..ubuf+size-1 is
 342  *      readable by the user process.
 343  */
 344 
 345 static int sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347         struct socket *sock;
 348         int err;
 349         
 350         if (!(sock = socki_lookup(inode))) 
 351         {
 352                 printk("NET: sock_write: can't find socket for inode!\n");
 353                 return(-EBADF);
 354         }
 355 
 356         if (sock->flags & SO_ACCEPTCON) 
 357                 return(-EINVAL);
 358         
 359         if(size<0)
 360                 return -EINVAL;
 361         if(size==0)
 362                 return 0;
 363                 
 364         if ((err=verify_area(VERIFY_READ,ubuf,size))<0)
 365                 return err;
 366         return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
 367 }
 368 
 369 /*
 370  *      You can't read directories from a socket!
 371  */
 372  
 373 static int sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
     /* [previous][next][first][last][top][bottom][index][help] */
 374              int count)
 375 {
 376         return(-EBADF);
 377 }
 378 
 379 /*
 380  *      With an ioctl arg may well be a user mode pointer, but we don't know what to do
 381  *      with it - thats up to the protocol still.
 382  */
 383 
 384 int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 385            unsigned long arg)
 386 {
 387         struct socket *sock;
 388 
 389         if (!(sock = socki_lookup(inode))) 
 390         {
 391                 printk("NET: sock_ioctl: can't find socket for inode!\n");
 392                 return(-EBADF);
 393         }
 394         return(sock->ops->ioctl(sock, cmd, arg));
 395 }
 396 
 397 
 398 static int sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 399 {
 400         struct socket *sock;
 401 
 402         if (!(sock = socki_lookup(inode))) 
 403         {
 404                 printk("NET: sock_select: can't find socket for inode!\n");
 405                 return(0);
 406         }
 407 
 408         /*
 409          *      We can't return errors to select, so it's either yes or no. 
 410          */
 411 
 412         if (sock->ops && sock->ops->select)
 413                 return(sock->ops->select(sock, sel_type, wait));
 414         return(0);
 415 }
 416 
 417 
 418 void sock_close(struct inode *inode, struct file *filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 419 {
 420         struct socket *sock;
 421 
 422         /*
 423          *      It's possible the inode is NULL if we're closing an unfinished socket. 
 424          */
 425 
 426         if (!inode) 
 427                 return;
 428 
 429         if (!(sock = socki_lookup(inode))) 
 430         {
 431                 printk("NET: sock_close: can't find socket for inode!\n");
 432                 return;
 433         }
 434         sock_fasync(inode, filp, 0);
 435         sock_release(sock);
 436 }
 437 
 438 /*
 439  *      Update the socket async list
 440  */
 441  
 442 static int sock_fasync(struct inode *inode, struct file *filp, int on)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444         struct fasync_struct *fa, *fna=NULL, **prev;
 445         struct socket *sock;
 446         unsigned long flags;
 447         
 448         if (on)
 449         {
 450                 fna=(struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
 451                 if(fna==NULL)
 452                         return -ENOMEM;
 453         }
 454 
 455         sock = socki_lookup(inode);
 456         
 457         prev=&(sock->fasync_list);
 458         
 459         save_flags(flags);
 460         cli();
 461         
 462         for(fa=*prev; fa!=NULL; prev=&fa->fa_next,fa=*prev)
 463                 if(fa->fa_file==filp)
 464                         break;
 465         
 466         if(on)
 467         {
 468                 if(fa!=NULL)
 469                 {
 470                         kfree_s(fna,sizeof(struct fasync_struct));
 471                         restore_flags(flags);
 472                         return 0;
 473                 }
 474                 fna->fa_file=filp;
 475                 fna->magic=FASYNC_MAGIC;
 476                 fna->fa_next=sock->fasync_list;
 477                 sock->fasync_list=fna;
 478         }
 479         else
 480         {
 481                 if(fa!=NULL)
 482                 {
 483                         *prev=fa->fa_next;
 484                         kfree_s(fa,sizeof(struct fasync_struct));
 485                 }
 486         }
 487         restore_flags(flags);
 488         return 0;
 489 }
 490 
 491 int sock_wake_async(struct socket *sock, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493         if (!sock || !sock->fasync_list)
 494                 return -1;
 495         switch (how)
 496         {
 497                 case 0:
 498                         kill_fasync(sock->fasync_list, SIGIO);
 499                         break;
 500                 case 1:
 501                         if (!(sock->flags & SO_WAITDATA))
 502                                 kill_fasync(sock->fasync_list, SIGIO);
 503                         break;
 504                 case 2:
 505                         if (sock->flags & SO_NOSPACE)
 506                         {
 507                                 kill_fasync(sock->fasync_list, SIGIO);
 508                                 sock->flags &= ~SO_NOSPACE;
 509                         }
 510                         break;
 511         }
 512         return 0;
 513 }
 514 
 515         
 516 /*
 517  *      Wait for a connection.
 518  */
 519 
 520 int sock_awaitconn(struct socket *mysock, struct socket *servsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 521 {
 522         struct socket *last;
 523 
 524         /*
 525          *      We must be listening
 526          */
 527         if (!(servsock->flags & SO_ACCEPTCON)) 
 528         {
 529                 return(-EINVAL);
 530         }
 531 
 532         /*
 533          *      Put ourselves on the server's incomplete connection queue. 
 534          */
 535          
 536         mysock->next = NULL;
 537         cli();
 538         if (!(last = servsock->iconn)) 
 539                 servsock->iconn = mysock;
 540         else 
 541         {
 542                 while (last->next) 
 543                         last = last->next;
 544                 last->next = mysock;
 545         }
 546         mysock->state = SS_CONNECTING;
 547         mysock->conn = servsock;
 548         sti();
 549 
 550         /*
 551          * Wake up server, then await connection. server will set state to
 552          * SS_CONNECTED if we're connected.
 553          */
 554         wake_up_interruptible(servsock->wait);
 555         sock_wake_async(servsock, 0);
 556 
 557         if (mysock->state != SS_CONNECTED) 
 558         {
 559                 if (flags & O_NONBLOCK)
 560                         return -EINPROGRESS;
 561 
 562                 interruptible_sleep_on(mysock->wait);
 563                 if (mysock->state != SS_CONNECTED &&
 564                     mysock->state != SS_DISCONNECTING) 
 565                 {
 566                 /*
 567                  * if we're not connected we could have been
 568                  * 1) interrupted, so we need to remove ourselves
 569                  *    from the server list
 570                  * 2) rejected (mysock->conn == NULL), and have
 571                  *    already been removed from the list
 572                  */
 573                         if (mysock->conn == servsock) 
 574                         {
 575                                 cli();
 576                                 if ((last = servsock->iconn) == mysock)
 577                                         servsock->iconn = mysock->next;
 578                                 else 
 579                                 {
 580                                         while (last->next != mysock) 
 581                                                 last = last->next;
 582                                         last->next = mysock->next;
 583                                 }
 584                                 sti();
 585                         }
 586                         return(mysock->conn ? -EINTR : -EACCES);
 587                 }
 588         }
 589         return(0);
 590 }
 591 
 592 
 593 /*
 594  *      Perform the socket system call. we locate the appropriate
 595  *      family, then create a fresh socket.
 596  */
 597 
 598 static int sock_socket(int family, int type, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 599 {
 600         int i, fd;
 601         struct socket *sock;
 602         struct proto_ops *ops;
 603 
 604         /* Locate the correct protocol family. */
 605         for (i = 0; i < NPROTO; ++i) 
 606         {
 607                 if (pops[i] == NULL) continue;
 608                 if (pops[i]->family == family) 
 609                         break;
 610         }
 611 
 612         if (i == NPROTO) 
 613         {
 614                 return -EINVAL;
 615         }
 616 
 617         ops = pops[i];
 618 
 619 /*
 620  *      Check that this is a type that we know how to manipulate and
 621  *      the protocol makes sense here. The family can still reject the
 622  *      protocol later.
 623  */
 624   
 625         if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
 626                 type != SOCK_SEQPACKET && type != SOCK_RAW &&
 627                 type != SOCK_PACKET) || protocol < 0)
 628                         return(-EINVAL);
 629 
 630 /*
 631  *      Allocate the socket and allow the family to set things up. if
 632  *      the protocol is 0, the family is instructed to select an appropriate
 633  *      default.
 634  */
 635 
 636         if (!(sock = sock_alloc())) 
 637         {
 638                 printk("NET: sock_socket: no more sockets\n");
 639                 return(-ENOSR); /* Was: EAGAIN, but we are out of
 640                                    system resources! */
 641         }
 642 
 643         sock->type = type;
 644         sock->ops = ops;
 645         if ((i = sock->ops->create(sock, protocol)) < 0) 
 646         {
 647                 sock_release(sock);
 648                 return(i);
 649         }
 650 
 651         if ((fd = get_fd(SOCK_INODE(sock))) < 0) 
 652         {
 653                 sock_release(sock);
 654                 return(-EINVAL);
 655         }
 656 
 657         return(fd);
 658 }
 659 
 660 /*
 661  *      Create a pair of connected sockets.
 662  */
 663 
 664 static int sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
     /* [previous][next][first][last][top][bottom][index][help] */
 665 {
 666         int fd1, fd2, i;
 667         struct socket *sock1, *sock2;
 668         int er;
 669 
 670         /*
 671          * Obtain the first socket and check if the underlying protocol
 672          * supports the socketpair call.
 673          */
 674 
 675         if ((fd1 = sock_socket(family, type, protocol)) < 0) 
 676                 return(fd1);
 677         sock1 = sockfd_lookup(fd1, NULL);
 678         if (!sock1->ops->socketpair) 
 679         {
 680                 sys_close(fd1);
 681                 return(-EINVAL);
 682         }
 683 
 684         /*
 685          *      Now grab another socket and try to connect the two together. 
 686          */
 687 
 688         if ((fd2 = sock_socket(family, type, protocol)) < 0) 
 689         {
 690                 sys_close(fd1);
 691                 return(-EINVAL);
 692         }
 693 
 694         sock2 = sockfd_lookup(fd2, NULL);
 695         if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) 
 696         {
 697                 sys_close(fd1);
 698                 sys_close(fd2);
 699                 return(i);
 700         }
 701 
 702         sock1->conn = sock2;
 703         sock2->conn = sock1;
 704         sock1->state = SS_CONNECTED;
 705         sock2->state = SS_CONNECTED;
 706 
 707         er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
 708         if(er)
 709         {
 710                 sys_close(fd1);
 711                 sys_close(fd2);
 712                 return er;
 713         }
 714         put_fs_long(fd1, &usockvec[0]);
 715         put_fs_long(fd2, &usockvec[1]);
 716 
 717         return(0);
 718 }
 719 
 720 
 721 /*
 722  *      Bind a name to a socket. Nothing much to do here since it's
 723  *      the protocol's responsibility to handle the local address.
 724  *
 725  *      We move the socket address to kernel space before we call
 726  *      the protocol layer (having also checked the address is ok).
 727  */
 728  
 729 static int sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 730 {
 731         struct socket *sock;
 732         int i;
 733         char address[MAX_SOCK_ADDR];
 734         int err;
 735 
 736         if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
 737                 return(-EBADF);
 738         
 739         if (!(sock = sockfd_lookup(fd, NULL))) 
 740                 return(-ENOTSOCK);
 741   
 742         if((err=move_addr_to_kernel(umyaddr,addrlen,address))<0)
 743                 return err;
 744   
 745         if ((i = sock->ops->bind(sock, (struct sockaddr *)address, addrlen)) < 0) 
 746         {
 747                 return(i);
 748         }
 749         return(0);
 750 }
 751 
 752 
 753 /*
 754  *      Perform a listen. Basically, we allow the protocol to do anything
 755  *      necessary for a listen, and if that works, we mark the socket as
 756  *      ready for listening.
 757  */
 758 
 759 static int sock_listen(int fd, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 760 {
 761         struct socket *sock;
 762 
 763         if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
 764                 return(-EBADF);
 765         if (!(sock = sockfd_lookup(fd, NULL))) 
 766                 return(-ENOTSOCK);
 767 
 768         if (sock->state != SS_UNCONNECTED) 
 769         {
 770                 return(-EINVAL);
 771         }
 772 
 773         if (sock->ops && sock->ops->listen)
 774                 sock->ops->listen(sock, backlog);
 775         sock->flags |= SO_ACCEPTCON;
 776         return(0);
 777 }
 778 
 779 
 780 /*
 781  *      For accept, we attempt to create a new socket, set up the link
 782  *      with the client, wake up the client, then return the new
 783  *      connected fd. We collect the address of the connector in kernel
 784  *      space and move it to user at the very end. This is buggy because
 785  *      we open the socket then return an error.
 786  */
 787 
 788 static int sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 789 {
 790         struct file *file;
 791         struct socket *sock, *newsock;
 792         int i;
 793         char address[MAX_SOCK_ADDR];
 794         int len;
 795 
 796         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
 797                 return(-EBADF);
 798         if (!(sock = sockfd_lookup(fd, &file))) 
 799                 return(-ENOTSOCK);
 800         if (sock->state != SS_UNCONNECTED) 
 801         {
 802                 return(-EINVAL);
 803         }
 804         if (!(sock->flags & SO_ACCEPTCON)) 
 805         {
 806                 return(-EINVAL);
 807         }
 808 
 809         if (!(newsock = sock_alloc())) 
 810         {
 811                 printk("NET: sock_accept: no more sockets\n");
 812                 return(-ENOSR); /* Was: EAGAIN, but we are out of system
 813                                    resources! */
 814         }
 815         newsock->type = sock->type;
 816         newsock->ops = sock->ops;
 817         if ((i = sock->ops->dup(newsock, sock)) < 0) 
 818         {
 819                 sock_release(newsock);
 820                 return(i);
 821         }
 822 
 823         i = newsock->ops->accept(sock, newsock, file->f_flags);
 824         if ( i < 0) 
 825         {
 826                 sock_release(newsock);
 827                 return(i);
 828         }
 829 
 830         if ((fd = get_fd(SOCK_INODE(newsock))) < 0) 
 831         {
 832                 sock_release(newsock);
 833                 return(-EINVAL);
 834         }
 835 
 836         if (upeer_sockaddr)
 837         {
 838                 newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
 839                 move_addr_to_user(address,len, upeer_sockaddr, upeer_addrlen);
 840         }
 841         return(fd);
 842 }
 843 
 844 
 845 /*
 846  *      Attempt to connect to a socket with the server address.  The address
 847  *      is in user space so we verify it is OK and move it to kernel space.
 848  */
 849  
 850 static int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 851 {
 852         struct socket *sock;
 853         struct file *file;
 854         int i;
 855         char address[MAX_SOCK_ADDR];
 856         int err;
 857 
 858         if (fd < 0 || fd >= NR_OPEN || (file=current->files->fd[fd]) == NULL)
 859                 return(-EBADF);
 860         if (!(sock = sockfd_lookup(fd, &file)))
 861                 return(-ENOTSOCK);
 862 
 863         if((err=move_addr_to_kernel(uservaddr,addrlen,address))<0)
 864                 return err;
 865   
 866         switch(sock->state) 
 867         {
 868                 case SS_UNCONNECTED:
 869                         /* This is ok... continue with connect */
 870                         break;
 871                 case SS_CONNECTED:
 872                         /* Socket is already connected */
 873                         if(sock->type == SOCK_DGRAM) /* Hack for now - move this all into the protocol */
 874                                 break;
 875                         return -EISCONN;
 876                 case SS_CONNECTING:
 877                         /* Not yet connected... we will check this. */
 878                 
 879                         /*
 880                          *      FIXME:  for all protocols what happens if you start
 881                          *      an async connect fork and both children connect. Clean
 882                          *      this up in the protocols!
 883                          */
 884                         break;
 885                 default:
 886                         return(-EINVAL);
 887         }
 888         i = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, file->f_flags);
 889         if (i < 0) 
 890         {
 891                 return(i);
 892         }
 893         return(0);
 894 }
 895 
 896 /*
 897  *      Get the local address ('name') of a socket object. Move the obtained
 898  *      name to user space.
 899  */
 900 
 901 static int sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 902 {
 903         struct socket *sock;
 904         char address[MAX_SOCK_ADDR];
 905         int len;
 906         int err;
 907         
 908         if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
 909                 return(-EBADF);
 910         if (!(sock = sockfd_lookup(fd, NULL)))
 911                 return(-ENOTSOCK);
 912 
 913         err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
 914         if(err)
 915                 return err;
 916         if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
 917                 return err;
 918         return 0;
 919 }
 920 
 921 /*
 922  *      Get the remote address ('name') of a socket object. Move the obtained
 923  *      name to user space.
 924  */
 925  
 926 static int sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 927 {
 928         struct socket *sock;
 929         char address[MAX_SOCK_ADDR];
 930         int len;
 931         int err;
 932 
 933         if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
 934                 return(-EBADF);
 935         if (!(sock = sockfd_lookup(fd, NULL)))
 936                 return(-ENOTSOCK);
 937 
 938         err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
 939         if(err)
 940                 return err;
 941         if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
 942                 return err;
 943         return 0;
 944 }
 945 
 946 /*
 947  *      Send a datagram down a socket. The datagram as with write() is
 948  *      in user space. We check it can be read.
 949  */
 950 
 951 static int sock_send(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 952 {
 953         struct socket *sock;
 954         struct file *file;
 955         int err;
 956 
 957         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
 958                 return(-EBADF);
 959         if (!(sock = sockfd_lookup(fd, NULL))) 
 960                 return(-ENOTSOCK);
 961 
 962         if(len<0)
 963                 return -EINVAL;
 964         err=verify_area(VERIFY_READ, buff, len);
 965         if(err)
 966                 return err;
 967         return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
 968 }
 969 
 970 /*
 971  *      Send a datagram to a given address. We move the address into kernel
 972  *      space and check the user space data area is readable before invoking
 973  *      the protocol.
 974  */
 975 
 976 static int sock_sendto(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 977            struct sockaddr *addr, int addr_len)
 978 {
 979         struct socket *sock;
 980         struct file *file;
 981         char address[MAX_SOCK_ADDR];
 982         int err;
 983         
 984         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
 985                 return(-EBADF);
 986         if (!(sock = sockfd_lookup(fd, NULL)))
 987                 return(-ENOTSOCK);
 988 
 989         if(len<0)
 990                 return -EINVAL;
 991         err=verify_area(VERIFY_READ,buff,len);
 992         if(err)
 993                 return err;
 994         
 995         if((err=move_addr_to_kernel(addr,addr_len,address))<0)
 996                 return err;
 997 
 998         return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
 999                 flags, (struct sockaddr *)address, addr_len));
1000 }
1001 
1002 
1003 /*
1004  *      Receive a datagram from a socket. This isn't really right. The BSD manual
1005  *      pages explicitly state that recv is recvfrom with a NULL to argument. The
1006  *      Linux stack gets the right results for the wrong reason and this need to
1007  *      be tidied in the inet layer and removed from here.
1008  *      We check the buffer is writable and valid.
1009  */
1010 
1011 static int sock_recv(int fd, void * buff, int len, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1012 {
1013         struct socket *sock;
1014         struct file *file;
1015         int err;
1016 
1017         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1018                 return(-EBADF);
1019 
1020         if (!(sock = sockfd_lookup(fd, NULL))) 
1021                 return(-ENOTSOCK);
1022                 
1023         if(len<0)
1024                 return -EINVAL;
1025         if(len==0)
1026                 return 0;
1027         err=verify_area(VERIFY_WRITE, buff, len);
1028         if(err)
1029                 return err;
1030 
1031         return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
1032 }
1033 
1034 /*
1035  *      Receive a frame from the socket and optionally record the address of the 
1036  *      sender. We verify the buffers are writable and if needed move the
1037  *      sender address from kernel to user space.
1038  */
1039 
1040 static int sock_recvfrom(int fd, void * buff, int len, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
1041              struct sockaddr *addr, int *addr_len)
1042 {
1043         struct socket *sock;
1044         struct file *file;
1045         char address[MAX_SOCK_ADDR];
1046         int err;
1047         int alen;
1048         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1049                 return(-EBADF);
1050         if (!(sock = sockfd_lookup(fd, NULL))) 
1051                 return(-ENOTSOCK);
1052         if(len<0)
1053                 return -EINVAL;
1054         if(len==0)
1055                 return 0;
1056 
1057         err=verify_area(VERIFY_WRITE,buff,len);
1058         if(err)
1059                 return err;
1060   
1061         len=sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
1062                      flags, (struct sockaddr *)address, &alen);
1063 
1064         if(len<0)
1065                 return len;
1066         if(addr!=NULL && (err=move_addr_to_user(address,alen, addr, addr_len))<0)
1067                 return err;
1068 
1069         return len;
1070 }
1071 
1072 /*
1073  *      Set a socket option. Because we don't know the option lengths we have
1074  *      to pass the user mode parameter for the protocols to sort out.
1075  */
1076  
1077 static int sock_setsockopt(int fd, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
1078 {
1079         struct socket *sock;
1080         struct file *file;
1081         
1082         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1083                 return(-EBADF);
1084         if (!(sock = sockfd_lookup(fd, NULL))) 
1085                 return(-ENOTSOCK);
1086 
1087         return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
1088 }
1089 
1090 /*
1091  *      Get a socket option. Because we don't know the option lengths we have
1092  *      to pass a user mode parameter for the protocols to sort out.
1093  */
1094 
1095 static int sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
1096 {
1097         struct socket *sock;
1098         struct file *file;
1099 
1100         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1101                 return(-EBADF);
1102         if (!(sock = sockfd_lookup(fd, NULL)))
1103                 return(-ENOTSOCK);
1104             
1105         if (!sock->ops || !sock->ops->getsockopt) 
1106                 return(0);
1107         return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
1108 }
1109 
1110 
1111 /*
1112  *      Shutdown a socket.
1113  */
1114  
1115 static int sock_shutdown(int fd, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1116 {
1117         struct socket *sock;
1118         struct file *file;
1119 
1120         if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1121                 return(-EBADF);
1122         if (!(sock = sockfd_lookup(fd, NULL))) 
1123                 return(-ENOTSOCK);
1124 
1125         return(sock->ops->shutdown(sock, how));
1126 }
1127 
1128 
1129 /*
1130  *      Perform a file control on a socket file descriptor.
1131  */
1132 
1133 int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1134 {
1135         struct socket *sock;
1136 
1137         sock = socki_lookup (filp->f_inode);
1138         if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
1139                 return(sock->ops->fcntl(sock, cmd, arg));
1140         return(-EINVAL);
1141 }
1142 
1143 
1144 /*
1145  *      System call vectors. Since I (RIB) want to rewrite sockets as streams,
1146  *      we have this level of indirection. Not a lot of overhead, since more of
1147  *      the work is done via read/write/select directly.
1148  *
1149  *      I'm now expanding this up to a higher level to separate the assorted
1150  *      kernel/user space manipulations and global assumptions from the protocol
1151  *      layers proper - AC.
1152  */
1153 
1154 asmlinkage int sys_socketcall(int call, unsigned long *args)
     /* [previous][next][first][last][top][bottom][index][help] */
1155 {
1156         int er;
1157         switch(call) 
1158         {
1159                 case SYS_SOCKET:
1160                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1161                         if(er)
1162                                 return er;
1163                         return(sock_socket(get_fs_long(args+0),
1164                                 get_fs_long(args+1),
1165                                 get_fs_long(args+2)));
1166                 case SYS_BIND:
1167                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1168                         if(er)
1169                                 return er;
1170                         return(sock_bind(get_fs_long(args+0),
1171                                 (struct sockaddr *)get_fs_long(args+1),
1172                                 get_fs_long(args+2)));
1173                 case SYS_CONNECT:
1174                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1175                         if(er)
1176                                 return er;
1177                         return(sock_connect(get_fs_long(args+0),
1178                                 (struct sockaddr *)get_fs_long(args+1),
1179                                 get_fs_long(args+2)));
1180                 case SYS_LISTEN:
1181                         er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
1182                         if(er)
1183                                 return er;
1184                         return(sock_listen(get_fs_long(args+0),
1185                                 get_fs_long(args+1)));
1186                 case SYS_ACCEPT:
1187                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1188                         if(er)
1189                                 return er;
1190                         return(sock_accept(get_fs_long(args+0),
1191                                 (struct sockaddr *)get_fs_long(args+1),
1192                                 (int *)get_fs_long(args+2)));
1193                 case SYS_GETSOCKNAME:
1194                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1195                         if(er)
1196                                 return er;
1197                         return(sock_getsockname(get_fs_long(args+0),
1198                                 (struct sockaddr *)get_fs_long(args+1),
1199                                 (int *)get_fs_long(args+2)));
1200                 case SYS_GETPEERNAME:
1201                         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
1202                         if(er)
1203                                 return er;
1204                         return(sock_getpeername(get_fs_long(args+0),
1205                                 (struct sockaddr *)get_fs_long(args+1),
1206                                 (int *)get_fs_long(args+2)));
1207                 case SYS_SOCKETPAIR:
1208                         er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
1209                         if(er)
1210                                 return er;
1211                         return(sock_socketpair(get_fs_long(args+0),
1212                                 get_fs_long(args+1),
1213                                 get_fs_long(args+2),
1214                                 (unsigned long *)get_fs_long(args+3)));
1215                 case SYS_SEND:
1216                         er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
1217                         if(er)
1218                                 return er;
1219                         return(sock_send(get_fs_long(args+0),
1220                                 (void *)get_fs_long(args+1),
1221                                 get_fs_long(args+2),
1222                                 get_fs_long(args+3)));
1223                 case SYS_SENDTO:
1224                         er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
1225                         if(er)
1226                                 return er;
1227                         return(sock_sendto(get_fs_long(args+0),
1228                                 (void *)get_fs_long(args+1),
1229                                 get_fs_long(args+2),
1230                                 get_fs_long(args+3),
1231                                 (struct sockaddr *)get_fs_long(args+4),
1232                                 get_fs_long(args+5)));
1233                 case SYS_RECV:
1234                         er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
1235                         if(er)
1236                                 return er;
1237                         return(sock_recv(get_fs_long(args+0),
1238                                 (void *)get_fs_long(args+1),
1239                                 get_fs_long(args+2),
1240                                 get_fs_long(args+3)));
1241                 case SYS_RECVFROM:
1242                         er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
1243                         if(er)
1244                                 return er;
1245                         return(sock_recvfrom(get_fs_long(args+0),
1246                                 (void *)get_fs_long(args+1),
1247                                 get_fs_long(args+2),
1248                                 get_fs_long(args+3),
1249                                 (struct sockaddr *)get_fs_long(args+4),
1250                                 (int *)get_fs_long(args+5)));
1251                 case SYS_SHUTDOWN:
1252                         er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
1253                         if(er)
1254                                 return er;
1255                         return(sock_shutdown(get_fs_long(args+0),
1256                                 get_fs_long(args+1)));
1257                 case SYS_SETSOCKOPT:
1258                         er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
1259                         if(er)
1260                                 return er;
1261                         return(sock_setsockopt(get_fs_long(args+0),
1262                                 get_fs_long(args+1),
1263                                 get_fs_long(args+2),
1264                                 (char *)get_fs_long(args+3),
1265                                 get_fs_long(args+4)));
1266                 case SYS_GETSOCKOPT:
1267                         er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
1268                         if(er)
1269                                 return er;
1270                         return(sock_getsockopt(get_fs_long(args+0),
1271                                 get_fs_long(args+1),
1272                                 get_fs_long(args+2),
1273                                 (char *)get_fs_long(args+3),
1274                                 (int *)get_fs_long(args+4)));
1275                 default:
1276                         return(-EINVAL);
1277         }
1278 }
1279 
1280 /*
1281  *      This function is called by a protocol handler that wants to
1282  *      advertise its address family, and have it linked into the
1283  *      SOCKET module.
1284  */
1285  
1286 int sock_register(int family, struct proto_ops *ops)
     /* [previous][next][first][last][top][bottom][index][help] */
1287 {
1288         int i;
1289 
1290         cli();
1291         for(i = 0; i < NPROTO; i++) 
1292         {
1293                 if (pops[i] != NULL) 
1294                         continue;
1295                 pops[i] = ops;
1296                 pops[i]->family = family;
1297                 sti();
1298                 return(i);
1299         }
1300         sti();
1301         return(-ENOMEM);
1302 }
1303 
1304 /*
1305  *      This function is called by a protocol handler that wants to
1306  *      remove its address family, and have it unlinked from the
1307  *      SOCKET module.
1308  */
1309  
1310 int sock_unregister(int family)
     /* [previous][next][first][last][top][bottom][index][help] */
1311 {
1312         int i;
1313 
1314         cli();
1315         for(i = 0; i < NPROTO; i++) 
1316         {
1317                 if (pops[i] == NULL) 
1318                         continue;
1319                 if(pops[i]->family == family)
1320                 {
1321                         pops[i]=NULL;
1322                         sti();
1323                         return(i);
1324                 }
1325         }
1326         sti();
1327         return(-ENOENT);
1328 }
1329 
1330 void proto_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1331 {
1332         extern struct net_proto protocols[];    /* Network protocols */
1333         struct net_proto *pro;
1334 
1335         /* Kick all configured protocols. */
1336         pro = protocols;
1337         while (pro->name != NULL) 
1338         {
1339                 (*pro->init_func)(pro);
1340                 pro++;
1341         }
1342         /* We're all done... */
1343 }
1344 
1345 
1346 void sock_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1347 {
1348         int i;
1349 
1350         printk("Swansea University Computer Society NET3.019\n");
1351 
1352         /*
1353          *      Initialize all address (protocol) families. 
1354          */
1355          
1356         for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1357 
1358         /*
1359          *      Initialize the protocols module. 
1360          */
1361 
1362         proto_init();
1363 
1364 #ifdef CONFIG_NET
1365         /* 
1366          *      Initialize the DEV module. 
1367          */
1368 
1369         dev_init();
1370   
1371         /*
1372          *      And the bottom half handler 
1373          */
1374 
1375         bh_base[NET_BH].routine= net_bh;
1376         enable_bh(NET_BH);
1377 #endif  
1378 }
1379 
1380 int socket_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1381 {
1382         int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
1383         if (offset >= len)
1384         {
1385                 *start = buffer;
1386                 return 0;
1387         }
1388         *start = buffer + offset;
1389         len -= offset;
1390         if (len > length)
1391                 len = length;
1392         return len;
1393 }

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