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

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