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         sk->localroute=0;
 507         
 508         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
 509         memset(&sk->ipx_source_addr,'\0',sizeof(sk->ipx_source_addr));
 510         sk->mtu=IPX_MTU;
 511         
 512         if(sock!=NULL)
 513         {
 514                 sock->data=(void *)sk;
 515                 sk->sleep=sock->wait;
 516         }
 517         
 518         sk->state_change=def_callback1;
 519         sk->data_ready=def_callback2;
 520         sk->write_space=def_callback1;
 521         sk->error_report=def_callback1;
 522 
 523         sk->zapped=1;
 524         return(0);
 525 }
 526 
 527 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 528 {
 529         return(ipx_create(newsock,SOCK_DGRAM));
 530 }
 531 
 532 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 533 {
 534         ipx_socket *sk=(ipx_socket *)sock->data;
 535         if(sk==NULL)
 536                 return(0);
 537         if(!sk->dead)
 538                 sk->state_change(sk);
 539         sk->dead=1;
 540         sock->data=NULL;
 541         ipx_destroy_socket(sk);
 542         return(0);
 543 }
 544                 
 545 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 546 {
 547         ipx_socket *sk;
 548         int err;
 549         struct sockaddr_ipx addr;
 550         struct ipx_route *rt;
 551         
 552         sk=(ipx_socket *)sock->data;
 553         if(sk==NULL)
 554         {
 555                 printk("IPX:bind:sock->data=NULL\n");
 556                 return 0;
 557         }
 558 
 559         if(sk->zapped==0)
 560                 return(-EIO);
 561                 
 562         err=verify_area(VERIFY_READ,uaddr,addr_len);
 563         if(err)
 564                 return err;
 565         if(addr_len!=sizeof(addr))
 566                 return -EINVAL;
 567         memcpy_fromfs(&addr,uaddr,addr_len);
 568         
 569         if(ntohs(addr.sipx_port)<0x4000 && !suser())
 570                 return(-EPERM); /* protect IPX system stuff like routing/sap */
 571         
 572         /* Source addresses are easy. It must be our network:node pair for
 573            an interface routed to IPX with the ipx routing ioctl() */
 574 
 575         if(ipx_find_socket(addr.sipx_port)!=NULL)
 576         {
 577                 if(sk->debug)
 578                         printk("IPX: bind failed because port %X in use.\n",
 579                                 (int)addr.sipx_port);
 580                 return(-EADDRINUSE);       
 581         }
 582         sk->ipx_source_addr.sock=addr.sipx_port;
 583         memcpy(sk->ipx_source_addr.node,addr.sipx_node,sizeof(sk->ipx_source_addr.node));
 584         sk->ipx_source_addr.net=addr.sipx_network;
 585         if((rt=ipxrtr_get_dev(sk->ipx_source_addr.net))==NULL)
 586         {
 587                 if(sk->debug)
 588                         printk("IPX: bind failed (no device for net %lX)\n",
 589                                 sk->ipx_source_addr.net);
 590                 return(-EADDRNOTAVAIL);
 591         }
 592         memset(sk->ipx_source_addr.node,'\0',6);
 593         memcpy(sk->ipx_source_addr.node,rt->dev->dev_addr,rt->dev->addr_len);
 594         ipx_insert_socket(sk);
 595         sk->zapped=0;
 596         if(sk->debug)
 597                 printk("IPX: socket is bound.\n");
 598         return(0);
 599 }
 600 
 601 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 602         int addr_len, int flags)
 603 {
 604         ipx_socket *sk=(ipx_socket *)sock->data;
 605         struct sockaddr_ipx addr;
 606         int err;
 607         
 608         if(sk==NULL)
 609         {
 610                 printk("IPX:connect:sock->data=NULL!\n");
 611                 return 0;
 612         }
 613 
 614         sk->state = TCP_CLOSE;  
 615         sock->state = SS_UNCONNECTED;
 616         
 617         if(addr_len!=sizeof(addr))
 618                 return(-EINVAL);
 619         err=verify_area(VERIFY_READ,uaddr,addr_len);
 620         if(err)
 621                 return err;
 622         memcpy_fromfs(&addr,uaddr,sizeof(addr));
 623         
 624         if(ntohs(addr.sipx_port)<0x4000 && !suser())
 625                 return -EPERM;
 626         if(sk->ipx_source_addr.net==0)  /* Must bind first - no autobinding in this */
 627                 return -EINVAL;
 628                 
 629         
 630         sk->ipx_dest_addr.net=addr.sipx_network;
 631         sk->ipx_dest_addr.sock=addr.sipx_port;
 632         memcpy(sk->ipx_dest_addr.node,addr.sipx_node,sizeof(sk->ipx_source_addr.node));
 633         if(ipxrtr_get_dev(sk->ipx_dest_addr.net)==NULL)
 634                 return -ENETUNREACH;
 635         sock->state = SS_CONNECTED;
 636         sk->state=TCP_ESTABLISHED;
 637         return(0);
 638 }
 639 
 640 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 641 {
 642         return(-EOPNOTSUPP);
 643 }
 644 
 645 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 646 {
 647         if(newsock->data)
 648                 kfree_s(newsock->data,sizeof(ipx_socket));
 649         return -EOPNOTSUPP;
 650 }
 651 
 652 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 653         int *uaddr_len, int peer)
 654 {
 655         ipx_address *addr;
 656         struct sockaddr_ipx sipx;
 657         ipx_socket *sk;
 658         int len;
 659         int err;
 660         
 661         sk=(ipx_socket *)sock->data;
 662         
 663         err = verify_area(VERIFY_WRITE,uaddr_len,sizeof(long));
 664         if(err)
 665                 return err;
 666                 
 667         len = get_fs_long(uaddr_len);
 668         
 669         err = verify_area(VERIFY_WRITE, uaddr, len);
 670         if(err)
 671                 return err;
 672         
 673         if(len<sizeof(struct sockaddr_ipx))
 674                 return -EINVAL;
 675                 
 676         if(peer)
 677         {
 678                 if(sk->state!=TCP_ESTABLISHED)
 679                         return -ENOTCONN;
 680                 addr=&sk->ipx_dest_addr;
 681         }
 682         else
 683                 addr=&sk->ipx_source_addr;
 684                 
 685         sipx.sipx_family = AF_IPX;
 686         sipx.sipx_port = addr->sock;
 687         sipx.sipx_network = addr->net;
 688         memcpy(sipx.sipx_node,addr->node,sizeof(sipx.sipx_node));
 689         memcpy_tofs(uaddr,&sipx,sizeof(sipx));
 690         put_fs_long(len,uaddr_len);
 691         return(0);
 692 }
 693 
 694 
 695 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 696 {
 697         /* NULL here for pt means the packet was looped back */
 698         ipx_socket *sock;
 699         unsigned char *buff;
 700         ipx_packet *ipx;
 701         ipx_route *rt;
 702         
 703         buff=skb->data;
 704         buff+=dev->hard_header_len;
 705         ipx=(ipx_packet *)buff;
 706         
 707         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM)
 708         {
 709                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
 710                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
 711                    the same... */
 712                 kfree_skb(skb,FREE_READ);
 713                 return(0);
 714         }
 715         
 716         /* Too small */
 717         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)+dev->hard_header_len)
 718         {
 719                 kfree_skb(skb,FREE_READ);
 720                 return(0);
 721         }
 722         
 723         /* Too many hops */
 724         if(ipx->ipx_tctrl>16)
 725         {
 726                 kfree_skb(skb,FREE_READ);
 727                 return(0);
 728         }
 729         
 730         /* Not us/broadcast */
 731         if(memcmp(dev->dev_addr,ipx->ipx_dest.node,dev->addr_len)!=0
 732              && memcmp(ipx_broadcast_node,ipx->ipx_dest.node,dev->addr_len)!=0)
 733         {
 734                 /**********************************************************************************************
 735                 
 736                         IPX router. Roughly as per the Novell spec. This doesn't handle netbios flood fill
 737                         broadcast frames. See the Novell IPX router specification for more details
 738                         (for ftp from ftp.novell.com)
 739                         
 740                 ***********************************************************************************************/
 741                 
 742                 struct sk_buff *skb2;
 743                 int free_it=0;
 744                 
 745                 /* Rule: Don't forward packets that have exceeded the hop limit. This is fixed at 16 in IPX */
 746                 if(ipx->ipx_tctrl==16)
 747                 {
 748                         kfree_skb(skb,FREE_READ);
 749                         return(0);
 750                 }
 751 
 752                 /* Don't forward if we don't have a route. We ought to go off and start hunting out routes but
 753                    if someone needs this _THEY_ can add it */           
 754                 rt=ipxrtr_get_dev(ipx->ipx_dest.net);
 755                 if(rt==NULL)   /* Unlike IP we can send on the interface we received. Eg doing DIX/802.3 conversion */
 756                 {
 757                         kfree_skb(skb,FREE_READ);
 758                         return(0);
 759                 }
 760                 if(rt->dev->hard_header_len!=dev->hard_header_len)
 761                 {
 762                         /* A different header length causes a copy. Awkward to avoid with the current
 763                            sk_buff stuff. */
 764                         skb2=alloc_skb(skb->len,GFP_ATOMIC);
 765                         if(skb2==NULL)
 766                         {
 767                                 kfree_skb(skb,FREE_READ);
 768                                 return 0;
 769                         }
 770                         free_it=1;
 771                         skb2->free=1;
 772                         skb2->len=skb->len;
 773                         memcpy((char *)(skb2+1),(char *)(skb+1),skb->len);
 774                         buff=(char *)(skb2+1);
 775                         ipx=(ipx_packet *)(buff+dev->hard_header_len);
 776                 }
 777                 else
 778                 {
 779                         skb2=skb;
 780                         buff=(char *)(skb+1);
 781                 }
 782                 /* Now operate on the buffer */
 783                 /* Increase hop count */
 784                 ipx->ipx_tctrl++;
 785                 /* If the route is a gateway then forward to it */
 786                 
 787                 dev->hard_header(buff, dev, 
 788                         (rt->flags&IPX_RT_BLUEBOOK)?ntohs(ETH_P_IPX):ntohs(skb2->len),
 789                         (rt->flags&IPX_RT_ROUTED)?rt->router_node:ipx->ipx_dest.node,
 790                         NULL,   /* Our source */
 791                         skb2->len,
 792                         skb2);
 793                         
 794                 dev_queue_xmit(skb2,dev,SOPRI_NORMAL);
 795 
 796                 if(free_it)
 797                         kfree_skb(skb,FREE_READ);
 798                 return(0);
 799         }
 800         /************ End of router: Now sanity check stuff for us ***************/
 801         
 802         /* Ok its for us ! */
 803         
 804         sock=ipx_find_socket(ipx->ipx_dest.sock);
 805         if(sock==NULL)  /* But not one of our sockets */
 806         {
 807                 kfree_skb(skb,FREE_READ);
 808                 return(0);
 809         }
 810         
 811         if(sock->rmem_alloc>=sock->rcvbuf)
 812         {
 813                 kfree_skb(skb,FREE_READ);       /* Socket is full */
 814                 return(0);
 815         }
 816         
 817         sock->rmem_alloc+=skb->mem_len;
 818         skb_queue_tail(&sock->receive_queue,skb);
 819         if(!sock->dead)
 820                 sock->data_ready(sock,skb->len);
 821         return(0);
 822 }
 823 
 824 
 825 
 826 
 827 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 828         unsigned flags, struct sockaddr *usip, int addr_len)
 829 {
 830         ipx_socket *sk=(ipx_socket *)sock->data;
 831         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
 832         int err;
 833         struct sockaddr_ipx sipx;
 834         struct sk_buff *skb;
 835         struct device *dev;
 836         struct ipx_packet *ipx;
 837         int size;
 838         ipx_route *rt;
 839 
 840         if(flags&~MSG_DONTROUTE)
 841                 return -EINVAL;
 842         if(len<0)
 843                 return -EINVAL;
 844         if(len == 0)
 845                 return 0;
 846                 
 847         if(usipx)
 848         {
 849                 if(addr_len <sizeof(sipx))
 850                         return(-EINVAL);
 851                 err=verify_area(VERIFY_READ,usipx,sizeof(sipx));
 852                 if(err)
 853                         return(err);
 854                 memcpy_fromfs(&sipx,usipx,sizeof(sipx));
 855                 if(sipx.sipx_family != AF_IPX)
 856                         return -EINVAL;
 857                 if(htons(sipx.sipx_port)<0x4000 && !suser())
 858                         return -EPERM;
 859         }
 860         else
 861         {
 862                 if(sk->state!=TCP_ESTABLISHED)
 863                         return -ENOTCONN;
 864                 sipx.sipx_family=AF_IPX;
 865                 sipx.sipx_port=sk->ipx_dest_addr.sock;
 866                 sipx.sipx_network=sk->ipx_dest_addr.net;
 867                 memcpy(sipx.sipx_node,sk->ipx_dest_addr.node,sizeof(sipx.sipx_node));
 868         }
 869         
 870         if(sk->debug)
 871                 printk("IPX: sendto: Addresses built.\n");
 872         if(!sk->broadcast && memcmp(&sipx.sipx_node,&ipx_broadcast_node,6)==0)
 873                 return -ENETUNREACH;
 874         /* Build a packet */
 875         
 876         if(sk->debug)
 877                 printk("IPX: sendto: building packet.\n");
 878         err=verify_area(VERIFY_READ,ubuf,len);
 879         if(err)
 880                 return err;
 881                 
 882         size=sizeof(ipx_packet)+len;    /* For mac headers */
 883 
 884         /* Find out where this has to go */
 885         rt=ipxrtr_get_dev(sipx.sipx_network);
 886         /* No suitable route - no gateways when not routing */
 887         if(rt==NULL || ((flags&IPX_RT_ROUTED)&& ((flags&MSG_DONTROUTE)||sk->localroute)))
 888         {
 889                 return -ENETUNREACH;
 890         }
 891         
 892         dev=rt->dev;
 893         
 894         size+=dev->hard_header_len;
 895                 
 896         if(sk->debug)
 897                 printk("IPX: sendto: allocating buffer (%d)\n",size-sizeof(struct sk_buff));
 898         
 899         if(size+sk->wmem_alloc>sk->sndbuf)
 900                 return -EAGAIN;
 901                 
 902         skb=alloc_skb(size,GFP_KERNEL);
 903         if(skb==NULL)
 904                 return -ENOMEM;
 905         if(skb->mem_len+sk->wmem_alloc>sk->sndbuf)
 906         {
 907                 kfree_skb(skb,FREE_WRITE);
 908                 return -EAGAIN;
 909         }
 910 
 911         sk->wmem_alloc+=skb->mem_len;
 912         skb->sk=sk;
 913         skb->free=1;
 914         skb->arp=1;
 915         skb->len=size-sizeof(struct sk_buff);
 916 
 917         if(sk->debug)
 918                 printk("Building MAC header.\n");               
 919         skb->dev=rt->dev;
 920         
 921         dev->hard_header(skb->data,skb->dev,
 922                 (rt->flags&IPX_RT_BLUEBOOK)?ETH_P_IPX:ETH_P_802_3),
 923                 (rt->flags&IPX_RT_ROUTED)?rt->router_node:sipx.sipx_node,
 924                 NULL,
 925                 len+sizeof(ipx_packet),
 926                 skb);
 927 
 928         /* Now the IPX */
 929         if(sk->debug)
 930                 printk("Building IPX Header.\n");
 931         ipx=(ipx_packet *)skb->data+skb->dev->hard_header_len;
 932         ipx->ipx_checksum=0xFFFF;
 933         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
 934         ipx->ipx_tctrl=0;
 935         ipx->ipx_type=sk->ipx_type;
 936         memcpy(&ipx->ipx_source,&sk->ipx_source_addr,sizeof(ipx->ipx_source));
 937         ipx->ipx_dest.net=sipx.sipx_network;
 938         memcpy(ipx->ipx_dest.node,sipx.sipx_node,sizeof(ipx->ipx_dest.node));
 939         ipx->ipx_dest.sock=sipx.sipx_port;
 940         if(sk->debug)
 941                 printk("IPX: Appending user data.\n");
 942         /* User data follows immediately after the IPX data */
 943         memcpy_fromfs((char *)(ipx+1),ubuf,len);
 944         if(sk->debug)
 945                 printk("IPX: Transmitting buffer\n");
 946         if(dev->flags&IFF_LOOPBACK)
 947                 /* loop back */
 948                 ipx_rcv(skb,dev,NULL);
 949         else
 950                 dev_queue_xmit(skb,dev,SOPRI_NORMAL);
 951         return len;
 952 }
 953 
 954 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 955 {
 956         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
 957 }
 958 
 959 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 960 {
 961         return ipx_send(sock,ubuf,size,noblock,0);
 962 }
 963 
 964 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 965                    unsigned flags, struct sockaddr *sip, int *addr_len)
 966 {
 967         ipx_socket *sk=(ipx_socket *)sock->data;
 968         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
 969         /* FILL ME IN */
 970         int copied = 0;
 971         struct sk_buff *skb;
 972         int er;
 973 
 974         if(sk->err)
 975         {
 976                 er= -sk->err;
 977                 sk->err=0;
 978                 return er;
 979         }
 980         
 981         if(size==0)
 982                 return 0;
 983         if(size<0)
 984                 return -EINVAL;
 985         if(addr_len)
 986         {
 987                 er=verify_area(VERIFY_WRITE,addr_len,sizeof(*addr_len));
 988                 if(er)
 989                         return er;
 990                 put_fs_long(sizeof(*sipx),addr_len);
 991         }
 992         if(sipx)
 993         {
 994                 er=verify_area(VERIFY_WRITE,sipx,sizeof(*sipx));
 995                 if(er)
 996                         return er;
 997         }
 998         er=verify_area(VERIFY_WRITE,ubuf,size);
 999         if(er)
1000                 return er;
1001         skb=skb_recv_datagram(sk,flags,noblock,&er);
1002         if(skb==NULL)
1003                 return er;
1004         copied=(size<skb->len)?size:skb->len;
1005         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1006         sk->stamp=skb->stamp;
1007         
1008         if(sipx)
1009         {
1010                 struct sockaddr_ipx addr;
1011                 
1012                 addr.sipx_family=AF_IPX;
1013                 addr.sipx_port=((ipx_packet*)skb->h.raw)->ipx_source.sock;
1014                 memcpy(addr.sipx_node,((ipx_packet*)skb->h.raw)->ipx_source.node,sizeof(addr.sipx_node));
1015                 addr.sipx_network=((ipx_packet*)skb->h.raw)->ipx_source.net;
1016                 memcpy_tofs(sipx,&addr,sizeof(*sipx));
1017         }
1018         skb_free_datagram(skb);
1019         return(copied);
1020 }               
1021 
1022 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1023         unsigned flags)
1024 {
1025         ipx_socket *sk=(ipx_socket *)sock->data;
1026         if(sk->zapped)
1027                 return -ENOTCONN;
1028         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1029 }
1030 
1031 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1032 {
1033         return ipx_recv(sock,ubuf,size,noblock,0);
1034 }
1035 
1036 
1037 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1038 {
1039         return -EOPNOTSUPP;
1040 }
1041 
1042 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1043 {
1044         ipx_socket *sk=(ipx_socket *)sock->data;
1045         
1046         return datagram_select(sk,sel_type,wait);
1047 }
1048 
1049 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1050 {
1051         
1052         switch(cmd)
1053         {
1054                 case SIOCADDRT:
1055                 case SIOCDELRT:
1056                         if(!suser())
1057                                 return -EPERM;
1058                         return(ipxrtr_ioctl(cmd,(void *)arg));
1059                 default:
1060                         return -EINVAL;
1061         }
1062         /*NOTREACHED*/
1063         return(0);
1064 }
1065 
1066 static struct proto_ops ipx_proto_ops = {
1067         AF_IPX,
1068         
1069         ipx_create,
1070         ipx_dup,
1071         ipx_release,
1072         ipx_bind,
1073         ipx_connect,
1074         ipx_socketpair,
1075         ipx_accept,
1076         ipx_getname,
1077         ipx_read,
1078         ipx_write,
1079         ipx_select,
1080         ipx_ioctl,
1081         ipx_listen,
1082         ipx_send,
1083         ipx_recv,
1084         ipx_sendto,
1085         ipx_recvfrom,
1086         ipx_shutdown,
1087         ipx_setsockopt,
1088         ipx_getsockopt,
1089         ipx_fcntl,
1090 };
1091 
1092 /* Called by ddi.c on kernel start up */
1093 
1094 static struct packet_type ipx_8023_packet_type = 
1095 {
1096         0,      /* MUTTER ntohs(ETH_P_8023),*/
1097         0,              /* copy */
1098         ipx_rcv,
1099         NULL,
1100         NULL,
1101 };
1102  
1103 static struct packet_type ipx_dix_packet_type = 
1104 {
1105         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1106         0,              /* copy */
1107         ipx_rcv,
1108         NULL,
1109         NULL,
1110 };
1111  
1112 
1113 void ipx_proto_init(struct ddi_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1114 {
1115         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1116         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1117         dev_add_pack(&ipx_dix_packet_type);
1118         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1119         dev_add_pack(&ipx_8023_packet_type);
1120         
1121         printk("Swansea University Computer Society IPX 0.24 BETA for NET3 ALPHA.008\n");
1122         
1123 }
1124 
1125 #endif

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