root/net/inet/ipx.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipx_remove_socket
  2. ipx_insert_socket
  3. ipx_find_socket
  4. ipx_destroy_socket
  5. ipx_get_info
  6. ipxrtr_get_dev
  7. ipxrtr_create
  8. ipxrtr_delete
  9. ipxrtr_ioctl
  10. ipx_rt_get_info
  11. ipx_fcntl
  12. ipx_setsockopt
  13. ipx_getsockopt
  14. ipx_listen
  15. def_callback1
  16. def_callback2
  17. ipx_create
  18. ipx_dup
  19. ipx_release
  20. ipx_bind
  21. ipx_connect
  22. ipx_socketpair
  23. ipx_accept
  24. ipx_getname
  25. ipx_rcv
  26. ipx_sendto
  27. ipx_send
  28. ipx_write
  29. ipx_recvfrom
  30. ipx_recv
  31. ipx_read
  32. ipx_shutdown
  33. ipx_select
  34. ipx_ioctl
  35. ipx_proto_init

   1 /*
   2  *      Implements an IPX socket layer (badly - but I'm working on it).
   3  *
   4  *      This code is derived from work by
   5  *              Ross Biro       :       Writing the original IP stack
   6  *              Fred Van Kempen :       Tidying up the TCP/IP
   7  *
   8  *      Many thanks go to Keith Baker, Institute For Industrial Information
   9  *      Technology Ltd, Swansea University for allowing me to work on this
  10  *      in my own time even though it was in some ways related to commercial
  11  *      work I am currently employed to do there.
  12  *
  13  *      All the material in this file is subject to the Gnu license version 2.
  14  *      Neither Alan Cox nor the Swansea University Computer Society admit liability
  15  *      nor provide warranty for any of this software. This material is provided 
  16  *      as is and at no charge.         
  17  *
  18  *      Revision 0.21:  Uses the new generic socket option code.
  19  *      Revision 0.22:  Gcc clean ups and drop out device registration. Use the
  20  *                      new multi-protocol edition of hard_header 
  21  *      Revision 0.23:  IPX /proc by Mark Evans.
  22  *                      Adding a route will overwrite any existing route to the same
  23  *                      network.
  24  *      Revision 0.24:  Supports new /proc with no 4K limit
  25  *
  26  */
  27  
  28 #include <linux/config.h>
  29 #include <linux/errno.h>
  30 #include <linux/types.h>
  31 #include <linux/socket.h>
  32 #include <linux/in.h>
  33 #include <linux/kernel.h>
  34 #include <linux/sched.h>
  35 #include <linux/timer.h>
  36 #include <linux/string.h>
  37 #include <linux/sockios.h>
  38 #include <linux/net.h>
  39 #include <linux/ipx.h>
  40 #include <linux/inet.h>
  41 #include <linux/netdevice.h>
  42 #include <linux/skbuff.h>
  43 #include "sock.h"
  44 #include <asm/segment.h>
  45 #include <asm/system.h>
  46 #include <linux/fcntl.h>
  47 #include <linux/mm.h>
  48 #include <linux/interrupt.h>
  49 
  50 #ifdef CONFIG_IPX
  51 /***********************************************************************************************************************\
  52 *                                                                                                                       *
  53 *                                               Handlers for the socket list.                                           *
  54 *                                                                                                                       *
  55 \***********************************************************************************************************************/
  56 
  57 static ipx_socket *volatile ipx_socket_list=NULL;
  58 
  59 /*
  60  *      Note: Sockets may not be removed _during_ an interrupt or inet_bh
  61  *      handler using this technique. They can be added although we do not
  62  *      use this facility.
  63  */
  64  
  65 static void ipx_remove_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         ipx_socket *s;
  68         
  69         cli();
  70         s=ipx_socket_list;
  71         if(s==sk)
  72         {
  73                 ipx_socket_list=s->next;
  74                 sti();
  75                 return;
  76         }
  77         while(s && s->next)
  78         {
  79                 if(s->next==sk)
  80                 {
  81                         s->next=sk->next;
  82                         sti();
  83                         return;
  84                 }
  85                 s=s->next;
  86         }
  87         sti();
  88 }
  89 
  90 static void ipx_insert_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         cli();
  93         sk->next=ipx_socket_list;
  94         ipx_socket_list=sk;
  95         sti();
  96 }
  97 
  98 static ipx_socket *ipx_find_socket(int port)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         ipx_socket *s;
 101         s=ipx_socket_list;
 102         while(s)
 103         {
 104                 if(s->ipx_source_addr.sock==port)
 105                 {
 106                         return(s);
 107                 }
 108                 s=s->next;
 109         }
 110         return(NULL);
 111 }
 112 
 113 /*
 114  *      This is only called from user mode. Thus it protects itself against
 115  *      interrupt users but doesn't worry about being called during work.
 116  *      Once it is removed from the queue no interrupt or bottom half will
 117  *      touch it and we are (fairly 8-) ) safe.
 118  */
 119  
 120 static void ipx_destroy_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         struct sk_buff *skb;
 123         ipx_remove_socket(sk);
 124         
 125         while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
 126         {
 127                 kfree_skb(skb,FREE_READ);
 128         }
 129         
 130         kfree_s(sk,sizeof(*sk));
 131 }
 132 
 133 
 134 /* Called from proc fs */
 135 int ipx_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         ipx_socket *s;
 138         int len=0;
 139         off_t pos=0;
 140         off_t begin=0;
 141 
 142         /* Theory.. Keep printing in the same place until we pass offset */
 143         
 144         len += sprintf (buffer,"Type local_address             rem_address              tx_queue rx_queue st uid\n");
 145         for (s = ipx_socket_list; s != NULL; s = s->next)
 146         {
 147                 len += sprintf (buffer+len,"%02X   ", s->ipx_type);
 148                 len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%02X ", htonl(s->ipx_source_addr.net),
 149                         s->ipx_source_addr.node[0], s->ipx_source_addr.node[1], s->ipx_source_addr.node[2],
 150                         s->ipx_source_addr.node[3], s->ipx_source_addr.node[4], s->ipx_source_addr.node[5],
 151                         htons(s->ipx_source_addr.sock));
 152                 len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%02X ", htonl(s->ipx_dest_addr.net),
 153                         s->ipx_dest_addr.node[0], s->ipx_dest_addr.node[1], s->ipx_dest_addr.node[2],
 154                         s->ipx_dest_addr.node[3], s->ipx_dest_addr.node[4], s->ipx_dest_addr.node[5],
 155                         htons(s->ipx_dest_addr.sock));
 156                 len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
 157                 len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
 158                 
 159                 /* Are we still dumping unwanted data then discard the record */
 160                 pos=begin+len;
 161                 
 162                 if(pos<offset)
 163                 {
 164                         len=0;                  /* Keep dumping into the buffer start */
 165                         begin=pos;
 166                 }
 167                 if(pos>offset+length)           /* We have dumped enough */
 168                         break;
 169         }
 170         
 171         /* The data in question runs from begin to begin+len */
 172         *start=buffer+(offset-begin);   /* Start of wanted data */
 173         len-=(offset-begin);            /* Remove unwanted header data from lenth */
 174         if(len>length)
 175                 len=length;             /* Remove unwanted tail data from length */
 176         
 177         return len;
 178 }
 179 
 180 /*******************************************************************************************************************\
 181 *                                                                                                                   *
 182 *                                       Routing tables for the IPX socket layer                                     *
 183 *                                                                                                                   *
 184 \*******************************************************************************************************************/
 185 
 186 
 187 static ipx_route *ipx_router_list=NULL;
 188 
 189 static ipx_route *ipxrtr_get_dev(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191         ipx_route *r;
 192         unsigned long flags;
 193         save_flags(flags);
 194         cli();
 195         r=ipx_router_list;
 196         while(r!=NULL)
 197         {
 198                 if(r->net==net)
 199                 {
 200                         restore_flags(flags);
 201                         return r;
 202                 }
 203                 r=r->next;
 204         }
 205         restore_flags(flags);
 206         return NULL;
 207 }
 208 
 209 static int ipxrtr_create(struct ipx_route_def *r)
     /* [previous][next][first][last][top][bottom][index][help] */
 210 {
 211         ipx_route *rt=ipxrtr_get_dev(r->ipx_network);
 212         struct device *dev;
 213 
 214         if(r->ipx_router_network!=0)
 215         {
 216                 /* Adding an indirect route */
 217                 ipx_route *rt1=ipxrtr_get_dev(r->ipx_router_network);
 218                 if(rt1==NULL)
 219                         return -ENETUNREACH;
 220                 if(rt1->flags&IPX_RT_ROUTED)
 221                         return -EMULTIHOP;
 222                 if (rt==NULL)
 223                 {
 224                         rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);  /* Because we are brave and don't lock the table! */
 225                         if(rt==NULL)
 226                                 return -EAGAIN;
 227                         rt->next=ipx_router_list;
 228                         ipx_router_list=rt;
 229                 }
 230                 rt->net=r->ipx_network;
 231                 rt->router_net=r->ipx_router_network;
 232                 memcpy(rt->router_node,r->ipx_router_node,sizeof(rt->router_node));
 233                 rt->flags=(rt1->flags&IPX_RT_BLUEBOOK)|IPX_RT_ROUTED;
 234                 rt->dev=rt1->dev;
 235                 return 0;
 236         }
 237         /* Add a direct route */
 238         dev=dev_get(r->ipx_device);
 239         if(dev==NULL)
 240                 return -ENODEV;
 241         /* Check addresses are suitable */
 242         if(dev->addr_len>6)
 243                 return -EINVAL;
 244         if(dev->addr_len<2)
 245                 return -EINVAL;
 246         /* Ok now create */
 247         if (rt==NULL)
 248         {
 249                 rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);  /* Because we are brave and don't lock the table! */
 250                 if(rt==NULL)
 251                         return -EAGAIN;
 252                 rt->next=ipx_router_list;
 253                 ipx_router_list=rt;
 254         }
 255         rt->router_net=0;
 256         memset(rt->router_node,0,sizeof(rt->router_node));
 257         rt->dev=dev;
 258         rt->net=r->ipx_network;
 259         rt->flags=r->ipx_flags&IPX_RT_BLUEBOOK;
 260         return 0;
 261 }
 262 
 263 static int ipxrtr_delete(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         ipx_route *r=ipx_router_list;
 266         if(r->net==net)
 267         {
 268                 ipx_router_list=r->next;
 269                 return 0;
 270         }
 271         while(r->next!=NULL)
 272         {
 273                 if(r->next->net==net)
 274                 {
 275                         ipx_route *d=r->next;
 276                         r->next=d->next;
 277                         kfree_s(d,sizeof(ipx_route));
 278                         return 0;
 279                 }
 280                 r=r->next;
 281         }
 282         return -ENOENT;
 283 }
 284 
 285 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287         int err;
 288         switch(cmd)
 289         {
 290                 case SIOCDELRT:
 291                         err=verify_area(VERIFY_READ,arg,sizeof(long));
 292                         if(err)
 293                                 return err;
 294                         return ipxrtr_delete(get_fs_long(arg));
 295                 case SIOCADDRT:
 296                 {
 297                         struct ipx_route_def f;
 298                         err=verify_area(VERIFY_READ,arg,sizeof(f));
 299                         if(err)
 300                                 return err;
 301                         memcpy_fromfs(&f,arg,sizeof(f));
 302                         return ipxrtr_create(&f);
 303                 }
 304                 default:
 305                         return -EINVAL;
 306         }
 307 }
 308 
 309 /* Called from proc fs */
 310 int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312         ipx_route *rt;
 313         int len=0;
 314         off_t pos=0;
 315         off_t begin=0;
 316 
 317         len += sprintf (buffer,"Net      Router                Flags Dev\n");
 318         for (rt = ipx_router_list; rt != NULL; rt = rt->next)
 319         {
 320                 len += sprintf (buffer+len,"%08lX %08lX:%02X%02X%02X%02X%02X%02X %02X    %s\n", ntohl(rt->net),
 321                         ntohl(rt->router_net), rt->router_node[0], rt->router_node[1], rt->router_node[2],
 322                         rt->router_node[3], rt->router_node[4], rt->router_node[5], rt->flags, rt->dev->name);
 323                 pos=begin+len;
 324                 if(pos<offset)
 325                 {
 326                         len=0;
 327                         begin=pos;
 328                 }
 329                 if(pos>offset+length)
 330                         break;
 331         }
 332         *start=buffer+(offset-begin);
 333         len-=(offset-begin);
 334         if(len>length)
 335                 len=length;
 336         return len;
 337 }
 338 
 339 /*******************************************************************************************************************\
 340 *                                                                                                                   *
 341 *             Handling for system calls applied via the various interfaces to an IPX socket object                  *
 342 *                                                                                                                   *
 343 \*******************************************************************************************************************/
 344  
 345 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347         ipx_socket *sk;
 348         
 349         sk=(ipx_socket *)sock->data;
 350         
 351         if(sk==NULL)
 352         {
 353                 printk("IPX:fcntl:passed sock->data=NULL\n");
 354                 return(0);
 355         }
 356         
 357         switch(cmd)
 358         {
 359                 default:
 360                         return(-EINVAL);
 361         }
 362 }
 363 
 364 static int ipx_setsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 365         char *optval, int optlen)
 366 {
 367         ipx_socket *sk;
 368         int err,opt;
 369         
 370         sk=(ipx_socket *)sock->data;
 371         
 372         if(sk==NULL)
 373         {
 374                 printk("IPX:setsockopt:passed sock->data=NULL\n");
 375                 return 0;
 376         }
 377         
 378         if(optval==NULL)
 379                 return(-EINVAL);
 380         err=verify_area(VERIFY_READ,optval,sizeof(int));
 381         if(err)
 382                 return err;
 383         opt=get_fs_long((unsigned long *)optval);
 384         
 385         switch(level)
 386         {
 387                 case SOL_IPX:
 388                         switch(optname)
 389                         {
 390                                 case IPX_TYPE:
 391                                         if(!suser())
 392                                                 return(-EPERM);
 393                                         sk->ipx_type=opt;
 394                                         return 0;
 395                                 default:
 396                                         return -EOPNOTSUPP;
 397                         }
 398                         break;
 399                         
 400                 case SOL_SOCKET:                
 401                         return sock_setsockopt(sk,level,optname,optval,optlen);
 402 
 403                 default:
 404                         return -EOPNOTSUPP;
 405         }
 406 }
 407 
 408 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 409         char *optval, int *optlen)
 410 {
 411         ipx_socket *sk;
 412         int val=0;
 413         int err;
 414         
 415         sk=(ipx_socket *)sock->data;
 416         if(sk==NULL)
 417         {
 418                 printk("IPX:getsockopt:passed NULL sock->data.\n");
 419                 return 0;
 420         }
 421 
 422         switch(level)
 423         {
 424 
 425                 case SOL_IPX:
 426                         switch(optname)
 427                         {
 428                                 case IPX_TYPE:
 429                                         val=sk->ipx_type;
 430                                         break;
 431                                 default:
 432                                         return -ENOPROTOOPT;
 433                         }
 434                         break;
 435                         
 436                 case SOL_SOCKET:
 437                         return sock_getsockopt(sk,level,optname,optval,optlen);
 438                         
 439                 default:
 440                         return -EOPNOTSUPP;
 441         }
 442         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
 443         if(err)
 444                 return err;
 445         put_fs_long(sizeof(int),(unsigned long *)optlen);
 446         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
 447         put_fs_long(val,(unsigned long *)optval);
 448         return(0);
 449 }
 450 
 451 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453         return -EOPNOTSUPP;
 454 }
 455 
 456 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 457 {
 458         if(!sk->dead)
 459                 wake_up_interruptible(sk->sleep);
 460 }
 461 
 462 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464         if(!sk->dead)
 465                 wake_up_interruptible(sk->sleep);
 466 }
 467 
 468 static int ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 469 {
 470         ipx_socket *sk;
 471         sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
 472         if(sk==NULL)
 473                 return(-ENOMEM);
 474         switch(sock->type)
 475         {
 476                 case SOCK_DGRAM:
 477                         break;
 478                 default:
 479                         kfree_s((void *)sk,sizeof(*sk));
 480                         return(-ESOCKTNOSUPPORT);
 481         }
 482         sk->stamp.tv_sec=0;
 483         sk->rmem_alloc=0;
 484         sk->dead=0;
 485         sk->next=NULL;
 486         sk->broadcast=0;
 487         sk->rcvbuf=SK_RMEM_MAX;
 488         sk->sndbuf=SK_WMEM_MAX;
 489         sk->wmem_alloc=0;
 490         sk->rmem_alloc=0;
 491         sk->inuse=0;
 492         sk->dead=0;
 493         sk->prot=NULL;  /* So we use default free mechanisms */
 494         sk->broadcast=0;
 495         sk->err=0;
 496         skb_queue_head_init(&sk->receive_queue);
 497         skb_queue_head_init(&sk->write_queue);
 498         sk->send_head=NULL;
 499         skb_queue_head_init(&sk->back_log);
 500         sk->mtu=512;
 501         sk->state=TCP_CLOSE;
 502         sk->socket=sock;
 503         sk->type=sock->type;
 504         sk->ipx_type=0;         /* General user level IPX */
 505         sk->debug=0;
 506         
 507         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
 508         memset(&sk->ipx_source_addr,'\0',sizeof(sk->ipx_source_addr));
 509         sk->mtu=IPX_MTU;
 510         
 511         if(sock!=NULL)
 512         {
 513                 sock->data=(void *)sk;
 514                 sk->sleep=sock->wait;
 515         }
 516         
 517         sk->state_change=def_callback1;
 518         sk->data_ready=def_callback2;
 519         sk->write_space=def_callback1;
 520         sk->error_report=def_callback1;
 521 
 522         sk->zapped=1;
 523         return(0);
 524 }
 525 
 526 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 527 {
 528         return(ipx_create(newsock,SOCK_DGRAM));
 529 }
 530 
 531 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 532 {
 533         ipx_socket *sk=(ipx_socket *)sock->data;
 534         if(sk==NULL)
 535                 return(0);
 536         if(!sk->dead)
 537                 sk->state_change(sk);
 538         sk->dead=1;
 539         sock->data=NULL;
 540         ipx_destroy_socket(sk);
 541         return(0);
 542 }
 543                 
 544 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 545 {
 546         ipx_socket *sk;
 547         int err;
 548         struct sockaddr_ipx addr;
 549         struct ipx_route *rt;
 550         
 551         sk=(ipx_socket *)sock->data;
 552         if(sk==NULL)
 553         {
 554                 printk("IPX:bind:sock->data=NULL\n");
 555                 return 0;
 556         }
 557 
 558         if(sk->zapped==0)
 559                 return(-EIO);
 560                 
 561         err=verify_area(VERIFY_READ,uaddr,addr_len);
 562         if(err)
 563                 return err;
 564         if(addr_len!=sizeof(addr))
 565                 return -EINVAL;
 566         memcpy_fromfs(&addr,uaddr,addr_len);
 567         
 568         if(ntohs(addr.sipx_port)<0x4000 && !suser())
 569                 return(-EPERM); /* protect IPX system stuff like routing/sap */
 570         
 571         /* Source addresses are easy. It must be our network:node pair for
 572            an interface routed to IPX with the ipx routing ioctl() */
 573 
 574         if(ipx_find_socket(addr.sipx_port)!=NULL)
 575         {
 576                 if(sk->debug)
 577                         printk("IPX: bind failed because port %X in use.\n",
 578                                 (int)addr.sipx_port);
 579                 return(-EADDRINUSE);       
 580         }
 581         sk->ipx_source_addr.sock=addr.sipx_port;
 582         memcpy(sk->ipx_source_addr.node,addr.sipx_node,sizeof(sk->ipx_source_addr.node));
 583         sk->ipx_source_addr.net=addr.sipx_network;
 584         if((rt=ipxrtr_get_dev(sk->ipx_source_addr.net))==NULL)
 585         {
 586                 if(sk->debug)
 587                         printk("IPX: bind failed (no device for net %lX)\n",
 588                                 sk->ipx_source_addr.net);
 589                 return(-EADDRNOTAVAIL);
 590         }
 591         memset(sk->ipx_source_addr.node,'\0',6);
 592         memcpy(sk->ipx_source_addr.node,rt->dev->dev_addr,rt->dev->addr_len);
 593         ipx_insert_socket(sk);
 594         sk->zapped=0;
 595         if(sk->debug)
 596                 printk("IPX: socket is bound.\n");
 597         return(0);
 598 }
 599 
 600 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 601         int addr_len, int flags)
 602 {
 603         ipx_socket *sk=(ipx_socket *)sock->data;
 604         struct sockaddr_ipx addr;
 605         int err;
 606         
 607         if(sk==NULL)
 608         {
 609                 printk("IPX:connect:sock->data=NULL!\n");
 610                 return 0;
 611         }
 612 
 613         sk->state = TCP_CLOSE;  
 614         sock->state = SS_UNCONNECTED;
 615         
 616         if(addr_len!=sizeof(addr))
 617                 return(-EINVAL);
 618         err=verify_area(VERIFY_READ,uaddr,addr_len);
 619         if(err)
 620                 return err;
 621         memcpy_fromfs(&addr,uaddr,sizeof(addr));
 622         
 623         if(ntohs(addr.sipx_port)<0x4000 && !suser())
 624                 return -EPERM;
 625         if(sk->ipx_source_addr.net==0)  /* Must bind first - no autobinding in this */
 626                 return -EINVAL;
 627                 
 628         
 629         sk->ipx_dest_addr.net=addr.sipx_network;
 630         sk->ipx_dest_addr.sock=addr.sipx_port;
 631         memcpy(sk->ipx_dest_addr.node,addr.sipx_node,sizeof(sk->ipx_source_addr.node));
 632         if(ipxrtr_get_dev(sk->ipx_dest_addr.net)==NULL)
 633                 return -ENETUNREACH;
 634         sock->state = SS_CONNECTED;
 635         sk->state=TCP_ESTABLISHED;
 636         return(0);
 637 }
 638 
 639 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         return(-EOPNOTSUPP);
 642 }
 643 
 644 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 645 {
 646         if(newsock->data)
 647                 kfree_s(newsock->data,sizeof(ipx_socket));
 648         return -EOPNOTSUPP;
 649 }
 650 
 651 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 652         int *uaddr_len, int peer)
 653 {
 654         ipx_address *addr;
 655         struct sockaddr_ipx sipx;
 656         ipx_socket *sk;
 657         int len;
 658         int err;
 659         
 660         sk=(ipx_socket *)sock->data;
 661         
 662         err = verify_area(VERIFY_WRITE,uaddr_len,sizeof(long));
 663         if(err)
 664                 return err;
 665                 
 666         len = get_fs_long(uaddr_len);
 667         
 668         err = verify_area(VERIFY_WRITE, uaddr, len);
 669         if(err)
 670                 return err;
 671         
 672         if(len<sizeof(struct sockaddr_ipx))
 673                 return -EINVAL;
 674                 
 675         if(peer)
 676         {
 677                 if(sk->state!=TCP_ESTABLISHED)
 678                         return -ENOTCONN;
 679                 addr=&sk->ipx_dest_addr;
 680         }
 681         else
 682                 addr=&sk->ipx_source_addr;
 683                 
 684         sipx.sipx_family = AF_IPX;
 685         sipx.sipx_port = addr->sock;
 686         sipx.sipx_network = addr->net;
 687         memcpy(sipx.sipx_node,addr->node,sizeof(sipx.sipx_node));
 688         memcpy_tofs(uaddr,&sipx,sizeof(sipx));
 689         put_fs_long(len,uaddr_len);
 690         return(0);
 691 }
 692 
 693 
 694 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 695 {
 696         /* NULL here for pt means the packet was looped back */
 697         ipx_socket *sock;
 698         unsigned char *buff;
 699         ipx_packet *ipx;
 700         ipx_route *rt;
 701         
 702         buff=skb->data;
 703         buff+=dev->hard_header_len;
 704         ipx=(ipx_packet *)buff;
 705         
 706         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM)
 707         {
 708                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
 709                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
 710                    the same... */
 711                 kfree_skb(skb,FREE_READ);
 712                 return(0);
 713         }
 714         
 715         /* Too small */
 716         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)+dev->hard_header_len)
 717         {
 718                 kfree_skb(skb,FREE_READ);
 719                 return(0);
 720         }
 721         
 722         /* Too many hops */
 723         if(ipx->ipx_tctrl>16)
 724         {
 725                 kfree_skb(skb,FREE_READ);
 726                 return(0);
 727         }
 728         
 729         /* Not us/broadcast */
 730         if(memcmp(dev->dev_addr,ipx->ipx_dest.node,dev->addr_len)!=0
 731              && memcmp(ipx_broadcast_node,ipx->ipx_dest.node,dev->addr_len)!=0)
 732         {
 733                 /**********************************************************************************************
 734                 
 735                         IPX router. Roughly as per the Novell spec. This doesn't handle netbios flood fill
 736                         broadcast frames. See the Novell IPX router specification for more details
 737                         (for ftp from ftp.novell.com)
 738                         
 739                 ***********************************************************************************************/
 740                 
 741                 struct sk_buff *skb2;
 742                 int free_it=0;
 743                 
 744                 /* Rule: Don't forward packets that have exceeded the hop limit. This is fixed at 16 in IPX */
 745                 if(ipx->ipx_tctrl==16)
 746                 {
 747                         kfree_skb(skb,FREE_READ);
 748                         return(0);
 749                 }
 750 
 751                 /* Don't forward if we don't have a route. We ought to go off and start hunting out routes but
 752                    if someone needs this _THEY_ can add it */           
 753                 rt=ipxrtr_get_dev(ipx->ipx_dest.net);
 754                 if(rt==NULL)   /* Unlike IP we can send on the interface we received. Eg doing DIX/802.3 conversion */
 755                 {
 756                         kfree_skb(skb,FREE_READ);
 757                         return(0);
 758                 }
 759                 if(rt->dev->hard_header_len!=dev->hard_header_len)
 760                 {
 761                         /* A different header length causes a copy. Awkward to avoid with the current
 762                            sk_buff stuff. */
 763                         skb2=alloc_skb(skb->len,GFP_ATOMIC);
 764                         if(skb2==NULL)
 765                         {
 766                                 kfree_skb(skb,FREE_READ);
 767                                 return 0;
 768                         }
 769                         free_it=1;
 770                         skb2->free=1;
 771                         skb2->len=skb->len;
 772                         memcpy((char *)(skb2+1),(char *)(skb+1),skb->len);
 773                         buff=(char *)(skb2+1);
 774                         ipx=(ipx_packet *)(buff+dev->hard_header_len);
 775                 }
 776                 else
 777                 {
 778                         skb2=skb;
 779                         buff=(char *)(skb+1);
 780                 }
 781                 /* Now operate on the buffer */
 782                 /* Increase hop count */
 783                 ipx->ipx_tctrl++;
 784                 /* If the route is a gateway then forward to it */
 785                 
 786                 dev->hard_header(buff, dev, 
 787                         (rt->flags&IPX_RT_BLUEBOOK)?ntohs(ETH_P_IPX):ntohs(skb2->len),
 788                         (rt->flags&IPX_RT_ROUTED)?rt->router_node:ipx->ipx_dest.node,
 789                         NULL,   /* Our source */
 790                         skb2->len,
 791                         skb2);
 792                         
 793                 dev_queue_xmit(skb2,dev,SOPRI_NORMAL);
 794 
 795                 if(free_it)
 796                         kfree_skb(skb,FREE_READ);
 797                 return(0);
 798         }
 799         /************ End of router: Now sanity check stuff for us ***************/
 800         
 801         /* Ok its for us ! */
 802         
 803         sock=ipx_find_socket(ipx->ipx_dest.sock);
 804         if(sock==NULL)  /* But not one of our sockets */
 805         {
 806                 kfree_skb(skb,FREE_READ);
 807                 return(0);
 808         }
 809         
 810         if(sock->rmem_alloc>=sock->rcvbuf)
 811         {
 812                 kfree_skb(skb,FREE_READ);       /* Socket is full */
 813                 return(0);
 814         }
 815         
 816         sock->rmem_alloc+=skb->mem_len;
 817         skb_queue_tail(&sock->receive_queue,skb);
 818         if(!sock->dead)
 819                 sock->data_ready(sock,skb->len);
 820         return(0);
 821 }
 822 
 823 
 824 
 825 
 826 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 827         unsigned flags, struct sockaddr *usip, int addr_len)
 828 {
 829         ipx_socket *sk=(ipx_socket *)sock->data;
 830         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
 831         int err;
 832         struct sockaddr_ipx sipx;
 833         struct sk_buff *skb;
 834         struct device *dev;
 835         struct ipx_packet *ipx;
 836         int size;
 837         ipx_route *rt;
 838 
 839         if(flags)
 840                 return -EINVAL;
 841         if(len<0)
 842                 return -EINVAL;
 843         if(len == 0)
 844                 return 0;
 845                 
 846         if(usipx)
 847         {
 848                 if(addr_len <sizeof(sipx))
 849                         return(-EINVAL);
 850                 err=verify_area(VERIFY_READ,usipx,sizeof(sipx));
 851                 if(err)
 852                         return(err);
 853                 memcpy_fromfs(&sipx,usipx,sizeof(sipx));
 854                 if(sipx.sipx_family != AF_IPX)
 855                         return -EINVAL;
 856                 if(htons(sipx.sipx_port)<0x4000 && !suser())
 857                         return -EPERM;
 858         }
 859         else
 860         {
 861                 if(sk->state!=TCP_ESTABLISHED)
 862                         return -ENOTCONN;
 863                 sipx.sipx_family=AF_IPX;
 864                 sipx.sipx_port=sk->ipx_dest_addr.sock;
 865                 sipx.sipx_network=sk->ipx_dest_addr.net;
 866                 memcpy(sipx.sipx_node,sk->ipx_dest_addr.node,sizeof(sipx.sipx_node));
 867         }
 868         
 869         if(sk->debug)
 870                 printk("IPX: sendto: Addresses built.\n");
 871         if(!sk->broadcast && memcmp(&sipx.sipx_node,&ipx_broadcast_node,6)==0)
 872                 return -ENETUNREACH;
 873         /* Build a packet */
 874         
 875         if(sk->debug)
 876                 printk("IPX: sendto: building packet.\n");
 877         err=verify_area(VERIFY_READ,ubuf,len);
 878         if(err)
 879                 return err;
 880                 
 881         size=sizeof(ipx_packet)+len;    /* For mac headers */
 882 
 883         /* Find out where this has to go */
 884         rt=ipxrtr_get_dev(sipx.sipx_network);
 885         if(rt==NULL)
 886         {
 887                 return -ENETUNREACH;
 888         }
 889         
 890         dev=rt->dev;
 891         
 892         size+=dev->hard_header_len;
 893                 
 894         if(sk->debug)
 895                 printk("IPX: sendto: allocating buffer (%d)\n",size-sizeof(struct sk_buff));
 896         
 897         if(size+sk->wmem_alloc>sk->sndbuf)
 898                 return -EAGAIN;
 899                 
 900         skb=alloc_skb(size,GFP_KERNEL);
 901         if(skb==NULL)
 902                 return -ENOMEM;
 903         if(skb->mem_len+sk->wmem_alloc>sk->sndbuf)
 904         {
 905                 kfree_skb(skb,FREE_WRITE);
 906                 return -EAGAIN;
 907         }
 908 
 909         sk->wmem_alloc+=skb->mem_len;
 910         skb->sk=sk;
 911         skb->free=1;
 912         skb->arp=1;
 913         skb->len=size-sizeof(struct sk_buff);
 914 
 915         if(sk->debug)
 916                 printk("Building MAC header.\n");               
 917         skb->dev=rt->dev;
 918         
 919         dev->hard_header(skb->data,skb->dev,
 920                 (rt->flags&IPX_RT_BLUEBOOK)?ntohs(ETH_P_IPX):ntohs(len+sizeof(ipx_packet)),
 921                 (rt->flags&IPX_RT_ROUTED)?rt->router_node:sipx.sipx_node,
 922                 NULL,
 923                 len+sizeof(ipx_packet),
 924                 skb);
 925 
 926         /* Now the IPX */
 927         if(sk->debug)
 928                 printk("Building IPX Header.\n");
 929         ipx=(ipx_packet *)skb->data+skb->dev->hard_header_len;
 930         ipx->ipx_checksum=0xFFFF;
 931         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
 932         ipx->ipx_tctrl=0;
 933         ipx->ipx_type=sk->ipx_type;
 934         memcpy(&ipx->ipx_source,&sk->ipx_source_addr,sizeof(ipx->ipx_source));
 935         ipx->ipx_dest.net=sipx.sipx_network;
 936         memcpy(ipx->ipx_dest.node,sipx.sipx_node,sizeof(ipx->ipx_dest.node));
 937         ipx->ipx_dest.sock=sipx.sipx_port;
 938         if(sk->debug)
 939                 printk("IPX: Appending user data.\n");
 940         /* User data follows immediately after the IPX data */
 941         memcpy_fromfs((char *)(ipx+1),ubuf,len);
 942         if(sk->debug)
 943                 printk("IPX: Transmitting buffer\n");
 944         if(dev->flags&IFF_LOOPBACK)
 945                 /* loop back */
 946                 ipx_rcv(skb,dev,NULL);
 947         else
 948                 dev_queue_xmit(skb,dev,SOPRI_NORMAL);
 949         return len;
 950 }
 951 
 952 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 953 {
 954         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
 955 }
 956 
 957 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 958 {
 959         return ipx_send(sock,ubuf,size,noblock,0);
 960 }
 961 
 962 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 963                    unsigned flags, struct sockaddr *sip, int *addr_len)
 964 {
 965         ipx_socket *sk=(ipx_socket *)sock->data;
 966         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
 967         /* FILL ME IN */
 968         int copied = 0;
 969         struct sk_buff *skb;
 970         int er;
 971 
 972         if(sk->err)
 973         {
 974                 er= -sk->err;
 975                 sk->err=0;
 976                 return er;
 977         }
 978         
 979         if(size==0)
 980                 return 0;
 981         if(size<0)
 982                 return -EINVAL;
 983         if(addr_len)
 984         {
 985                 er=verify_area(VERIFY_WRITE,addr_len,sizeof(*addr_len));
 986                 if(er)
 987                         return er;
 988                 put_fs_long(sizeof(*sipx),addr_len);
 989         }
 990         if(sipx)
 991         {
 992                 er=verify_area(VERIFY_WRITE,sipx,sizeof(*sipx));
 993                 if(er)
 994                         return er;
 995         }
 996         er=verify_area(VERIFY_WRITE,ubuf,size);
 997         if(er)
 998                 return er;
 999         skb=skb_recv_datagram(sk,flags,noblock,&er);
1000         if(skb==NULL)
1001                 return er;
1002         copied=(size<skb->len)?size:skb->len;
1003         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1004         sk->stamp=skb->stamp;
1005         
1006         if(sipx)
1007         {
1008                 struct sockaddr_ipx addr;
1009                 
1010                 addr.sipx_family=AF_IPX;
1011                 addr.sipx_port=((ipx_packet*)skb->h.raw)->ipx_source.sock;
1012                 memcpy(addr.sipx_node,((ipx_packet*)skb->h.raw)->ipx_source.node,sizeof(addr.sipx_node));
1013                 addr.sipx_network=((ipx_packet*)skb->h.raw)->ipx_source.net;
1014                 memcpy_tofs(sipx,&addr,sizeof(*sipx));
1015         }
1016         skb_free_datagram(skb);
1017         return(copied);
1018 }               
1019 
1020 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1021         unsigned flags)
1022 {
1023         ipx_socket *sk=(ipx_socket *)sock->data;
1024         if(sk->zapped)
1025                 return -ENOTCONN;
1026         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1027 }
1028 
1029 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1030 {
1031         return ipx_recv(sock,ubuf,size,noblock,0);
1032 }
1033 
1034 
1035 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1036 {
1037         return -EOPNOTSUPP;
1038 }
1039 
1040 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1041 {
1042         ipx_socket *sk=(ipx_socket *)sock->data;
1043         
1044         return datagram_select(sk,sel_type,wait);
1045 }
1046 
1047 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1048 {
1049         
1050         switch(cmd)
1051         {
1052                 case SIOCADDRT:
1053                 case SIOCDELRT:
1054                         if(!suser())
1055                                 return -EPERM;
1056                         return(ipxrtr_ioctl(cmd,(void *)arg));
1057                 default:
1058                         return -EINVAL;
1059         }
1060         /*NOTREACHED*/
1061         return(0);
1062 }
1063 
1064 static struct proto_ops ipx_proto_ops = {
1065         AF_IPX,
1066         
1067         ipx_create,
1068         ipx_dup,
1069         ipx_release,
1070         ipx_bind,
1071         ipx_connect,
1072         ipx_socketpair,
1073         ipx_accept,
1074         ipx_getname,
1075         ipx_read,
1076         ipx_write,
1077         ipx_select,
1078         ipx_ioctl,
1079         ipx_listen,
1080         ipx_send,
1081         ipx_recv,
1082         ipx_sendto,
1083         ipx_recvfrom,
1084         ipx_shutdown,
1085         ipx_setsockopt,
1086         ipx_getsockopt,
1087         ipx_fcntl,
1088 };
1089 
1090 /* Called by ddi.c on kernel start up */
1091 
1092 static struct packet_type ipx_8023_packet_type = 
1093 {
1094         0,      /* MUTTER ntohs(ETH_P_8023),*/
1095         0,              /* copy */
1096         ipx_rcv,
1097         NULL,
1098         NULL,
1099 };
1100  
1101 static struct packet_type ipx_dix_packet_type = 
1102 {
1103         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1104         0,              /* copy */
1105         ipx_rcv,
1106         NULL,
1107         NULL,
1108 };
1109  
1110 
1111 void ipx_proto_init(struct ddi_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1112 {
1113         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1114         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1115         dev_add_pack(&ipx_dix_packet_type);
1116         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1117         dev_add_pack(&ipx_8023_packet_type);
1118         
1119         printk("Swansea University Computer Society IPX 0.24 BETA for NET3 ALPHA.008\n");
1120         
1121 }
1122 
1123 #endif

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