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

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