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. ipx_map_frame_type
  22. ipxitf_create
  23. ipxitf_delete
  24. ipxitf_auto_create
  25. ipxitf_ioctl
  26. ipxrtr_lookup
  27. ipxrtr_add_route
  28. ipxrtr_del_routes
  29. ipxrtr_create
  30. ipxrtr_delete
  31. ipxrtr_route_packet
  32. ipxrtr_route_skb
  33. ipxrtr_ioctl
  34. ipx_frame_name
  35. ipx_device_name
  36. ipx_get_interface_info
  37. ipx_get_info
  38. ipx_rt_get_info
  39. ipx_fcntl
  40. ipx_setsockopt
  41. ipx_getsockopt
  42. ipx_listen
  43. def_callback1
  44. def_callback2
  45. ipx_create
  46. ipx_release
  47. ipx_dup
  48. ipx_first_free_socketnum
  49. ipx_bind
  50. ipx_connect
  51. ipx_socketpair
  52. ipx_accept
  53. ipx_getname
  54. dump_data
  55. dump_addr
  56. dump_hdr
  57. dump_pkt
  58. ipx_rcv
  59. ipx_sendto
  60. ipx_send
  61. ipx_recvfrom
  62. ipx_write
  63. ipx_recv
  64. ipx_read
  65. ipx_shutdown
  66. ipx_select
  67. ipx_ioctl
  68. 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 propagated 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 originating 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) && 
 548                 (ipx->ipx_source.net == ipx->ipx_dest.net)) {
 549                 /* NB: NetWare servers lie about their hop count so we
 550                  * dropped the test based on it.  This is the best way
 551                  * to determine this is a 0 hop count packet.
 552                  */
 553                 if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL) {
 554                         intrfc->if_netnum = ipx->ipx_source.net;
 555                         (void) ipxitf_add_local_route(intrfc);
 556                 } else {
 557                         printk("IPX: Network number collision %lx\n\t%s %s and %s %s\n",
 558                                 htonl(ipx->ipx_source.net), 
 559                                 ipx_device_name(i),
 560                                 ipx_frame_name(i->if_dlink_type),
 561                                 ipx_device_name(intrfc),
 562                                 ipx_frame_name(intrfc->if_dlink_type));
 563                 }
 564         }
 565 
 566         if (intrfc->if_netnum != ipx->ipx_dest.net) {
 567                 /* We only route point-to-point packets. */
 568                 if ((skb->pkt_type != PACKET_BROADCAST) &&
 569                         (skb->pkt_type != PACKET_MULTICAST))
 570                         return ipxrtr_route_skb(skb);
 571                 
 572                 kfree_skb(skb,FREE_READ);
 573                 return 0;
 574         }
 575 
 576         /* see if we should keep it */
 577         if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) 
 578                 || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) {
 579                 return ipxitf_demux_socket(intrfc, skb, 0);
 580         }
 581 
 582         /* we couldn't pawn it off so unload it */
 583         kfree_skb(skb,FREE_READ);
 584         return 0;
 585 }
 586 
 587 static void
 588 ipxitf_insert(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 589 {
 590         ipx_interface   *i;
 591 
 592         intrfc->if_next = NULL;
 593         if (ipx_interfaces == NULL) {
 594                 ipx_interfaces = intrfc;
 595         } else {
 596                 for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
 597                         ;
 598                 i->if_next = intrfc;
 599         }
 600 
 601         if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 602                 ipx_primary_net = intrfc;
 603 }
 604 
 605 static int 
 606 ipxitf_create_internal(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 607 {
 608         ipx_interface   *intrfc;
 609 
 610         /* Only one primary network allowed */
 611         if (ipx_primary_net != NULL) return -EEXIST;
 612 
 613         /* Must have a valid network number */
 614         if (idef->ipx_network == 0L) return -EADDRNOTAVAIL;
 615         if (ipxitf_find_using_net(idef->ipx_network) != NULL)
 616                 return -EADDRINUSE;
 617 
 618         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 619         if (intrfc==NULL)
 620                 return -EAGAIN;
 621         intrfc->if_dev=NULL;
 622         intrfc->if_netnum=idef->ipx_network;
 623         intrfc->if_dlink_type = 0;
 624         intrfc->if_dlink = NULL;
 625         intrfc->if_sklist = NULL;
 626         intrfc->if_internal = 1;
 627         intrfc->if_ipx_offset = 0;
 628         intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 629         memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
 630         ipx_internal_net = intrfc;
 631         ipx_primary_net = intrfc;
 632         ipxitf_insert(intrfc);
 633         return ipxitf_add_local_route(intrfc);
 634 }
 635 
 636 static int
 637 ipx_map_frame_type(unsigned char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 638 {
 639         switch (type) {
 640         case IPX_FRAME_ETHERII: return htons(ETH_P_IPX);
 641         case IPX_FRAME_8022: return htons(ETH_P_802_2);
 642         case IPX_FRAME_SNAP: return htons(ETH_P_SNAP);
 643         case IPX_FRAME_8023: return htons(ETH_P_802_3);
 644         }
 645         return 0;
 646 }
 647 
 648 static int 
 649 ipxitf_create(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 650 {
 651         struct device   *dev;
 652         unsigned short  dlink_type = 0;
 653         struct datalink_proto   *datalink = NULL;
 654         ipx_interface   *intrfc;
 655 
 656         if (idef->ipx_special == IPX_INTERNAL) 
 657                 return ipxitf_create_internal(idef);
 658 
 659         if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
 660                 return -EEXIST;
 661 
 662         if ((idef->ipx_network != 0L) &&
 663                 (ipxitf_find_using_net(idef->ipx_network) != NULL))
 664                 return -EADDRINUSE;
 665 
 666         switch (idef->ipx_dlink_type) {
 667         case IPX_FRAME_ETHERII: 
 668                 dlink_type = htons(ETH_P_IPX);
 669                 datalink = pEII_datalink;
 670                 break;
 671         case IPX_FRAME_8022:
 672                 dlink_type = htons(ETH_P_802_2);
 673                 datalink = p8022_datalink;
 674                 break;
 675         case IPX_FRAME_SNAP:
 676                 dlink_type = htons(ETH_P_SNAP);
 677                 datalink = pSNAP_datalink;
 678                 break;
 679         case IPX_FRAME_8023:
 680                 dlink_type = htons(ETH_P_802_3);
 681                 datalink = p8023_datalink;
 682                 break;
 683         case IPX_FRAME_NONE:
 684         default:
 685                 break;
 686         }
 687 
 688         if (datalink == NULL) 
 689                 return -EPROTONOSUPPORT;
 690 
 691         dev=dev_get(idef->ipx_device);
 692         if (dev==NULL) 
 693                 return -ENODEV;
 694 
 695         if (!(dev->flags & IFF_UP))
 696                 return -ENETDOWN;
 697 
 698         /* Check addresses are suitable */
 699         if(dev->addr_len>IPX_NODE_LEN)
 700                 return -EINVAL;
 701 
 702         if(dev->addr_len<2)
 703                 return -EINVAL;
 704 
 705         if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) {
 706 
 707                 /* Ok now create */
 708                 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 709                 if (intrfc==NULL)
 710                         return -EAGAIN;
 711                 intrfc->if_dev=dev;
 712                 intrfc->if_netnum=idef->ipx_network;
 713                 intrfc->if_dlink_type = dlink_type;
 714                 intrfc->if_dlink = datalink;
 715                 intrfc->if_sklist = NULL;
 716                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 717                 /* Setup primary if necessary */
 718                 if ((idef->ipx_special == IPX_PRIMARY)) 
 719                         ipx_primary_net = intrfc;
 720                 intrfc->if_internal = 0;
 721                 intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
 722                 memset(intrfc->if_node, 0, IPX_NODE_LEN);
 723                 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len);
 724 
 725                 ipxitf_insert(intrfc);
 726         }
 727 
 728         /* If the network number is known, add a route */
 729         if (intrfc->if_netnum == 0L) 
 730                 return 0;
 731 
 732         return ipxitf_add_local_route(intrfc);
 733 }
 734 
 735 static int 
 736 ipxitf_delete(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 737 {
 738         struct device   *dev = NULL;
 739         unsigned short  dlink_type = 0;
 740         ipx_interface   *intrfc;
 741 
 742         if (idef->ipx_special == IPX_INTERNAL) {
 743                 if (ipx_internal_net != NULL) {
 744                         ipxitf_down(ipx_internal_net);
 745                         return 0;
 746                 }
 747                 return -ENOENT;
 748         }
 749 
 750         dlink_type = ipx_map_frame_type(idef->ipx_dlink_type);
 751         if (dlink_type == 0)
 752                 return -EPROTONOSUPPORT;
 753 
 754         dev=dev_get(idef->ipx_device);
 755         if(dev==NULL) return -ENODEV;
 756 
 757         intrfc = ipxitf_find_using_phys(dev, dlink_type);
 758         if (intrfc != NULL) {
 759                 ipxitf_down(intrfc);
 760                 return 0;
 761         }
 762         return -EINVAL;
 763 }
 764 
 765 static ipx_interface *
 766 ipxitf_auto_create(struct device *dev, unsigned short dlink_type)
     /* [previous][next][first][last][top][bottom][index][help] */
 767 {
 768         struct datalink_proto *datalink = NULL;
 769         ipx_interface   *intrfc;
 770 
 771         switch (htons(dlink_type)) {
 772         case ETH_P_IPX: datalink = pEII_datalink; break;
 773         case ETH_P_802_2: datalink = p8022_datalink; break;
 774         case ETH_P_SNAP: datalink = pSNAP_datalink; break;
 775         case ETH_P_802_3: datalink = p8023_datalink; break;
 776         default: return NULL;
 777         }
 778         
 779         if (dev == NULL)
 780                 return NULL;
 781 
 782         /* Check addresses are suitable */
 783         if(dev->addr_len>IPX_NODE_LEN) return NULL;
 784 
 785         if(dev->addr_len<2) return NULL;
 786 
 787         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 788         if (intrfc!=NULL) {
 789                 intrfc->if_dev=dev;
 790                 intrfc->if_netnum=0L;
 791                 intrfc->if_dlink_type = dlink_type;
 792                 intrfc->if_dlink = datalink;
 793                 intrfc->if_sklist = NULL;
 794                 intrfc->if_internal = 0;
 795                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 796                 intrfc->if_ipx_offset = dev->hard_header_len + 
 797                         datalink->header_length;
 798                 memset(intrfc->if_node, 0, IPX_NODE_LEN);
 799                 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
 800                         dev->dev_addr, dev->addr_len);
 801                 ipxitf_insert(intrfc);
 802         }
 803 
 804         return intrfc;
 805 }
 806 
 807 static int 
 808 ipxitf_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 809 {
 810         int err;
 811         switch(cmd)
 812         {
 813                 case SIOCSIFADDR:
 814                 {
 815                         struct ifreq ifr;
 816                         struct sockaddr_ipx *sipx;
 817                         ipx_interface_definition f;
 818                         err=verify_area(VERIFY_READ,arg,sizeof(ifr));
 819                         if(err)
 820                                 return err;
 821                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
 822                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
 823                         if(sipx->sipx_family!=AF_IPX)
 824                                 return -EINVAL;
 825                         f.ipx_network=sipx->sipx_network;
 826                         memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device));
 827                         memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
 828                         f.ipx_dlink_type=sipx->sipx_type;
 829                         f.ipx_special=sipx->sipx_special;
 830                         if(sipx->sipx_action==IPX_DLTITF)
 831                                 return ipxitf_delete(&f);
 832                         else
 833                                 return ipxitf_create(&f);
 834                 }
 835                 case SIOCGIFADDR:
 836                 {
 837                         struct ifreq ifr;
 838                         struct sockaddr_ipx *sipx;
 839                         ipx_interface *ipxif;
 840                         struct device *dev;
 841                         err=verify_area(VERIFY_WRITE,arg,sizeof(ifr));
 842                         if(err)
 843                                 return err;
 844                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
 845                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
 846                         dev=dev_get(ifr.ifr_name);
 847                         if(!dev)
 848                                 return -ENODEV;
 849                         ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type));
 850                         if(ipxif==NULL)
 851                                 return -EADDRNOTAVAIL;
 852                         sipx->sipx_network=ipxif->if_netnum;
 853                         memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node));
 854                         memcpy_tofs(arg,&ifr,sizeof(ifr));
 855                         return 0;
 856                 }
 857                 case SIOCAIPXITFCRT:
 858                         err=verify_area(VERIFY_READ,arg,sizeof(char));
 859                         if(err)
 860                                 return err;
 861                         return ipxcfg_set_auto_create(get_fs_byte(arg));
 862                 case SIOCAIPXPRISLT:
 863                         err=verify_area(VERIFY_READ,arg,sizeof(char));
 864                         if(err)
 865                                 return err;
 866                         return ipxcfg_set_auto_select(get_fs_byte(arg));
 867                 default:
 868                         return -EINVAL;
 869         }
 870 }
 871 
 872 /*******************************************************************************************************************\
 873 *                                                                                                                   *
 874 *                                       Routing tables for the IPX socket layer                                     *
 875 *                                                                                                                   *
 876 \*******************************************************************************************************************/
 877 
 878 static ipx_route *
 879 ipxrtr_lookup(unsigned long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 880 {
 881         ipx_route *r;
 882 
 883         for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next)
 884                 ;
 885 
 886         return r;
 887 }
 888 
 889 static int
 890 ipxrtr_add_route(unsigned long network, ipx_interface *intrfc, unsigned char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 891 {
 892         ipx_route       *rt;
 893 
 894         /* Get a route structure; either existing or create */
 895         rt = ipxrtr_lookup(network);
 896         if (rt==NULL) {
 897                 rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
 898                 if(rt==NULL)
 899                         return -EAGAIN;
 900                 rt->ir_next=ipx_routes;
 901                 ipx_routes=rt;
 902         }
 903 
 904         rt->ir_net = network;
 905         rt->ir_intrfc = intrfc;
 906         if (node == NULL) {
 907                 memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
 908                 rt->ir_routed = 0;
 909         } else {
 910                 memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
 911                 rt->ir_routed=1;
 912         }
 913         return 0;
 914 }
 915 
 916 static void
 917 ipxrtr_del_routes(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 918 {
 919         ipx_route       **r, *tmp;
 920 
 921         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
 922                 if (tmp->ir_intrfc == intrfc) {
 923                         *r = tmp->ir_next;
 924                         kfree_s(tmp, sizeof(ipx_route));
 925                 } else {
 926                         r = &(tmp->ir_next);
 927                 }
 928         }
 929 }
 930 
 931 static int 
 932 ipxrtr_create(ipx_route_definition *rd)
     /* [previous][next][first][last][top][bottom][index][help] */
 933 {
 934         ipx_interface *intrfc;
 935 
 936         /* Find the appropriate interface */
 937         intrfc = ipxitf_find_using_net(rd->ipx_router_network);
 938         if (intrfc == NULL)
 939                 return -ENETUNREACH;
 940 
 941         return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
 942 }
 943 
 944 
 945 static int 
 946 ipxrtr_delete(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 947 {
 948         ipx_route       **r;
 949         ipx_route       *tmp;
 950 
 951         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
 952                 if (tmp->ir_net == net) {
 953                         if (!(tmp->ir_routed)) {
 954                                 /* Directly connected; can't lose route */
 955                                 return -EPERM;
 956                         }
 957                         *r = tmp->ir_next;
 958                         kfree_s(tmp, sizeof(ipx_route));
 959                         return 0;
 960                 } 
 961                 r = &(tmp->ir_next);
 962         }
 963 
 964         return -ENOENT;
 965 }
 966 
 967 static int
 968 ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, void *ubuf, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 969 {
 970         struct sk_buff *skb;
 971         ipx_interface *intrfc;
 972         ipx_packet *ipx;
 973         int size;
 974         int ipx_offset;
 975         ipx_route *rt = NULL;
 976 
 977         /* Find the appropriate interface on which to send packet */
 978         if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) {
 979                 usipx->sipx_network = ipx_primary_net->if_netnum;
 980                 intrfc = ipx_primary_net;
 981         } else {
 982                 rt = ipxrtr_lookup(usipx->sipx_network);
 983                 if (rt==NULL) {
 984                         return -ENETUNREACH;
 985                 }
 986                 intrfc = rt->ir_intrfc;
 987         }
 988         
 989         ipx_offset = intrfc->if_ipx_offset;
 990         size=sizeof(ipx_packet)+len;
 991         size += ipx_offset;
 992 
 993         if(size+sk->wmem_alloc>sk->sndbuf) return -EAGAIN;
 994                 
 995         skb=alloc_skb(size,GFP_KERNEL);
 996         if(skb==NULL) return -ENOMEM;
 997                 
 998         skb->sk=sk;
 999         skb->len=size;
1000         skb->free=1;
1001         skb->arp=1;
1002 
1003         /* Fill in IPX header */
1004         ipx=(ipx_packet *)&(skb->data[ipx_offset]);
1005         ipx->ipx_checksum=0xFFFF;
1006         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
1007         ipx->ipx_tctrl=0;
1008         ipx->ipx_type=usipx->sipx_type;
1009         skb->h.raw = (unsigned char *)ipx;
1010 
1011         ipx->ipx_source.net = sk->ipx_intrfc->if_netnum;
1012         memcpy(ipx->ipx_source.node, sk->ipx_intrfc->if_node, IPX_NODE_LEN);
1013         ipx->ipx_source.sock = sk->ipx_port;
1014         ipx->ipx_dest.net=usipx->sipx_network;
1015         memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
1016         ipx->ipx_dest.sock=usipx->sipx_port;
1017 
1018         memcpy_fromfs((char *)(ipx+1),ubuf,len);
1019         return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
1020                                 rt->ir_router_node : ipx->ipx_dest.node);
1021 }
1022         
1023 static int
1024 ipxrtr_route_skb(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
1025 {
1026         ipx_packet      *ipx = (ipx_packet *) (skb->h.raw);
1027         ipx_route       *r;
1028         ipx_interface   *i;
1029 
1030         r = ipxrtr_lookup(ipx->ipx_dest.net);
1031         if (r == NULL) {
1032                 /* no known route */
1033                 kfree_skb(skb,FREE_READ);
1034                 return 0;
1035         }
1036         i = r->ir_intrfc;
1037         (void)ipxitf_send(i, skb, (r->ir_routed) ? 
1038                         r->ir_router_node : ipx->ipx_dest.node);
1039         return 0;
1040 }
1041 
1042 /*
1043  *      We use a normal struct rtentry for route handling
1044  */
1045  
1046 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1047 {
1048         int err;
1049         struct rtentry rt;      /* Use these to behave like 'other' stacks */
1050         struct sockaddr_ipx *sg,*st;
1051 
1052         err=verify_area(VERIFY_READ,arg,sizeof(rt));
1053         if(err)
1054                 return err;
1055                 
1056         memcpy_fromfs(&rt,arg,sizeof(rt));
1057         
1058         sg=(struct sockaddr_ipx *)&rt.rt_gateway;
1059         st=(struct sockaddr_ipx *)&rt.rt_dst;
1060         
1061         if(!(rt.rt_flags&RTF_GATEWAY))
1062                 return -EINVAL;         /* Direct routes are fixed */
1063         if(sg->sipx_family!=AF_IPX)
1064                 return -EINVAL;
1065         if(st->sipx_family!=AF_IPX)
1066                 return -EINVAL;
1067                 
1068         switch(cmd)
1069         {
1070                 case SIOCDELRT:
1071                         return ipxrtr_delete(st->sipx_network);
1072                 case SIOCADDRT:
1073                 {
1074                         struct ipx_route_definition f;
1075                         f.ipx_network=st->sipx_network;
1076                         f.ipx_router_network=sg->sipx_network;
1077                         memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
1078                         return ipxrtr_create(&f);
1079                 }
1080                 default:
1081                         return -EINVAL;
1082         }
1083 }
1084 
1085 static char *
1086 ipx_frame_name(unsigned short frame)
     /* [previous][next][first][last][top][bottom][index][help] */
1087 {
1088         switch (ntohs(frame)) {
1089         case ETH_P_IPX: return "EtherII";
1090         case ETH_P_802_2: return "802.2";
1091         case ETH_P_SNAP: return "SNAP";
1092         case ETH_P_802_3: return "802.3";
1093         default: return "None";
1094         }
1095 }
1096 
1097 static char *
1098 ipx_device_name(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1099 {
1100         return (intrfc->if_internal ? "Internal" :
1101                 (intrfc->if_dev ? intrfc->if_dev->name : "Unknown"));
1102 }
1103 
1104 /* Called from proc fs */
1105 int 
1106 ipx_get_interface_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1107 {
1108         ipx_interface *i;
1109         int len=0;
1110         off_t pos=0;
1111         off_t begin=0;
1112 
1113         /* Theory.. Keep printing in the same place until we pass offset */
1114         
1115         len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", 
1116                 "Node_Address", "Primary", "Device", "Frame_Type");
1117         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1118                 len += sprintf(buffer+len, "%08lX   ", ntohl(i->if_netnum));
1119                 len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ", 
1120                                 i->if_node[0], i->if_node[1], i->if_node[2],
1121                                 i->if_node[3], i->if_node[4], i->if_node[5]);
1122                 len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
1123                         "Yes" : "No");
1124                 len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
1125                 len += sprintf (buffer+len, "%s\n", 
1126                         ipx_frame_name(i->if_dlink_type));
1127 
1128                 /* Are we still dumping unwanted data then discard the record */
1129                 pos=begin+len;
1130                 
1131                 if(pos<offset) {
1132                         len=0;                  /* Keep dumping into the buffer start */
1133                         begin=pos;
1134                 }
1135                 if(pos>offset+length)           /* We have dumped enough */
1136                         break;
1137         }
1138         
1139         /* The data in question runs from begin to begin+len */
1140         *start=buffer+(offset-begin);   /* Start of wanted data */
1141         len-=(offset-begin);            /* Remove unwanted header data from length */
1142         if(len>length)
1143                 len=length;             /* Remove unwanted tail data from length */
1144         
1145         return len;
1146 }
1147 
1148 int 
1149 ipx_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1150 {
1151         ipx_socket *s;
1152         ipx_interface *i;
1153         int len=0;
1154         off_t pos=0;
1155         off_t begin=0;
1156 
1157         /* Theory.. Keep printing in the same place until we pass offset */
1158         
1159         len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
1160                         "Remote_Address", "Tx_Queue", "Rx_Queue", 
1161                         "State", "Uid");
1162         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1163                 for (s = i->if_sklist; s != NULL; s = s->next) {
1164                         len += sprintf (buffer+len,"%08lX:%04X  ", 
1165                                 htonl(i->if_netnum),
1166                                 htons(s->ipx_port));
1167                         if (s->state!=TCP_ESTABLISHED) {
1168                                 len += sprintf(buffer+len, "%-28s", "Not_Connected");
1169                         } else {
1170                                 len += sprintf (buffer+len,
1171                                         "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
1172                                         htonl(s->ipx_dest_addr.net),
1173                                         s->ipx_dest_addr.node[0], s->ipx_dest_addr.node[1], 
1174                                         s->ipx_dest_addr.node[2], s->ipx_dest_addr.node[3], 
1175                                         s->ipx_dest_addr.node[4], s->ipx_dest_addr.node[5],
1176                                         htons(s->ipx_dest_addr.sock));
1177                         }
1178                         len += sprintf (buffer+len,"%08lX  %08lX  ", 
1179                                 s->wmem_alloc, s->rmem_alloc);
1180                         len += sprintf (buffer+len,"%02X     %03d\n", 
1181                                 s->state, SOCK_INODE(s->socket)->i_uid);
1182                 
1183                         /* Are we still dumping unwanted data then discard the record */
1184                         pos=begin+len;
1185                 
1186                         if(pos<offset)
1187                         {
1188                                 len=0;                  /* Keep dumping into the buffer start */
1189                                 begin=pos;
1190                         }
1191                         if(pos>offset+length)           /* We have dumped enough */
1192                                 break;
1193                 }
1194         }
1195         
1196         /* The data in question runs from begin to begin+len */
1197         *start=buffer+(offset-begin);   /* Start of wanted data */
1198         len-=(offset-begin);            /* Remove unwanted header data from length */
1199         if(len>length)
1200                 len=length;             /* Remove unwanted tail data from length */
1201         
1202         return len;
1203 }
1204 
1205 int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
1206 {
1207         ipx_route *rt;
1208         int len=0;
1209         off_t pos=0;
1210         off_t begin=0;
1211 
1212         len += sprintf (buffer,"%-11s%-13s%s\n", 
1213                         "Network", "Router_Net", "Router_Node");
1214         for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
1215         {
1216                 len += sprintf (buffer+len,"%08lX   ", ntohl(rt->ir_net));
1217                 if (rt->ir_routed) {
1218                         len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n", 
1219                                 ntohl(rt->ir_intrfc->if_netnum), 
1220                                 rt->ir_router_node[0], rt->ir_router_node[1], 
1221                                 rt->ir_router_node[2], rt->ir_router_node[3], 
1222                                 rt->ir_router_node[4], rt->ir_router_node[5]);
1223                 } else {
1224                         len += sprintf (buffer+len, "%-13s%s\n",
1225                                         "Directly", "Connected");
1226                 }
1227                 pos=begin+len;
1228                 if(pos<offset)
1229                 {
1230                         len=0;
1231                         begin=pos;
1232                 }
1233                 if(pos>offset+length)
1234                         break;
1235         }
1236         *start=buffer+(offset-begin);
1237         len-=(offset-begin);
1238         if(len>length)
1239                 len=length;
1240         return len;
1241 }
1242 
1243 /*******************************************************************************************************************\
1244 *                                                                                                                   *
1245 *             Handling for system calls applied via the various interfaces to an IPX socket object                  *
1246 *                                                                                                                   *
1247 \*******************************************************************************************************************/
1248  
1249 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1250 {
1251         switch(cmd)
1252         {
1253                 default:
1254                         return(-EINVAL);
1255         }
1256 }
1257 
1258 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
1259 {
1260         ipx_socket *sk;
1261         int err,opt;
1262         
1263         sk=(ipx_socket *)sock->data;
1264         
1265         if(optval==NULL)
1266                 return(-EINVAL);
1267 
1268         err=verify_area(VERIFY_READ,optval,sizeof(int));
1269         if(err)
1270                 return err;
1271         opt=get_fs_long((unsigned long *)optval);
1272         
1273         switch(level)
1274         {
1275                 case SOL_IPX:
1276                         switch(optname)
1277                         {
1278                                 case IPX_TYPE:
1279                                         sk->ipx_type=opt;
1280                                         return 0;
1281                                 default:
1282                                         return -EOPNOTSUPP;
1283                         }
1284                         break;
1285                         
1286                 case SOL_SOCKET:                
1287                         return sock_setsockopt(sk,level,optname,optval,optlen);
1288 
1289                 default:
1290                         return -EOPNOTSUPP;
1291         }
1292 }
1293 
1294 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
1295         char *optval, int *optlen)
1296 {
1297         ipx_socket *sk;
1298         int val=0;
1299         int err;
1300         
1301         sk=(ipx_socket *)sock->data;
1302 
1303         switch(level)
1304         {
1305 
1306                 case SOL_IPX:
1307                         switch(optname)
1308                         {
1309                                 case IPX_TYPE:
1310                                         val=sk->ipx_type;
1311                                         break;
1312                                 default:
1313                                         return -ENOPROTOOPT;
1314                         }
1315                         break;
1316                         
1317                 case SOL_SOCKET:
1318                         return sock_getsockopt(sk,level,optname,optval,optlen);
1319                         
1320                 default:
1321                         return -EOPNOTSUPP;
1322         }
1323         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
1324         if(err)
1325                 return err;
1326         put_fs_long(sizeof(int),(unsigned long *)optlen);
1327         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
1328         put_fs_long(val,(unsigned long *)optval);
1329         return(0);
1330 }
1331 
1332 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
1333 {
1334         return -EOPNOTSUPP;
1335 }
1336 
1337 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1338 {
1339         if(!sk->dead)
1340                 wake_up_interruptible(sk->sleep);
1341 }
1342 
1343 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
1344 {
1345         if(!sk->dead)
1346         {
1347                 wake_up_interruptible(sk->sleep);
1348                 sock_wake_async(sk->socket, 1);
1349         }
1350 }
1351 
1352 static int 
1353 ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
1354 {
1355         ipx_socket *sk;
1356         sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
1357         if(sk==NULL)
1358                 return(-ENOMEM);
1359         switch(sock->type)
1360         {
1361                 case SOCK_DGRAM:
1362                         break;
1363                 default:
1364                         kfree_s((void *)sk,sizeof(*sk));
1365                         return(-ESOCKTNOSUPPORT);
1366         }
1367         sk->dead=0;
1368         sk->next=NULL;
1369         sk->broadcast=0;
1370         sk->rcvbuf=SK_RMEM_MAX;
1371         sk->sndbuf=SK_WMEM_MAX;
1372         sk->wmem_alloc=0;
1373         sk->rmem_alloc=0;
1374         sk->inuse=0;
1375         sk->shutdown=0;
1376         sk->prot=NULL;  /* So we use default free mechanisms */
1377         sk->broadcast=0;
1378         sk->err=0;
1379         skb_queue_head_init(&sk->receive_queue);
1380         skb_queue_head_init(&sk->write_queue);
1381         sk->send_head=NULL;
1382         skb_queue_head_init(&sk->back_log);
1383         sk->state=TCP_CLOSE;
1384         sk->socket=sock;
1385         sk->type=sock->type;
1386         sk->ipx_type=0;         /* General user level IPX */
1387         sk->debug=0;
1388         sk->ipx_intrfc = NULL;
1389         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
1390         sk->ipx_port = 0;
1391         sk->mtu=IPX_MTU;
1392         
1393         if(sock!=NULL)
1394         {
1395                 sock->data=(void *)sk;
1396                 sk->sleep=sock->wait;
1397         }
1398         
1399         sk->state_change=def_callback1;
1400         sk->data_ready=def_callback2;
1401         sk->write_space=def_callback1;
1402         sk->error_report=def_callback1;
1403 
1404         sk->zapped=1;
1405         return 0;
1406 }
1407 
1408 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
1409 {
1410         ipx_socket *sk=(ipx_socket *)sock->data;
1411         if(sk==NULL)
1412                 return(0);
1413         if(!sk->dead)
1414                 sk->state_change(sk);
1415         sk->dead=1;
1416         sock->data=NULL;
1417         ipx_destroy_socket(sk);
1418         return(0);
1419 }
1420 
1421 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
1422 {
1423         return(ipx_create(newsock,SOCK_DGRAM));
1424 }
1425 
1426 static unsigned short 
1427 ipx_first_free_socketnum(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1428 {
1429         unsigned short  socketNum = intrfc->if_sknum;
1430 
1431         if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1432                 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1433 
1434         while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
1435                 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1436                         socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1437                 else
1438                         socketNum++;
1439 
1440         intrfc->if_sknum = socketNum;
1441         return  ntohs(socketNum);
1442 }
1443         
1444 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
1445 {
1446         ipx_socket *sk;
1447         ipx_interface *intrfc;
1448         struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
1449         
1450         sk=(ipx_socket *)sock->data;
1451         
1452         if(sk->zapped==0)
1453                 return -EIO;
1454                 
1455         if(addr_len!=sizeof(struct sockaddr_ipx))
1456                 return -EINVAL;
1457         
1458         intrfc = ipxitf_find_using_net(addr->sipx_network);
1459         if (intrfc == NULL)
1460                 return -EADDRNOTAVAIL;
1461 
1462         if (addr->sipx_port == 0) {
1463                 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1464                 if (addr->sipx_port == 0)
1465                         return -EINVAL;
1466         }
1467 
1468         if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1469                 return -EPERM;  /* protect IPX system stuff like routing/sap */
1470         
1471         /* Source addresses are easy. It must be our network:node pair for
1472            an interface routed to IPX with the ipx routing ioctl() */
1473 
1474         if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1475                 if(sk->debug)
1476                         printk("IPX: bind failed because port %X in use.\n",
1477                                 (int)addr->sipx_port);
1478                 return -EADDRINUSE;        
1479         }
1480 
1481         sk->ipx_port=addr->sipx_port;
1482         ipxitf_insert_socket(intrfc, sk);
1483         sk->zapped=0;
1484         if(sk->debug)
1485                 printk("IPX: socket is bound.\n");
1486         return 0;
1487 }
1488 
1489 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1490         int addr_len, int flags)
1491 {
1492         ipx_socket *sk=(ipx_socket *)sock->data;
1493         struct sockaddr_ipx *addr;
1494         
1495         sk->state = TCP_CLOSE;  
1496         sock->state = SS_UNCONNECTED;
1497 
1498         if(addr_len!=sizeof(*addr))
1499                 return(-EINVAL);
1500         addr=(struct sockaddr_ipx *)uaddr;
1501         
1502         if(sk->ipx_port==0)
1503         /* put the autobinding in */
1504         {
1505                 struct sockaddr_ipx uaddr;
1506                 int ret;
1507         
1508                 uaddr.sipx_port = 0;
1509                 uaddr.sipx_network = 0L; 
1510                 ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1511                 if (ret != 0) return (ret);
1512         }
1513         
1514         if(ipxrtr_lookup(addr->sipx_network)==NULL)
1515                 return -ENETUNREACH;
1516         sk->ipx_dest_addr.net=addr->sipx_network;
1517         sk->ipx_dest_addr.sock=addr->sipx_port;
1518         memcpy(sk->ipx_dest_addr.node,addr->sipx_node,IPX_NODE_LEN);
1519         sk->ipx_type=addr->sipx_type;
1520         sock->state = SS_CONNECTED;
1521         sk->state=TCP_ESTABLISHED;
1522         return 0;
1523 }
1524 
1525 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
1526 {
1527         return(-EOPNOTSUPP);
1528 }
1529 
1530 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1531 {
1532         if(newsock->data)
1533                 kfree_s(newsock->data,sizeof(ipx_socket));
1534         return -EOPNOTSUPP;
1535 }
1536 
1537 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1538         int *uaddr_len, int peer)
1539 {
1540         ipx_address *addr;
1541         struct sockaddr_ipx sipx;
1542         ipx_socket *sk;
1543         
1544         sk=(ipx_socket *)sock->data;
1545         
1546         *uaddr_len = sizeof(struct sockaddr_ipx);
1547                 
1548         if(peer) {
1549                 if(sk->state!=TCP_ESTABLISHED)
1550                         return -ENOTCONN;
1551                 addr=&sk->ipx_dest_addr;
1552                 sipx.sipx_network = addr->net;
1553                 memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
1554                 sipx.sipx_port = addr->sock;
1555         } else {
1556                 if (sk->ipx_intrfc != NULL) {
1557                         sipx.sipx_network = sk->ipx_intrfc->if_netnum;
1558                         memcpy(sipx.sipx_node, sk->ipx_intrfc->if_node,
1559                                 IPX_NODE_LEN);
1560                 } else {
1561                         sipx.sipx_network = 0L;
1562                         memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1563                 }
1564                 sipx.sipx_port = sk->ipx_port;
1565         }
1566                 
1567         sipx.sipx_family = AF_IPX;
1568         sipx.sipx_type = sk->ipx_type;
1569         memcpy(uaddr,&sipx,sizeof(sipx));
1570         return 0;
1571 }
1572 
1573 #if 0
1574 /*
1575  * User to dump IPX packets (debugging)
1576  */
1577 void dump_data(char *str,unsigned char *d) {
     /* [previous][next][first][last][top][bottom][index][help] */
1578   static char h2c[] = "0123456789ABCDEF";
1579   int l,i;
1580   char *p, b[64];
1581   for (l=0;l<16;l++) {
1582     p = b;
1583     for (i=0; i < 8 ; i++) {
1584       *(p++) = h2c[d[i] & 0x0f];
1585       *(p++) = h2c[(d[i] >> 4) & 0x0f];
1586       *(p++) = ' ';
1587     }
1588     *(p++) = '-';
1589     *(p++) = ' ';
1590     for (i=0; i < 8 ; i++)  *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
1591     *p = '\000';
1592     d += i;
1593     printk("%s-%04X: %s\n",str,l*8,b);
1594   }
1595 }
1596 
1597 void dump_addr(char *str,ipx_address *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1598   printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
1599    str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
1600    p->node[3],p->node[4],p->node[5],ntohs(p->sock));
1601 }
1602 
1603 void dump_hdr(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1604   printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
1605    str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
1606    p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
1607   dump_addr("  IPX-DST",&p->ipx_dest);
1608   dump_addr("  IPX-SRC",&p->ipx_source);
1609 }
1610 
1611 void dump_pkt(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1612   dump_hdr(str,p);
1613   dump_data(str,(unsigned char *)p);
1614 }
1615 #endif
1616 
1617 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
1618 {
1619         /* NULL here for pt means the packet was looped back */
1620         ipx_interface   *intrfc;
1621         ipx_packet *ipx;
1622         
1623         ipx=(ipx_packet *)skb->h.raw;
1624         
1625         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) {
1626                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
1627                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
1628                    the same... */
1629                 kfree_skb(skb,FREE_READ);
1630                 return 0;
1631         }
1632         
1633         /* Too small */
1634         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
1635                 kfree_skb(skb,FREE_READ);
1636                 return 0;
1637         }
1638         
1639         /* Determine what local ipx endpoint this is */
1640         intrfc = ipxitf_find_using_phys(dev, pt->type);
1641         if (intrfc == NULL) {
1642                 if (ipxcfg_auto_create_interfaces) {
1643                         intrfc = ipxitf_auto_create(dev, pt->type);
1644                 }
1645 
1646                 if (intrfc == NULL) {
1647                         /* Not one of ours */
1648                         kfree_skb(skb,FREE_READ);
1649                         return 0;
1650                 }
1651         }
1652 
1653         return ipxitf_rcv(intrfc, skb);
1654 }
1655 
1656 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1657         unsigned flags, struct sockaddr *usip, int addr_len)
1658 {
1659         ipx_socket *sk=(ipx_socket *)sock->data;
1660         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
1661         struct sockaddr_ipx local_sipx;
1662         int retval;
1663 
1664         if (sk->zapped) return -EIO; /* Socket not bound */
1665         if(flags) return -EINVAL;
1666                 
1667         if(usipx) {
1668                 if(sk->ipx_port == 0) {
1669                         struct sockaddr_ipx uaddr;
1670                         int ret;
1671 
1672                         uaddr.sipx_port = 0;
1673                         uaddr.sipx_network = 0L; 
1674                         ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1675                         if (ret != 0) return ret;
1676                 }
1677 
1678                 if(addr_len <sizeof(*usipx))
1679                         return -EINVAL;
1680                 if(usipx->sipx_family != AF_IPX)
1681                         return -EINVAL;
1682         } else {
1683                 if(sk->state!=TCP_ESTABLISHED)
1684                         return -ENOTCONN;
1685                 usipx=&local_sipx;
1686                 usipx->sipx_family=AF_IPX;
1687                 usipx->sipx_type=sk->ipx_type;
1688                 usipx->sipx_port=sk->ipx_dest_addr.sock;
1689                 usipx->sipx_network=sk->ipx_dest_addr.net;
1690                 memcpy(usipx->sipx_node,sk->ipx_dest_addr.node,IPX_NODE_LEN);
1691         }
1692         
1693         retval = ipxrtr_route_packet(sk, usipx, ubuf, len);
1694         if (retval < 0) return retval;
1695 
1696         return len;
1697 }
1698 
1699 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1700 {
1701         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
1702 }
1703 
1704 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1705                    unsigned flags, struct sockaddr *sip, int *addr_len)
1706 {
1707         ipx_socket *sk=(ipx_socket *)sock->data;
1708         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
1709         struct ipx_packet       *ipx = NULL;
1710         /* FILL ME IN */
1711         int copied = 0;
1712         struct sk_buff *skb;
1713         int er;
1714         
1715         if(sk->err)
1716         {
1717                 er= -sk->err;
1718                 sk->err=0;
1719                 return er;
1720         }
1721         
1722         if (sk->zapped)
1723                 return -EIO;
1724 
1725         if(addr_len)
1726                 *addr_len=sizeof(*sipx);
1727 
1728         skb=skb_recv_datagram(sk,flags,noblock,&er);
1729         if(skb==NULL)
1730                 return er;
1731 
1732         ipx = (ipx_packet *)(skb->h.raw);
1733         copied=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
1734         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1735         
1736         if(sipx)
1737         {
1738                 sipx->sipx_family=AF_IPX;
1739                 sipx->sipx_port=ipx->ipx_source.sock;
1740                 memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
1741                 sipx->sipx_network=ipx->ipx_source.net;
1742                 sipx->sipx_type = ipx->ipx_type;
1743         }
1744         skb_free_datagram(skb);
1745         return(copied);
1746 }               
1747 
1748 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1749 {
1750         return ipx_send(sock,ubuf,size,noblock,0);
1751 }
1752 
1753 
1754 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1755         unsigned flags)
1756 {
1757         ipx_socket *sk=(ipx_socket *)sock->data;
1758         if(sk->zapped)
1759                 return -ENOTCONN;
1760         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1761 }
1762 
1763 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1764 {
1765         return ipx_recv(sock,ubuf,size,noblock,0);
1766 }
1767 
1768 
1769 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1770 {
1771         return -EOPNOTSUPP;
1772 }
1773 
1774 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1775 {
1776         ipx_socket *sk=(ipx_socket *)sock->data;
1777         
1778         return datagram_select(sk,sel_type,wait);
1779 }
1780 
1781 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1782 {
1783         int err;
1784         long amount=0;
1785         ipx_socket *sk=(ipx_socket *)sock->data;
1786         
1787         switch(cmd)
1788         {
1789                 case TIOCOUTQ:
1790                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1791                         if(err)
1792                                 return err;
1793                         amount=sk->sndbuf-sk->wmem_alloc;
1794                         if(amount<0)
1795                                 amount=0;
1796                         put_fs_long(amount,(unsigned long *)arg);
1797                         return 0;
1798                 case TIOCINQ:
1799                 {
1800                         struct sk_buff *skb;
1801                         /* These two are safe on a single CPU system as only user tasks fiddle here */
1802                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
1803                                 amount=skb->len;
1804                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1805                         put_fs_long(amount,(unsigned long *)arg);
1806                         return 0;
1807                 }
1808                 case SIOCADDRT:
1809                 case SIOCDELRT:
1810                         if(!suser())
1811                                 return -EPERM;
1812                         return(ipxrtr_ioctl(cmd,(void *)arg));
1813                 case SIOCSIFADDR:
1814                 case SIOCGIFADDR:
1815                 case SIOCAIPXITFCRT:
1816                 case SIOCAIPXPRISLT:
1817                         if(!suser())
1818                                 return -EPERM;
1819                         return(ipxitf_ioctl(cmd,(void *)arg));
1820                 case SIOCIPXCFGDATA: 
1821                 {
1822                         err=verify_area(VERIFY_WRITE,(void *)arg,
1823                                 sizeof(ipx_config_data));
1824                         if(err) return err;
1825                         return(ipxcfg_get_config_data((void *)arg));
1826                 }
1827                 case SIOCGSTAMP:
1828                         if (sk)
1829                         {
1830                                 if(sk->stamp.tv_sec==0)
1831                                         return -ENOENT;
1832                                 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
1833                                 if(err)
1834                                         return err;
1835                                         memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
1836                                 return 0;
1837                         }
1838                         return -EINVAL;
1839                 case SIOCGIFDSTADDR:
1840                 case SIOCSIFDSTADDR:
1841                 case SIOCGIFBRDADDR:
1842                 case SIOCSIFBRDADDR:
1843                 case SIOCGIFNETMASK:
1844                 case SIOCSIFNETMASK:
1845                         return -EINVAL;
1846                 default:
1847                         return(dev_ioctl(cmd,(void *) arg));
1848         }
1849         /*NOTREACHED*/
1850         return(0);
1851 }
1852 
1853 static struct proto_ops ipx_proto_ops = {
1854         AF_IPX,
1855         
1856         ipx_create,
1857         ipx_dup,
1858         ipx_release,
1859         ipx_bind,
1860         ipx_connect,
1861         ipx_socketpair,
1862         ipx_accept,
1863         ipx_getname,
1864         ipx_read,
1865         ipx_write,
1866         ipx_select,
1867         ipx_ioctl,
1868         ipx_listen,
1869         ipx_send,
1870         ipx_recv,
1871         ipx_sendto,
1872         ipx_recvfrom,
1873         ipx_shutdown,
1874         ipx_setsockopt,
1875         ipx_getsockopt,
1876         ipx_fcntl,
1877 };
1878 
1879 /* Called by ddi.c on kernel start up */
1880 
1881 static struct packet_type ipx_8023_packet_type = 
1882 
1883 {
1884         0,      /* MUTTER ntohs(ETH_P_8023),*/
1885         NULL,           /* All devices */
1886         ipx_rcv,
1887         NULL,
1888         NULL,
1889 };
1890  
1891 static struct packet_type ipx_dix_packet_type = 
1892 {
1893         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1894         NULL,           /* All devices */
1895         ipx_rcv,
1896         NULL,
1897         NULL,
1898 };
1899  
1900 static struct notifier_block ipx_dev_notifier={
1901         ipxitf_device_event,
1902         NULL,
1903         0
1904 };
1905 
1906 
1907 extern struct datalink_proto    *make_EII_client(void);
1908 extern struct datalink_proto    *make_8023_client(void);
1909 
1910 void ipx_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1911 {
1912         unsigned char   val = 0xE0;
1913         unsigned char   snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
1914 
1915         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1916 
1917         pEII_datalink = make_EII_client();
1918         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1919         dev_add_pack(&ipx_dix_packet_type);
1920 
1921         p8023_datalink = make_8023_client();
1922         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1923         dev_add_pack(&ipx_8023_packet_type);
1924         
1925         if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
1926                 printk("IPX: Unable to register with 802.2\n");
1927 
1928         if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
1929                 printk("IPX: Unable to register with SNAP\n");
1930         
1931         register_netdevice_notifier(&ipx_dev_notifier);
1932                 
1933         printk("Swansea University Computer Society IPX 0.29 BETA for NET3.019\n");
1934         printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
1935 }
1936 #endif

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