|
|
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 [email protected] */ ! 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.