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

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