Annotation of linux/net/socket.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com