|
|
1.1 ! root 1: /* sock.c */ ! 2: /* ! 3: Copyright (C) 1992 Ross Biro ! 4: ! 5: This program is free software; you can redistribute it and/or modify ! 6: it under the terms of the GNU General Public License as published by ! 7: the Free Software Foundation; either version 2, or (at your option) ! 8: any later version. ! 9: ! 10: This program is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: The Author may be reached as [email protected] or ! 20: C/O Department of Mathematics; Stanford University; Stanford, CA 94305 ! 21: */ ! 22: #include <linux/errno.h> ! 23: #include <linux/types.h> ! 24: #include <linux/socket.h> ! 25: #include <netinet/in.h> ! 26: #include <linux/kernel.h> ! 27: #include <linux/sched.h> ! 28: #include <linux/timer.h> ! 29: #include <linux/sock_ioctl.h> ! 30: #include <asm/memory.h> ! 31: #include "../kern_sock.h" ! 32: #include "timer.h" ! 33: #include "ip.h" ! 34: #include "tcp.h" ! 35: #include "udp.h" ! 36: #include "sock.h" ! 37: #include <asm/segment.h> ! 38: #include <asm/system.h> ! 39: #include <linux/fcntl.h> ! 40: ! 41: #ifdef MEM_DEBUG ! 42: #define MPRINTK printk ! 43: #else ! 44: #define MPRINTK dummy_routine ! 45: #endif ! 46: ! 47: #define min(a,b) ((a)<(b)?(a):(b)) ! 48: #define swap(a,b) {unsigned long c; c=a; a=b; b=c;} ! 49: ! 50: extern struct proto tcp_prot; ! 51: extern struct proto udp_prot; ! 52: extern struct proto raw_prot; ! 53: extern struct proto packet_prot; ! 54: ! 55: static int ip_proto_init(void); ! 56: static int ip_proto_create(struct socket *sock, int protocol); ! 57: static int ip_proto_dup(struct socket *newsock, struct socket *oldsock); ! 58: static int ip_proto_release(struct socket *sock, struct socket *peer); ! 59: static int ip_proto_bind(struct socket *sock, struct sockaddr *umyaddr, ! 60: int sockaddr_len); ! 61: static int ip_proto_connect(struct socket *sock, struct sockaddr *uservaddr, ! 62: int sockaddr_len, int flags); ! 63: static int ip_proto_socketpair(struct socket *sock1, struct socket *sock2); ! 64: static int ip_proto_accept(struct socket *sock, struct socket *newsock, int flags); ! 65: static int ip_proto_getname(struct socket *sock, struct sockaddr *usockaddr, ! 66: int *usockaddr_len, int peer); ! 67: static int ip_proto_read(struct socket *sock, char *ubuf, int size, ! 68: int nonblock); ! 69: static int ip_proto_write(struct socket *sock, char *ubuf, int size, ! 70: int nonblock); ! 71: static int ip_proto_select(struct socket *sock, int which, select_table *wait); ! 72: static int ip_proto_ioctl(struct socket *sock, unsigned int cmd, ! 73: unsigned long arg); ! 74: static int ip_proto_listen(struct socket *sock, int backlog); ! 75: ! 76: static int ip_proto_send (struct socket *sock, void *buff, int len, ! 77: int nonblock, unsigned flags); ! 78: static int ip_proto_recv (struct socket *sock, void *buff, int len, ! 79: int nonblock, unsigned flags); ! 80: static int ip_proto_sendto (struct socket *sock, void *buff, int len, ! 81: int nonblock, unsigned flags, ! 82: struct sockaddr *addr, int addr_len); ! 83: static int ip_proto_recvfrom (struct socket *sock, void *buff, int len, ! 84: int nonblock, unsigned flags, ! 85: struct sockaddr *addr, int *addr_len); ! 86: ! 87: static int ip_proto_shutdown (struct socket *sock, int how); ! 88: ! 89: ! 90: static int ip_proto_setsockopt (struct socket *sock, int level, int optname, ! 91: char *optval, int optlen); ! 92: static int ip_proto_getsockopt (struct socket *sock, int level, int optname, ! 93: char *optval, int *optlen); ! 94: static int ip_proto_fcntl (struct socket *sock, unsigned int cmd, ! 95: unsigned long arg); ! 96: ! 97: ! 98: struct proto_ops inet_proto_ops = ! 99: { ! 100: ip_proto_init, ! 101: ip_proto_create, ! 102: ip_proto_dup, ! 103: ip_proto_release, ! 104: ip_proto_bind, ! 105: ip_proto_connect, ! 106: ip_proto_socketpair, ! 107: ip_proto_accept, ! 108: ip_proto_getname, ! 109: ip_proto_read, ! 110: ip_proto_write, ! 111: ip_proto_select, ! 112: ip_proto_ioctl, ! 113: ip_proto_listen, ! 114: ip_proto_send, ! 115: ip_proto_recv, ! 116: ip_proto_sendto, ! 117: ip_proto_recvfrom, ! 118: ip_proto_shutdown, ! 119: ip_proto_setsockopt, ! 120: ip_proto_getsockopt, ! 121: ip_proto_fcntl ! 122: }; ! 123: ! 124: void ! 125: print_sk (volatile struct sock *sk) ! 126: { ! 127: PRINTK (" wmem_alloc = %d\n", sk->wmem_alloc); ! 128: PRINTK (" rmem_alloc = %d\n", sk->rmem_alloc); ! 129: PRINTK (" send_head = %X\n", sk->send_head); ! 130: PRINTK (" state = %d\n",sk->state); ! 131: PRINTK (" wback = %X, rqueue = %X\n", sk->wback, sk->rqueue); ! 132: PRINTK (" wfront = %X\n", sk->wfront); ! 133: PRINTK (" daddr = %X, saddr = %X\n", sk->daddr,sk->saddr); ! 134: PRINTK (" num = %d", sk->num); ! 135: PRINTK (" next = %X\n", sk->next); ! 136: PRINTK (" send_seq = %d, acked_seq = %d, copied_seq = %d\n", ! 137: sk->send_seq, sk->acked_seq, sk->copied_seq); ! 138: PRINTK (" rcv_ack_seq = %d, window_seq = %d, fin_seq = %d\n", ! 139: sk->rcv_ack_seq, sk->window_seq, sk->fin_seq); ! 140: PRINTK (" prot = %X\n", sk->prot); ! 141: PRINTK (" pair = %X, back_log = %X\n", sk->pair,sk->back_log); ! 142: PRINTK (" inuse = %d , blog = %d\n", sk->inuse, sk->blog); ! 143: PRINTK (" dead = %d delay_acks=%d\n", sk->dead, sk->delay_acks); ! 144: PRINTK (" retransmits = %d, timeout = %d\n", sk->retransmits, sk->timeout); ! 145: PRINTK (" cong_window = %d, packets_out = %d\n", sk->cong_window, ! 146: sk->packets_out); ! 147: } ! 148: ! 149: void ! 150: print_skb(struct sk_buff *skb) ! 151: { ! 152: PRINTK (" prev = %X, next = %X\n", skb->prev, skb->next); ! 153: PRINTK (" sk = %X link3 = %X\n", skb->sk, skb->link3); ! 154: PRINTK (" mem_addr = %X, mem_len = %d\n", skb->mem_addr, skb->mem_len); ! 155: PRINTK (" used = %d free = %d\n", skb->used,skb->free); ! 156: } ! 157: ! 158: /* just used to reference some pointers to keep gcc from over optimizing ! 159: my code so that it doesn't work. */ ! 160: void dummy_routine(void *dummy, ...) ! 161: { ! 162: return; ! 163: } ! 164: ! 165: void ! 166: lock_skb (struct sk_buff *skb) ! 167: { ! 168: if (skb->lock) ! 169: { ! 170: printk ("*** bug more than one lock on sk_buff. \n"); ! 171: } ! 172: skb->lock = 1; ! 173: } ! 174: ! 175: ! 176: void ! 177: free_skb (struct sk_buff *skb, int rw) ! 178: { ! 179: if (skb->lock) ! 180: { ! 181: skb->free = 1; ! 182: return; ! 183: } ! 184: if (skb->sk) ! 185: { ! 186: if (rw) ! 187: { ! 188: skb->sk->prot->rfree (skb->sk, skb->mem_addr, skb->mem_len); ! 189: } ! 190: else ! 191: { ! 192: skb->sk->prot->wfree (skb->sk, skb->mem_addr, skb->mem_len); ! 193: } ! 194: } ! 195: else ! 196: { ! 197: free_s (skb->mem_addr, skb->mem_len); ! 198: } ! 199: } ! 200: ! 201: void ! 202: unlock_skb (struct sk_buff *skb, int rw) ! 203: { ! 204: if (skb->lock != 1) ! 205: { ! 206: printk ("*** bug unlocking non-locked sk_buff. \n"); ! 207: } ! 208: skb->lock = 0; ! 209: if (skb->free) ! 210: free_skb (skb, rw); ! 211: } ! 212: ! 213: static int ! 214: sk_inuse( struct proto *prot, int num) ! 215: { ! 216: volatile struct sock *sk; ! 217: for (sk = prot->sock_array[num & (SOCK_ARRAY_SIZE -1 )]; ! 218: sk != NULL; sk=sk->next) ! 219: { ! 220: if (sk->dummy_th.source == num) return (1); ! 221: } ! 222: return (0); ! 223: } ! 224: ! 225: unsigned short ! 226: get_new_socknum(struct proto *prot, unsigned short base) ! 227: { ! 228: static int start=0; ! 229: /* used to cycle through the port numbers so the chances of ! 230: a confused connection drop. */ ! 231: ! 232: int i,j; ! 233: int best=0; ! 234: int size=32767; /* a big num. */ ! 235: volatile struct sock *sk; ! 236: start++; ! 237: if (base == 0) base = PROT_SOCK+1+(start % 1024); ! 238: if (base <= PROT_SOCK) ! 239: { ! 240: base += PROT_SOCK+(start % 1024); ! 241: } ! 242: ! 243: /* now look through the entire array and try to find an empty ! 244: ptr. */ ! 245: for (i = 0; i < SOCK_ARRAY_SIZE; i++) ! 246: { ! 247: j = 0; ! 248: sk = prot->sock_array[(i+base+1) & (SOCK_ARRAY_SIZE -1)]; ! 249: while (sk != NULL) ! 250: { ! 251: sk = sk->next; ! 252: j++; ! 253: } ! 254: if (j == 0) return (i+base+1); ! 255: if (j < size) ! 256: { ! 257: best = i; ! 258: size = j; ! 259: } ! 260: } ! 261: /* now make sure the one we want is not in use. */ ! 262: while (sk_inuse (prot, base +best+1)) ! 263: { ! 264: best += SOCK_ARRAY_SIZE; ! 265: } ! 266: return (best+base+1); ! 267: ! 268: } ! 269: ! 270: void ! 271: put_sock(unsigned short num, volatile struct sock *sk) ! 272: { ! 273: volatile struct sock *sk1; ! 274: volatile struct sock *sk2; ! 275: int mask; ! 276: ! 277: PRINTK ("put_sock (num = %d, sk = %X\n", num, sk); ! 278: sk->num = num; ! 279: sk->next = NULL; ! 280: num = num & (SOCK_ARRAY_SIZE -1); ! 281: ! 282: /* we can't have an interupt renter here. */ ! 283: cli(); ! 284: if (sk->prot->sock_array[num] == NULL) ! 285: { ! 286: sk->prot->sock_array[num] = sk; ! 287: sti(); ! 288: return; ! 289: } ! 290: sti(); ! 291: for (mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask) ! 292: { ! 293: if (mask & sk->saddr) ! 294: { ! 295: mask = mask << 8; ! 296: break; ! 297: } ! 298: } ! 299: ! 300: PRINTK ("mask = %X\n", mask); ! 301: ! 302: cli(); ! 303: sk1 = sk->prot->sock_array[num]; ! 304: for (sk2 = sk1; sk2 != NULL; sk2=sk2->next) ! 305: { ! 306: if (!(sk2->saddr & mask)) ! 307: { ! 308: if (sk2 == sk1) ! 309: { ! 310: sk->next = sk->prot->sock_array[num]; ! 311: sk->prot->sock_array[num] = sk; ! 312: sti(); ! 313: return; ! 314: } ! 315: sk->next = sk2; ! 316: sk1->next= sk; ! 317: sti(); ! 318: return; ! 319: } ! 320: sk1 = sk2; ! 321: } ! 322: /* goes at the end. */ ! 323: sk->next = NULL; ! 324: sk1->next = sk; ! 325: sti(); ! 326: } ! 327: ! 328: ! 329: static void ! 330: remove_sock(volatile struct sock *sk1) ! 331: { ! 332: volatile struct sock *sk2; ! 333: PRINTK ("remove_sock(sk1=%X)\n",sk1); ! 334: ! 335: /* we can't have this changing out from under us. */ ! 336: cli(); ! 337: sk2=sk1->prot->sock_array[sk1->num & (SOCK_ARRAY_SIZE -1)]; ! 338: if (sk2 == sk1) ! 339: { ! 340: sk1->prot->sock_array[sk1->num & (SOCK_ARRAY_SIZE -1)] = sk1->next; ! 341: sti(); ! 342: return; ! 343: } ! 344: while (sk2->next != sk1) ! 345: { ! 346: if (sk2 == NULL) ! 347: { ! 348: sti(); ! 349: PRINTK ("remove_sock: sock not found.\n"); ! 350: return; ! 351: } ! 352: sk2=sk2->next; ! 353: } ! 354: sk2->next = sk1->next; ! 355: sti(); ! 356: } ! 357: ! 358: void ! 359: destroy_sock(volatile struct sock *sk) ! 360: { ! 361: ! 362: struct sk_buff *skb; ! 363: PRINTK ("destroying socket %X\n",sk); ! 364: /* just to be safe. */ ! 365: sk->inuse = 1; ! 366: ! 367: remove_sock (sk); ! 368: /* now we can no longer get new packets. */ ! 369: ! 370: delete_timer((struct timer *)&sk->time_wait); ! 371: ! 372: /* cleanup up the write buffer. */ ! 373: for (skb = sk->wfront; skb != NULL; ) ! 374: { ! 375: struct sk_buff *skb2; ! 376: skb2=skb->next; ! 377: free_skb(skb, FREE_WRITE); ! 378: skb=skb2; ! 379: } ! 380: ! 381: sk->wfront = NULL; ! 382: ! 383: if (sk->rqueue != NULL) ! 384: { ! 385: skb = sk->rqueue; ! 386: do { ! 387: struct sk_buff *skb2; ! 388: skb2=skb->next; ! 389: /* this will take care of closing sockets that were ! 390: listening and didn't accept everything. */ ! 391: ! 392: if (skb->sk != NULL && skb->sk != sk) ! 393: { ! 394: skb->sk->dead = 1; ! 395: skb->sk->prot->close (skb->sk, 0); ! 396: } ! 397: free_skb(skb, FREE_READ); ! 398: skb=skb2; ! 399: } while (skb != sk->rqueue); ! 400: } ! 401: ! 402: sk->rqueue = NULL; ! 403: ! 404: /* now we need to clean up the send head. */ ! 405: for (skb = sk->send_head; skb != NULL; ) ! 406: { ! 407: struct sk_buff *skb2; ! 408: /* we need to remove skb from the transmit queue. */ ! 409: cli(); ! 410: /* see if it's in a transmit queue. */ ! 411: if (skb->next != NULL) ! 412: { ! 413: if (skb->next != skb) ! 414: { ! 415: skb->next->prev = skb->prev; ! 416: skb->prev->next = skb->next; ! 417: } ! 418: else ! 419: { ! 420: int i; ! 421: for (i = 0; i < DEV_NUMBUFFS; i++) ! 422: { ! 423: if (skb->dev && skb->dev->buffs[i] == skb) ! 424: { ! 425: skb->dev->buffs[i]= NULL; ! 426: break; ! 427: } ! 428: } ! 429: } ! 430: } ! 431: sti(); ! 432: skb2=skb->link3; ! 433: free_skb(skb, FREE_WRITE); ! 434: skb=skb2; ! 435: } ! 436: ! 437: sk->send_head = NULL; ! 438: ! 439: /* and now the backlog. */ ! 440: ! 441: if (sk->back_log != NULL) ! 442: { ! 443: /* this should never happen. */ ! 444: printk ("cleaning back_log. \n"); ! 445: cli(); ! 446: skb = sk->back_log; ! 447: do { ! 448: struct sk_buff *skb2; ! 449: skb2=skb->next; ! 450: free_skb(skb, FREE_READ); ! 451: skb=skb2; ! 452: } while (skb != sk->back_log); ! 453: sti(); ! 454: } ! 455: ! 456: sk->back_log = NULL; ! 457: ! 458: /* now if everything is gone we can free the socket structure, ! 459: otherwise we need to keep it around until everything is gone. */ ! 460: if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) ! 461: { ! 462: free_s ((void *)sk,sizeof (*sk)); ! 463: } ! 464: else ! 465: { ! 466: /* this should never happen. */ ! 467: /* actually it can if an ack has just been sent. */ ! 468: PRINTK ("possible memory leak in socket = %X\n", sk); ! 469: print_sk (sk); ! 470: sk->destroy = 1; ! 471: sk->ack_backlog = 0; ! 472: sk->inuse = 0; ! 473: sk->time_wait.len = SOCK_DESTROY_TIME; ! 474: sk->timeout = TIME_DESTROY; ! 475: reset_timer ((struct timer *)&sk->time_wait); ! 476: } ! 477: ! 478: } ! 479: ! 480: ! 481: static int ! 482: ip_proto_fcntl (struct socket *sock, unsigned int cmd, unsigned long arg) ! 483: { ! 484: volatile struct sock *sk; ! 485: sk=sock->data; ! 486: if (sk == NULL) ! 487: { ! 488: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 489: return (0); ! 490: } ! 491: switch (cmd) ! 492: { ! 493: case F_SETOWN: ! 494: sk->proc = arg; ! 495: return (0); ! 496: ! 497: case F_GETOWN: ! 498: return (sk->proc); ! 499: ! 500: default: ! 501: return (-EINVAL); ! 502: } ! 503: } ! 504: ! 505: static int ! 506: ip_proto_setsockopt(struct socket *sock, int level, int optname, ! 507: char *optval, int optlen) ! 508: { ! 509: volatile struct sock *sk; ! 510: int val; ! 511: /* This should really pass things on to the other levels. */ ! 512: if (level != SOL_SOCKET) return (-EOPNOTSUPP); ! 513: sk = sock->data; ! 514: if (sk == NULL) ! 515: { ! 516: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 517: return (0); ! 518: } ! 519: verify_area (optval, sizeof (int)); ! 520: val = get_fs_long ((unsigned long *)optval); ! 521: switch (optname) ! 522: { ! 523: case SO_TYPE: ! 524: case SO_ERROR: ! 525: default: ! 526: return (-ENOPROTOOPT); ! 527: ! 528: case SO_DEBUG: /* not implemented. */ ! 529: case SO_DONTROUTE: ! 530: case SO_BROADCAST: ! 531: case SO_SNDBUF: ! 532: case SO_RCVBUF: ! 533: return (0); ! 534: ! 535: case SO_REUSEADDR: ! 536: if (val) ! 537: sk->reuse = 1; ! 538: else ! 539: sk->reuse = 1; ! 540: return (0); ! 541: ! 542: case SO_KEEPALIVE: ! 543: if (val) ! 544: sk->keepopen = 1; ! 545: else ! 546: sk->keepopen = 0; ! 547: return (0); ! 548: ! 549: case SO_OOBINLINE: ! 550: if (val) ! 551: sk->urginline = 1; ! 552: else ! 553: sk->urginline = 0; ! 554: return (0); ! 555: ! 556: case SO_NO_CHECK: ! 557: if (val) ! 558: sk->no_check = 1; ! 559: else ! 560: sk->no_check = 0; ! 561: return (0); ! 562: ! 563: case SO_PRIORITY: ! 564: if (val >= 0 && val < DEV_NUMBUFFS) ! 565: { ! 566: sk->priority = val; ! 567: } ! 568: else ! 569: { ! 570: return (-EINVAL); ! 571: } ! 572: return (0); ! 573: ! 574: } ! 575: } ! 576: ! 577: static int ! 578: ip_proto_getsockopt(struct socket *sock, int level, int optname, ! 579: char *optval, int *optlen) ! 580: { ! 581: volatile struct sock *sk; ! 582: int val; ! 583: /* This should really pass things on to the other levels. */ ! 584: if (level != SOL_SOCKET) return (-EOPNOTSUPP); ! 585: sk = sock->data; ! 586: if (sk == NULL) ! 587: { ! 588: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 589: return (0); ! 590: } ! 591: switch (optname) ! 592: { ! 593: default: ! 594: return (-ENOPROTOOPT); ! 595: ! 596: case SO_DEBUG: /* not implemented. */ ! 597: case SO_DONTROUTE: ! 598: case SO_BROADCAST: ! 599: case SO_SNDBUF: ! 600: case SO_RCVBUF: ! 601: val = 0; ! 602: break; ! 603: ! 604: case SO_REUSEADDR: ! 605: val = sk->reuse; ! 606: break; ! 607: ! 608: case SO_KEEPALIVE: ! 609: val = sk->keepopen; ! 610: break; ! 611: ! 612: case SO_TYPE: ! 613: if (sk->prot == &tcp_prot) ! 614: val = SOCK_STREAM; ! 615: else ! 616: val = SOCK_DGRAM; ! 617: break; ! 618: ! 619: case SO_ERROR: ! 620: val = sk->err; ! 621: sk->err = 0; ! 622: break; ! 623: ! 624: case SO_OOBINLINE: ! 625: val = sk->urginline; ! 626: break; ! 627: ! 628: case SO_NO_CHECK: ! 629: val = sk->no_check; ! 630: break; ! 631: ! 632: case SO_PRIORITY: ! 633: val = sk->priority; ! 634: break; ! 635: } ! 636: verify_area (optlen, sizeof (int)); ! 637: put_fs_long (sizeof(int),(unsigned long *) optlen); ! 638: ! 639: verify_area(optval, sizeof (int)); ! 640: put_fs_long (val, (unsigned long *)optval); ! 641: return (0); ! 642: } ! 643: ! 644: static int ! 645: ip_proto_listen(struct socket *sock, int backlog) ! 646: { ! 647: volatile struct sock *sk; ! 648: sk = sock->data; ! 649: if (sk == NULL) ! 650: { ! 651: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 652: return (0); ! 653: } ! 654: sk->state = TCP_LISTEN; ! 655: return (0); ! 656: } ! 657: ! 658: /* Hardware should be inited here. */ ! 659: static int ip_proto_init(void) ! 660: { ! 661: int i; ! 662: struct device *dev; ! 663: struct ip_protocol *p; ! 664: seq_offset = CURRENT_TIME*250; ! 665: /* add all the protocols. */ ! 666: for (i = 0; i < SOCK_ARRAY_SIZE; i++) ! 667: { ! 668: tcp_prot.sock_array[i] = NULL; ! 669: udp_prot.sock_array[i] = NULL; ! 670: raw_prot.sock_array[i] = NULL; ! 671: } ! 672: ! 673: for (p = ip_protocol_base; p != NULL;) ! 674: { ! 675: struct ip_protocol *tmp; ! 676: /* add all the protocols. */ ! 677: tmp = p->next; ! 678: add_ip_protocol (p); ! 679: p = tmp; ! 680: } ! 681: ! 682: /* add the devices */ ! 683: for (dev = dev_base; dev != NULL; dev=dev->next) ! 684: { ! 685: if (dev->init) ! 686: dev->init(dev); ! 687: } ! 688: timer_table[NET_TIMER].fn = net_timer; ! 689: return (0); ! 690: } ! 691: ! 692: static int ! 693: ip_proto_create (struct socket *sock, int protocol) ! 694: { ! 695: volatile struct sock *sk; ! 696: struct proto *prot; ! 697: int err; ! 698: ! 699: sk = malloc (sizeof (*sk)); ! 700: if (sk == NULL) ! 701: return (-ENOMEM); ! 702: sk->num = 0; ! 703: ! 704: ! 705: switch (sock->type) ! 706: { ! 707: case SOCK_STREAM: ! 708: case SOCK_SEQPACKET: ! 709: if (protocol && protocol != IP_TCP) ! 710: { ! 711: free_s ((void *)sk, sizeof (*sk)); ! 712: return (-EPROTONOSUPPORT); ! 713: } ! 714: sk->no_check = TCP_NO_CHECK; ! 715: prot = &tcp_prot; ! 716: break; ! 717: ! 718: case SOCK_DGRAM: ! 719: if (protocol && protocol != IP_UDP) ! 720: { ! 721: free_s ((void *)sk, sizeof (*sk)); ! 722: return (-EPROTONOSUPPORT); ! 723: } ! 724: sk->no_check = UDP_NO_CHECK; ! 725: prot=&udp_prot; ! 726: break; ! 727: ! 728: case SOCK_RAW: ! 729: if (!suser()) ! 730: { ! 731: free_s ((void *)sk, sizeof (*sk)); ! 732: return (-EPERM); ! 733: } ! 734: ! 735: if (!protocol) ! 736: { ! 737: free_s ((void *)sk, sizeof (*sk)); ! 738: return (-EPROTONOSUPPORT); ! 739: } ! 740: prot = &raw_prot; ! 741: sk->reuse = 1; ! 742: sk->no_check = 0; /* doesn't matter no checksum is preformed ! 743: anyway. */ ! 744: sk->num = protocol; ! 745: break; ! 746: ! 747: case SOCK_PACKET: ! 748: if (!suser()) ! 749: { ! 750: free_s ((void *)sk, sizeof (*sk)); ! 751: return (-EPERM); ! 752: } ! 753: ! 754: if (!protocol) ! 755: { ! 756: free_s ((void *)sk, sizeof (*sk)); ! 757: return (-EPROTONOSUPPORT); ! 758: } ! 759: prot = &packet_prot; ! 760: sk->reuse = 1; ! 761: sk->no_check = 0; /* doesn't matter no checksum is preformed ! 762: anyway. */ ! 763: sk->num = protocol; ! 764: break; ! 765: ! 766: ! 767: default: ! 768: free_s ((void *)sk, sizeof (*sk)); ! 769: return (-ESOCKTNOSUPPORT); ! 770: ! 771: } ! 772: sk->protocol = protocol; ! 773: sk->wmem_alloc = 0; ! 774: sk->rmem_alloc = 0; ! 775: sk->pair = NULL; ! 776: sk->opt = NULL; ! 777: sk->send_seq = 0; ! 778: sk->acked_seq = 0; ! 779: sk->copied_seq = 0; ! 780: sk->fin_seq = 0; ! 781: sk->proc = 0; ! 782: sk->rtt = TCP_WRITE_TIME; ! 783: sk->packets_out = 0; ! 784: sk->cong_window = 1; /* start with only sending one packet at a time. */ ! 785: sk->exp_growth = 1; /* if set cong_window grow exponentially every time ! 786: we get an ack. */ ! 787: sk->urginline = 0; ! 788: sk->intr = 0; ! 789: sk->linger = 0; ! 790: sk->destroy = 0; ! 791: sk->reuse = 0; ! 792: sk->priority = 1; ! 793: sk->shutdown = 0; ! 794: sk->urg = 0; ! 795: sk->keepopen = 0; ! 796: sk->done = 0; ! 797: sk->ack_backlog = 0; ! 798: sk->window = 0; ! 799: sk->bytes_rcv = 0; ! 800: sk->state = TCP_CLOSE; ! 801: sk->dead = 0; ! 802: sk->ack_timed = 0; ! 803: ! 804: /* this is how many unacked bytes we will accept for ! 805: this socket. */ ! 806: ! 807: sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ ! 808: ! 809: /* how many packets we should send before forcing an ack. ! 810: if this is set to zero it is the same as sk->delay_acks = 0 */ ! 811: ! 812: sk->max_ack_backlog = MAX_ACK_BACKLOG; ! 813: sk->inuse = 0; ! 814: sk->delay_acks = 1; /* default to waiting a while before sending ! 815: acks. */ ! 816: sk->wback = NULL; ! 817: sk->wfront = NULL; ! 818: sk->rqueue = NULL; ! 819: sk->mtu = 576; ! 820: sk->prot = prot; ! 821: sk->sleep = sock->wait; ! 822: sk->daddr = 0; ! 823: sk->saddr = MY_IP_ADDR; ! 824: sk->err = 0; ! 825: sk->next = NULL; ! 826: sk->pair = NULL; ! 827: sk->send_tail = NULL; ! 828: sk->send_head = NULL; ! 829: sk->time_wait.len = TCP_CONNECT_TIME; ! 830: sk->time_wait.when = 0; ! 831: sk->time_wait.sk = sk; ! 832: sk->time_wait.next = NULL; ! 833: sk->timeout = 0; ! 834: sk->back_log = NULL; ! 835: sk->blog = 0; ! 836: sock->data =(void *) sk; ! 837: sk->dummy_th.doff = sizeof (sk->dummy_th)/4; ! 838: sk->dummy_th.res1=0; ! 839: sk->dummy_th.res2=0; ! 840: sk->dummy_th.urg_ptr = 0; ! 841: sk->dummy_th.fin = 0; ! 842: sk->dummy_th.syn = 0; ! 843: sk->dummy_th.rst = 0; ! 844: sk->dummy_th.psh = 0; ! 845: sk->dummy_th.ack = 0; ! 846: sk->dummy_th.urg = 0; ! 847: sk->dummy_th.dest = 0; ! 848: if (sk->num) ! 849: { ! 850: put_sock (sk->num, sk); ! 851: } ! 852: else ! 853: { ! 854: sk->num = get_new_socknum(sk->prot, 0); ! 855: } ! 856: /* make sure there was a free socket. */ ! 857: if (sk->num == 0) ! 858: { ! 859: destroy_sock(sk); ! 860: return (-EAGAIN); ! 861: } ! 862: put_sock(sk->num, sk); ! 863: sk->dummy_th.source = net16(sk->num); ! 864: if (sk->prot->init) ! 865: { ! 866: err = sk->prot->init(sk); ! 867: if (err != 0) ! 868: { ! 869: destroy_sock (sk); ! 870: return (err); ! 871: } ! 872: } ! 873: return (0); ! 874: } ! 875: ! 876: static int ! 877: ip_proto_dup (struct socket *newsock, struct socket *oldsock) ! 878: { ! 879: return (ip_proto_create (newsock, ! 880: ((volatile struct sock *)(oldsock->data))->protocol)); ! 881: } ! 882: ! 883: /* the peer socket should always be NULL. */ ! 884: static int ! 885: ip_proto_release(struct socket *sock, struct socket *peer) ! 886: { ! 887: volatile struct sock *sk; ! 888: sk = sock->data; ! 889: if (sk == NULL) return (0); ! 890: wake_up (sk->sleep); ! 891: /* start closing the connection. This may take a while. */ ! 892: /* if linger is set, we don't return until the close is ! 893: complete. Other wise we return immediately. The ! 894: actually closing is done the same either way. */ ! 895: if (sk->linger == 0) ! 896: { ! 897: sk->prot->close(sk,0); ! 898: sk->dead = 1; ! 899: } ! 900: else ! 901: { ! 902: sk->prot->close(sk, 0); ! 903: cli(); ! 904: while (sk->state != TCP_CLOSE) ! 905: { ! 906: interruptible_sleep_on (sk->sleep); ! 907: if (current->signal & ~current->blocked) ! 908: { ! 909: sti(); ! 910: return (-ERESTARTSYS); ! 911: } ! 912: } ! 913: sti(); ! 914: sk->dead = 1; ! 915: } ! 916: ! 917: sk->inuse = 1; ! 918: /* this will destroy it. */ ! 919: release_sock (sk); ! 920: sock->data = NULL; ! 921: return (0); ! 922: } ! 923: ! 924: ! 925: static int ! 926: ip_proto_bind (struct socket *sock, struct sockaddr *uaddr, ! 927: int addr_len) ! 928: { ! 929: struct sockaddr_in addr; ! 930: volatile struct sock *sk, *sk2; ! 931: unsigned short snum; ! 932: sk = sock->data; ! 933: if (sk == NULL) ! 934: { ! 935: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 936: return (0); ! 937: } ! 938: /* check this error. */ ! 939: if (sk->state != TCP_CLOSE) return (-EIO); ! 940: verify_area (uaddr, addr_len); ! 941: memcpy_fromfs (&addr, uaddr, min (sizeof (addr), addr_len)); ! 942: if (addr.sin_family && addr.sin_family != AF_INET) ! 943: return (-EIO); /* this needs to be changed. */ ! 944: snum = net16(addr.sin_port); ! 945: PRINTK ("bind sk =%X to port = %d\n", sk, snum); ! 946: print_sk (sk); ! 947: sk = sock->data; ! 948: ! 949: /* we can't just leave the socket bound wherever it is, it might be bound ! 950: to a priveledged port. However, since there seems to be a bug here, ! 951: we will leave it if the port is not priveledged(sp?) */ ! 952: ! 953: if (snum == 0) ! 954: { ! 955: if ( sk->num > PROT_SOCK) return (0); ! 956: snum = get_new_socknum (sk->prot, 0); ! 957: } ! 958: ! 959: if (snum <= PROT_SOCK && !suser()) ! 960: return (-EPERM); ! 961: ! 962: if (my_ip_addr(addr.sin_addr.s_addr) || addr.sin_addr.s_addr == 0) ! 963: sk->saddr = addr.sin_addr.s_addr; ! 964: PRINTK ("sock_array[%d] = %X:\n", snum & (SOCK_ARRAY_SIZE -1), ! 965: sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]); ! 966: print_sk (sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]); ! 967: ! 968: /* make sure we are allowed to bind here. */ ! 969: for (sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]; ! 970: sk2 != NULL; ! 971: sk2 = sk2->next) ! 972: { ! 973: if (sk2->num != snum) continue; ! 974: if (sk2->saddr != sk->saddr) continue; ! 975: if (!sk->reuse) return (-EADDRINUSE); ! 976: if (!sk2->reuse) return (-EADDRINUSE); ! 977: } ! 978: remove_sock (sk); ! 979: put_sock(snum, sk); ! 980: sk->dummy_th.source = net16(sk->num); ! 981: sk->daddr = 0; ! 982: sk->dummy_th.dest = 0; ! 983: return (0); ! 984: } ! 985: ! 986: static int ! 987: ip_proto_connect (struct socket *sock, struct sockaddr * uaddr, ! 988: int addr_len, int flags) ! 989: { ! 990: volatile struct sock *sk; ! 991: int err; ! 992: sock->conn = NULL; ! 993: sk = sock->data; ! 994: if (sk == NULL) ! 995: { ! 996: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 997: return (0); ! 998: } ! 999: if (sk->prot->connect == NULL) ! 1000: return (-EOPNOTSUPP); ! 1001: ! 1002: if (sk->intr == 0) ! 1003: { ! 1004: err = sk->prot->connect (sk, (struct sockaddr_in *)uaddr, addr_len); ! 1005: if (err < 0) return (err); ! 1006: } ! 1007: ! 1008: sock->state = SS_CONNECTED; ! 1009: ! 1010: if (flags & O_NONBLOCK) return (0); ! 1011: ! 1012: cli(); /* avoid the race condition */ ! 1013: ! 1014: while (sk->state != TCP_ESTABLISHED && sk->state < TCP_CLOSING) ! 1015: { ! 1016: interruptible_sleep_on (sk->sleep); ! 1017: if (current->signal & ~current->blocked) ! 1018: { ! 1019: sti(); ! 1020: sk->intr = 1; ! 1021: return (-ERESTARTSYS); ! 1022: } ! 1023: } ! 1024: sti(); ! 1025: sk->intr = 0; ! 1026: if (sk->state != TCP_ESTABLISHED && sk->err) ! 1027: { ! 1028: return (-sk->err); ! 1029: } ! 1030: return (0); ! 1031: } ! 1032: ! 1033: static int ! 1034: ip_proto_socketpair (struct socket *sock1, struct socket *sock2) ! 1035: { ! 1036: return (-EOPNOTSUPP); ! 1037: } ! 1038: ! 1039: static int ! 1040: ip_proto_accept (struct socket *sock, struct socket *newsock, int flags) ! 1041: { ! 1042: volatile struct sock *sk1, *sk2; ! 1043: sk1= sock->data; ! 1044: if (sk1 == NULL) ! 1045: { ! 1046: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1047: return (0); ! 1048: } ! 1049: newsock->data = NULL; ! 1050: if (sk1->prot->accept == NULL) return (-EOPNOTSUPP); ! 1051: /* restore the state if we have been interrupted, and ! 1052: then returned. */ ! 1053: if (sk1->pair != NULL ) ! 1054: { ! 1055: sk2 = sk1->pair; ! 1056: sk1->pair = NULL; ! 1057: } ! 1058: else ! 1059: { ! 1060: sk2 = sk1->prot->accept (sk1,flags); ! 1061: if (sk2 == NULL) ! 1062: return (-sk1->err); ! 1063: } ! 1064: newsock->data = (void *)sk2; ! 1065: sk2->sleep = (void *)newsock->wait; ! 1066: newsock->conn = NULL; ! 1067: if (flags & O_NONBLOCK) ! 1068: return (0); ! 1069: ! 1070: cli(); /* avoid the race. */ ! 1071: while (sk2->state == TCP_SYN_RECV) ! 1072: { ! 1073: interruptible_sleep_on (sk2->sleep); ! 1074: if (current->signal & ~current->blocked) ! 1075: { ! 1076: sti(); ! 1077: sk1->pair = sk2; ! 1078: sk2->sleep = NULL; ! 1079: newsock->data = NULL; ! 1080: return (-ERESTARTSYS); ! 1081: } ! 1082: } ! 1083: sti(); ! 1084: ! 1085: if (sk2->state != TCP_ESTABLISHED && sk2->err) ! 1086: { ! 1087: int err; ! 1088: err = -sk2->err; ! 1089: destroy_sock (sk2); ! 1090: newsock->data = NULL; ! 1091: return (err); ! 1092: } ! 1093: newsock->state = SS_CONNECTED; ! 1094: return (0); ! 1095: } ! 1096: ! 1097: static int ! 1098: ip_proto_getname(struct socket *sock, struct sockaddr *uaddr, ! 1099: int *uaddr_len, int peer) ! 1100: { ! 1101: struct sockaddr_in sin; ! 1102: volatile struct sock *sk; ! 1103: int len; ! 1104: verify_area(uaddr_len, sizeof (len)); ! 1105: len = get_fs_long(uaddr_len); ! 1106: /* check this error. */ ! 1107: if (len < sizeof (sin)) return (-EINVAL); ! 1108: verify_area (uaddr, len); ! 1109: sin.sin_family=AF_INET; ! 1110: sk = sock->data; ! 1111: if (sk == NULL) ! 1112: { ! 1113: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1114: return (0); ! 1115: } ! 1116: if (peer) ! 1117: { ! 1118: if (sk->state != TCP_ESTABLISHED) ! 1119: return (-ENOTCONN); ! 1120: sin.sin_port = sk->dummy_th.dest; ! 1121: sin.sin_addr.s_addr = sk->daddr; ! 1122: } ! 1123: else ! 1124: { ! 1125: sin.sin_port = sk->dummy_th.source; ! 1126: sin.sin_addr.s_addr = sk->saddr; ! 1127: } ! 1128: len = sizeof (sin); ! 1129: memcpy_tofs(uaddr, &sin, sizeof (sin)); ! 1130: put_fs_long (len, uaddr_len); ! 1131: return (0); ! 1132: } ! 1133: ! 1134: static int ! 1135: ip_proto_read (struct socket *sock, char *ubuf, int size, int noblock) ! 1136: { ! 1137: volatile struct sock *sk; ! 1138: sk = sock->data; ! 1139: if (sk == NULL) ! 1140: { ! 1141: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1142: return (0); ! 1143: } ! 1144: if (sk->shutdown & RCV_SHUTDOWN) ! 1145: return (-EIO); ! 1146: return (sk->prot->read (sk, ubuf, size, noblock,0)); ! 1147: } ! 1148: ! 1149: static int ! 1150: ip_proto_recv (struct socket *sock, void *ubuf, int size, int noblock, ! 1151: unsigned flags) ! 1152: { ! 1153: volatile struct sock *sk; ! 1154: sk = sock->data; ! 1155: if (sk == NULL) ! 1156: { ! 1157: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1158: return (0); ! 1159: } ! 1160: if (sk->shutdown & RCV_SHUTDOWN) ! 1161: return (-EIO); ! 1162: return (sk->prot->read (sk, ubuf, size, noblock, flags)); ! 1163: } ! 1164: ! 1165: static int ! 1166: ip_proto_write (struct socket *sock, char *ubuf, int size, int noblock) ! 1167: { ! 1168: volatile struct sock *sk; ! 1169: sk = sock->data; ! 1170: if (sk == NULL) ! 1171: { ! 1172: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1173: return (0); ! 1174: } ! 1175: if (sk->shutdown & SEND_SHUTDOWN) ! 1176: return (-EIO); ! 1177: return (sk->prot->write (sk, ubuf, size, noblock, 0)); ! 1178: } ! 1179: ! 1180: ! 1181: static int ! 1182: ip_proto_send (struct socket *sock, void *ubuf, int size, int noblock, ! 1183: unsigned flags) ! 1184: { ! 1185: volatile struct sock *sk; ! 1186: sk = sock->data; ! 1187: if (sk == NULL) ! 1188: { ! 1189: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1190: return (0); ! 1191: } ! 1192: if (sk->shutdown & SEND_SHUTDOWN) ! 1193: return (-EIO); ! 1194: return (sk->prot->write (sk, ubuf, size, noblock, flags)); ! 1195: } ! 1196: ! 1197: ! 1198: static int ! 1199: ip_proto_sendto (struct socket *sock, void *ubuf, int size, int noblock, ! 1200: unsigned flags, struct sockaddr *sin, int addr_len ) ! 1201: { ! 1202: volatile struct sock *sk; ! 1203: sk = sock->data; ! 1204: if (sk == NULL) ! 1205: { ! 1206: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1207: return (0); ! 1208: } ! 1209: if (sk->shutdown & SEND_SHUTDOWN) ! 1210: return (-EIO); ! 1211: if (sk->prot->sendto == NULL) return (-EOPNOTSUPP); ! 1212: return (sk->prot->sendto (sk, ubuf, size, noblock, flags, ! 1213: (struct sockaddr_in *)sin, addr_len)); ! 1214: } ! 1215: ! 1216: static int ! 1217: ip_proto_recvfrom (struct socket *sock, void *ubuf, int size, int noblock, ! 1218: unsigned flags, struct sockaddr *sin, int *addr_len ) ! 1219: { ! 1220: volatile struct sock *sk; ! 1221: sk = sock->data; ! 1222: if (sk == NULL) ! 1223: { ! 1224: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1225: return (0); ! 1226: } ! 1227: if (sk->shutdown & RCV_SHUTDOWN) ! 1228: return (-EIO); ! 1229: if (sk->prot->recvfrom == NULL) return (-EOPNOTSUPP); ! 1230: return (sk->prot->recvfrom (sk, ubuf, size, noblock, flags, ! 1231: (struct sockaddr_in*)sin, addr_len)); ! 1232: } ! 1233: ! 1234: static int ! 1235: ip_proto_shutdown (struct socket *sock, int how) ! 1236: { ! 1237: volatile struct sock *sk; ! 1238: /* this should really check to make sure the socket is ! 1239: a tcp socket. */ ! 1240: how++; /* maps 0->1 has the advantage of making bit 1 rcvs and ! 1241: 1->2 bit 2 snds. ! 1242: 2->3 */ ! 1243: if (how & ~SHUTDOWN_MASK) return (-EINVAL); ! 1244: sk = sock->data; ! 1245: if (sk == NULL) ! 1246: { ! 1247: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1248: return (0); ! 1249: } ! 1250: if (sk->state != TCP_ESTABLISHED) return (-ENOTCONN); ! 1251: sk->shutdown |= how; ! 1252: return (0); ! 1253: } ! 1254: ! 1255: static int ! 1256: ip_proto_select (struct socket *sock, int sel_type, select_table *wait ) ! 1257: { ! 1258: volatile struct sock *sk; ! 1259: sk = sock->data; ! 1260: if (sk == NULL) ! 1261: { ! 1262: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1263: return (0); ! 1264: } ! 1265: ! 1266: if (sk->prot->select == NULL) ! 1267: { ! 1268: PRINTK ("select on non-selectable socket. \n"); ! 1269: return (0); ! 1270: } ! 1271: return (sk->prot->select(sk, sel_type, wait)); ! 1272: } ! 1273: ! 1274: /* these should be distributed to the different protocol routines. */ ! 1275: static int ! 1276: ip_proto_ioctl (struct socket *sock, unsigned int cmd, ! 1277: unsigned long arg) ! 1278: { ! 1279: volatile struct sock *sk; ! 1280: sk = sock->data; ! 1281: if (sk == NULL) ! 1282: { ! 1283: printk ("Warning: sock->data = NULL: %d\n" ,__LINE__); ! 1284: return (0); ! 1285: } ! 1286: ! 1287: PRINTK ("in ip_proto_ioctl\n"); ! 1288: switch (cmd) ! 1289: { ! 1290: ! 1291: case IP_SET_DEV: ! 1292: if (!suser()) ! 1293: return (-EPERM); ! 1294: return (ip_set_dev((struct ip_config *)arg)); ! 1295: #if 0 ! 1296: case IP_ADD_ROUTE: ! 1297: ip_add_route ((struct rtable *) arg); ! 1298: return (0); ! 1299: #endif ! 1300: default: ! 1301: if (!sk->prot->ioctl) ! 1302: return (-EINVAL); ! 1303: return (sk->prot->ioctl (sk, cmd, arg)); ! 1304: } ! 1305: } ! 1306: ! 1307: #ifdef MEM_DEBUG ! 1308: ! 1309: struct mem ! 1310: { ! 1311: unsigned long check; ! 1312: struct mem *other; ! 1313: unsigned long len; ! 1314: unsigned short buff[10]; ! 1315: }; ! 1316: ! 1317: static void ! 1318: print_mem (struct mem *m) ! 1319: { ! 1320: int i; ! 1321: MPRINTK("mem:\n"); ! 1322: MPRINTK(" check=%X, other = %X\n", m->check, m->other); ! 1323: MPRINTK(" len=%d buff:\n " , m->len); ! 1324: for (i = 0; i < 10; i++) ! 1325: { ! 1326: MPRINTK ("0x%02X ",m->buff[i]); ! 1327: } ! 1328: MPRINTK ("\n"); ! 1329: } ! 1330: ! 1331: static void * ! 1332: smalloc (unsigned long size) ! 1333: { ! 1334: struct mem *head, *tail; ! 1335: static unsigned short count; ! 1336: int i; ! 1337: int sum; ! 1338: unsigned char *ptr; ! 1339: ! 1340: MPRINTK ("smalloc (size = %d)\n",size); ! 1341: head = malloc (size + 2*sizeof (*head)); ! 1342: if (head == NULL) return (NULL); ! 1343: tail = (struct mem *)((unsigned char *)(head+1) + size); ! 1344: ! 1345: head->other = tail; ! 1346: tail->other = head; ! 1347: ! 1348: tail->len = size; ! 1349: head->len = size; ! 1350: for (i = 0; i < 10; i++) ! 1351: { ! 1352: tail->buff[i]=count++; ! 1353: head->buff[i]=count; ! 1354: } ! 1355: ! 1356: ptr = (unsigned char *)head; ! 1357: head->check = 0; ! 1358: sum = 0; ! 1359: ! 1360: for (i = 0; i < sizeof (*head); i ++) ! 1361: { ! 1362: sum+= ptr[i]; ! 1363: } ! 1364: ! 1365: head->check = ~sum; ! 1366: ptr = (unsigned char *)tail; ! 1367: tail->check = 0; ! 1368: sum = 0; ! 1369: ! 1370: for (i = 0; i < sizeof (*head); i ++) ! 1371: { ! 1372: sum+= ptr[i]; ! 1373: } ! 1374: ! 1375: tail->check = ~sum; ! 1376: MPRINTK ("head = %X:\n", head); ! 1377: print_mem(head); ! 1378: MPRINTK ("tail = %X:\n", tail); ! 1379: print_mem(tail); ! 1380: return (head+1); ! 1381: } ! 1382: ! 1383: void ! 1384: sfree (void *data, unsigned long len) ! 1385: { ! 1386: int i; ! 1387: int sum; ! 1388: int csum; ! 1389: unsigned char *ptr; ! 1390: int bad = 0; ! 1391: struct mem *head, *tail; ! 1392: MPRINTK ("sfree(data=%X, len = %d)\n", data, len); ! 1393: head = data; ! 1394: head--; ! 1395: tail = (struct mem *)((unsigned char *)(head+1) + len); ! 1396: print_mem (head); ! 1397: print_mem (tail); ! 1398: if (head->other != tail) ! 1399: { ! 1400: MPRINTK ("sfree: head->other != tail:\n"); ! 1401: bad = 1; ! 1402: } ! 1403: if (tail->other != head) ! 1404: { ! 1405: MPRINTK ("sfree: tail->other != head:\n"); ! 1406: bad =1 ; ! 1407: } ! 1408: if (head ->len != len) ! 1409: { ! 1410: MPRINTK ("sfree: head->len != len"); ! 1411: bad = 1; ! 1412: } ! 1413: if (tail ->len != len) ! 1414: { ! 1415: MPRINTK ("sfree: tail->len != len"); ! 1416: bad = 1; ! 1417: } ! 1418: csum = head->check; ! 1419: ptr = (unsigned char *)head; ! 1420: head->check = 0; ! 1421: sum = 0; ! 1422: for (i = 0; i < sizeof (*head); i ++) ! 1423: { ! 1424: sum+= ptr[i]; ! 1425: } ! 1426: if (csum != ~sum) ! 1427: { ! 1428: MPRINTK ("sfree: head failed checksum\n"); ! 1429: bad = 1; ! 1430: } ! 1431: csum = tail->check; ! 1432: ptr = (unsigned char *)tail; ! 1433: tail->check = 0; ! 1434: sum = 0; ! 1435: for (i = 0; i < sizeof (*head); i ++) ! 1436: { ! 1437: sum+= ptr[i]; ! 1438: } ! 1439: if (csum != ~sum) ! 1440: { ! 1441: MPRINTK ("sfree: tail failed checksum\n"); ! 1442: bad = 1; ! 1443: } ! 1444: if (!bad) ! 1445: free_s (head, len+2*sizeof (*head)); ! 1446: else ! 1447: schedule(); ! 1448: } ! 1449: #else ! 1450: static void * ! 1451: smalloc (unsigned long size) ! 1452: { ! 1453: return (malloc (size)); ! 1454: } ! 1455: static void ! 1456: sfree(void *data, unsigned long len) ! 1457: { ! 1458: free_s(data,len); ! 1459: } ! 1460: #endif ! 1461: ! 1462: void * ! 1463: sock_wmalloc(volatile struct sock *sk, unsigned long size, int force) ! 1464: { ! 1465: void *tmp; ! 1466: if (sk) ! 1467: { ! 1468: if (sk->wmem_alloc + size >= SK_WMEM_MAX && !force) ! 1469: { ! 1470: MPRINTK ("sock_wmalloc(%X,%d,%d) returning NULL\n", ! 1471: sk, size, force); ! 1472: return (NULL); ! 1473: } ! 1474: cli(); ! 1475: sk->wmem_alloc+= size; ! 1476: sti(); ! 1477: } ! 1478: if (sk) ! 1479: tmp = smalloc (size); ! 1480: else ! 1481: tmp = malloc (size); ! 1482: ! 1483: MPRINTK ("sock_wmalloc(%X,%d,%d) returning %X\n",sk, size, force, tmp); ! 1484: return (tmp); ! 1485: } ! 1486: ! 1487: void * ! 1488: sock_rmalloc(volatile struct sock *sk, unsigned long size, int force) ! 1489: { ! 1490: struct mem *tmp; ! 1491: if (sk ) ! 1492: { ! 1493: if (sk->rmem_alloc + size >= SK_RMEM_MAX && !force) ! 1494: { ! 1495: MPRINTK ("sock_rmalloc(%X,%d,%d) returning NULL\n",sk,size,force); ! 1496: return (NULL); ! 1497: } ! 1498: cli(); ! 1499: sk->rmem_alloc+= size; ! 1500: sti(); ! 1501: } ! 1502: if (sk) ! 1503: tmp = smalloc (size); ! 1504: else ! 1505: tmp = malloc (size); ! 1506: ! 1507: MPRINTK ("sock_rmalloc(%X,%d,%d) returning %X\n",sk, size, force, tmp); ! 1508: return (tmp); ! 1509: } ! 1510: ! 1511: ! 1512: unsigned long ! 1513: sock_rspace (volatile struct sock *sk) ! 1514: { ! 1515: int amt; ! 1516: if (sk != NULL) ! 1517: { ! 1518: if (sk->rmem_alloc >= SK_RMEM_MAX-2*MIN_WINDOW) return (0); ! 1519: amt = min ((SK_RMEM_MAX-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW); ! 1520: if (amt < 0) return (0); ! 1521: return (amt); ! 1522: } ! 1523: return (0); ! 1524: } ! 1525: ! 1526: unsigned long ! 1527: sock_wspace (volatile struct sock *sk) ! 1528: { ! 1529: if (sk != NULL) ! 1530: { ! 1531: if (sk->shutdown & SEND_SHUTDOWN) return (0); ! 1532: if (sk->wmem_alloc >= SK_WMEM_MAX) return (0); ! 1533: return (SK_WMEM_MAX-sk->wmem_alloc ); ! 1534: } ! 1535: return (0); ! 1536: } ! 1537: ! 1538: ! 1539: void ! 1540: sock_wfree (volatile struct sock *sk, void *mem, unsigned long size) ! 1541: { ! 1542: MPRINTK ("sock_wfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size); ! 1543: if (sk) ! 1544: { ! 1545: sk->wmem_alloc -= size; ! 1546: sfree(mem,size); ! 1547: /* in case it might be waiting for more memory. */ ! 1548: if (!sk->dead && sk->wmem_alloc > SK_WMEM_MAX/2) wake_up(sk->sleep); ! 1549: if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) ! 1550: { ! 1551: MPRINTK ("recovered lost memory, destroying sock = %X\n",sk); ! 1552: delete_timer ((struct timer *)&sk->time_wait); ! 1553: free_s ((void *)sk, sizeof (*sk)); ! 1554: } ! 1555: } ! 1556: else ! 1557: { ! 1558: free_s (mem, size); ! 1559: } ! 1560: } ! 1561: ! 1562: void ! 1563: sock_rfree (volatile struct sock *sk, void *mem, unsigned long size) ! 1564: { ! 1565: MPRINTK ("sock_rfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size); ! 1566: if (sk) ! 1567: { ! 1568: sk->rmem_alloc -= size; ! 1569: sfree(mem,size); ! 1570: if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) ! 1571: { ! 1572: delete_timer ((struct timer *)&sk->time_wait); ! 1573: free_s ((void *)sk, sizeof (*sk)); ! 1574: } ! 1575: } ! 1576: else ! 1577: { ! 1578: free_s (mem, size); ! 1579: } ! 1580: } ! 1581: ! 1582: ! 1583: /* This routine must find a socket given a tcp header. Everyhting ! 1584: is assumed to be in net order. */ ! 1585: ! 1586: volatile struct sock *get_sock (struct proto *prot, unsigned short num, ! 1587: unsigned long raddr, ! 1588: unsigned short rnum, unsigned long laddr) ! 1589: { ! 1590: volatile struct sock *s; ! 1591: PRINTK ("get_sock (prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n", ! 1592: prot, num, raddr, rnum, laddr); ! 1593: ! 1594: /* SOCK_ARRAY_SIZE must be a power of two. This will work better ! 1595: than a prime unless 3 or more sockets end up using the same ! 1596: array entry. This should not be a problem because most ! 1597: well known sockets don't overlap that much, and for ! 1598: the other ones, we can just be careful about picking our ! 1599: socket number when we choose an arbitrary one. */ ! 1600: ! 1601: for (s=prot->sock_array[num&(SOCK_ARRAY_SIZE-1)]; s != NULL; s=s->next) ! 1602: { ! 1603: if (s->num == num) ! 1604: { ! 1605: /* we need to see if this is the socket that we want. */ ! 1606: if (!ip_addr_match (s->daddr, raddr)) ! 1607: continue; ! 1608: if (s->dummy_th.dest != rnum && s->dummy_th.dest != 0) ! 1609: continue; ! 1610: if (!ip_addr_match (s->saddr, laddr)) ! 1611: continue; ! 1612: return (s); ! 1613: } ! 1614: } ! 1615: return (NULL); ! 1616: } ! 1617: ! 1618: void release_sock (volatile struct sock *sk) ! 1619: { ! 1620: if (sk->blog) return; ! 1621: /* see if we have any packets built up. */ ! 1622: ! 1623: cli(); ! 1624: sk->inuse = 1; ! 1625: while (sk->back_log != NULL) ! 1626: { ! 1627: struct sk_buff *skb; ! 1628: sk->blog = 1; ! 1629: skb = sk->back_log; ! 1630: PRINTK ("release_sock: skb = %X:\n",skb); ! 1631: print_skb(skb); ! 1632: if (skb->next != skb) ! 1633: { ! 1634: sk->back_log = skb->next; ! 1635: skb->prev->next = skb->next; ! 1636: skb->next->prev = skb->prev; ! 1637: } ! 1638: else ! 1639: { ! 1640: sk->back_log = NULL; ! 1641: } ! 1642: sti(); ! 1643: PRINTK ("sk->back_log = %X\n",sk->back_log); ! 1644: if (sk->prot->rcv) ! 1645: sk->prot->rcv(skb, skb->dev, sk->opt, ! 1646: skb->saddr, skb->len, skb->daddr, 1, ! 1647: /* only used for/by raw sockets. */ ! 1648: (struct ip_protocol *)sk->pair); ! 1649: cli(); ! 1650: } ! 1651: sk->blog = 0; ! 1652: sk->inuse = 0; ! 1653: sti(); ! 1654: if (sk->dead && sk->state == TCP_CLOSE) ! 1655: { ! 1656: /* should be about 2 rtt's */ ! 1657: sk->time_wait.len = min (sk->rtt * 2, TCP_DONE_TIME); ! 1658: sk->timeout = TIME_DONE; ! 1659: reset_timer ((struct timer *)&sk->time_wait); ! 1660: } ! 1661: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.