root/net/inet/ipx.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipxcfg_set_auto_create
  2. ipxcfg_set_auto_select
  3. ipxcfg_get_config_data
  4. ipx_remove_socket
  5. ipx_destroy_socket
  6. ipxitf_clear_primary_net
  7. ipxitf_find_using_phys
  8. ipxitf_find_using_net
  9. ipxitf_insert_socket
  10. ipxitf_find_socket
  11. ipxitf_down
  12. ipxitf_device_event
  13. ipxitf_def_skb_handler
  14. ipxitf_demux_socket
  15. ipxitf_adjust_skbuff
  16. ipxitf_send
  17. ipxitf_add_local_route
  18. ipxitf_rcv
  19. ipxitf_insert
  20. ipxitf_create_internal
  21. ipxitf_create
  22. ipxitf_delete
  23. ipxitf_auto_create
  24. ipxitf_ioctl
  25. ipxrtr_lookup
  26. ipxrtr_add_route
  27. ipxrtr_del_routes
  28. ipxrtr_create
  29. ipxrtr_delete
  30. ipxrtr_route_packet
  31. ipxrtr_route_skb
  32. ipxrtr_ioctl
  33. ipx_frame_name
  34. ipx_device_name
  35. ipx_get_interface_info
  36. ipx_get_info
  37. ipx_rt_get_info
  38. ipx_fcntl
  39. ipx_setsockopt
  40. ipx_getsockopt
  41. ipx_listen
  42. def_callback1
  43. def_callback2
  44. ipx_create
  45. ipx_release
  46. ipx_dup
  47. ipx_first_free_socketnum
  48. ipx_bind
  49. ipx_connect
  50. ipx_socketpair
  51. ipx_accept
  52. ipx_getname
  53. dump_data
  54. dump_addr
  55. dump_hdr
  56. dump_pkt
  57. ipx_rcv
  58. ipx_sendto
  59. ipx_send
  60. ipx_recvfrom
  61. ipx_write
  62. ipx_recv
  63. ipx_read
  64. ipx_shutdown
  65. ipx_select
  66. ipx_ioctl
  67. 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  *      Revision 0.27:  Autobind <Mark Evans>
  30  *      Revision 0.28:  Small fix for multiple local networks <Thomas Winder>
  31  *      Revision 0.29:  Assorted major errors removed <Mark Evans>
  32  *                      Small correction to promisc mode error fix <Alan Cox>
  33  *                      Asynchronous I/O support.
  34  *                      Changed to use notifiers and the newer packet_type stuff.
  35  *                      Assorted major fixes <Alejandro Liu>
  36  *
  37  *      Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
  38  *      Neither Greg Page nor Caldera, Inc. admit liability nor provide 
  39  *      warranty for any of this software. This material is provided 
  40  *      "AS-IS" and at no charge.               
  41  */
  42   
  43 #include <linux/config.h>
  44 #include <linux/errno.h>
  45 #include <linux/types.h>
  46 #include <linux/socket.h>
  47 #include <linux/in.h>
  48 #include <linux/kernel.h>
  49 #include <linux/sched.h>
  50 #include <linux/timer.h>
  51 #include <linux/string.h>
  52 #include <linux/sockios.h>
  53 #include <linux/net.h>
  54 #include <linux/ipx.h>
  55 #include <linux/inet.h>
  56 #include <linux/netdevice.h>
  57 #include <linux/skbuff.h>
  58 #include "sock.h"
  59 #include <asm/segment.h>
  60 #include <asm/system.h>
  61 #include <linux/fcntl.h>
  62 #include <linux/mm.h>
  63 #include <linux/termios.h>      /* For TIOCOUTQ/INQ */
  64 #include <linux/interrupt.h>
  65 #include "p8022.h"
  66 #include "psnap.h"
  67 
  68 #ifdef CONFIG_IPX
  69 /* Configuration Variables */
  70 static unsigned char    ipxcfg_max_hops = 16;
  71 static char     ipxcfg_auto_select_primary = 0;
  72 static char     ipxcfg_auto_create_interfaces = 0;
  73 
  74 /* Global Variables */
  75 static struct datalink_proto    *p8022_datalink = NULL;
  76 static struct datalink_proto    *pEII_datalink = NULL;
  77 static struct datalink_proto    *p8023_datalink = NULL;
  78 static struct datalink_proto    *pSNAP_datalink = NULL;
  79 
  80 static ipx_interface    *ipx_interfaces = NULL;
  81 static ipx_route        *ipx_routes = NULL;
  82 static ipx_interface    *ipx_internal_net = NULL;
  83 static ipx_interface    *ipx_primary_net = NULL;
  84 
  85 static int
  86 ipxcfg_set_auto_create(char val)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         ipxcfg_auto_create_interfaces = val;
  89         return 0;
  90 }
  91                 
  92 static int
  93 ipxcfg_set_auto_select(char val)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95         ipxcfg_auto_select_primary = val;
  96         if (val && (ipx_primary_net == NULL))
  97                 ipx_primary_net = ipx_interfaces;
  98         return 0;
  99 }
 100 
 101 static int
 102 ipxcfg_get_config_data(ipx_config_data *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         ipx_config_data vals;
 105         
 106         vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
 107         vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
 108         memcpy_tofs(arg, &vals, sizeof(vals));
 109         return 0;
 110 }
 111 
 112 
 113 /***********************************************************************************************************************\
 114 *                                                                                                                       *
 115 *                                               Handlers for the socket list.                                           *
 116 *                                                                                                                       *
 117 \***********************************************************************************************************************/
 118 
 119 /*
 120  *      Note: Sockets may not be removed _during_ an interrupt or inet_bh
 121  *      handler using this technique. They can be added although we do not
 122  *      use this facility.
 123  */
 124  
 125 static void 
 126 ipx_remove_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         ipx_socket      *s;
 129         ipx_interface   *intrfc;
 130         unsigned long   flags;
 131 
 132         save_flags(flags);
 133         cli();
 134         
 135         /* Determine interface with which socket is associated */
 136         intrfc = sk->ipx_intrfc;
 137         if (intrfc == NULL) {
 138                 restore_flags(flags);
 139                 return;
 140         }
 141 
 142         s=intrfc->if_sklist;
 143         if(s==sk) {
 144                 intrfc->if_sklist=s->next;
 145                 restore_flags(flags);
 146                 return;
 147         } 
 148 
 149         while(s && s->next) {
 150                 if(s->next==sk) {
 151                         s->next=sk->next;
 152                         restore_flags(flags);
 153                         return;
 154                 }
 155                 s=s->next;
 156         }
 157         restore_flags(flags);
 158 }
 159 
 160 /*
 161  *      This is only called from user mode. Thus it protects itself against
 162  *      interrupt users but doesn't worry about being called during work.
 163  *      Once it is removed from the queue no interrupt or bottom half will
 164  *      touch it and we are (fairly 8-) ) safe.
 165  */
 166  
 167 static void 
 168 ipx_destroy_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         struct sk_buff  *skb;
 171 
 172         ipx_remove_socket(sk);
 173         while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
 174                 kfree_skb(skb,FREE_READ);
 175         }
 176         
 177         kfree_s(sk,sizeof(*sk));
 178 }
 179         
 180 /* The following code is used to support IPX Interfaces (IPXITF).  An
 181  * IPX interface is defined by a physical device and a frame type.
 182  */
 183 
 184 static ipx_route * ipxrtr_lookup(unsigned long);
 185  
 186 static void
 187 ipxitf_clear_primary_net(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189         if (ipxcfg_auto_select_primary && (ipx_interfaces != NULL))
 190                 ipx_primary_net = ipx_interfaces;
 191         else
 192                 ipx_primary_net = NULL;
 193 }
 194 
 195 static ipx_interface *
 196 ipxitf_find_using_phys(struct device *dev, unsigned short datalink)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         ipx_interface   *i;
 199 
 200         for (i=ipx_interfaces; 
 201                 i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink)); 
 202                 i=i->if_next)
 203                 ;
 204         return i;
 205 }
 206 
 207 static ipx_interface *
 208 ipxitf_find_using_net(unsigned long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         ipx_interface   *i;
 211 
 212         if (net == 0L)
 213                 return ipx_primary_net;
 214 
 215         for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next)
 216                 ;
 217 
 218         return i;
 219 }
 220 
 221 /* Sockets are bound to a particular IPX interface. */
 222 static void
 223 ipxitf_insert_socket(ipx_interface *intrfc, ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225         ipx_socket      *s;
 226 
 227         sk->ipx_intrfc = intrfc;
 228         sk->next = NULL;
 229         if (intrfc->if_sklist == NULL) {
 230                 intrfc->if_sklist = sk;
 231         } else {
 232                 for (s = intrfc->if_sklist; s->next != NULL; s = s->next)
 233                         ;
 234                 s->next = sk;
 235         }
 236 }
 237 
 238 static ipx_socket *
 239 ipxitf_find_socket(ipx_interface *intrfc, unsigned short port)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241         ipx_socket      *s;
 242 
 243         for (s=intrfc->if_sklist; 
 244                 (s != NULL) && (s->ipx_port != port); 
 245                 s=s->next)
 246                 ;
 247 
 248         return s;
 249 }
 250 
 251 static void ipxrtr_del_routes(ipx_interface *);
 252 
 253 static void
 254 ipxitf_down(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 255 {
 256         ipx_interface   *i;
 257         ipx_socket      *s, *t;
 258 
 259         /* Delete all routes associated with this interface */
 260         ipxrtr_del_routes(intrfc);
 261 
 262         /* error sockets */
 263         for (s = intrfc->if_sklist; s != NULL; ) {
 264                 s->err = ENOLINK;
 265                 s->error_report(s);
 266                 s->ipx_intrfc = NULL;
 267                 s->ipx_port = 0;
 268                 s->zapped=1;    /* Indicates it is no longer bound */
 269                 t = s;
 270                 s = s->next;
 271                 t->next = NULL;
 272         }
 273         intrfc->if_sklist = NULL;
 274 
 275         /* remove this interface from list */
 276         if (intrfc == ipx_interfaces) {
 277                 ipx_interfaces = intrfc->if_next;
 278         } else {
 279                 for (i = ipx_interfaces; 
 280                         (i != NULL) && (i->if_next != intrfc);
 281                         i = i->if_next)
 282                         ;
 283                 if ((i != NULL) && (i->if_next == intrfc)) 
 284                         i->if_next = intrfc->if_next;
 285         }
 286 
 287         /* remove this interface from *special* networks */
 288         if (intrfc == ipx_primary_net)
 289                 ipxitf_clear_primary_net();
 290         if (intrfc == ipx_internal_net)
 291                 ipx_internal_net = NULL;
 292 
 293         kfree_s(intrfc, sizeof(*intrfc));
 294 }
 295 
 296 static int 
 297 ipxitf_device_event(unsigned long event, void *ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299         struct device *dev = ptr;
 300         ipx_interface *i, *tmp;
 301 
 302         if(event!=NETDEV_DOWN)
 303                 return NOTIFY_DONE;
 304 
 305         for (i = ipx_interfaces; i != NULL; ) {
 306         
 307                 tmp = i->if_next;
 308                 if (i->if_dev == dev) 
 309                         ipxitf_down(i);
 310                 i = tmp;
 311 
 312         }
 313 
 314         return NOTIFY_DONE;
 315 }
 316 
 317 static int
 318 ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320         int     retval;
 321 
 322         if((retval = sock_queue_rcv_skb(sock, skb))<0) {
 323                 /*
 324                  *      We do a FREE_WRITE here because this indicates how
 325                  *      to treat the socket with which the packet is 
 326                  *      associated.  If this packet is associated with a
 327                  *      socket at all, it must be the originator of the 
 328                  *      packet.   Incoming packets will have no socket 
 329                  *      associated with them at this point.
 330                  */
 331                 kfree_skb(skb,FREE_WRITE);
 332         }
 333         return retval;
 334 }
 335 
 336 static int
 337 ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) 
     /* [previous][next][first][last][top][bottom][index][help] */
 338 {
 339         ipx_packet      *ipx = (ipx_packet *)(skb->h.raw);
 340         ipx_socket      *sock1 = NULL, *sock2 = NULL;
 341         struct sk_buff  *skb1 = NULL, *skb2 = NULL;
 342         int             ipx_offset;
 343 
 344         sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
 345 
 346         /*
 347          *      We need to check if there is a primary net and if
 348          *      this is addressed to one of the *SPECIAL* sockets because
 349          *      these need to be propogated to the primary net.
 350          *      The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
 351          *      0x456(Diagnostic).
 352          */
 353         if (ipx_primary_net && (intrfc != ipx_primary_net)) {
 354                 switch (ntohs(ipx->ipx_dest.sock)) {
 355                 case 0x452:
 356                 case 0x453:
 357                 case 0x456:
 358                         /*
 359                          *      The appropriate thing to do here is to
 360                          *      dup the packet and route to the primary net
 361                          *      interface via ipxitf_send; however, we'll cheat
 362                          *      and just demux it here.
 363                          */
 364                         sock2 = ipxitf_find_socket(ipx_primary_net, 
 365                                         ipx->ipx_dest.sock);
 366                         break;
 367                 default:
 368                         break;
 369                 }
 370         }
 371 
 372         /* if there is nothing to do, return */
 373         if ((sock1 == NULL) && (sock2 == NULL)) {
 374                 if (!copy) 
 375                         kfree_skb(skb,FREE_WRITE);
 376                 return 0;
 377         }
 378 
 379         ipx_offset = (char *)(skb->h.raw) - (char *)(skb->data);
 380 
 381         /* This next segment of code is a little awkward, but it sets it up
 382          * so that the appropriate number of copies of the SKB are made and 
 383          * that skb1 and skb2 point to it (them) so that it (they) can be 
 384          * demuxed to sock1 and/or sock2.  If we are unable to make enough
 385          * copies, we do as much as is possible.
 386          */
 387         if (copy) {
 388                 skb1 = skb_clone(skb, GFP_ATOMIC);
 389                 if (skb1 != NULL) {
 390                         skb1->h.raw = (unsigned char *)&(skb1->data[ipx_offset]);
 391                         skb1->arp = skb1->free = 1;
 392                 }
 393         } else {
 394                 skb1 = skb;
 395         }
 396         
 397         if (skb1 == NULL) return -ENOMEM; 
 398 
 399         /* Do we need 2 SKBs? */
 400         if (sock1 && sock2) {
 401                 skb2 = skb_clone(skb1, GFP_ATOMIC);
 402                 if (skb2 != NULL) {
 403                         skb2->h.raw = (unsigned char *)&(skb2->data[ipx_offset]);
 404                         skb2->arp = skb2->free = 1;
 405                 }
 406         } else {
 407                 skb2 = skb1;
 408         }
 409                 
 410         if (sock1) {
 411                 (void) ipxitf_def_skb_handler(sock1, skb1);
 412         }
 413 
 414         if (skb2 == NULL) return -ENOMEM;
 415 
 416         if (sock2) {
 417                 (void) ipxitf_def_skb_handler(sock2, skb2);
 418         }
 419 
 420         return 0;
 421 }
 422 
 423 static struct sk_buff *
 424 ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 425 {
 426         struct sk_buff  *skb2;
 427         int     in_offset = skb->h.raw - skb->data;
 428         int     out_offset = intrfc->if_ipx_offset;
 429         char    *oldraw;
 430         int     len;
 431 
 432         /* Hopefully, most cases */
 433         if (in_offset == out_offset) {
 434                 return skb;
 435         }
 436 
 437         /* Existing SKB will work, just need to move things around a little */
 438         if (in_offset > out_offset) {
 439                 oldraw = skb->h.raw;
 440                 skb->h.raw = &(skb->data[out_offset]);
 441                 memmove(skb->h.raw, oldraw, skb->len);
 442                 skb->len += out_offset;
 443                 return skb;
 444         }
 445 
 446         /* Need new SKB */
 447         len = skb->len + out_offset;
 448         skb2 = alloc_skb(len, GFP_ATOMIC);
 449         if (skb2 != NULL) {
 450                 skb2->h.raw = &(skb2->data[out_offset]);
 451                 skb2->len = len;
 452                 skb2->free=1;
 453                 skb2->arp=1;
 454                 memcpy(skb2->h.raw, skb->h.raw, skb->len);
 455         }
 456         kfree_skb(skb, FREE_WRITE);
 457         return skb2;
 458 }
 459 
 460 static int
 461 ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463         ipx_packet      *ipx = (ipx_packet *)(skb->h.raw);
 464         struct device   *dev = intrfc->if_dev;
 465         struct datalink_proto   *dl = intrfc->if_dlink;
 466         char            dest_node[IPX_NODE_LEN];
 467         int             send_to_wire = 1;
 468         
 469         /* We need to know how many skbuffs it will take to send out this
 470          * packet to avoid unnecessary copies.
 471          */
 472         if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) 
 473                 send_to_wire = 0;
 474 
 475         /* See if this should be demuxed to sockets on this interface */
 476         if (ipx->ipx_dest.net == intrfc->if_netnum) {
 477                 if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) 
 478                         return ipxitf_demux_socket(intrfc, skb, 0);
 479                 if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) {
 480                         ipxitf_demux_socket(intrfc, skb, send_to_wire);
 481                         if (!send_to_wire) return 0;
 482                 }
 483         }
 484 
 485         /* if the orginating net is not equal to our net; this is routed */
 486         if (ipx->ipx_source.net != intrfc->if_netnum) {
 487                 if (++(ipx->ipx_tctrl) > ipxcfg_max_hops) 
 488                         send_to_wire = 0;
 489         }
 490 
 491         if (!send_to_wire) {
 492                 /*
 493                  *      We do a FREE_WRITE here because this indicates how
 494                  *      to treat the socket with which the packet is 
 495                  *      associated.  If this packet is associated with a
 496                  *      socket at all, it must be the originator of the 
 497                  *      packet.   Routed packets will have no socket associated
 498                  *      with them.
 499                  */
 500                 kfree_skb(skb,FREE_WRITE);
 501                 return 0;
 502         }
 503 
 504         /* In some case, ipxitf_adjust_skbuff can overwrite node */
 505         memcpy(dest_node, node, IPX_NODE_LEN);
 506 
 507         /* make any compensation for differing physical/data link size */
 508         skb = ipxitf_adjust_skbuff(intrfc, skb);
 509         if (skb == NULL) return 0;
 510 
 511         /* set up data link and physical headers */
 512         skb->dev = dev;
 513         dl->datalink_header(dl, skb, dest_node);
 514 
 515         if (skb->sk != NULL) {
 516                 /* This is an outbound packet from this host.  We need to 
 517                  * increment the write count.
 518                  */
 519                 skb->sk->wmem_alloc += skb->mem_len;
 520         }
 521 
 522         /* Send it out */
 523         dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 524         return 0;
 525 }
 526 
 527 static int
 528 ipxrtr_add_route(unsigned long, ipx_interface *, unsigned char *);
 529 
 530 static int
 531 ipxitf_add_local_route(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 532 {
 533         return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
 534 }
 535 
 536 static char * ipx_frame_name(unsigned short);
 537 static char * ipx_device_name(ipx_interface *);
 538 static int ipxrtr_route_skb(struct sk_buff *);
 539 
 540 static int 
 541 ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 542 {
 543         ipx_packet      *ipx = (ipx_packet *) (skb->h.raw);
 544         ipx_interface   *i;
 545 
 546         /* See if we should update our network number */
 547         if ((intrfc->if_netnum == 0L) && (ipx->ipx_tctrl == 0)) {
 548                 if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL) {
 549                         intrfc->if_netnum = ipx->ipx_source.net;
 550                         (void) ipxitf_add_local_route(intrfc);
 551                 } else {
 552                         printk("IPX: Network number collision %lx\n\t%s %s and %s %s\n",
 553                                 htonl(ipx->ipx_source.net), 
 554                                 ipx_device_name(i),
 555                                 ipx_frame_name(i->if_dlink_type),
 556                                 ipx_device_name(intrfc),
 557                                 ipx_frame_name(intrfc->if_dlink_type));
 558                 }
 559         }
 560 
 561         if (intrfc->if_netnum != ipx->ipx_dest.net)
 562                 return ipxrtr_route_skb(skb);
 563 
 564         /* see if we should keep it */
 565         if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) 
 566                 || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) {
 567                 return ipxitf_demux_socket(intrfc, skb, 0);
 568         }
 569 
 570         /* we couldn't pawn it off so unload it */
 571         kfree_skb(skb,FREE_READ);
 572         return 0;
 573 }
 574 
 575 static void
 576 ipxitf_insert(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 577 {
 578         ipx_interface   *i;
 579 
 580         intrfc->if_next = NULL;
 581         if (ipx_interfaces == NULL) {
 582                 ipx_interfaces = intrfc;
 583         } else {
 584                 for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
 585                         ;
 586                 i->if_next = intrfc;
 587         }
 588 
 589         if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 590                 ipx_primary_net = intrfc;
 591 }
 592 
 593 static int 
 594 ipxitf_create_internal(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 595 {
 596         ipx_interface   *intrfc;
 597 
 598         /* Only one primary network allowed */
 599         if (ipx_primary_net != NULL) return -EEXIST;
 600 
 601         /* Must have a valid network number */
 602         if (idef->ipx_network == 0L) return -EADDRNOTAVAIL;
 603         if (ipxitf_find_using_net(idef->ipx_network) != NULL)
 604                 return -EADDRINUSE;
 605 
 606         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 607         if (intrfc==NULL)
 608                 return -EAGAIN;
 609         intrfc->if_dev=NULL;
 610         intrfc->if_netnum=idef->ipx_network;
 611         intrfc->if_dlink_type = 0;
 612         intrfc->if_dlink = NULL;
 613         intrfc->if_sklist = NULL;
 614         intrfc->if_internal = 1;
 615         intrfc->if_ipx_offset = 0;
 616         intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 617         memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
 618         ipx_internal_net = intrfc;
 619         ipx_primary_net = intrfc;
 620         ipxitf_insert(intrfc);
 621         return ipxitf_add_local_route(intrfc);
 622 }
 623 
 624 static int 
 625 ipxitf_create(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 626 {
 627         struct device   *dev;
 628         unsigned short  dlink_type = 0;
 629         struct datalink_proto   *datalink = NULL;
 630         ipx_interface   *intrfc;
 631 
 632         if (idef->ipx_internal) 
 633                 return ipxitf_create_internal(idef);
 634 
 635         if (idef->ipx_primary && (ipx_primary_net != NULL))
 636                 return -EEXIST;
 637 
 638         if ((idef->ipx_network != 0L) &&
 639                 (ipxitf_find_using_net(idef->ipx_network) != NULL))
 640                 return -EADDRINUSE;
 641 
 642         switch (idef->ipx_dlink_type) {
 643         case IPX_FRAME_ETHERII: 
 644                 dlink_type = htons(ETH_P_IPX);
 645                 datalink = pEII_datalink;
 646                 break;
 647         case IPX_FRAME_8022:
 648                 dlink_type = htons(ETH_P_802_2);
 649                 datalink = p8022_datalink;
 650                 break;
 651         case IPX_FRAME_SNAP:
 652                 dlink_type = htons(ETH_P_SNAP);
 653                 datalink = pSNAP_datalink;
 654                 break;
 655         case IPX_FRAME_8023:
 656                 dlink_type = htons(ETH_P_802_3);
 657                 datalink = p8023_datalink;
 658                 break;
 659         case IPX_FRAME_NONE:
 660         default:
 661                 break;
 662         }
 663 
 664         if (datalink == NULL) 
 665                 return -EPROTONOSUPPORT;
 666 
 667         dev=dev_get(idef->ipx_device);
 668         if(dev==NULL)
 669                 return -ENODEV;
 670 
 671         /* Check addresses are suitable */
 672         if(dev->addr_len>IPX_NODE_LEN)
 673                 return -EINVAL;
 674 
 675         if(dev->addr_len<2)
 676                 return -EINVAL;
 677 
 678         if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) {
 679 
 680                 /* Ok now create */
 681                 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 682                 if (intrfc==NULL)
 683                         return -EAGAIN;
 684                 intrfc->if_dev=dev;
 685                 intrfc->if_netnum=idef->ipx_network;
 686                 intrfc->if_dlink_type = dlink_type;
 687                 intrfc->if_dlink = datalink;
 688                 intrfc->if_sklist = NULL;
 689                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 690                 /* Setup primary if necessary */
 691                 if (idef->ipx_primary) ipx_primary_net = intrfc;
 692                 intrfc->if_internal = 0;
 693                 intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
 694                 memset(intrfc->if_node, 0, IPX_NODE_LEN);
 695                 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len);
 696 
 697                 ipxitf_insert(intrfc);
 698         }
 699 
 700         /* If the network number is known, add a route */
 701         if (intrfc->if_netnum == 0L) 
 702                 return 0;
 703 
 704         return ipxitf_add_local_route(intrfc);
 705 }
 706 
 707 static int 
 708 ipxitf_delete(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 709 {
 710         struct device   *dev = NULL;
 711         unsigned short  dlink_type = 0;
 712         ipx_interface   *intrfc;
 713 
 714         if (idef->ipx_internal) {
 715                 if (ipx_internal_net != NULL) {
 716                         ipxitf_down(ipx_internal_net);
 717                         return 0;
 718                 }
 719                 return -ENOENT;
 720         }
 721 
 722         switch (idef->ipx_dlink_type) {
 723         case IPX_FRAME_ETHERII: 
 724                 dlink_type = htons(ETH_P_IPX);
 725                 break;
 726         case IPX_FRAME_8022:
 727                 dlink_type = htons(ETH_P_802_2);
 728                 break;
 729         case IPX_FRAME_SNAP:
 730                 dlink_type = htons(ETH_P_SNAP);
 731                 break;
 732         case IPX_FRAME_8023:
 733                 dlink_type = htons(ETH_P_802_3);
 734                 break;
 735         case IPX_FRAME_NONE:
 736         default:
 737                 return -EPROTONOSUPPORT;
 738                 break;
 739         }
 740 
 741         dev=dev_get(idef->ipx_device);
 742         if(dev==NULL) return -ENODEV;
 743 
 744         intrfc = ipxitf_find_using_phys(dev, dlink_type);
 745         if (intrfc != NULL) {
 746                 ipxitf_down(intrfc);
 747                 return 0;
 748         }
 749         return -EINVAL;
 750 }
 751 
 752 static ipx_interface *
 753 ipxitf_auto_create(struct device *dev, unsigned short dlink_type)
     /* [previous][next][first][last][top][bottom][index][help] */
 754 {
 755         struct datalink_proto *datalink = NULL;
 756         ipx_interface   *intrfc;
 757 
 758         switch (htons(dlink_type)) {
 759         case ETH_P_IPX: datalink = pEII_datalink; break;
 760         case ETH_P_802_2: datalink = p8022_datalink; break;
 761         case ETH_P_SNAP: datalink = pSNAP_datalink; break;
 762         case ETH_P_802_3: datalink = p8023_datalink; break;
 763         default: return NULL;
 764         }
 765         
 766         if (dev == NULL)
 767                 return NULL;
 768 
 769         /* Check addresses are suitable */
 770         if(dev->addr_len>IPX_NODE_LEN) return NULL;
 771 
 772         if(dev->addr_len<2) return NULL;
 773 
 774         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 775         if (intrfc!=NULL) {
 776                 intrfc->if_dev=dev;
 777                 intrfc->if_netnum=0L;
 778                 intrfc->if_dlink_type = dlink_type;
 779                 intrfc->if_dlink = datalink;
 780                 intrfc->if_sklist = NULL;
 781                 intrfc->if_internal = 0;
 782                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 783                 intrfc->if_ipx_offset = dev->hard_header_len + 
 784                         datalink->header_length;
 785                 memset(intrfc->if_node, 0, IPX_NODE_LEN);
 786                 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
 787                         dev->dev_addr, dev->addr_len);
 788                 ipxitf_insert(intrfc);
 789         }
 790 
 791         return intrfc;
 792 }
 793 
 794 static int 
 795 ipxitf_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797         int err;
 798         switch(cmd)
 799         {
 800                 case SIOCSIFADDR:
 801                 {
 802                         struct ifreq ifr;
 803                         struct sockaddr_ipx *sipx;
 804                         ipx_interface_definition f;
 805                         err=verify_area(VERIFY_READ,arg,sizeof(ifr));
 806                         if(err)
 807                                 return err;
 808                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
 809                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
 810                         if(sipx->sipx_family!=AF_IPX)
 811                                 return -EINVAL;
 812                         f.ipx_network=sipx->sipx_network;
 813                         memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device));
 814                         f.ipx_dlink_type=sipx->sipx_type;
 815                         f.ipx_primary=sipx->sipx_primary;
 816                         f.ipx_internal=sipx->sipx_internal;
 817                         if(sipx->sipx_network==0)
 818                                 return ipxitf_delete(&f);
 819                         else
 820                                 return ipxitf_create(&f);
 821                 }
 822                 case SIOCGIFADDR:
 823                 {
 824                         struct ifreq ifr;
 825                         struct sockaddr_ipx *sipx;
 826                         ipx_interface *ipxif;
 827                         struct device *dev;
 828                         err=verify_area(VERIFY_WRITE,arg,sizeof(ifr));
 829                         if(err)
 830                                 return err;
 831                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
 832                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
 833                         dev=dev_get(ifr.ifr_name);
 834                         if(!dev)
 835                                 return -ENODEV;
 836                         ipxif=ipxitf_find_using_phys(dev, sipx->sipx_type);
 837                         if(ipxif==NULL)
 838                                 return -EADDRNOTAVAIL;
 839                         sipx->sipx_network=ipxif->if_netnum;
 840                         memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node));
 841                                                 
 842                 }
 843                 case SIOCAIPXITFCRT:
 844                         err=verify_area(VERIFY_READ,arg,sizeof(char));
 845                         if(err)
 846                                 return err;
 847                         return ipxcfg_set_auto_create(get_fs_byte(arg));
 848                 case SIOCAIPXPRISLT:
 849                         err=verify_area(VERIFY_READ,arg,sizeof(char));
 850                         if(err)
 851                                 return err;
 852                         return ipxcfg_set_auto_select(get_fs_byte(arg));
 853                 default:
 854                         return -EINVAL;
 855         }
 856 }
 857 
 858 /*******************************************************************************************************************\
 859 *                                                                                                                   *
 860 *                                       Routing tables for the IPX socket layer                                     *
 861 *                                                                                                                   *
 862 \*******************************************************************************************************************/
 863 
 864 static ipx_route *
 865 ipxrtr_lookup(unsigned long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 866 {
 867         ipx_route *r;
 868 
 869         for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next)
 870                 ;
 871 
 872         return r;
 873 }
 874 
 875 static int
 876 ipxrtr_add_route(unsigned long network, ipx_interface *intrfc, unsigned char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 877 {
 878         ipx_route       *rt;
 879 
 880         /* Get a route structure; either existing or create */
 881         rt = ipxrtr_lookup(network);
 882         if (rt==NULL) {
 883                 rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
 884                 if(rt==NULL)
 885                         return -EAGAIN;
 886                 rt->ir_next=ipx_routes;
 887                 ipx_routes=rt;
 888         }
 889 
 890         rt->ir_net = network;
 891         rt->ir_intrfc = intrfc;
 892         if (node == NULL) {
 893                 memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
 894                 rt->ir_routed = 0;
 895         } else {
 896                 memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
 897                 rt->ir_routed=1;
 898         }
 899         return 0;
 900 }
 901 
 902 static void
 903 ipxrtr_del_routes(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905         ipx_route       **r, *tmp;
 906 
 907         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
 908                 if (tmp->ir_intrfc == intrfc) {
 909                         *r = tmp->ir_next;
 910                         kfree_s(tmp, sizeof(ipx_route));
 911                 } else {
 912                         r = &(tmp->ir_next);
 913                 }
 914         }
 915 }
 916 
 917 static int 
 918 ipxrtr_create(ipx_route_definition *rd)
     /* [previous][next][first][last][top][bottom][index][help] */
 919 {
 920         ipx_interface *intrfc;
 921 
 922         /* Find the appropriate interface */
 923         intrfc = ipxitf_find_using_net(rd->ipx_router_network);
 924         if (intrfc == NULL)
 925                 return -ENETUNREACH;
 926 
 927         return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
 928 }
 929 
 930 
 931 static int 
 932 ipxrtr_delete(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 933 {
 934         ipx_route       **r;
 935         ipx_route       *tmp;
 936 
 937         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
 938                 if (tmp->ir_net == net) {
 939                         if (!(tmp->ir_routed)) {
 940                                 /* Directly connected; can't lose route */
 941                                 return -EPERM;
 942                         }
 943                         *r = tmp->ir_next;
 944                         kfree_s(tmp, sizeof(ipx_route));
 945                         return 0;
 946                 } 
 947                 r = &(tmp->ir_next);
 948         }
 949 
 950         return -ENOENT;
 951 }
 952 
 953 static int
 954 ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, void *ubuf, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 955 {
 956         struct sk_buff *skb;
 957         ipx_interface *intrfc;
 958         ipx_packet *ipx;
 959         int size;
 960         int ipx_offset;
 961         ipx_route *rt = NULL;
 962 
 963         /* Find the appropriate interface on which to send packet */
 964         if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) {
 965                 usipx->sipx_network = ipx_primary_net->if_netnum;
 966                 intrfc = ipx_primary_net;
 967         } else {
 968                 rt = ipxrtr_lookup(usipx->sipx_network);
 969                 if (rt==NULL) {
 970                         return -ENETUNREACH;
 971                 }
 972                 intrfc = rt->ir_intrfc;
 973         }
 974         
 975         ipx_offset = intrfc->if_ipx_offset;
 976         size=sizeof(ipx_packet)+len;
 977         size += ipx_offset;
 978 
 979         if(size+sk->wmem_alloc>sk->sndbuf) return -EAGAIN;
 980                 
 981         skb=alloc_skb(size,GFP_KERNEL);
 982         if(skb==NULL) return -ENOMEM;
 983                 
 984         skb->sk=sk;
 985         skb->len=size;
 986         skb->free=1;
 987         skb->arp=1;
 988 
 989         /* Fill in IPX header */
 990         ipx=(ipx_packet *)&(skb->data[ipx_offset]);
 991         ipx->ipx_checksum=0xFFFF;
 992         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
 993         ipx->ipx_tctrl=0;
 994         ipx->ipx_type=usipx->sipx_type;
 995         skb->h.raw = (unsigned char *)ipx;
 996 
 997         ipx->ipx_source.net = sk->ipx_intrfc->if_netnum;
 998         memcpy(ipx->ipx_source.node, sk->ipx_intrfc->if_node, IPX_NODE_LEN);
 999         ipx->ipx_source.sock = sk->ipx_port;
1000         ipx->ipx_dest.net=usipx->sipx_network;
1001         memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
1002         ipx->ipx_dest.sock=usipx->sipx_port;
1003 
1004         memcpy_fromfs((char *)(ipx+1),ubuf,len);
1005         return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
1006                                 rt->ir_router_node : ipx->ipx_dest.node);
1007 }
1008         
1009 static int
1010 ipxrtr_route_skb(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
1011 {
1012         ipx_packet      *ipx = (ipx_packet *) (skb->h.raw);
1013         ipx_route       *r;
1014         ipx_interface   *i;
1015 
1016         r = ipxrtr_lookup(ipx->ipx_dest.net);
1017         if (r == NULL) {
1018                 /* no known route */
1019                 kfree_skb(skb,FREE_READ);
1020                 return 0;
1021         }
1022         i = r->ir_intrfc;
1023         (void)ipxitf_send(i, skb, (r->ir_routed) ? 
1024                         r->ir_router_node : ipx->ipx_dest.node);
1025         return 0;
1026 }
1027 
1028 /*
1029  *      We use a normal struct rtentry for route handling
1030  */
1031  
1032 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1033 {
1034         int err;
1035         struct rtentry rt;      /* Use these to behave like 'other' stacks */
1036         struct sockaddr_ipx *sg,*st;
1037 
1038         err=verify_area(VERIFY_READ,arg,sizeof(rt));
1039         if(err)
1040                 return err;
1041                 
1042         memcpy_fromfs(&rt,arg,sizeof(rt));
1043         
1044         sg=(struct sockaddr_ipx *)&rt.rt_gateway;
1045         st=(struct sockaddr_ipx *)&rt.rt_dst;
1046         
1047         if(!(rt.rt_flags&RTF_GATEWAY))
1048                 return -EINVAL;         /* Direct routes are fixed */
1049         if(sg->sipx_family!=AF_IPX)
1050                 return -EINVAL;
1051         if(st->sipx_family!=AF_IPX)
1052                 return -EINVAL;
1053                 
1054         switch(cmd)
1055         {
1056                 case SIOCDELRT:
1057                         return ipxrtr_delete(sg->sipx_network);
1058                 case SIOCADDRT:
1059                 {
1060                         struct ipx_route_definition f;
1061                         f.ipx_network=st->sipx_network;
1062                         f.ipx_router_network=sg->sipx_network;
1063                         memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
1064                         return ipxrtr_create(&f);
1065                 }
1066                 default:
1067                         return -EINVAL;
1068         }
1069 }
1070 
1071 static char *
1072 ipx_frame_name(unsigned short frame)
     /* [previous][next][first][last][top][bottom][index][help] */
1073 {
1074         switch (ntohs(frame)) {
1075         case ETH_P_IPX: return "EtherII";
1076         case ETH_P_802_2: return "802.2";
1077         case ETH_P_SNAP: return "SNAP";
1078         case ETH_P_802_3: return "802.3";
1079         default: return "None";
1080         }
1081 }
1082 
1083 static char *
1084 ipx_device_name(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1085 {
1086         return (intrfc->if_internal ? "Internal" :
1087                 (intrfc->if_dev ? intrfc->if_dev->name : "Unknown"));
1088 }
1089 
1090 /* Called from proc fs */
1091 int 
1092 ipx_get_interface_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1093 {
1094         ipx_interface *i;
1095         int len=0;
1096         off_t pos=0;
1097         off_t begin=0;
1098 
1099         /* Theory.. Keep printing in the same place until we pass offset */
1100         
1101         len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", 
1102                 "Node_Address", "Primary", "Device", "Frame_Type");
1103         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1104                 len += sprintf(buffer+len, "%08lX   ", ntohl(i->if_netnum));
1105                 len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ", 
1106                                 i->if_node[0], i->if_node[1], i->if_node[2],
1107                                 i->if_node[3], i->if_node[4], i->if_node[5]);
1108                 len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
1109                         "Yes" : "No");
1110                 len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
1111                 len += sprintf (buffer+len, "%s\n", 
1112                         ipx_frame_name(i->if_dlink_type));
1113 
1114                 /* Are we still dumping unwanted data then discard the record */
1115                 pos=begin+len;
1116                 
1117                 if(pos<offset) {
1118                         len=0;                  /* Keep dumping into the buffer start */
1119                         begin=pos;
1120                 }
1121                 if(pos>offset+length)           /* We have dumped enough */
1122                         break;
1123         }
1124         
1125         /* The data in question runs from begin to begin+len */
1126         *start=buffer+(offset-begin);   /* Start of wanted data */
1127         len-=(offset-begin);            /* Remove unwanted header data from length */
1128         if(len>length)
1129                 len=length;             /* Remove unwanted tail data from length */
1130         
1131         return len;
1132 }
1133 
1134 int 
1135 ipx_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1136 {
1137         ipx_socket *s;
1138         ipx_interface *i;
1139         int len=0;
1140         off_t pos=0;
1141         off_t begin=0;
1142 
1143         /* Theory.. Keep printing in the same place until we pass offset */
1144         
1145         len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
1146                         "Remote_Address", "Tx_Queue", "Rx_Queue", 
1147                         "State", "Uid");
1148         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1149                 for (s = i->if_sklist; s != NULL; s = s->next) {
1150                         len += sprintf (buffer+len,"%08lX:%04X  ", 
1151                                 htonl(i->if_netnum),
1152                                 htons(s->ipx_port));
1153                         if (s->state!=TCP_ESTABLISHED) {
1154                                 len += sprintf(buffer+len, "%-28s", "Not_Connected");
1155                         } else {
1156                                 len += sprintf (buffer+len,
1157                                         "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
1158                                         htonl(s->ipx_dest_addr.net),
1159                                         s->ipx_dest_addr.node[0], s->ipx_dest_addr.node[1], 
1160                                         s->ipx_dest_addr.node[2], s->ipx_dest_addr.node[3], 
1161                                         s->ipx_dest_addr.node[4], s->ipx_dest_addr.node[5],
1162                                         htons(s->ipx_dest_addr.sock));
1163                         }
1164                         len += sprintf (buffer+len,"%08lX  %08lX  ", 
1165                                 s->wmem_alloc, s->rmem_alloc);
1166                         len += sprintf (buffer+len,"%02X     %03d\n", 
1167                                 s->state, SOCK_INODE(s->socket)->i_uid);
1168                 
1169                         /* Are we still dumping unwanted data then discard the record */
1170                         pos=begin+len;
1171                 
1172                         if(pos<offset)
1173                         {
1174                                 len=0;                  /* Keep dumping into the buffer start */
1175                                 begin=pos;
1176                         }
1177                         if(pos>offset+length)           /* We have dumped enough */
1178                                 break;
1179                 }
1180         }
1181         
1182         /* The data in question runs from begin to begin+len */
1183         *start=buffer+(offset-begin);   /* Start of wanted data */
1184         len-=(offset-begin);            /* Remove unwanted header data from length */
1185         if(len>length)
1186                 len=length;             /* Remove unwanted tail data from length */
1187         
1188         return len;
1189 }
1190 
1191 int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1192 {
1193         ipx_route *rt;
1194         int len=0;
1195         off_t pos=0;
1196         off_t begin=0;
1197 
1198         len += sprintf (buffer,"%-11s%-13s%s\n", 
1199                         "Network", "Router_Net", "Router_Node");
1200         for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
1201         {
1202                 len += sprintf (buffer+len,"%08lX   ", ntohl(rt->ir_net));
1203                 if (rt->ir_routed) {
1204                         len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n", 
1205                                 ntohl(rt->ir_intrfc->if_netnum), 
1206                                 rt->ir_router_node[0], rt->ir_router_node[1], 
1207                                 rt->ir_router_node[2], rt->ir_router_node[3], 
1208                                 rt->ir_router_node[4], rt->ir_router_node[5]);
1209                 } else {
1210                         len += sprintf (buffer+len, "%-13s%s\n",
1211                                         "Directly", "Connected");
1212                 }
1213                 pos=begin+len;
1214                 if(pos<offset)
1215                 {
1216                         len=0;
1217                         begin=pos;
1218                 }
1219                 if(pos>offset+length)
1220                         break;
1221         }
1222         *start=buffer+(offset-begin);
1223         len-=(offset-begin);
1224         if(len>length)
1225                 len=length;
1226         return len;
1227 }
1228 
1229 /*******************************************************************************************************************\
1230 *                                                                                                                   *
1231 *             Handling for system calls applied via the various interfaces to an IPX socket object                  *
1232 *                                                                                                                   *
1233 \*******************************************************************************************************************/
1234  
1235 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1236 {
1237         switch(cmd)
1238         {
1239                 default:
1240                         return(-EINVAL);
1241         }
1242 }
1243 
1244 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
1245 {
1246         ipx_socket *sk;
1247         int err,opt;
1248         
1249         sk=(ipx_socket *)sock->data;
1250         
1251         if(optval==NULL)
1252                 return(-EINVAL);
1253 
1254         err=verify_area(VERIFY_READ,optval,sizeof(int));
1255         if(err)
1256                 return err;
1257         opt=get_fs_long((unsigned long *)optval);
1258         
1259         switch(level)
1260         {
1261                 case SOL_IPX:
1262                         switch(optname)
1263                         {
1264                                 case IPX_TYPE:
1265                                         if(!suser())
1266                                                 return(-EPERM);
1267                                         sk->ipx_type=opt;
1268                                         return 0;
1269                                 default:
1270                                         return -EOPNOTSUPP;
1271                         }
1272                         break;
1273                         
1274                 case SOL_SOCKET:                
1275                         return sock_setsockopt(sk,level,optname,optval,optlen);
1276 
1277                 default:
1278                         return -EOPNOTSUPP;
1279         }
1280 }
1281 
1282 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
1283         char *optval, int *optlen)
1284 {
1285         ipx_socket *sk;
1286         int val=0;
1287         int err;
1288         
1289         sk=(ipx_socket *)sock->data;
1290 
1291         switch(level)
1292         {
1293 
1294                 case SOL_IPX:
1295                         switch(optname)
1296                         {
1297                                 case IPX_TYPE:
1298                                         val=sk->ipx_type;
1299                                         break;
1300                                 default:
1301                                         return -ENOPROTOOPT;
1302                         }
1303                         break;
1304                         
1305                 case SOL_SOCKET:
1306                         return sock_getsockopt(sk,level,optname,optval,optlen);
1307                         
1308                 default:
1309                         return -EOPNOTSUPP;
1310         }
1311         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
1312         if(err)
1313                 return err;
1314         put_fs_long(sizeof(int),(unsigned long *)optlen);
1315         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
1316         put_fs_long(val,(unsigned long *)optval);
1317         return(0);
1318 }
1319 
1320 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
1321 {
1322         return -EOPNOTSUPP;
1323 }
1324 
1325 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1326 {
1327         if(!sk->dead)
1328                 wake_up_interruptible(sk->sleep);
1329 }
1330 
1331 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
1332 {
1333         if(!sk->dead)
1334         {
1335                 wake_up_interruptible(sk->sleep);
1336                 sock_wake_async(sk->socket, 1);
1337         }
1338 }
1339 
1340 static int 
1341 ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
1342 {
1343         ipx_socket *sk;
1344         sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
1345         if(sk==NULL)
1346                 return(-ENOMEM);
1347         switch(sock->type)
1348         {
1349                 case SOCK_DGRAM:
1350                         break;
1351                 default:
1352                         kfree_s((void *)sk,sizeof(*sk));
1353                         return(-ESOCKTNOSUPPORT);
1354         }
1355         sk->dead=0;
1356         sk->next=NULL;
1357         sk->broadcast=0;
1358         sk->rcvbuf=SK_RMEM_MAX;
1359         sk->sndbuf=SK_WMEM_MAX;
1360         sk->wmem_alloc=0;
1361         sk->rmem_alloc=0;
1362         sk->inuse=0;
1363         sk->shutdown=0;
1364         sk->prot=NULL;  /* So we use default free mechanisms */
1365         sk->broadcast=0;
1366         sk->err=0;
1367         skb_queue_head_init(&sk->receive_queue);
1368         skb_queue_head_init(&sk->write_queue);
1369         sk->send_head=NULL;
1370         skb_queue_head_init(&sk->back_log);
1371         sk->state=TCP_CLOSE;
1372         sk->socket=sock;
1373         sk->type=sock->type;
1374         sk->ipx_type=0;         /* General user level IPX */
1375         sk->debug=0;
1376         sk->ipx_intrfc = NULL;
1377         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
1378         sk->ipx_port = 0;
1379         sk->mtu=IPX_MTU;
1380         
1381         if(sock!=NULL)
1382         {
1383                 sock->data=(void *)sk;
1384                 sk->sleep=sock->wait;
1385         }
1386         
1387         sk->state_change=def_callback1;
1388         sk->data_ready=def_callback2;
1389         sk->write_space=def_callback1;
1390         sk->error_report=def_callback1;
1391 
1392         sk->zapped=1;
1393         return 0;
1394 }
1395 
1396 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
1397 {
1398         ipx_socket *sk=(ipx_socket *)sock->data;
1399         if(sk==NULL)
1400                 return(0);
1401         if(!sk->dead)
1402                 sk->state_change(sk);
1403         sk->dead=1;
1404         sock->data=NULL;
1405         ipx_destroy_socket(sk);
1406         return(0);
1407 }
1408 
1409 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
1410 {
1411         return(ipx_create(newsock,SOCK_DGRAM));
1412 }
1413 
1414 static unsigned short 
1415 ipx_first_free_socketnum(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1416 {
1417         unsigned short  socketNum = intrfc->if_sknum;
1418 
1419         if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1420                 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1421 
1422         while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
1423                 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1424                         socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1425                 else
1426                         socketNum++;
1427 
1428         intrfc->if_sknum = socketNum;
1429         return  ntohs(socketNum);
1430 }
1431         
1432 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
1433 {
1434         ipx_socket *sk;
1435         ipx_interface *intrfc;
1436         struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
1437         
1438         sk=(ipx_socket *)sock->data;
1439         
1440         if(sk->zapped==0)
1441                 return -EIO;
1442                 
1443         if(addr_len!=sizeof(struct sockaddr_ipx))
1444                 return -EINVAL;
1445         
1446         intrfc = ipxitf_find_using_net(addr->sipx_network);
1447         if (intrfc == NULL)
1448                 return -EADDRNOTAVAIL;
1449 
1450         if (addr->sipx_port == 0) {
1451                 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1452                 if (addr->sipx_port == 0)
1453                         return -EINVAL;
1454         }
1455 
1456         if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1457                 return -EPERM;  /* protect IPX system stuff like routing/sap */
1458         
1459         /* Source addresses are easy. It must be our network:node pair for
1460            an interface routed to IPX with the ipx routing ioctl() */
1461 
1462         if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1463                 if(sk->debug)
1464                         printk("IPX: bind failed because port %X in use.\n",
1465                                 (int)addr->sipx_port);
1466                 return -EADDRINUSE;        
1467         }
1468 
1469         sk->ipx_port=addr->sipx_port;
1470         ipxitf_insert_socket(intrfc, sk);
1471         sk->zapped=0;
1472         if(sk->debug)
1473                 printk("IPX: socket is bound.\n");
1474         return 0;
1475 }
1476 
1477 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1478         int addr_len, int flags)
1479 {
1480         ipx_socket *sk=(ipx_socket *)sock->data;
1481         struct sockaddr_ipx *addr;
1482         
1483         sk->state = TCP_CLOSE;  
1484         sock->state = SS_UNCONNECTED;
1485 
1486         if(addr_len!=sizeof(*addr))
1487                 return(-EINVAL);
1488         addr=(struct sockaddr_ipx *)uaddr;
1489         
1490         if(sk->ipx_port==0)
1491         /* put the autobinding in */
1492         {
1493                 struct sockaddr_ipx uaddr;
1494                 int ret;
1495         
1496                 uaddr.sipx_port = 0;
1497                 uaddr.sipx_network = 0L; 
1498                 ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1499                 if (ret != 0) return (ret);
1500         }
1501         
1502         if(ipxrtr_lookup(addr->sipx_network)==NULL)
1503                 return -ENETUNREACH;
1504         sk->ipx_dest_addr.net=addr->sipx_network;
1505         sk->ipx_dest_addr.sock=addr->sipx_port;
1506         memcpy(sk->ipx_dest_addr.node,addr->sipx_node,IPX_NODE_LEN);
1507         sk->ipx_type=addr->sipx_type;
1508         sock->state = SS_CONNECTED;
1509         sk->state=TCP_ESTABLISHED;
1510         return 0;
1511 }
1512 
1513 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
1514 {
1515         return(-EOPNOTSUPP);
1516 }
1517 
1518 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1519 {
1520         if(newsock->data)
1521                 kfree_s(newsock->data,sizeof(ipx_socket));
1522         return -EOPNOTSUPP;
1523 }
1524 
1525 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1526         int *uaddr_len, int peer)
1527 {
1528         ipx_address *addr;
1529         struct sockaddr_ipx sipx;
1530         ipx_socket *sk;
1531         
1532         sk=(ipx_socket *)sock->data;
1533         
1534         *uaddr_len = sizeof(struct sockaddr_ipx);
1535                 
1536         if(peer) {
1537                 if(sk->state!=TCP_ESTABLISHED)
1538                         return -ENOTCONN;
1539                 addr=&sk->ipx_dest_addr;
1540                 sipx.sipx_network = addr->net;
1541                 memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
1542                 sipx.sipx_port = addr->sock;
1543         } else {
1544                 if (sk->ipx_intrfc != NULL) {
1545                         sipx.sipx_network = sk->ipx_intrfc->if_netnum;
1546                         memcpy(sipx.sipx_node, sk->ipx_intrfc->if_node,
1547                                 IPX_NODE_LEN);
1548                 } else {
1549                         sipx.sipx_network = 0L;
1550                         memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1551                 }
1552                 sipx.sipx_port = sk->ipx_port;
1553         }
1554                 
1555         sipx.sipx_family = AF_IPX;
1556         sipx.sipx_type = sk->ipx_type;
1557         memcpy(uaddr,&sipx,sizeof(sipx));
1558         return 0;
1559 }
1560 
1561 #if 0
1562 /*
1563  * User to dump IPX packets (debugging)
1564  */
1565 void dump_data(char *str,unsigned char *d) {
     /* [previous][next][first][last][top][bottom][index][help] */
1566   static char h2c[] = "0123456789ABCDEF";
1567   int l,i;
1568   char *p, b[64];
1569   for (l=0;l<16;l++) {
1570     p = b;
1571     for (i=0; i < 8 ; i++) {
1572       *(p++) = h2c[d[i] & 0x0f];
1573       *(p++) = h2c[(d[i] >> 4) & 0x0f];
1574       *(p++) = ' ';
1575     }
1576     *(p++) = '-';
1577     *(p++) = ' ';
1578     for (i=0; i < 8 ; i++)  *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
1579     *p = '\000';
1580     d += i;
1581     printk("%s-%04X: %s\n",str,l*8,b);
1582   }
1583 }
1584 
1585 void dump_addr(char *str,ipx_address *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1586   printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
1587    str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
1588    p->node[3],p->node[4],p->node[5],ntohs(p->sock));
1589 }
1590 
1591 void dump_hdr(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1592   printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
1593    str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
1594    p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
1595   dump_addr("  IPX-DST",&p->ipx_dest);
1596   dump_addr("  IPX-SRC",&p->ipx_source);
1597 }
1598 
1599 void dump_pkt(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1600   dump_hdr(str,p);
1601   dump_data(str,(unsigned char *)p);
1602 }
1603 #endif
1604 
1605 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
1606 {
1607         /* NULL here for pt means the packet was looped back */
1608         ipx_interface   *intrfc;
1609         ipx_packet *ipx;
1610         
1611         ipx=(ipx_packet *)skb->h.raw;
1612         
1613         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) {
1614                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
1615                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
1616                    the same... */
1617                 kfree_skb(skb,FREE_READ);
1618                 return 0;
1619         }
1620         
1621         /* Too small */
1622         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
1623                 kfree_skb(skb,FREE_READ);
1624                 return 0;
1625         }
1626         
1627         /* Determine what local ipx endpoint this is */
1628         intrfc = ipxitf_find_using_phys(dev, pt->type);
1629         if (intrfc == NULL) {
1630                 if (ipxcfg_auto_create_interfaces) {
1631                         intrfc = ipxitf_auto_create(dev, pt->type);
1632                 }
1633 
1634                 if (intrfc == NULL) {
1635                         /* Not one of ours */
1636                         kfree_skb(skb,FREE_READ);
1637                         return 0;
1638                 }
1639         }
1640 
1641         return ipxitf_rcv(intrfc, skb);
1642 }
1643 
1644 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1645         unsigned flags, struct sockaddr *usip, int addr_len)
1646 {
1647         ipx_socket *sk=(ipx_socket *)sock->data;
1648         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
1649         struct sockaddr_ipx local_sipx;
1650         int retval;
1651 
1652         if (sk->zapped) return -EIO; /* Socket not bound */
1653         if(flags) return -EINVAL;
1654                 
1655         if(usipx) {
1656                 if(sk->ipx_port == 0) {
1657                         struct sockaddr_ipx uaddr;
1658                         int ret;
1659 
1660                         uaddr.sipx_port = 0;
1661                         uaddr.sipx_network = 0L; 
1662                         ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1663                         if (ret != 0) return ret;
1664                 }
1665 
1666                 if(addr_len <sizeof(*usipx))
1667                         return -EINVAL;
1668                 if(usipx->sipx_family != AF_IPX)
1669                         return -EINVAL;
1670 
1671                 if(htons(usipx->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1672                         return -EPERM;
1673         } else {
1674                 if(sk->state!=TCP_ESTABLISHED)
1675                         return -ENOTCONN;
1676                 usipx=&local_sipx;
1677                 usipx->sipx_family=AF_IPX;
1678                 usipx->sipx_type=sk->ipx_type;
1679                 usipx->sipx_port=sk->ipx_dest_addr.sock;
1680                 usipx->sipx_network=sk->ipx_dest_addr.net;
1681                 memcpy(usipx->sipx_node,sk->ipx_dest_addr.node,IPX_NODE_LEN);
1682         }
1683         
1684         retval = ipxrtr_route_packet(sk, usipx, ubuf, len);
1685         if (retval < 0) return retval;
1686 
1687         return len;
1688 }
1689 
1690 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1691 {
1692         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
1693 }
1694 
1695 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1696                    unsigned flags, struct sockaddr *sip, int *addr_len)
1697 {
1698         ipx_socket *sk=(ipx_socket *)sock->data;
1699         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
1700         struct ipx_packet       *ipx = NULL;
1701         /* FILL ME IN */
1702         int copied = 0;
1703         struct sk_buff *skb;
1704         int er;
1705         
1706         if(sk->err)
1707         {
1708                 er= -sk->err;
1709                 sk->err=0;
1710                 return er;
1711         }
1712         
1713         if (sk->zapped)
1714                 return -EIO;
1715 
1716         if(addr_len)
1717                 *addr_len=sizeof(*sipx);
1718 
1719         skb=skb_recv_datagram(sk,flags,noblock,&er);
1720         if(skb==NULL)
1721                 return er;
1722 
1723         ipx = (ipx_packet *)(skb->h.raw);
1724         copied=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
1725         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1726         
1727         if(sipx)
1728         {
1729                 sipx->sipx_family=AF_IPX;
1730                 sipx->sipx_port=ipx->ipx_source.sock;
1731                 memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
1732                 sipx->sipx_network=ipx->ipx_source.net;
1733                 sipx->sipx_type = ipx->ipx_type;
1734         }
1735         skb_free_datagram(skb);
1736         return(copied);
1737 }               
1738 
1739 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1740 {
1741         return ipx_send(sock,ubuf,size,noblock,0);
1742 }
1743 
1744 
1745 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1746         unsigned flags)
1747 {
1748         ipx_socket *sk=(ipx_socket *)sock->data;
1749         if(sk->zapped)
1750                 return -ENOTCONN;
1751         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1752 }
1753 
1754 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1755 {
1756         return ipx_recv(sock,ubuf,size,noblock,0);
1757 }
1758 
1759 
1760 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1761 {
1762         return -EOPNOTSUPP;
1763 }
1764 
1765 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1766 {
1767         ipx_socket *sk=(ipx_socket *)sock->data;
1768         
1769         return datagram_select(sk,sel_type,wait);
1770 }
1771 
1772 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1773 {
1774         int err;
1775         long amount=0;
1776         ipx_socket *sk=(ipx_socket *)sock->data;
1777         
1778         switch(cmd)
1779         {
1780                 case TIOCOUTQ:
1781                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1782                         if(err)
1783                                 return err;
1784                         amount=sk->sndbuf-sk->wmem_alloc;
1785                         if(amount<0)
1786                                 amount=0;
1787                         put_fs_long(amount,(unsigned long *)arg);
1788                         return 0;
1789                 case TIOCINQ:
1790                 {
1791                         struct sk_buff *skb;
1792                         /* These two are safe on a single CPU system as only user tasks fiddle here */
1793                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
1794                                 amount=skb->len;
1795                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1796                         put_fs_long(amount,(unsigned long *)arg);
1797                         return 0;
1798                 }
1799                 case SIOCADDRT:
1800                 case SIOCDELRT:
1801                         if(!suser())
1802                                 return -EPERM;
1803                         return(ipxrtr_ioctl(cmd,(void *)arg));
1804                 case SIOCSIFADDR:
1805                 case SIOCGIFADDR:
1806                 case SIOCAIPXITFCRT:
1807                 case SIOCAIPXPRISLT:
1808                         if(!suser())
1809                                 return -EPERM;
1810                         return(ipxitf_ioctl(cmd,(void *)arg));
1811                 case SIOCIPXCFGDATA: 
1812                 {
1813                         err=verify_area(VERIFY_WRITE,(void *)arg,
1814                                 sizeof(ipx_config_data));
1815                         if(err) return err;
1816                         return(ipxcfg_get_config_data((void *)arg));
1817                 }
1818                 case SIOCGSTAMP:
1819                         if (sk)
1820                         {
1821                                 if(sk->stamp.tv_sec==0)
1822                                         return -ENOENT;
1823                                 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
1824                                 if(err)
1825                                         return err;
1826                                         memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
1827                                 return 0;
1828                         }
1829                         return -EINVAL;
1830                 case SIOCGIFDSTADDR:
1831                 case SIOCSIFDSTADDR:
1832                 case SIOCGIFBRDADDR:
1833                 case SIOCSIFBRDADDR:
1834                 case SIOCGIFNETMASK:
1835                 case SIOCSIFNETMASK:
1836                         return -EINVAL;
1837                 default:
1838                         return(dev_ioctl(cmd,(void *) arg));
1839         }
1840         /*NOTREACHED*/
1841         return(0);
1842 }
1843 
1844 static struct proto_ops ipx_proto_ops = {
1845         AF_IPX,
1846         
1847         ipx_create,
1848         ipx_dup,
1849         ipx_release,
1850         ipx_bind,
1851         ipx_connect,
1852         ipx_socketpair,
1853         ipx_accept,
1854         ipx_getname,
1855         ipx_read,
1856         ipx_write,
1857         ipx_select,
1858         ipx_ioctl,
1859         ipx_listen,
1860         ipx_send,
1861         ipx_recv,
1862         ipx_sendto,
1863         ipx_recvfrom,
1864         ipx_shutdown,
1865         ipx_setsockopt,
1866         ipx_getsockopt,
1867         ipx_fcntl,
1868 };
1869 
1870 /* Called by ddi.c on kernel start up */
1871 
1872 static struct packet_type ipx_8023_packet_type = 
1873 
1874 {
1875         0,      /* MUTTER ntohs(ETH_P_8023),*/
1876         NULL,           /* All devices */
1877         ipx_rcv,
1878         NULL,
1879         NULL,
1880 };
1881  
1882 static struct packet_type ipx_dix_packet_type = 
1883 {
1884         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1885         NULL,           /* All devices */
1886         ipx_rcv,
1887         NULL,
1888         NULL,
1889 };
1890  
1891 static struct notifier_block ipx_dev_notifier={
1892         ipxitf_device_event,
1893         NULL,
1894         0
1895 };
1896 
1897 
1898 extern struct datalink_proto    *make_EII_client(void);
1899 extern struct datalink_proto    *make_8023_client(void);
1900 
1901 void ipx_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1902 {
1903         unsigned char   val = 0xE0;
1904         unsigned char   snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
1905 
1906         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1907 
1908         pEII_datalink = make_EII_client();
1909         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1910         dev_add_pack(&ipx_dix_packet_type);
1911 
1912         p8023_datalink = make_8023_client();
1913         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1914         dev_add_pack(&ipx_8023_packet_type);
1915         
1916         if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
1917                 printk("IPX: Unable to register with 802.2\n");
1918 
1919         if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
1920                 printk("IPX: Unable to register with SNAP\n");
1921         
1922         register_netdevice_notifier(&ipx_dev_notifier);
1923                 
1924         printk("Swansea University Computer Society IPX 0.29 BETA for NET3.019\n");
1925         printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
1926 }
1927 #endif

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