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_get_interface_info
  37. ipx_get_info
  38. ipx_rt_get_info
  39. ipx_fcntl
  40. ipx_setsockopt
  41. ipx_getsockopt
  42. ipx_listen
  43. def_callback1
  44. def_callback2
  45. ipx_create
  46. ipx_release
  47. ipx_dup
  48. ipx_first_free_socketnum
  49. ipx_bind
  50. ipx_connect
  51. ipx_socketpair
  52. ipx_accept
  53. ipx_getname
  54. dump_data
  55. dump_addr
  56. dump_hdr
  57. dump_pkt
  58. ipx_rcv
  59. ipx_sendto
  60. ipx_send
  61. ipx_recvfrom
  62. ipx_write
  63. ipx_recv
  64. ipx_read
  65. ipx_shutdown
  66. ipx_select
  67. ipx_ioctl
  68. ipx_proto_init

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

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