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                                         if(!suser())
1280                                                 return(-EPERM);
1281                                         sk->ipx_type=opt;
1282                                         return 0;
1283                                 default:
1284                                         return -EOPNOTSUPP;
1285                         }
1286                         break;
1287                         
1288                 case SOL_SOCKET:                
1289                         return sock_setsockopt(sk,level,optname,optval,optlen);
1290 
1291                 default:
1292                         return -EOPNOTSUPP;
1293         }
1294 }
1295 
1296 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
1297         char *optval, int *optlen)
1298 {
1299         ipx_socket *sk;
1300         int val=0;
1301         int err;
1302         
1303         sk=(ipx_socket *)sock->data;
1304 
1305         switch(level)
1306         {
1307 
1308                 case SOL_IPX:
1309                         switch(optname)
1310                         {
1311                                 case IPX_TYPE:
1312                                         val=sk->ipx_type;
1313                                         break;
1314                                 default:
1315                                         return -ENOPROTOOPT;
1316                         }
1317                         break;
1318                         
1319                 case SOL_SOCKET:
1320                         return sock_getsockopt(sk,level,optname,optval,optlen);
1321                         
1322                 default:
1323                         return -EOPNOTSUPP;
1324         }
1325         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
1326         if(err)
1327                 return err;
1328         put_fs_long(sizeof(int),(unsigned long *)optlen);
1329         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
1330         put_fs_long(val,(unsigned long *)optval);
1331         return(0);
1332 }
1333 
1334 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
1335 {
1336         return -EOPNOTSUPP;
1337 }
1338 
1339 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1340 {
1341         if(!sk->dead)
1342                 wake_up_interruptible(sk->sleep);
1343 }
1344 
1345 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
1346 {
1347         if(!sk->dead)
1348         {
1349                 wake_up_interruptible(sk->sleep);
1350                 sock_wake_async(sk->socket, 1);
1351         }
1352 }
1353 
1354 static int 
1355 ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
1356 {
1357         ipx_socket *sk;
1358         sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
1359         if(sk==NULL)
1360                 return(-ENOMEM);
1361         switch(sock->type)
1362         {
1363                 case SOCK_DGRAM:
1364                         break;
1365                 default:
1366                         kfree_s((void *)sk,sizeof(*sk));
1367                         return(-ESOCKTNOSUPPORT);
1368         }
1369         sk->dead=0;
1370         sk->next=NULL;
1371         sk->broadcast=0;
1372         sk->rcvbuf=SK_RMEM_MAX;
1373         sk->sndbuf=SK_WMEM_MAX;
1374         sk->wmem_alloc=0;
1375         sk->rmem_alloc=0;
1376         sk->inuse=0;
1377         sk->shutdown=0;
1378         sk->prot=NULL;  /* So we use default free mechanisms */
1379         sk->broadcast=0;
1380         sk->err=0;
1381         skb_queue_head_init(&sk->receive_queue);
1382         skb_queue_head_init(&sk->write_queue);
1383         sk->send_head=NULL;
1384         skb_queue_head_init(&sk->back_log);
1385         sk->state=TCP_CLOSE;
1386         sk->socket=sock;
1387         sk->type=sock->type;
1388         sk->ipx_type=0;         /* General user level IPX */
1389         sk->debug=0;
1390         sk->ipx_intrfc = NULL;
1391         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
1392         sk->ipx_port = 0;
1393         sk->mtu=IPX_MTU;
1394         
1395         if(sock!=NULL)
1396         {
1397                 sock->data=(void *)sk;
1398                 sk->sleep=sock->wait;
1399         }
1400         
1401         sk->state_change=def_callback1;
1402         sk->data_ready=def_callback2;
1403         sk->write_space=def_callback1;
1404         sk->error_report=def_callback1;
1405 
1406         sk->zapped=1;
1407         return 0;
1408 }
1409 
1410 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
1411 {
1412         ipx_socket *sk=(ipx_socket *)sock->data;
1413         if(sk==NULL)
1414                 return(0);
1415         if(!sk->dead)
1416                 sk->state_change(sk);
1417         sk->dead=1;
1418         sock->data=NULL;
1419         ipx_destroy_socket(sk);
1420         return(0);
1421 }
1422 
1423 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
1424 {
1425         return(ipx_create(newsock,SOCK_DGRAM));
1426 }
1427 
1428 static unsigned short 
1429 ipx_first_free_socketnum(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1430 {
1431         unsigned short  socketNum = intrfc->if_sknum;
1432 
1433         if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1434                 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1435 
1436         while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
1437                 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1438                         socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1439                 else
1440                         socketNum++;
1441 
1442         intrfc->if_sknum = socketNum;
1443         return  ntohs(socketNum);
1444 }
1445         
1446 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
1447 {
1448         ipx_socket *sk;
1449         ipx_interface *intrfc;
1450         struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
1451         
1452         sk=(ipx_socket *)sock->data;
1453         
1454         if(sk->zapped==0)
1455                 return -EIO;
1456                 
1457         if(addr_len!=sizeof(struct sockaddr_ipx))
1458                 return -EINVAL;
1459         
1460         intrfc = ipxitf_find_using_net(addr->sipx_network);
1461         if (intrfc == NULL)
1462                 return -EADDRNOTAVAIL;
1463 
1464         if (addr->sipx_port == 0) {
1465                 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1466                 if (addr->sipx_port == 0)
1467                         return -EINVAL;
1468         }
1469 
1470         if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1471                 return -EPERM;  /* protect IPX system stuff like routing/sap */
1472         
1473         /* Source addresses are easy. It must be our network:node pair for
1474            an interface routed to IPX with the ipx routing ioctl() */
1475 
1476         if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1477                 if(sk->debug)
1478                         printk("IPX: bind failed because port %X in use.\n",
1479                                 (int)addr->sipx_port);
1480                 return -EADDRINUSE;        
1481         }
1482 
1483         sk->ipx_port=addr->sipx_port;
1484         ipxitf_insert_socket(intrfc, sk);
1485         sk->zapped=0;
1486         if(sk->debug)
1487                 printk("IPX: socket is bound.\n");
1488         return 0;
1489 }
1490 
1491 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1492         int addr_len, int flags)
1493 {
1494         ipx_socket *sk=(ipx_socket *)sock->data;
1495         struct sockaddr_ipx *addr;
1496         
1497         sk->state = TCP_CLOSE;  
1498         sock->state = SS_UNCONNECTED;
1499 
1500         if(addr_len!=sizeof(*addr))
1501                 return(-EINVAL);
1502         addr=(struct sockaddr_ipx *)uaddr;
1503         
1504         if(sk->ipx_port==0)
1505         /* put the autobinding in */
1506         {
1507                 struct sockaddr_ipx uaddr;
1508                 int ret;
1509         
1510                 uaddr.sipx_port = 0;
1511                 uaddr.sipx_network = 0L; 
1512                 ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1513                 if (ret != 0) return (ret);
1514         }
1515         
1516         if(ipxrtr_lookup(addr->sipx_network)==NULL)
1517                 return -ENETUNREACH;
1518         sk->ipx_dest_addr.net=addr->sipx_network;
1519         sk->ipx_dest_addr.sock=addr->sipx_port;
1520         memcpy(sk->ipx_dest_addr.node,addr->sipx_node,IPX_NODE_LEN);
1521         sk->ipx_type=addr->sipx_type;
1522         sock->state = SS_CONNECTED;
1523         sk->state=TCP_ESTABLISHED;
1524         return 0;
1525 }
1526 
1527 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
1528 {
1529         return(-EOPNOTSUPP);
1530 }
1531 
1532 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1533 {
1534         if(newsock->data)
1535                 kfree_s(newsock->data,sizeof(ipx_socket));
1536         return -EOPNOTSUPP;
1537 }
1538 
1539 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1540         int *uaddr_len, int peer)
1541 {
1542         ipx_address *addr;
1543         struct sockaddr_ipx sipx;
1544         ipx_socket *sk;
1545         
1546         sk=(ipx_socket *)sock->data;
1547         
1548         *uaddr_len = sizeof(struct sockaddr_ipx);
1549                 
1550         if(peer) {
1551                 if(sk->state!=TCP_ESTABLISHED)
1552                         return -ENOTCONN;
1553                 addr=&sk->ipx_dest_addr;
1554                 sipx.sipx_network = addr->net;
1555                 memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
1556                 sipx.sipx_port = addr->sock;
1557         } else {
1558                 if (sk->ipx_intrfc != NULL) {
1559                         sipx.sipx_network = sk->ipx_intrfc->if_netnum;
1560                         memcpy(sipx.sipx_node, sk->ipx_intrfc->if_node,
1561                                 IPX_NODE_LEN);
1562                 } else {
1563                         sipx.sipx_network = 0L;
1564                         memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1565                 }
1566                 sipx.sipx_port = sk->ipx_port;
1567         }
1568                 
1569         sipx.sipx_family = AF_IPX;
1570         sipx.sipx_type = sk->ipx_type;
1571         memcpy(uaddr,&sipx,sizeof(sipx));
1572         return 0;
1573 }
1574 
1575 #if 0
1576 /*
1577  * User to dump IPX packets (debugging)
1578  */
1579 void dump_data(char *str,unsigned char *d) {
     /* [previous][next][first][last][top][bottom][index][help] */
1580   static char h2c[] = "0123456789ABCDEF";
1581   int l,i;
1582   char *p, b[64];
1583   for (l=0;l<16;l++) {
1584     p = b;
1585     for (i=0; i < 8 ; i++) {
1586       *(p++) = h2c[d[i] & 0x0f];
1587       *(p++) = h2c[(d[i] >> 4) & 0x0f];
1588       *(p++) = ' ';
1589     }
1590     *(p++) = '-';
1591     *(p++) = ' ';
1592     for (i=0; i < 8 ; i++)  *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
1593     *p = '\000';
1594     d += i;
1595     printk("%s-%04X: %s\n",str,l*8,b);
1596   }
1597 }
1598 
1599 void dump_addr(char *str,ipx_address *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1600   printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
1601    str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
1602    p->node[3],p->node[4],p->node[5],ntohs(p->sock));
1603 }
1604 
1605 void dump_hdr(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1606   printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
1607    str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
1608    p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
1609   dump_addr("  IPX-DST",&p->ipx_dest);
1610   dump_addr("  IPX-SRC",&p->ipx_source);
1611 }
1612 
1613 void dump_pkt(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
1614   dump_hdr(str,p);
1615   dump_data(str,(unsigned char *)p);
1616 }
1617 #endif
1618 
1619 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
1620 {
1621         /* NULL here for pt means the packet was looped back */
1622         ipx_interface   *intrfc;
1623         ipx_packet *ipx;
1624         
1625         ipx=(ipx_packet *)skb->h.raw;
1626         
1627         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) {
1628                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
1629                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
1630                    the same... */
1631                 kfree_skb(skb,FREE_READ);
1632                 return 0;
1633         }
1634         
1635         /* Too small */
1636         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
1637                 kfree_skb(skb,FREE_READ);
1638                 return 0;
1639         }
1640         
1641         /* Determine what local ipx endpoint this is */
1642         intrfc = ipxitf_find_using_phys(dev, pt->type);
1643         if (intrfc == NULL) {
1644                 if (ipxcfg_auto_create_interfaces) {
1645                         intrfc = ipxitf_auto_create(dev, pt->type);
1646                 }
1647 
1648                 if (intrfc == NULL) {
1649                         /* Not one of ours */
1650                         kfree_skb(skb,FREE_READ);
1651                         return 0;
1652                 }
1653         }
1654 
1655         return ipxitf_rcv(intrfc, skb);
1656 }
1657 
1658 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1659         unsigned flags, struct sockaddr *usip, int addr_len)
1660 {
1661         ipx_socket *sk=(ipx_socket *)sock->data;
1662         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
1663         struct sockaddr_ipx local_sipx;
1664         int retval;
1665 
1666         if (sk->zapped) return -EIO; /* Socket not bound */
1667         if(flags) return -EINVAL;
1668                 
1669         if(usipx) {
1670                 if(sk->ipx_port == 0) {
1671                         struct sockaddr_ipx uaddr;
1672                         int ret;
1673 
1674                         uaddr.sipx_port = 0;
1675                         uaddr.sipx_network = 0L; 
1676                         ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1677                         if (ret != 0) return ret;
1678                 }
1679 
1680                 if(addr_len <sizeof(*usipx))
1681                         return -EINVAL;
1682                 if(usipx->sipx_family != AF_IPX)
1683                         return -EINVAL;
1684 
1685                 if(htons(usipx->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1686                         return -EPERM;
1687         } else {
1688                 if(sk->state!=TCP_ESTABLISHED)
1689                         return -ENOTCONN;
1690                 usipx=&local_sipx;
1691                 usipx->sipx_family=AF_IPX;
1692                 usipx->sipx_type=sk->ipx_type;
1693                 usipx->sipx_port=sk->ipx_dest_addr.sock;
1694                 usipx->sipx_network=sk->ipx_dest_addr.net;
1695                 memcpy(usipx->sipx_node,sk->ipx_dest_addr.node,IPX_NODE_LEN);
1696         }
1697         
1698         retval = ipxrtr_route_packet(sk, usipx, ubuf, len);
1699         if (retval < 0) return retval;
1700 
1701         return len;
1702 }
1703 
1704 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1705 {
1706         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
1707 }
1708 
1709 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1710                    unsigned flags, struct sockaddr *sip, int *addr_len)
1711 {
1712         ipx_socket *sk=(ipx_socket *)sock->data;
1713         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
1714         struct ipx_packet       *ipx = NULL;
1715         /* FILL ME IN */
1716         int copied = 0;
1717         struct sk_buff *skb;
1718         int er;
1719         
1720         if(sk->err)
1721         {
1722                 er= -sk->err;
1723                 sk->err=0;
1724                 return er;
1725         }
1726         
1727         if (sk->zapped)
1728                 return -EIO;
1729 
1730         if(addr_len)
1731                 *addr_len=sizeof(*sipx);
1732 
1733         skb=skb_recv_datagram(sk,flags,noblock,&er);
1734         if(skb==NULL)
1735                 return er;
1736 
1737         ipx = (ipx_packet *)(skb->h.raw);
1738         copied=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
1739         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1740         
1741         if(sipx)
1742         {
1743                 sipx->sipx_family=AF_IPX;
1744                 sipx->sipx_port=ipx->ipx_source.sock;
1745                 memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
1746                 sipx->sipx_network=ipx->ipx_source.net;
1747                 sipx->sipx_type = ipx->ipx_type;
1748         }
1749         skb_free_datagram(skb);
1750         return(copied);
1751 }               
1752 
1753 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1754 {
1755         return ipx_send(sock,ubuf,size,noblock,0);
1756 }
1757 
1758 
1759 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1760         unsigned flags)
1761 {
1762         ipx_socket *sk=(ipx_socket *)sock->data;
1763         if(sk->zapped)
1764                 return -ENOTCONN;
1765         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1766 }
1767 
1768 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1769 {
1770         return ipx_recv(sock,ubuf,size,noblock,0);
1771 }
1772 
1773 
1774 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1775 {
1776         return -EOPNOTSUPP;
1777 }
1778 
1779 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1780 {
1781         ipx_socket *sk=(ipx_socket *)sock->data;
1782         
1783         return datagram_select(sk,sel_type,wait);
1784 }
1785 
1786 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1787 {
1788         int err;
1789         long amount=0;
1790         ipx_socket *sk=(ipx_socket *)sock->data;
1791         
1792         switch(cmd)
1793         {
1794                 case TIOCOUTQ:
1795                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1796                         if(err)
1797                                 return err;
1798                         amount=sk->sndbuf-sk->wmem_alloc;
1799                         if(amount<0)
1800                                 amount=0;
1801                         put_fs_long(amount,(unsigned long *)arg);
1802                         return 0;
1803                 case TIOCINQ:
1804                 {
1805                         struct sk_buff *skb;
1806                         /* These two are safe on a single CPU system as only user tasks fiddle here */
1807                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
1808                                 amount=skb->len;
1809                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1810                         put_fs_long(amount,(unsigned long *)arg);
1811                         return 0;
1812                 }
1813                 case SIOCADDRT:
1814                 case SIOCDELRT:
1815                         if(!suser())
1816                                 return -EPERM;
1817                         return(ipxrtr_ioctl(cmd,(void *)arg));
1818                 case SIOCSIFADDR:
1819                 case SIOCGIFADDR:
1820                 case SIOCAIPXITFCRT:
1821                 case SIOCAIPXPRISLT:
1822                         if(!suser())
1823                                 return -EPERM;
1824                         return(ipxitf_ioctl(cmd,(void *)arg));
1825                 case SIOCIPXCFGDATA: 
1826                 {
1827                         err=verify_area(VERIFY_WRITE,(void *)arg,
1828                                 sizeof(ipx_config_data));
1829                         if(err) return err;
1830                         return(ipxcfg_get_config_data((void *)arg));
1831                 }
1832                 case SIOCGSTAMP:
1833                         if (sk)
1834                         {
1835                                 if(sk->stamp.tv_sec==0)
1836                                         return -ENOENT;
1837                                 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
1838                                 if(err)
1839                                         return err;
1840                                         memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
1841                                 return 0;
1842                         }
1843                         return -EINVAL;
1844                 case SIOCGIFDSTADDR:
1845                 case SIOCSIFDSTADDR:
1846                 case SIOCGIFBRDADDR:
1847                 case SIOCSIFBRDADDR:
1848                 case SIOCGIFNETMASK:
1849                 case SIOCSIFNETMASK:
1850                         return -EINVAL;
1851                 default:
1852                         return(dev_ioctl(cmd,(void *) arg));
1853         }
1854         /*NOTREACHED*/
1855         return(0);
1856 }
1857 
1858 static struct proto_ops ipx_proto_ops = {
1859         AF_IPX,
1860         
1861         ipx_create,
1862         ipx_dup,
1863         ipx_release,
1864         ipx_bind,
1865         ipx_connect,
1866         ipx_socketpair,
1867         ipx_accept,
1868         ipx_getname,
1869         ipx_read,
1870         ipx_write,
1871         ipx_select,
1872         ipx_ioctl,
1873         ipx_listen,
1874         ipx_send,
1875         ipx_recv,
1876         ipx_sendto,
1877         ipx_recvfrom,
1878         ipx_shutdown,
1879         ipx_setsockopt,
1880         ipx_getsockopt,
1881         ipx_fcntl,
1882 };
1883 
1884 /* Called by ddi.c on kernel start up */
1885 
1886 static struct packet_type ipx_8023_packet_type = 
1887 
1888 {
1889         0,      /* MUTTER ntohs(ETH_P_8023),*/
1890         NULL,           /* All devices */
1891         ipx_rcv,
1892         NULL,
1893         NULL,
1894 };
1895  
1896 static struct packet_type ipx_dix_packet_type = 
1897 {
1898         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1899         NULL,           /* All devices */
1900         ipx_rcv,
1901         NULL,
1902         NULL,
1903 };
1904  
1905 static struct notifier_block ipx_dev_notifier={
1906         ipxitf_device_event,
1907         NULL,
1908         0
1909 };
1910 
1911 
1912 extern struct datalink_proto    *make_EII_client(void);
1913 extern struct datalink_proto    *make_8023_client(void);
1914 
1915 void ipx_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1916 {
1917         unsigned char   val = 0xE0;
1918         unsigned char   snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
1919 
1920         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1921 
1922         pEII_datalink = make_EII_client();
1923         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1924         dev_add_pack(&ipx_dix_packet_type);
1925 
1926         p8023_datalink = make_8023_client();
1927         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1928         dev_add_pack(&ipx_8023_packet_type);
1929         
1930         if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
1931                 printk("IPX: Unable to register with 802.2\n");
1932 
1933         if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
1934                 printk("IPX: Unable to register with SNAP\n");
1935         
1936         register_netdevice_notifier(&ipx_dev_notifier);
1937                 
1938         printk("Swansea University Computer Society IPX 0.29 BETA for NET3.019\n");
1939         printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
1940 }
1941 #endif

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