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

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