root/net/inet/sock.c

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

DEFINITIONS

This source file includes following definitions.
  1. print_sk
  2. print_skb
  3. sk_inuse
  4. get_new_socknum
  5. put_sock
  6. remove_sock
  7. destroy_sock
  8. inet_fcntl
  9. inet_setsockopt
  10. inet_getsockopt
  11. inet_listen
  12. inet_create
  13. inet_dup
  14. inet_release
  15. inet_bind
  16. inet_connect
  17. inet_socketpair
  18. inet_accept
  19. inet_getname
  20. inet_read
  21. inet_recv
  22. inet_write
  23. inet_send
  24. inet_sendto
  25. inet_recvfrom
  26. inet_shutdown
  27. inet_select
  28. inet_ioctl
  29. sock_wmalloc
  30. sock_rmalloc
  31. sock_rspace
  32. sock_wspace
  33. sock_wfree
  34. sock_rfree
  35. get_sock
  36. release_sock
  37. inet_fioctl
  38. inet_proto_init

   1 /*
   2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3  *              operating system.  INET is implemented using the  BSD Socket
   4  *              interface as the means of communication with the user level.
   5  *
   6  *              SOCK - AF_INET protocol family socket handler.
   7  *
   8  * Version:     @(#)sock.c      1.0.17  06/02/93
   9  *
  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *              Florian La Roche, <flla@stud.uni-sb.de>
  13  *
  14  * Fixes:
  15  *              Alan Cox        :       Numerous verify_area() problems
  16  *              Alan Cox        :       Connecting on a connecting socket
  17  *                                      now returns an error for tcp.
  18  *              Alan Cox        :       sock->protocol is set correctly.
  19  *                                      and is not sometimes left as 0.
  20  *              Alan Cox        :       connect handles icmp errors on a
  21  *                                      connect properly. Unfortunately there
  22  *                                      is a restart syscall nasty there. I
  23  *                                      can't match BSD without hacking the C
  24  *                                      library. Ideas urgently sought!
  25  *              Alan Cox        :       Disallow bind() to addresses that are
  26  *                                      not ours - especially broadcast ones!!
  27  *              Alan Cox        :       Socket 1024 _IS_ ok for users. (fencepost)
  28  *              Alan Cox        :       sock_wfree/sock_rfree don't destroy sockets,
  29  *                                      instead they leave that for the DESTROY timer.
  30  *              Alan Cox        :       Clean up error flag in accept
  31  *              Alan Cox        :       TCP ack handling is buggy, the DESTROY timer
  32  *                                      was buggy. Put a remove_sock() in the handler
  33  *                                      for memory when we hit 0. Also altered the timer
  34  *                                      code. The ACK stuff can wait and needs major 
  35  *                                      TCP layer surgery.
  36  *              Alan Cox        :       Fixed TCP ack bug, removed remove sock
  37  *                                      and fixed timer/inet_bh race.
  38  *              Alan Cox        :       Added zapped flag for TCP
  39  *              Alan Cox        :       Move kfree_skb into skbuff.c and tidied up surplus code
  40  *              Alan Cox        :       for new sk_buff allocations wmalloc/rmalloc now call alloc_skb
  41  *              Alan Cox        :       kfree_s calls now are kfree_skbmem so we can track skb resources
  42  *              Alan Cox        :       Supports socket option broadcast now as does udp. Packet and raw need fixing.
  43  *              Alan Cox        :       Added RCVBUF,SNDBUF size setting. It suddenely occured to me how easy it was so...
  44  *              Rick Sladkey    :       Relaxed UDP rules for matching packets.
  45  *              C.E.Hawkins     :       IFF_PROMISC/SIOCGHWADDR support
  46  *      Pauline Middelink       :       Pidentd support
  47  *              Alan Cox        :       Fixed connect() taking signals I think.
  48  *              Alan Cox        :       SO_LINGER supported
  49  *
  50  * To Fix:
  51  *
  52  *
  53  *              This program is free software; you can redistribute it and/or
  54  *              modify it under the terms of the GNU General Public License
  55  *              as published by the Free Software Foundation; either version
  56  *              2 of the License, or (at your option) any later version.
  57  */
  58 
  59 #include <linux/config.h>
  60 #include <linux/errno.h>
  61 #include <linux/types.h>
  62 #include <linux/socket.h>
  63 #include <linux/in.h>
  64 #include <linux/kernel.h>
  65 #include <linux/major.h>
  66 #include <linux/sched.h>
  67 #include <linux/timer.h>
  68 #include <linux/string.h>
  69 #include <linux/sockios.h>
  70 #include <linux/net.h>
  71 #include <linux/fcntl.h>
  72 #include <linux/mm.h>
  73 #include <linux/interrupt.h>
  74 
  75 #include <asm/segment.h>
  76 #include <asm/system.h>
  77 
  78 #include "inet.h"
  79 #include "dev.h"
  80 #include "ip.h"
  81 #include "protocol.h"
  82 #include "arp.h"
  83 #include "route.h"
  84 #include "tcp.h"
  85 #include "udp.h"
  86 #include "skbuff.h"
  87 #include "sock.h"
  88 #include "raw.h"
  89 #include "icmp.h"
  90 
  91 
  92 int inet_debug = DBG_OFF;               /* INET module debug flag       */
  93 
  94 
  95 #define min(a,b)        ((a)<(b)?(a):(b))
  96 
  97 extern struct proto packet_prot;
  98 
  99 
 100 void
 101 print_sk(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103   if (!sk) {
 104         printk("  print_sk(NULL)\n");
 105         return;
 106   }
 107   printk("  wmem_alloc = %lu\n", sk->wmem_alloc);
 108   printk("  rmem_alloc = %lu\n", sk->rmem_alloc);
 109   printk("  send_head = %p\n", sk->send_head);
 110   printk("  state = %d\n",sk->state);
 111   printk("  wback = %p, rqueue = %p\n", sk->wback, sk->rqueue);
 112   printk("  wfront = %p\n", sk->wfront);
 113   printk("  daddr = %lX, saddr = %lX\n", sk->daddr,sk->saddr);
 114   printk("  num = %d", sk->num);
 115   printk(" next = %p\n", sk->next);
 116   printk("  send_seq = %ld, acked_seq = %ld, copied_seq = %ld\n",
 117           sk->send_seq, sk->acked_seq, sk->copied_seq);
 118   printk("  rcv_ack_seq = %ld, window_seq = %ld, fin_seq = %ld\n",
 119           sk->rcv_ack_seq, sk->window_seq, sk->fin_seq);
 120   printk("  prot = %p\n", sk->prot);
 121   printk("  pair = %p, back_log = %p\n", sk->pair,sk->back_log);
 122   printk("  inuse = %d , blog = %d\n", sk->inuse, sk->blog);
 123   printk("  dead = %d delay_acks=%d\n", sk->dead, sk->delay_acks);
 124   printk("  retransmits = %ld, timeout = %d\n", sk->retransmits, sk->timeout);
 125   printk("  cong_window = %d, packets_out = %d\n", sk->cong_window,
 126           sk->packets_out);
 127   printk("  urg = %d shutdown=%d\n", sk->urg, sk->shutdown);
 128 }
 129 
 130 
 131 void
 132 print_skb(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134   if (!skb) {
 135         printk("  print_skb(NULL)\n");
 136         return;
 137   }
 138   printk("  prev = %p, next = %p\n", skb->prev, skb->next);
 139   printk("  sk = %p link3 = %p\n", skb->sk, skb->link3);
 140   printk("  mem_addr = %p, mem_len = %lu\n", skb->mem_addr, skb->mem_len);
 141   printk("  used = %d free = %d\n", skb->used,skb->free);
 142 }
 143 
 144 
 145 
 146 static int
 147 sk_inuse(struct proto *prot, int num)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149   struct sock *sk;
 150 
 151   for(sk = prot->sock_array[num & (SOCK_ARRAY_SIZE -1 )];
 152       sk != NULL;
 153       sk=sk->next) {
 154         if (sk->num == num) return(1);
 155   }
 156   return(0);
 157 }
 158 
 159 
 160 unsigned short
 161 get_new_socknum(struct proto *prot, unsigned short base)
     /* [previous][next][first][last][top][bottom][index][help] */
 162 {
 163   static int start=0;
 164 
 165   /*
 166    * Used to cycle through the port numbers so the
 167    * chances of a confused connection drop.
 168    */
 169   int i, j;
 170   int best = 0;
 171   int size = 32767; /* a big num. */
 172   struct sock *sk;
 173 
 174   if (base == 0) base = PROT_SOCK+1+(start % 1024);
 175   if (base <= PROT_SOCK) {
 176         base += PROT_SOCK+(start % 1024);
 177   }
 178 
 179   /* Now look through the entire array and try to find an empty ptr. */
 180   for(i=0; i < SOCK_ARRAY_SIZE; i++) {
 181         j = 0;
 182         sk = prot->sock_array[(i+base+1) &(SOCK_ARRAY_SIZE -1)];
 183         while(sk != NULL) {
 184                 sk = sk->next;
 185                 j++;
 186         }
 187         if (j == 0) {
 188                 start =(i+1+start )%1024;
 189                 DPRINTF((DBG_INET, "get_new_socknum returning %d, start = %d\n",
 190                                                         i + base + 1, start));
 191                 return(i+base+1);
 192         }
 193         if (j < size) {
 194                 best = i;
 195                 size = j;
 196         }
 197   }
 198 
 199   /* Now make sure the one we want is not in use. */
 200   while(sk_inuse(prot, base +best+1)) {
 201         best += SOCK_ARRAY_SIZE;
 202   }
 203   DPRINTF((DBG_INET, "get_new_socknum returning %d, start = %d\n",
 204                                                 best + base + 1, start));
 205   return(best+base+1);
 206 }
 207 
 208 
 209 void
 210 put_sock(unsigned short num, struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212   struct sock *sk1;
 213   struct sock *sk2;
 214   int mask;
 215 
 216   DPRINTF((DBG_INET, "put_sock(num = %d, sk = %X\n", num, sk));
 217   sk->num = num;
 218   sk->next = NULL;
 219   num = num &(SOCK_ARRAY_SIZE -1);
 220 
 221   /* We can't have an interupt re-enter here. */
 222   cli();
 223   if (sk->prot->sock_array[num] == NULL) {
 224         sk->prot->sock_array[num] = sk;
 225         sti();
 226         return;
 227   }
 228   sti();
 229   for(mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask) {
 230         if ((mask & sk->saddr) &&
 231             (mask & sk->saddr) != (mask & 0xffffffff)) {
 232                 mask = mask << 8;
 233                 break;
 234         }
 235   }
 236   DPRINTF((DBG_INET, "mask = %X\n", mask));
 237 
 238   cli();
 239   sk1 = sk->prot->sock_array[num];
 240   for(sk2 = sk1; sk2 != NULL; sk2=sk2->next) {
 241         if (!(sk2->saddr & mask)) {
 242                 if (sk2 == sk1) {
 243                         sk->next = sk->prot->sock_array[num];
 244                         sk->prot->sock_array[num] = sk;
 245                         sti();
 246                         return;
 247                 }
 248                 sk->next = sk2;
 249                 sk1->next= sk;
 250                 sti();
 251                 return;
 252         }
 253         sk1 = sk2;
 254   }
 255 
 256   /* Goes at the end. */
 257   sk->next = NULL;
 258   sk1->next = sk;
 259   sti();
 260 }
 261 
 262 
 263 static void
 264 remove_sock(struct sock *sk1)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266   struct sock *sk2;
 267 
 268   DPRINTF((DBG_INET, "remove_sock(sk1=%X)\n", sk1));
 269   if (!sk1) {
 270         printk("sock.c: remove_sock: sk1 == NULL\n");
 271         return;
 272   }
 273 
 274   if (!sk1->prot) {
 275         printk("sock.c: remove_sock: sk1->prot == NULL\n");
 276         return;
 277   }
 278 
 279   /* We can't have this changing out from under us. */
 280   cli();
 281   sk2 = sk1->prot->sock_array[sk1->num &(SOCK_ARRAY_SIZE -1)];
 282   if (sk2 == sk1) {
 283         sk1->prot->sock_array[sk1->num &(SOCK_ARRAY_SIZE -1)] = sk1->next;
 284         sti();
 285         return;
 286   }
 287 
 288   while(sk2 && sk2->next != sk1) {
 289         sk2 = sk2->next;
 290   }
 291 
 292   if (sk2) {
 293         sk2->next = sk1->next;
 294         sti();
 295         return;
 296   }
 297   sti();
 298 
 299   if (sk1->num != 0) DPRINTF((DBG_INET, "remove_sock: sock not found.\n"));
 300 }
 301 
 302 
 303 void
 304 destroy_sock(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 305 {
 306         struct sk_buff *skb;
 307 
 308         DPRINTF((DBG_INET, "destroying socket %X\n", sk));
 309         sk->inuse = 1;                  /* just to be safe. */
 310 
 311         /* Incase it's sleeping somewhere. */
 312         if (!sk->dead) 
 313                 wake_up(sk->sleep);
 314 
 315         remove_sock(sk);
 316   
 317         /* Now we can no longer get new packets. */
 318         delete_timer(sk);
 319 
 320 
 321         if (sk->send_tmp != NULL) 
 322         {
 323                 IS_SKB(sk->send_tmp);
 324                 kfree_skb(sk->send_tmp, FREE_WRITE);
 325         }
 326 
 327   /* Cleanup up the write buffer. */
 328         for(skb = sk->wfront; skb != NULL; ) 
 329         {
 330                 struct sk_buff *skb2;
 331 
 332                 skb2=(struct sk_buff *)skb->next;
 333                 if (skb->magic != TCP_WRITE_QUEUE_MAGIC) {
 334                         printk("sock.c:destroy_sock write queue with bad magic(%X)\n",
 335                                                                 skb->magic);
 336                         break;
 337                 }
 338                 IS_SKB(skb);
 339                 kfree_skb(skb, FREE_WRITE);
 340                 skb = skb2;
 341         }
 342 
 343         sk->wfront = NULL;
 344         sk->wback = NULL;
 345 
 346         if (sk->rqueue != NULL) 
 347         {
 348                 while((skb=skb_dequeue(&sk->rqueue))!=NULL)
 349                 {
 350                 /*
 351                  * This will take care of closing sockets that were
 352                  * listening and didn't accept everything.
 353                  */
 354                         if (skb->sk != NULL && skb->sk != sk) 
 355                         {
 356                                 IS_SKB(skb);
 357                                 skb->sk->dead = 1;
 358                                 skb->sk->prot->close(skb->sk, 0);
 359                         }
 360                         IS_SKB(skb);
 361                         kfree_skb(skb, FREE_READ);
 362                 }
 363         }
 364         sk->rqueue = NULL;
 365 
 366   /* Now we need to clean up the send head. */
 367         for(skb = sk->send_head; skb != NULL; ) 
 368         {
 369                 struct sk_buff *skb2;
 370 
 371                 /*
 372                  * We need to remove skb from the transmit queue,
 373                  * or maybe the arp queue.
 374                  */
 375                 cli();
 376                 /* see if it's in a transmit queue. */
 377                 /* this can be simplified quite a bit.  Look */
 378                 /* at tcp.c:tcp_ack to see how. */
 379                 if (skb->next != NULL) 
 380                 {
 381                         IS_SKB(skb);
 382                         skb_unlink(skb);
 383                 }
 384                 skb->dev = NULL;
 385                 sti();
 386                 skb2 = (struct sk_buff *)skb->link3;
 387                 kfree_skb(skb, FREE_WRITE);
 388                 skb = skb2;
 389         }       
 390         sk->send_head = NULL;
 391 
 392         /* And now the backlog. */
 393         if (sk->back_log != NULL) 
 394         {
 395                 /* this should never happen. */
 396                 printk("cleaning back_log. \n");
 397                 cli();
 398                 skb = (struct sk_buff *)sk->back_log;
 399                 do 
 400                 {
 401                         struct sk_buff *skb2;
 402         
 403                         skb2 = (struct sk_buff *)skb->next;
 404                         kfree_skb(skb, FREE_READ);
 405                         skb = skb2;
 406                 }
 407                 while(skb != sk->back_log);
 408                 sti();
 409         }
 410         sk->back_log = NULL;
 411 
 412   /* Now if it has a half accepted/ closed socket. */
 413         if (sk->pair) 
 414         {
 415                 sk->pair->dead = 1;
 416                 sk->pair->prot->close(sk->pair, 0);
 417                 sk->pair = NULL;
 418         }
 419 
 420   /*
 421    * Now if everything is gone we can free the socket
 422    * structure, otherwise we need to keep it around until
 423    * everything is gone.
 424    */
 425           if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
 426           {
 427                 kfree_s((void *)sk,sizeof(*sk));
 428           } 
 429           else 
 430           {
 431                 /* this should never happen. */
 432                 /* actually it can if an ack has just been sent. */
 433                 DPRINTF((DBG_INET, "possible memory leak in socket = %X\n", sk));
 434                 sk->destroy = 1;
 435                 sk->ack_backlog = 0;
 436                 sk->inuse = 0;
 437                 reset_timer(sk, TIME_DESTROY, SOCK_DESTROY_TIME);
 438         }
 439         DPRINTF((DBG_INET, "leaving destroy_sock\n"));
 440 }
 441 
 442 
 443 static int
 444 inet_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 445 {
 446   struct sock *sk;
 447 
 448   sk = (struct sock *) sock->data;
 449   if (sk == NULL) {
 450         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
 451         return(0);
 452   }
 453 
 454   switch(cmd) {
 455         case F_SETOWN:
 456                 /*
 457                  * This is a little restrictive, but it's the only
 458                  * way to make sure that you can't send a sigurg to
 459                  * another process.
 460                  */
 461                 if (!suser() && current->pgrp != -arg &&
 462                                 current->pid != arg) return(-EPERM);
 463                 sk->proc = arg;
 464                 return(0);
 465         case F_GETOWN:
 466                 return(sk->proc);
 467         default:
 468                 return(-EINVAL);
 469   }
 470 }
 471 
 472 
 473 static int
 474 inet_setsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 475                     char *optval, int optlen)
 476 {
 477   struct sock *sk;
 478   int val;
 479   int err;
 480   struct linger ling;
 481   
 482   /* This should really pass things on to the other levels. */
 483   if (level != SOL_SOCKET) return(-EOPNOTSUPP);
 484 
 485   sk = (struct sock *) sock->data;
 486   if (sk == NULL) {
 487         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
 488         return(0);
 489   }
 490   if (optval == NULL) return(-EINVAL);
 491 
 492   err=verify_area(VERIFY_READ, optval, sizeof(int));
 493   if(err)
 494         return err;
 495         
 496   val = get_fs_long((unsigned long *)optval);
 497   switch(optname) {
 498         case SO_TYPE:
 499         case SO_ERROR:
 500                 return(-ENOPROTOOPT);
 501 
 502         case SO_DEBUG:  
 503                 sk->debug=val?1:0;
 504         case SO_DONTROUTE:      /* Still to be implemented */
 505                 return(0);
 506         case SO_BROADCAST:
 507                 sk->broadcast=val?1:0;
 508                 return 0;
 509         case SO_SNDBUF:
 510                 if(val>32767)
 511                         val=32767;
 512                 if(val<256)
 513                         val=256;
 514                 sk->sndbuf=val;
 515                 return 0;
 516         case SO_LINGER:
 517                 err=verify_area(VERIFY_READ,optval,sizeof(ling));
 518                 if(err)
 519                         return err;
 520                 memcpy_fromfs(&ling,optval,sizeof(ling));
 521                 if(ling.l_onoff==0)
 522                         sk->linger=0;
 523                 else
 524                 {
 525                         sk->lingertime=ling.l_linger;
 526                         sk->linger=1;
 527                 }
 528                 return 0;
 529         case SO_RCVBUF:
 530                 if(val>32767)
 531                         val=32767;
 532                 if(val<256)
 533                         val=256;
 534                 sk->rcvbuf=val;
 535                 return(0);
 536 
 537         case SO_REUSEADDR:
 538                 if (val) sk->reuse = 1;
 539                   else sk->reuse = 0;
 540                 return(0);
 541 
 542         case SO_KEEPALIVE:
 543                 if (val) sk->keepopen = 1;
 544                   else sk->keepopen = 0;
 545                 return(0);
 546 
 547          case SO_OOBINLINE:
 548                 if (val) sk->urginline = 1;
 549                   else sk->urginline = 0;
 550                 return(0);
 551 
 552          case SO_NO_CHECK:
 553                 if (val) sk->no_check = 1;
 554                   else sk->no_check = 0;
 555                 return(0);
 556 
 557          case SO_PRIORITY:
 558                 if (val >= 0 && val < DEV_NUMBUFFS) {
 559                         sk->priority = val;
 560                 } else {
 561                         return(-EINVAL);
 562                 }
 563                 return(0);
 564 
 565         default:
 566                 return(-ENOPROTOOPT);
 567   }
 568 }
 569 
 570 
 571 static int
 572 inet_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 573                     char *optval, int *optlen)
 574 {
 575   struct sock *sk;
 576   int val;
 577   int err;
 578   struct linger ling;
 579   
 580   /* This should really pass things on to the other levels. */
 581   if (level != SOL_SOCKET) return(-EOPNOTSUPP);
 582 
 583   sk = (struct sock *) sock->data;
 584   if (sk == NULL) {
 585         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
 586         return(0);
 587   }
 588 
 589   switch(optname) {
 590         case SO_DEBUG:          
 591                 val = sk->debug;
 592                 break;
 593                 
 594         case SO_DONTROUTE:      /* One last option to implement */
 595                 val = 0;
 596                 break;
 597                 
 598         case SO_BROADCAST:
 599                 val= sk->broadcast;
 600                 break;
 601                 
 602         case SO_LINGER:
 603                 
 604                 err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
 605                 if(err)
 606                         return err;
 607                 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
 608                 if(err)
 609                         return err;
 610                 put_fs_long(sizeof(ling),(unsigned long *)optlen);
 611                 ling.l_onoff=sk->linger;
 612                 ling.l_linger=sk->lingertime;
 613                 memcpy_tofs(optval,&ling,sizeof(ling));
 614                 return 0;
 615                 
 616         case SO_SNDBUF:
 617                 val=sk->sndbuf;
 618                 break;
 619                 
 620         case SO_RCVBUF:
 621                 val =sk->rcvbuf;
 622                 break;
 623 
 624         case SO_REUSEADDR:
 625                 val = sk->reuse;
 626                 break;
 627 
 628         case SO_KEEPALIVE:
 629                 val = sk->keepopen;
 630                 break;
 631 
 632         case SO_TYPE:
 633                 if (sk->prot == &tcp_prot) val = SOCK_STREAM;
 634                   else val = SOCK_DGRAM;
 635                 break;
 636 
 637         case SO_ERROR:
 638                 val = sk->err;
 639                 sk->err = 0;
 640                 break;
 641 
 642         case SO_OOBINLINE:
 643                 val = sk->urginline;
 644                 break;
 645 
 646         case SO_NO_CHECK:
 647                 val = sk->no_check;
 648                 break;
 649 
 650         case SO_PRIORITY:
 651                 val = sk->priority;
 652                 break;
 653 
 654         default:
 655                 return(-ENOPROTOOPT);
 656   }
 657   err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
 658   if(err)
 659         return err;
 660   put_fs_long(sizeof(int),(unsigned long *) optlen);
 661 
 662   err=verify_area(VERIFY_WRITE, optval, sizeof(int));
 663   if(err)
 664         return err;
 665   put_fs_long(val,(unsigned long *)optval);
 666 
 667   return(0);
 668 }
 669 
 670 
 671 static int
 672 inet_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 673 {
 674   struct sock *sk;
 675 
 676   sk = (struct sock *) sock->data;
 677   if (sk == NULL) {
 678         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
 679         return(0);
 680   }
 681 
 682   /* We may need to bind the socket. */
 683   if (sk->num == 0) {
 684         sk->num = get_new_socknum(sk->prot, 0);
 685         if (sk->num == 0) return(-EAGAIN);
 686         put_sock(sk->num, sk);
 687         sk->dummy_th.source = ntohs(sk->num);
 688   }
 689 
 690   /* We might as well re use these. */ 
 691   sk->max_ack_backlog = backlog;
 692   if (sk->state != TCP_LISTEN) {
 693         sk->ack_backlog = 0;
 694         sk->state = TCP_LISTEN;
 695   }
 696   return(0);
 697 }
 698 
 699 
 700 static int
 701 inet_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 702 {
 703   struct sock *sk;
 704   struct proto *prot;
 705   int err;
 706 
 707   sk = (struct sock *) kmalloc(sizeof(*sk), GFP_KERNEL);
 708   if (sk == NULL) 
 709         return(-ENOMEM);
 710   sk->num = 0;
 711 
 712   switch(sock->type) {
 713         case SOCK_STREAM:
 714         case SOCK_SEQPACKET:
 715                 if (protocol && protocol != IPPROTO_TCP) {
 716                         kfree_s((void *)sk, sizeof(*sk));
 717                         return(-EPROTONOSUPPORT);
 718                 }
 719                 protocol = IPPROTO_TCP;
 720                 sk->no_check = TCP_NO_CHECK;
 721                 prot = &tcp_prot;
 722                 break;
 723 
 724         case SOCK_DGRAM:
 725                 if (protocol && protocol != IPPROTO_UDP) {
 726                         kfree_s((void *)sk, sizeof(*sk));
 727                         return(-EPROTONOSUPPORT);
 728                 }
 729                 protocol = IPPROTO_UDP;
 730                 sk->no_check = UDP_NO_CHECK;
 731                 prot=&udp_prot;
 732                 break;
 733       
 734         case SOCK_RAW:
 735                 if (!suser()) {
 736                         kfree_s((void *)sk, sizeof(*sk));
 737                         return(-EPERM);
 738                 }
 739                 if (!protocol) {
 740                         kfree_s((void *)sk, sizeof(*sk));
 741                         return(-EPROTONOSUPPORT);
 742                 }
 743                 prot = &raw_prot;
 744                 sk->reuse = 1;
 745                 sk->no_check = 0;       /*
 746                                          * Doesn't matter no checksum is
 747                                          * preformed anyway.
 748                                          */
 749                 sk->num = protocol;
 750                 break;
 751 
 752         case SOCK_PACKET:
 753                 if (!suser()) {
 754                         kfree_s((void *)sk, sizeof(*sk));
 755                         return(-EPERM);
 756                 }
 757                 if (!protocol) {
 758                         kfree_s((void *)sk, sizeof(*sk));
 759                         return(-EPROTONOSUPPORT);
 760                 }
 761                 prot = &packet_prot;
 762                 sk->reuse = 1;
 763                 sk->no_check = 0;       /* Doesn't matter no checksum is
 764                                          * preformed anyway.
 765                                          */
 766                 sk->num = protocol;
 767                 break;
 768 
 769         default:
 770                 kfree_s((void *)sk, sizeof(*sk));
 771                 return(-ESOCKTNOSUPPORT);
 772   }
 773   sk->socket = sock;
 774   sk->protocol = protocol;
 775   sk->wmem_alloc = 0;
 776   sk->rmem_alloc = 0;
 777   sk->sndbuf = SK_WMEM_MAX;
 778   sk->rcvbuf = SK_RMEM_MAX;
 779   sk->pair = NULL;
 780   sk->opt = NULL;
 781   sk->send_seq = 0;
 782   sk->acked_seq = 0;
 783   sk->copied_seq = 0;
 784   sk->fin_seq = 0;
 785   sk->proc = 0;
 786   sk->rtt = TCP_WRITE_TIME;
 787   sk->mdev = 0;
 788   sk->backoff = 0;
 789   sk->packets_out = 0;
 790   sk->cong_window = 1; /* start with only sending one packet at a time. */
 791   sk->exp_growth = 1;  /* if set cong_window grow exponentially every time
 792                           we get an ack. */
 793   sk->urginline = 0;
 794   sk->intr = 0;
 795   sk->linger = 0;
 796   sk->destroy = 0;
 797   sk->reuse = 0;
 798   sk->priority = 1;
 799   sk->shutdown = 0;
 800   sk->urg = 0;
 801   sk->keepopen = 0;
 802   sk->zapped = 0;
 803   sk->done = 0;
 804   sk->ack_backlog = 0;
 805   sk->window = 0;
 806   sk->bytes_rcv = 0;
 807   sk->state = TCP_CLOSE;
 808   sk->dead = 0;
 809   sk->ack_timed = 0;
 810   sk->send_tmp = NULL;
 811   sk->mss = 0; /* we will try not to send any packets smaller than this. */
 812   sk->debug = 0;
 813 
 814   /* this is how many unacked bytes we will accept for this socket.  */
 815   sk->max_unacked = 2048; /* needs to be at most 2 full packets. */
 816 
 817   /* how many packets we should send before forcing an ack. 
 818      if this is set to zero it is the same as sk->delay_acks = 0 */
 819   sk->max_ack_backlog = 0;
 820   sk->inuse = 0;
 821   sk->delay_acks = 0;
 822   sk->wback = NULL;
 823   sk->wfront = NULL;
 824   sk->rqueue = NULL;
 825   sk->mtu = 576;
 826   sk->prot = prot;
 827   sk->sleep = sock->wait;
 828   sk->daddr = 0;
 829   sk->saddr = my_addr();
 830   sk->err = 0;
 831   sk->next = NULL;
 832   sk->pair = NULL;
 833   sk->send_tail = NULL;
 834   sk->send_head = NULL;
 835   sk->timeout = 0;
 836   sk->broadcast = 0;
 837   sk->timer.data = (unsigned long)sk;
 838   sk->timer.function = &net_timer;
 839   sk->back_log = NULL;
 840   sk->blog = 0;
 841   sock->data =(void *) sk;
 842   sk->dummy_th.doff = sizeof(sk->dummy_th)/4;
 843   sk->dummy_th.res1=0;
 844   sk->dummy_th.res2=0;
 845   sk->dummy_th.urg_ptr = 0;
 846   sk->dummy_th.fin = 0;
 847   sk->dummy_th.syn = 0;
 848   sk->dummy_th.rst = 0;
 849   sk->dummy_th.psh = 0;
 850   sk->dummy_th.ack = 0;
 851   sk->dummy_th.urg = 0;
 852   sk->dummy_th.dest = 0;
 853 
 854   if (sk->num) {
 855         /*
 856          * It assumes that any protocol which allows
 857          * the user to assign a number at socket
 858          * creation time automatically
 859          * shares.
 860          */
 861         put_sock(sk->num, sk);
 862         sk->dummy_th.source = ntohs(sk->num);
 863   }
 864 
 865   if (sk->prot->init) {
 866         err = sk->prot->init(sk);
 867         if (err != 0) {
 868                 destroy_sock(sk);
 869                 return(err);
 870         }
 871   }
 872   return(0);
 873 }
 874 
 875 
 876 static int
 877 inet_dup(struct socket *newsock, struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 878 {
 879   return(inet_create(newsock,
 880                    ((struct sock *)(oldsock->data))->protocol));
 881 }
 882 
 883 
 884 /* The peer socket should always be NULL. */
 885 static int
 886 inet_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 887 {
 888   struct sock *sk;
 889 
 890   sk = (struct sock *) sock->data;
 891   if (sk == NULL) return(0);
 892 
 893   DPRINTF((DBG_INET, "inet_release(sock = %X, peer = %X)\n", sock, peer));
 894   wake_up(sk->sleep);
 895 
 896   /* Start closing the connection.  This may take a while. */
 897   /*
 898    * If linger is set, we don't return until the close
 899    * is complete.  Other wise we return immediately. The
 900    * actually closing is done the same either way.
 901    */
 902   if (sk->linger == 0) {
 903         sk->prot->close(sk,0);
 904         sk->dead = 1;
 905   } else {
 906         DPRINTF((DBG_INET, "sk->linger set.\n"));
 907         sk->prot->close(sk, 0);
 908         cli();
 909         if (sk->lingertime)
 910                 current->timeout = jiffies + HZ*sk->lingertime;
 911         while(sk->state != TCP_CLOSE && current->timeout>0) {
 912                 interruptible_sleep_on(sk->sleep);
 913                 if (current->signal & ~current->blocked) {
 914                         sti();
 915                         current->timeout=0;
 916                         return(-ERESTARTSYS);
 917                 }
 918         }
 919         current->timeout=0;
 920         sti();
 921         sk->dead = 1;
 922   }
 923   sk->inuse = 1;
 924 
 925   /* This will destroy it. */
 926   release_sock(sk);
 927   sock->data = NULL;
 928   DPRINTF((DBG_INET, "inet_release returning\n"));
 929   return(0);
 930 }
 931 
 932 
 933 /* this needs to be changed to dissallow
 934    the rebinding of sockets.   What error
 935    should it return? */
 936 
 937 static int
 938 inet_bind(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 939                int addr_len)
 940 {
 941   struct sockaddr_in addr;
 942   struct sock *sk, *sk2;
 943   unsigned short snum;
 944   int err;
 945 
 946   sk = (struct sock *) sock->data;
 947   if (sk == NULL) {
 948         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
 949         return(0);
 950   }
 951 
 952   /* check this error. */
 953   if (sk->state != TCP_CLOSE) return(-EIO);
 954   if (sk->num != 0) return(-EINVAL);
 955 
 956   err=verify_area(VERIFY_READ, uaddr, addr_len);
 957   if(err)
 958         return err;
 959   memcpy_fromfs(&addr, uaddr, min(sizeof(addr), addr_len));
 960 
 961   snum = ntohs(addr.sin_port);
 962   DPRINTF((DBG_INET, "bind sk =%X to port = %d\n", sk, snum));
 963   sk = (struct sock *) sock->data;
 964 
 965   /*
 966    * We can't just leave the socket bound wherever it is, it might
 967    * be bound to a privileged port. However, since there seems to
 968    * be a bug here, we will leave it if the port is not privileged.
 969    */
 970   if (snum == 0) {
 971         snum = get_new_socknum(sk->prot, 0);
 972   }
 973   if (snum < PROT_SOCK && !suser()) return(-EACCES);
 974 
 975   if (addr.sin_addr.s_addr!=0 && chk_addr(addr.sin_addr.s_addr)!=IS_MYADDR)
 976         return(-EADDRNOTAVAIL); /* Source address MUST be ours! */
 977         
 978   if (chk_addr(addr.sin_addr.s_addr) || addr.sin_addr.s_addr == 0)
 979                                         sk->saddr = addr.sin_addr.s_addr;
 980 
 981   DPRINTF((DBG_INET, "sock_array[%d] = %X:\n", snum &(SOCK_ARRAY_SIZE -1),
 982                         sk->prot->sock_array[snum &(SOCK_ARRAY_SIZE -1)]));
 983 
 984   /* Make sure we are allowed to bind here. */
 985   cli();
 986 outside_loop:
 987   for(sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)];
 988                                         sk2 != NULL; sk2 = sk2->next) {
 989 #if     1       /* should be below! */
 990         if (sk2->num != snum) continue;
 991 /*      if (sk2->saddr != sk->saddr) continue; */
 992 #endif
 993         if (sk2->dead) {
 994                 destroy_sock(sk2);
 995                 goto outside_loop;
 996         }
 997         if (!sk->reuse) {
 998                 sti();
 999                 return(-EADDRINUSE);
1000         }
1001         if (sk2->num != snum) continue;         /* more than one */
1002         if (sk2->saddr != sk->saddr) continue;  /* socket per slot ! -FB */
1003         if (!sk2->reuse) {
1004                 sti();
1005                 return(-EADDRINUSE);
1006         }
1007   }
1008   sti();
1009 
1010   remove_sock(sk);
1011   put_sock(snum, sk);
1012   sk->dummy_th.source = ntohs(sk->num);
1013   sk->daddr = 0;
1014   sk->dummy_th.dest = 0;
1015   return(0);
1016 }
1017 
1018 
1019 static int
1020 inet_connect(struct socket *sock, struct sockaddr * uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1021                   int addr_len, int flags)
1022 {
1023   struct sock *sk;
1024   int err;
1025 
1026   sock->conn = NULL;
1027   sk = (struct sock *) sock->data;
1028   if (sk == NULL) {
1029         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1030         return(0);
1031   }
1032 
1033   if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
1034   {
1035         sock->state = SS_CONNECTED;
1036   /* Connection completing after a connect/EINPROGRESS/select/connect */
1037         return 0;       /* Rock and roll */
1038   }
1039 
1040   if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP &&
1041         (flags & O_NONBLOCK))
1042         return -EALREADY;       /* Connecting is currently in progress */
1043         
1044   if (sock->state != SS_CONNECTING) {
1045         /* We may need to bind the socket. */
1046         if (sk->num == 0) {
1047                 sk->num = get_new_socknum(sk->prot, 0);
1048                 if (sk->num == 0) 
1049                         return(-EAGAIN);
1050                 put_sock(sk->num, sk);
1051                 sk->dummy_th.source = htons(sk->num);
1052         }
1053 
1054         if (sk->prot->connect == NULL) 
1055                 return(-EOPNOTSUPP);
1056   
1057         err = sk->prot->connect(sk, (struct sockaddr_in *)uaddr, addr_len);
1058         if (err < 0) return(err);
1059   
1060         sock->state = SS_CONNECTING;
1061   }
1062 
1063   if (sk->state != TCP_ESTABLISHED &&(flags & O_NONBLOCK)) 
1064         return(-EINPROGRESS);
1065 
1066   cli(); /* avoid the race condition */
1067   while(sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) 
1068   {
1069         interruptible_sleep_on(sk->sleep);
1070         if (current->signal & ~current->blocked) {
1071                 sti();
1072                 return(-ERESTARTSYS);
1073         }
1074         /* This fixes a nasty in the tcp/ip code. There is a hideous hassle with
1075            icmp error packets wanting to close a tcp or udp socket. */
1076         if(sk->err && sk->protocol == IPPROTO_TCP)
1077         {
1078                 sti();
1079                 sock->state = SS_UNCONNECTED;
1080                 return -sk->err; /* set by tcp_err() */
1081         }
1082   }
1083   sti();
1084   sock->state = SS_CONNECTED;
1085 
1086   if (sk->state != TCP_ESTABLISHED && sk->err) {
1087         sock->state = SS_UNCONNECTED;
1088         return(-sk->err);
1089   }
1090   return(0);
1091 }
1092 
1093 
1094 static int
1095 inet_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
1096 {
1097   return(-EOPNOTSUPP);
1098 }
1099 
1100 
1101 static int
1102 inet_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1103 {
1104   struct sock *sk1, *sk2;
1105   int err;
1106 
1107   sk1 = (struct sock *) sock->data;
1108   if (sk1 == NULL) {
1109         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1110         return(0);
1111   }
1112 
1113   /*
1114    * We've been passed an extra socket.
1115    * We need to free it up because the tcp module creates
1116    * it's own when it accepts one.
1117    */
1118   if (newsock->data) kfree_s(newsock->data, sizeof(struct sock));
1119   newsock->data = NULL;
1120 
1121   if (sk1->prot->accept == NULL) return(-EOPNOTSUPP);
1122 
1123   /* Restore the state if we have been interrupted, and then returned. */
1124   if (sk1->pair != NULL ) {
1125         sk2 = sk1->pair;
1126         sk1->pair = NULL;
1127   } else {
1128         sk2 = sk1->prot->accept(sk1,flags);
1129         if (sk2 == NULL) {
1130                 if (sk1->err <= 0)
1131                         printk("Warning sock.c:sk1->err <= 0.  Returning non-error.\n");
1132                 err=sk1->err;
1133                 sk1->err=0;
1134                 return(-err);
1135         }
1136   }
1137   newsock->data = (void *)sk2;
1138   sk2->sleep = newsock->wait;
1139   newsock->conn = NULL;
1140   if (flags & O_NONBLOCK) return(0);
1141 
1142   cli(); /* avoid the race. */
1143   while(sk2->state == TCP_SYN_RECV) {
1144         interruptible_sleep_on(sk2->sleep);
1145         if (current->signal & ~current->blocked) {
1146                 sti();
1147                 sk1->pair = sk2;
1148                 sk2->sleep = NULL;
1149                 newsock->data = NULL;
1150                 return(-ERESTARTSYS);
1151         }
1152   }
1153   sti();
1154 
1155   if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) {
1156 
1157         err = -sk2->err;
1158         sk2->err=0;
1159         destroy_sock(sk2);
1160         newsock->data = NULL;
1161         return(err);
1162   }
1163   newsock->state = SS_CONNECTED;
1164   return(0);
1165 }
1166 
1167 
1168 static int
1169 inet_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1170                  int *uaddr_len, int peer)
1171 {
1172   struct sockaddr_in sin;
1173   struct sock *sk;
1174   int len;
1175   int err;
1176   
1177   
1178   err = verify_area(VERIFY_WRITE,uaddr_len,sizeof(long));
1179   if(err)
1180         return err;
1181         
1182   len=get_fs_long(uaddr_len);
1183   
1184   err = verify_area(VERIFY_WRITE, uaddr, len);
1185   if(err)
1186         return err;
1187         
1188   /* Check this error. */
1189   if (len < sizeof(sin)) return(-EINVAL);
1190 
1191   sin.sin_family = AF_INET;
1192   sk = (struct sock *) sock->data;
1193   if (sk == NULL) {
1194         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1195         return(0);
1196   }
1197   if (peer) {
1198         if (!tcp_connected(sk->state)) return(-ENOTCONN);
1199         sin.sin_port = sk->dummy_th.dest;
1200         sin.sin_addr.s_addr = sk->daddr;
1201   } else {
1202         sin.sin_port = sk->dummy_th.source;
1203         if (sk->saddr == 0) sin.sin_addr.s_addr = my_addr();
1204           else sin.sin_addr.s_addr = sk->saddr;
1205   }
1206   len = sizeof(sin);
1207 /*  verify_area(VERIFY_WRITE, uaddr, len); NOW DONE ABOVE */
1208   memcpy_tofs(uaddr, &sin, sizeof(sin));
1209 /*  verify_area(VERIFY_WRITE, uaddr_len, sizeof(len)); NOW DONE ABOVE */
1210   put_fs_long(len, uaddr_len);
1211   return(0);
1212 }
1213 
1214 
1215 static int
1216 inet_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1217 {
1218   struct sock *sk;
1219 
1220   sk = (struct sock *) sock->data;
1221   if (sk == NULL) {
1222         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1223         return(0);
1224   }
1225 
1226   /* We may need to bind the socket. */
1227   if (sk->num == 0) {
1228         sk->num = get_new_socknum(sk->prot, 0);
1229         if (sk->num == 0) return(-EAGAIN);
1230         put_sock(sk->num, sk);
1231         sk->dummy_th.source = ntohs(sk->num);
1232   }
1233   return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock,0));
1234 }
1235 
1236 
1237 static int
1238 inet_recv(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1239           unsigned flags)
1240 {
1241   struct sock *sk;
1242 
1243   sk = (struct sock *) sock->data;
1244   if (sk == NULL) {
1245         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1246         return(0);
1247   }
1248 
1249   /* We may need to bind the socket. */
1250   if (sk->num == 0) {
1251         sk->num = get_new_socknum(sk->prot, 0);
1252         if (sk->num == 0) return(-EAGAIN);
1253         put_sock(sk->num, sk);
1254         sk->dummy_th.source = ntohs(sk->num);
1255   }
1256   return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock, flags));
1257 }
1258 
1259 
1260 static int
1261 inet_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1262 {
1263   struct sock *sk;
1264 
1265   sk = (struct sock *) sock->data;
1266   if (sk == NULL) {
1267         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1268         return(0);
1269   }
1270   if (sk->shutdown & SEND_SHUTDOWN) {
1271         send_sig(SIGPIPE, current, 1);
1272         return(-EPIPE);
1273   }
1274 
1275   /* We may need to bind the socket. */
1276   if (sk->num == 0) {
1277         sk->num = get_new_socknum(sk->prot, 0);
1278         if (sk->num == 0) return(-EAGAIN);
1279         put_sock(sk->num, sk);
1280         sk->dummy_th.source = ntohs(sk->num);
1281   }
1282 
1283   return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, 0));
1284 }
1285 
1286 
1287 static int
1288 inet_send(struct socket *sock, void *ubuf, int size, int noblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
1289                unsigned flags)
1290 {
1291   struct sock *sk;
1292 
1293   sk = (struct sock *) sock->data;
1294   if (sk == NULL) {
1295         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1296         return(0);
1297   }
1298   if (sk->shutdown & SEND_SHUTDOWN) {
1299         send_sig(SIGPIPE, current, 1);
1300         return(-EPIPE);
1301   }
1302 
1303   /* We may need to bind the socket. */
1304   if (sk->num == 0) {
1305         sk->num = get_new_socknum(sk->prot, 0);
1306         if (sk->num == 0) return(-EAGAIN);
1307         put_sock(sk->num, sk);
1308         sk->dummy_th.source = ntohs(sk->num);
1309   }
1310 
1311   return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, flags));
1312 }
1313 
1314 
1315 static int
1316 inet_sendto(struct socket *sock, void *ubuf, int size, int noblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
1317             unsigned flags, struct sockaddr *sin, int addr_len)
1318 {
1319   struct sock *sk;
1320 
1321   sk = (struct sock *) sock->data;
1322   if (sk == NULL) {
1323         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1324         return(0);
1325   }
1326   if (sk->shutdown & SEND_SHUTDOWN) {
1327         send_sig(SIGPIPE, current, 1);
1328         return(-EPIPE);
1329   }
1330 
1331   if (sk->prot->sendto == NULL) return(-EOPNOTSUPP);
1332 
1333   /* We may need to bind the socket. */
1334   if (sk->num == 0) {
1335         sk->num = get_new_socknum(sk->prot, 0);
1336         if (sk->num == 0) return(-EAGAIN);
1337         put_sock(sk->num, sk);
1338         sk->dummy_th.source = ntohs(sk->num);
1339   }
1340 
1341   return(sk->prot->sendto(sk, (unsigned char *) ubuf, size, noblock, flags, 
1342                            (struct sockaddr_in *)sin, addr_len));
1343 }
1344 
1345 
1346 static int
1347 inet_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
1348                    unsigned flags, struct sockaddr *sin, int *addr_len )
1349 {
1350   struct sock *sk;
1351 
1352   sk = (struct sock *) sock->data;
1353   if (sk == NULL) {
1354         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1355         return(0);
1356   }
1357 
1358   if (sk->prot->recvfrom == NULL) return(-EOPNOTSUPP);
1359 
1360   /* We may need to bind the socket. */
1361   if (sk->num == 0) {
1362         sk->num = get_new_socknum(sk->prot, 0);
1363         if (sk->num == 0) return(-EAGAIN);
1364         put_sock(sk->num, sk);
1365         sk->dummy_th.source = ntohs(sk->num);
1366   }
1367 
1368   return(sk->prot->recvfrom(sk, (unsigned char *) ubuf, size, noblock, flags,
1369                              (struct sockaddr_in*)sin, addr_len));
1370 }
1371 
1372 
1373 static int
1374 inet_shutdown(struct socket *sock, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1375 {
1376   struct sock *sk;
1377 
1378   /*
1379    * This should really check to make sure
1380    * the socket is a TCP socket.
1381    */
1382   how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
1383                        1->2 bit 2 snds.
1384                        2->3 */
1385   if (how & ~SHUTDOWN_MASK) return(-EINVAL);
1386   sk = (struct sock *) sock->data;
1387   if (sk == NULL) {
1388         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1389         return(0);
1390   }
1391   if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
1392                                                 sock->state = SS_CONNECTED;
1393 
1394   if (!tcp_connected(sk->state)) return(-ENOTCONN);
1395   sk->shutdown |= how;
1396   if (sk->prot->shutdown) sk->prot->shutdown(sk, how);
1397   return(0);
1398 }
1399 
1400 
1401 static int
1402 inet_select(struct socket *sock, int sel_type, select_table *wait )
     /* [previous][next][first][last][top][bottom][index][help] */
1403 {
1404   struct sock *sk;
1405 
1406   sk = (struct sock *) sock->data;
1407   if (sk == NULL) {
1408         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1409         return(0);
1410   }
1411 
1412   if (sk->prot->select == NULL) {
1413         DPRINTF((DBG_INET, "select on non-selectable socket.\n"));
1414         return(0);
1415   }
1416   return(sk->prot->select(sk, sel_type, wait));
1417 }
1418 
1419 
1420 static int
1421 inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1422 {
1423   struct sock *sk;
1424   int err;
1425 
1426   DPRINTF((DBG_INET, "INET: in inet_ioctl\n"));
1427   sk = NULL;
1428   if (sock && (sk = (struct sock *) sock->data) == NULL) {
1429         printk("AF_INET: Warning: sock->data = NULL: %d\n" , __LINE__);
1430         return(0);
1431   }
1432 
1433   switch(cmd) {
1434         case FIOSETOWN:
1435         case SIOCSPGRP:
1436                 err=verify_area(VERIFY_READ,(int *)arg,sizeof(long));
1437                 if(err)
1438                         return err;
1439                 if (sk)
1440                         sk->proc = get_fs_long((int *) arg);
1441                 return(0);
1442         case FIOGETOWN:
1443         case SIOCGPGRP:
1444                 if (sk) {
1445                         err=verify_area(VERIFY_WRITE,(void *) arg, sizeof(long));
1446                         if(err)
1447                                 return err;
1448                         put_fs_long(sk->proc,(int *)arg);
1449                 }
1450                 return(0);
1451 #if 0   /* FIXME: */
1452         case SIOCATMARK:
1453                 printk("AF_INET: ioctl(SIOCATMARK, 0x%08X)\n",(void *) arg);
1454                 return(-EINVAL);
1455 #endif
1456 
1457         case DDIOCSDBG:
1458                 return(dbg_ioctl((void *) arg, DBG_INET));
1459 
1460         case SIOCADDRT:
1461         case SIOCDELRT:
1462                 return(rt_ioctl(cmd,(void *) arg));
1463 
1464         case SIOCDARP:
1465         case SIOCGARP:
1466         case SIOCSARP:
1467                 return(arp_ioctl(cmd,(void *) arg));
1468 
1469         case IP_SET_DEV:
1470         case SIOCGIFCONF:
1471         case SIOCGIFFLAGS:
1472         case SIOCSIFFLAGS:
1473         case SIOCGIFADDR:
1474         case SIOCSIFADDR:
1475         case SIOCGIFDSTADDR:
1476         case SIOCSIFDSTADDR:
1477         case SIOCGIFBRDADDR:
1478         case SIOCSIFBRDADDR:
1479         case SIOCGIFNETMASK:
1480         case SIOCSIFNETMASK:
1481         case SIOCGIFMETRIC:
1482         case SIOCSIFMETRIC:
1483         case SIOCGIFMEM:
1484         case SIOCSIFMEM:
1485         case SIOCGIFMTU:
1486         case SIOCSIFMTU:
1487         case SIOCSIFLINK:
1488         case SIOCGIFHWADDR:
1489                 return(dev_ioctl(cmd,(void *) arg));
1490 
1491         default:
1492                 if (!sk || !sk->prot->ioctl) return(-EINVAL);
1493                 return(sk->prot->ioctl(sk, cmd, arg));
1494   }
1495   /*NOTREACHED*/
1496   return(0);
1497 }
1498 
1499 
1500 void *
1501 sock_wmalloc(struct sock *sk, unsigned long size, int force,
     /* [previous][next][first][last][top][bottom][index][help] */
1502              int priority)
1503 {
1504   if (sk) {
1505         if (sk->wmem_alloc + size < sk->sndbuf || force) {
1506                 cli();
1507                 sk->wmem_alloc+= size;
1508                 sti();
1509                 return(alloc_skb(size, priority));
1510         }
1511         DPRINTF((DBG_INET, "sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
1512                                                 sk, size, force, priority));
1513         return(NULL);
1514   }
1515   return(alloc_skb(size, priority));
1516 }
1517 
1518 
1519 void *
1520 sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
1521 {
1522   if (sk) {
1523         if (sk->rmem_alloc + size < sk->rcvbuf || force) {
1524                 void *c = alloc_skb(size, priority);
1525                 cli();
1526                 if (c) sk->rmem_alloc += size;
1527                 sti();
1528                 return(c);
1529         }
1530         DPRINTF((DBG_INET, "sock_rmalloc(%X,%d,%d,%d) returning NULL\n",
1531                                                 sk,size,force, priority));
1532         return(NULL);
1533   }
1534   return(alloc_skb(size, priority));
1535 }
1536 
1537 
1538 unsigned long
1539 sock_rspace(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1540 {
1541   int amt;
1542 
1543   if (sk != NULL) {
1544         if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW) return(0);
1545         amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
1546         if (amt < 0) return(0);
1547         return(amt);
1548   }
1549   return(0);
1550 }
1551 
1552 
1553 unsigned long
1554 sock_wspace(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1555 {
1556   if (sk != NULL) {
1557         if (sk->shutdown & SEND_SHUTDOWN) return(0);
1558         if (sk->wmem_alloc >= sk->sndbuf) return(0);
1559         return(sk->sndbuf-sk->wmem_alloc );
1560   }
1561   return(0);
1562 }
1563 
1564 
1565 void
1566 sock_wfree(struct sock *sk, void *mem, unsigned long size)
     /* [previous][next][first][last][top][bottom][index][help] */
1567 {
1568   DPRINTF((DBG_INET, "sock_wfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));
1569 
1570   IS_SKB(mem);
1571   kfree_skbmem(mem, size);
1572   if (sk) {
1573         sk->wmem_alloc -= size;
1574 
1575         /* In case it might be waiting for more memory. */
1576         if (!sk->dead) wake_up(sk->sleep);
1577         if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {
1578                 DPRINTF((DBG_INET,
1579                         "recovered lost memory, sock = %X\n", sk));
1580         }
1581         return;
1582   }
1583 }
1584 
1585 
1586 void
1587 sock_rfree(struct sock *sk, void *mem, unsigned long size)
     /* [previous][next][first][last][top][bottom][index][help] */
1588 {
1589   DPRINTF((DBG_INET, "sock_rfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));
1590   IS_SKB(mem);
1591   kfree_skbmem(mem, size);
1592   if (sk) {
1593         sk->rmem_alloc -= size;
1594         if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {
1595                 DPRINTF((DBG_INET,
1596                         "recovered lot memory, sock = %X\n", sk));
1597         }
1598   }
1599 }
1600 
1601 
1602 /*
1603  * This routine must find a socket given a TCP or UDP header.
1604  * Everyhting is assumed to be in net order.
1605  */
1606 struct sock *get_sock(struct proto *prot, unsigned short num,
     /* [previous][next][first][last][top][bottom][index][help] */
1607                                 unsigned long raddr,
1608                                 unsigned short rnum, unsigned long laddr)
1609 {
1610   struct sock *s;
1611   unsigned short hnum;
1612 
1613   hnum = ntohs(num);
1614   DPRINTF((DBG_INET, "get_sock(prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n",
1615           prot, num, raddr, rnum, laddr));
1616 
1617   /*
1618    * SOCK_ARRAY_SIZE must be a power of two.  This will work better
1619    * than a prime unless 3 or more sockets end up using the same
1620    * array entry.  This should not be a problem because most
1621    * well known sockets don't overlap that much, and for
1622    * the other ones, we can just be careful about picking our
1623    * socket number when we choose an arbitrary one.
1624    */
1625   for(s = prot->sock_array[hnum & (SOCK_ARRAY_SIZE - 1)];
1626       s != NULL; s = s->next) 
1627   {
1628         if (s->num != hnum) 
1629                 continue;
1630         if(s->dead && (s->state == TCP_CLOSE))
1631                 continue;
1632         if(prot == &udp_prot)
1633                 return s;
1634         if(ip_addr_match(s->daddr,raddr)==0)
1635                 continue;
1636         if (s->dummy_th.dest != rnum && s->dummy_th.dest != 0) 
1637                 continue;
1638         if(ip_addr_match(s->saddr,laddr) == 0)
1639                 continue;
1640         return(s);
1641   }
1642   return(NULL);
1643 }
1644 
1645 
1646 void release_sock(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1647 {
1648   if (!sk) {
1649         printk("sock.c: release_sock sk == NULL\n");
1650         return;
1651   }
1652   if (!sk->prot) {
1653 /*      printk("sock.c: release_sock sk->prot == NULL\n"); */
1654         return;
1655   }
1656 
1657   if (sk->blog) return;
1658 
1659   /* See if we have any packets built up. */
1660   cli();
1661   sk->inuse = 1;
1662   while(sk->back_log != NULL) {
1663         struct sk_buff *skb;
1664 
1665         sk->blog = 1;
1666         skb =(struct sk_buff *)sk->back_log;
1667         DPRINTF((DBG_INET, "release_sock: skb = %X:\n", skb));
1668         if (skb->next != skb) {
1669                 sk->back_log = skb->next;
1670                 skb->prev->next = skb->next;
1671                 skb->next->prev = skb->prev;
1672         } else {
1673                 sk->back_log = NULL;
1674         }
1675         sti();
1676         DPRINTF((DBG_INET, "sk->back_log = %X\n", sk->back_log));
1677         if (sk->prot->rcv) sk->prot->rcv(skb, skb->dev, sk->opt,
1678                                          skb->saddr, skb->len, skb->daddr, 1,
1679 
1680         /* Only used for/by raw sockets. */
1681         (struct inet_protocol *)sk->pair); 
1682         cli();
1683   }
1684   sk->blog = 0;
1685   sk->inuse = 0;
1686   sti();
1687   if (sk->dead && sk->state == TCP_CLOSE) {
1688         /* Should be about 2 rtt's */
1689         reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
1690   }
1691 }
1692 
1693 
1694 static int
1695 inet_fioctl(struct inode *inode, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
1696          unsigned int cmd, unsigned long arg)
1697 {
1698   int minor, ret;
1699 
1700   /* Extract the minor number on which we work. */
1701   minor = MINOR(inode->i_rdev);
1702   if (minor != 0) return(-ENODEV);
1703 
1704   /* Now dispatch on the minor device. */
1705   switch(minor) {
1706         case 0:         /* INET */
1707                 ret = inet_ioctl(NULL, cmd, arg);
1708                 break;
1709         case 1:         /* IP */
1710                 ret = ip_ioctl(NULL, cmd, arg);
1711                 break;
1712         case 2:         /* ICMP */
1713                 ret = icmp_ioctl(NULL, cmd, arg);
1714                 break;
1715         case 3:         /* TCP */
1716                 ret = tcp_ioctl(NULL, cmd, arg);
1717                 break;
1718         case 4:         /* UDP */
1719                 ret = udp_ioctl(NULL, cmd, arg);
1720                 break;
1721         default:
1722                 ret = -ENODEV;
1723   }
1724 
1725   return(ret);
1726 }
1727 
1728 
1729 static struct file_operations inet_fops = {
1730   NULL,         /* LSEEK        */
1731   NULL,         /* READ         */
1732   NULL,         /* WRITE        */
1733   NULL,         /* READDIR      */
1734   NULL,         /* SELECT       */
1735   inet_fioctl,  /* IOCTL        */
1736   NULL,         /* MMAP         */
1737   NULL,         /* OPEN         */
1738   NULL          /* CLOSE        */
1739 };
1740 
1741 
1742 static struct proto_ops inet_proto_ops = {
1743   AF_INET,
1744 
1745   inet_create,
1746   inet_dup,
1747   inet_release,
1748   inet_bind,
1749   inet_connect,
1750   inet_socketpair,
1751   inet_accept,
1752   inet_getname, 
1753   inet_read,
1754   inet_write,
1755   inet_select,
1756   inet_ioctl,
1757   inet_listen,
1758   inet_send,
1759   inet_recv,
1760   inet_sendto,
1761   inet_recvfrom,
1762   inet_shutdown,
1763   inet_setsockopt,
1764   inet_getsockopt,
1765   inet_fcntl,
1766 };
1767 
1768 extern unsigned long seq_offset;
1769 
1770 /* Called by ddi.c on kernel startup.  */
1771 void inet_proto_init(struct ddi_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1772 {
1773   struct inet_protocol *p;
1774   int i;
1775 
1776   printk("Swansea University Computer Society Net2Debugged [1.24]\n");
1777   /* Set up our UNIX VFS major device. */
1778   if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) {
1779         printk("%s: cannot register major device %d!\n",
1780                                         pro->name, AF_INET_MAJOR);
1781         return;
1782   }
1783 
1784   /* Tell SOCKET that we are alive... */
1785   (void) sock_register(inet_proto_ops.family, &inet_proto_ops);
1786 
1787   seq_offset = CURRENT_TIME*250;
1788 
1789   /* Add all the protocols. */
1790   for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
1791         tcp_prot.sock_array[i] = NULL;
1792         udp_prot.sock_array[i] = NULL;
1793         raw_prot.sock_array[i] = NULL;
1794   }
1795   printk("IP Protocols: ");
1796   for(p = inet_protocol_base; p != NULL;) {
1797         struct inet_protocol *tmp;
1798 
1799         tmp = (struct inet_protocol *) p->next;
1800         inet_add_protocol(p);
1801         printk("%s%s",p->name,tmp?", ":"\n");
1802         p = tmp;
1803   }
1804 
1805   /* Initialize the DEV module. */
1806   dev_init();
1807 
1808   /* Initialize the "Buffer Head" pointers. */
1809   bh_base[INET_BH].routine = inet_bh;
1810 }

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