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

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