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_find_internal_socket
  12. ipxitf_down
  13. ipxitf_device_event
  14. ipxitf_def_skb_handler
  15. ipxitf_demux_socket
  16. ipxitf_demux_socket
  17. ipxitf_adjust_skbuff
  18. ipxitf_send
  19. ipxitf_add_local_route
  20. ipxitf_rcv
  21. ipxitf_insert
  22. ipxitf_create_internal
  23. ipx_map_frame_type
  24. ipxitf_create
  25. ipxitf_delete
  26. ipxitf_auto_create
  27. ipxitf_ioctl_real
  28. ipxitf_ioctl
  29. ipxrtr_lookup
  30. ipxrtr_add_route
  31. ipxrtr_del_routes
  32. ipxrtr_create
  33. ipxrtr_delete
  34. ipx_set_checksum
  35. ipxrtr_route_packet
  36. ipxrtr_route_skb
  37. ipxrtr_ioctl
  38. ipx_frame_name
  39. ipx_device_name
  40. ipx_interface_get_info
  41. ipx_get_info
  42. ipx_rt_get_info
  43. ipx_fcntl
  44. ipx_setsockopt
  45. ipx_getsockopt
  46. ipx_listen
  47. def_callback1
  48. def_callback2
  49. ipx_create
  50. ipx_release
  51. ipx_dup
  52. ipx_first_free_socketnum
  53. ipx_bind
  54. ipx_connect
  55. ipx_socketpair
  56. ipx_accept
  57. ipx_getname
  58. dump_data
  59. dump_addr
  60. dump_hdr
  61. dump_pkt
  62. ipx_rcv
  63. ipx_sendmsg
  64. ipx_recvmsg
  65. ipx_shutdown
  66. ipx_select
  67. ipx_ioctl
  68. ipx_proto_init
  69. ipx_proto_finito
  70. init_module
  71. cleanup_module

   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  *      Revision 0.33:  Internal network support, routing changes, uses a
  43  *                      protocol private area for ipx data.
  44  *      Revision 0.34:  Module support. <Jim Freeman>
  45  *      Revision 0.35:  Checksum support. <Neil Turton>, hooked in by <Alan Cox>
  46  *
  47  *      Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
  48  *      pair. Also, now usage count is managed this way
  49  *      -Count one if the auto_interface mode is on
  50  *      -Count one per configured interface
  51  *
  52  *      Jacques Gelinas (jacques@solucorp.qc.ca)
  53  *
  54  *
  55  *      Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
  56  *      Neither Greg Page nor Caldera, Inc. admit liability nor provide 
  57  *      warranty for any of this software. This material is provided 
  58  *      "AS-IS" and at no charge.               
  59  */
  60 
  61 #include <linux/module.h>
  62 
  63 #include <linux/config.h>
  64 #include <linux/errno.h>
  65 #include <linux/types.h>
  66 #include <linux/socket.h>
  67 #include <linux/in.h>
  68 #include <linux/kernel.h>
  69 #include <linux/sched.h>
  70 #include <linux/timer.h>
  71 #include <linux/string.h>
  72 #include <linux/sockios.h>
  73 #include <linux/net.h>
  74 #include <linux/netdevice.h>
  75 #include <net/ipx.h>
  76 #include <linux/inet.h>
  77 #include <linux/route.h>
  78 #include <net/sock.h>
  79 #include <asm/segment.h>
  80 #include <asm/system.h>
  81 #include <linux/fcntl.h>
  82 #include <linux/mm.h>
  83 #include <linux/termios.h>      /* For TIOCOUTQ/INQ */
  84 #include <linux/interrupt.h>
  85 #include <net/p8022.h>
  86 #include <net/p8022tr.h>
  87 #include <net/psnap.h>
  88 #include <linux/proc_fs.h>
  89 #include <linux/stat.h>
  90 #include <linux/firewall.h>
  91 
  92 #ifdef MODULE
  93 static void ipx_proto_finito(void);
  94 #endif /* def MODULE */
  95 
  96 /* Configuration Variables */
  97 static unsigned char    ipxcfg_max_hops = 16;
  98 static char             ipxcfg_auto_select_primary = 0;
  99 static char             ipxcfg_auto_create_interfaces = 0;
 100 
 101 /* Global Variables */
 102 static struct datalink_proto    *p8022_datalink = NULL;
 103 static struct datalink_proto    *p8022tr_datalink = NULL;
 104 static struct datalink_proto    *pEII_datalink = NULL;
 105 static struct datalink_proto    *p8023_datalink = NULL;
 106 static struct datalink_proto    *pSNAP_datalink = NULL;
 107 
 108 static ipx_route        *ipx_routes = NULL;
 109 static ipx_interface    *ipx_interfaces = NULL;
 110 static ipx_interface    *ipx_primary_net = NULL;
 111 static ipx_interface    *ipx_internal_net = NULL;
 112 
 113 static int
 114 ipxcfg_set_auto_create(char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         if (ipxcfg_auto_create_interfaces != val){
 117                 if (val){
 118                         MOD_INC_USE_COUNT;
 119                 }else{
 120                         MOD_DEC_USE_COUNT;
 121                 }
 122                 ipxcfg_auto_create_interfaces = val;
 123         }
 124         return 0;
 125 }
 126                 
 127 static int
 128 ipxcfg_set_auto_select(char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         ipxcfg_auto_select_primary = val;
 131         if (val && (ipx_primary_net == NULL))
 132                 ipx_primary_net = ipx_interfaces;
 133         return 0;
 134 }
 135 
 136 static int
 137 ipxcfg_get_config_data(ipx_config_data *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139         ipx_config_data vals;
 140         
 141         vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
 142         vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
 143         memcpy_tofs(arg, &vals, sizeof(vals));
 144         return 0;
 145 }
 146 
 147 
 148 /***********************************************************************************************************************\
 149 *                                                                                                                       *
 150 *                                               Handlers for the socket list.                                           *
 151 *                                                                                                                       *
 152 \***********************************************************************************************************************/
 153 
 154 /*
 155  *      Note: Sockets may not be removed _during_ an interrupt or inet_bh
 156  *      handler using this technique. They can be added although we do not
 157  *      use this facility.
 158  */
 159  
 160 static void 
 161 ipx_remove_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 162 {
 163         ipx_socket      *s;
 164         ipx_interface   *intrfc;
 165         unsigned long   flags;
 166 
 167         save_flags(flags);
 168         cli();
 169         
 170         /* Determine interface with which socket is associated */
 171         intrfc = sk->protinfo.af_ipx.intrfc;
 172         if (intrfc == NULL) {
 173                 restore_flags(flags);
 174                 return;
 175         }
 176 
 177         s=intrfc->if_sklist;
 178         if(s==sk) {
 179                 intrfc->if_sklist=s->next;
 180                 restore_flags(flags);
 181                 return;
 182         } 
 183 
 184         while(s && s->next) {
 185                 if(s->next==sk) {
 186                         s->next=sk->next;
 187                         restore_flags(flags);
 188                         return;
 189                 }
 190                 s=s->next;
 191         }
 192         restore_flags(flags);
 193 }
 194 
 195 /*
 196  *      This is only called from user mode. Thus it protects itself against
 197  *      interrupt users but doesn't worry about being called during work.
 198  *      Once it is removed from the queue no interrupt or bottom half will
 199  *      touch it and we are (fairly 8-) ) safe.
 200  */
 201  
 202 static void 
 203 ipx_destroy_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         struct sk_buff  *skb;
 206 
 207         ipx_remove_socket(sk);
 208         while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
 209                 kfree_skb(skb,FREE_READ);
 210         }
 211         
 212         sk_free(sk);
 213         MOD_DEC_USE_COUNT;
 214 }
 215         
 216 /* The following code is used to support IPX Interfaces (IPXITF).  An
 217  * IPX interface is defined by a physical device and a frame type.
 218  */
 219 
 220 static ipx_route * ipxrtr_lookup(unsigned long);
 221 
 222 static void
 223 ipxitf_clear_primary_net(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225         if (ipxcfg_auto_select_primary && (ipx_interfaces != NULL))
 226                 ipx_primary_net = ipx_interfaces;
 227         else
 228                 ipx_primary_net = NULL;
 229 }
 230 
 231 static ipx_interface *
 232 ipxitf_find_using_phys(struct device *dev, unsigned short datalink)
     /* [previous][next][first][last][top][bottom][index][help] */
 233 {
 234         ipx_interface   *i;
 235 
 236         for (i=ipx_interfaces; 
 237                 i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink)); 
 238                 i=i->if_next)
 239                 ;
 240         return i;
 241 }
 242 
 243 static ipx_interface *
 244 ipxitf_find_using_net(unsigned long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246         ipx_interface   *i;
 247 
 248         if (net == 0L)
 249                 return ipx_primary_net;
 250 
 251         for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next)
 252                 ;
 253 
 254         return i;
 255 }
 256 
 257 /* Sockets are bound to a particular IPX interface. */
 258 static void
 259 ipxitf_insert_socket(ipx_interface *intrfc, ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261         ipx_socket      *s;
 262 
 263         sk->protinfo.af_ipx.intrfc = intrfc;
 264         sk->next = NULL;
 265         if (intrfc->if_sklist == NULL) {
 266                 intrfc->if_sklist = sk;
 267         } else {
 268                 for (s = intrfc->if_sklist; s->next != NULL; s = s->next)
 269                         ;
 270                 s->next = sk;
 271         }
 272 }
 273 
 274 static ipx_socket *
 275 ipxitf_find_socket(ipx_interface *intrfc, unsigned short port)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         ipx_socket      *s;
 278 
 279         for (s=intrfc->if_sklist; 
 280                 (s != NULL) && (s->protinfo.af_ipx.port != port); 
 281                 s=s->next)
 282                 ;
 283 
 284         return s;
 285 }
 286 
 287 #ifdef CONFIG_IPX_INTERN
 288 
 289 static ipx_socket *
 290 ipxitf_find_internal_socket(ipx_interface *intrfc,
     /* [previous][next][first][last][top][bottom][index][help] */
 291                             unsigned char *node, unsigned short port)
 292 {
 293         ipx_socket *s = intrfc->if_sklist;
 294 
 295         while (s != NULL)
 296         {
 297                 if (   (s->protinfo.af_ipx.port == port)
 298                     && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0))
 299                 {
 300                         break;
 301                 }
 302                 s = s->next;
 303         }
 304         return s;
 305 }       
 306 #endif
 307 
 308 static void ipxrtr_del_routes(ipx_interface *);
 309 
 310 static void
 311 ipxitf_down(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313         ipx_interface   *i;
 314         ipx_socket      *s, *t;
 315 
 316         /* Delete all routes associated with this interface */
 317         ipxrtr_del_routes(intrfc);
 318 
 319         /* error sockets */
 320         for (s = intrfc->if_sklist; s != NULL; ) {
 321                 s->err = ENOLINK;
 322                 s->error_report(s);
 323                 s->protinfo.af_ipx.intrfc = NULL;
 324                 s->protinfo.af_ipx.port = 0;
 325                 s->zapped=1;    /* Indicates it is no longer bound */
 326                 t = s;
 327                 s = s->next;
 328                 t->next = NULL;
 329         }
 330         intrfc->if_sklist = NULL;
 331 
 332         /* remove this interface from list */
 333         if (intrfc == ipx_interfaces) {
 334                 ipx_interfaces = intrfc->if_next;
 335         } else {
 336                 for (i = ipx_interfaces; 
 337                         (i != NULL) && (i->if_next != intrfc);
 338                         i = i->if_next)
 339                         ;
 340                 if ((i != NULL) && (i->if_next == intrfc)) 
 341                         i->if_next = intrfc->if_next;
 342         }
 343 
 344         /* remove this interface from *special* networks */
 345         if (intrfc == ipx_primary_net)
 346                 ipxitf_clear_primary_net();
 347         if (intrfc == ipx_internal_net)
 348                 ipx_internal_net = NULL;
 349 
 350         kfree_s(intrfc, sizeof(*intrfc));
 351         /* sockets still dangling
 352          * - must be closed from user space
 353          */
 354         MOD_DEC_USE_COUNT;
 355         return;
 356 }
 357 
 358 static int 
 359 ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 360 {
 361         struct device *dev = ptr;
 362         ipx_interface *i, *tmp;
 363 
 364         if(event!=NETDEV_DOWN)
 365                 return NOTIFY_DONE;
 366 
 367         for (i = ipx_interfaces; i != NULL; ) {
 368         
 369                 tmp = i->if_next;
 370                 if (i->if_dev == dev) 
 371                         ipxitf_down(i);
 372                 i = tmp;
 373 
 374         }
 375 
 376         return NOTIFY_DONE;
 377 }
 378 
 379 static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 380 {
 381         int     retval;
 382 
 383         if((retval = sock_queue_rcv_skb(sock, skb))<0) 
 384         {
 385                 /*
 386                  * skb->sk is NULL here, so FREE_WRITE does not hurt
 387                  * the sending socket.
 388                  */
 389                 kfree_skb(skb,FREE_WRITE);
 390         }
 391         return retval;
 392 }
 393 
 394 /*
 395  * On input skb->sk is NULL. Nobody is charged for the memory.
 396  */
 397 
 398 #ifdef CONFIG_IPX_INTERN
 399 static int
 400 ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) 
     /* [previous][next][first][last][top][bottom][index][help] */
 401 {
 402         ipx_packet      *ipx = (ipx_packet *)(skb->h.raw);
 403         ipx_socket      *s;
 404 
 405         int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
 406                                    IPX_NODE_LEN) == 0);
 407 
 408         s = intrfc->if_sklist;
 409 
 410         while (s != NULL)
 411         {
 412                 if (   (s->protinfo.af_ipx.port == ipx->ipx_dest.sock)
 413                     && (   is_broadcast
 414                         || (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node,
 415                                    IPX_NODE_LEN) == 0)))
 416                 {
 417                         /* We found a socket to which to send */
 418                         struct sk_buff *skb1;
 419 
 420                         if (copy != 0)
 421                         {
 422                                 skb1 = skb_clone(skb, GFP_ATOMIC);
 423                                 if (skb1 != NULL)
 424                                 {
 425                                         skb1->arp = skb1->free = 1;
 426                                 }
 427                                 else
 428                                 {
 429                                         return -ENOMEM;
 430                                 }
 431                         }
 432                         else
 433                         {
 434                                 skb1 = skb;
 435                                 copy = 1; /* skb may only be used once */
 436                         }
 437                         ipxitf_def_skb_handler(s, skb1);
 438 
 439                         if (intrfc != ipx_internal_net)
 440                         {
 441                                 /* on an external interface, at most
 442                                  * one socket can listen.
 443                                  */
 444                                 break;
 445                         }
 446                 }
 447                 s = s->next;
 448         }
 449 
 450         if (copy == 0)
 451         {
 452                 /* skb was solely for us, and we did not make a copy,
 453                  * so free it. FREE_WRITE does not hurt, because
 454                  * skb->sk is NULL here.
 455                  */
 456                 kfree_skb(skb, FREE_WRITE);
 457         }
 458         return 0;
 459 }
 460 
 461 #else
 462 
 463 static int
 464 ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) 
     /* [previous][next][first][last][top][bottom][index][help] */
 465 {
 466         ipx_packet      *ipx = (ipx_packet *)(skb->h.raw);
 467         ipx_socket      *sock1 = NULL, *sock2 = NULL;
 468         struct sk_buff  *skb1 = NULL, *skb2 = NULL;
 469 
 470         sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
 471 
 472         /*
 473          *      We need to check if there is a primary net and if
 474          *      this is addressed to one of the *SPECIAL* sockets because
 475          *      these need to be propagated to the primary net.
 476          *      The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
 477          *      0x456(Diagnostic).
 478          */
 479          
 480         if (ipx_primary_net && (intrfc != ipx_primary_net)) 
 481         {
 482                 switch (ntohs(ipx->ipx_dest.sock)) 
 483                 {
 484                         case 0x452:
 485                         case 0x453:
 486                         case 0x456:
 487                                 /*
 488                                  *      The appropriate thing to do here is to
 489                                  *      dup the packet and route to the primary net
 490                                  *      interface via ipxitf_send; however, we'll cheat
 491                                  *      and just demux it here.
 492                                  */
 493                                 sock2 = ipxitf_find_socket(ipx_primary_net, 
 494                                         ipx->ipx_dest.sock);
 495                                 break;
 496                         default:
 497                                 break;
 498                 }
 499         }
 500 
 501         /* 
 502          *      if there is nothing to do, return. The kfree will
 503          *      cancel any charging.
 504          */
 505          
 506         if (sock1 == NULL && sock2 == NULL) 
 507         {
 508                 if (!copy) 
 509                         kfree_skb(skb,FREE_WRITE);
 510                 return 0;
 511         }
 512 
 513         /*
 514          * This next segment of code is a little awkward, but it sets it up
 515          * so that the appropriate number of copies of the SKB are made and 
 516          * that skb1 and skb2 point to it (them) so that it (they) can be 
 517          * demuxed to sock1 and/or sock2.  If we are unable to make enough
 518          * copies, we do as much as is possible.
 519          */
 520          
 521         if (copy) 
 522         {
 523                 skb1 = skb_clone(skb, GFP_ATOMIC);
 524                 if (skb1 != NULL) 
 525                         skb1->arp = skb1->free = 1;
 526         } 
 527         else 
 528         {
 529                 skb1 = skb;
 530         }
 531         
 532         if (skb1 == NULL) 
 533                 return -ENOMEM; 
 534 
 535         /*
 536          *      Do we need 2 SKBs? 
 537          */
 538          
 539         if (sock1 && sock2) 
 540         {
 541                 skb2 = skb_clone(skb1, GFP_ATOMIC);
 542                 if (skb2 != NULL) 
 543                         skb2->arp = skb2->free = 1;
 544         }
 545         else 
 546                 skb2 = skb1;
 547                 
 548         if (sock1)
 549                 (void) ipxitf_def_skb_handler(sock1, skb1);
 550 
 551         if (skb2 == NULL) 
 552                 return -ENOMEM;
 553 
 554         if (sock2)
 555                 (void) ipxitf_def_skb_handler(sock2, skb2);
 556 
 557         return 0;
 558 }
 559 #endif
 560 
 561 static struct sk_buff *
 562 ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 563 {
 564         struct sk_buff  *skb2;
 565         int     in_offset = skb->h.raw - skb->head;
 566         int     out_offset = intrfc->if_ipx_offset;
 567         int     len;
 568 
 569         /* Hopefully, most cases */
 570         if (in_offset >= out_offset) {
 571                 skb->arp = skb->free = 1;
 572                 return skb;
 573         }
 574 
 575         /* Need new SKB */
 576         len = skb->len + out_offset;
 577         skb2 = alloc_skb(len, GFP_ATOMIC);
 578         if (skb2 != NULL) {
 579                 skb_reserve(skb2,out_offset);
 580                 skb2->h.raw=skb_put(skb2,skb->len);
 581                 skb2->free=1;
 582                 skb2->arp=1;
 583                 memcpy(skb2->h.raw, skb->h.raw, skb->len);
 584         }
 585         kfree_skb(skb, FREE_WRITE);
 586         return skb2;
 587 }
 588 
 589 static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 590 {
 591         ipx_packet      *ipx = (ipx_packet *)(skb->h.raw);
 592         struct device   *dev = intrfc->if_dev;
 593         struct datalink_proto   *dl = intrfc->if_dlink;
 594         char            dest_node[IPX_NODE_LEN];
 595         int             send_to_wire = 1;
 596         int             addr_len;
 597         
 598         /* 
 599          *      We need to know how many skbuffs it will take to send out this
 600          *      packet to avoid unnecessary copies.
 601          */
 602          
 603         if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) 
 604                 send_to_wire = 0;       /* No non looped */
 605 
 606         /*
 607          *      See if this should be demuxed to sockets on this interface 
 608          *
 609          *      We want to ensure the original was eaten or that we only use
 610          *      up clones.
 611          */
 612          
 613         if (ipx->ipx_dest.net == intrfc->if_netnum) 
 614         {
 615                 /*
 616                  *      To our own node, loop and free the original.
 617                  */
 618                 if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) 
 619                 {
 620                         /*
 621                          *      Don't charge sender
 622                          */
 623                         if(skb->sk)
 624                         {
 625                                 atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
 626                                 skb->sk=NULL;
 627                         }
 628                         /*
 629                          *      Will charge receiver
 630                          */
 631                         return ipxitf_demux_socket(intrfc, skb, 0);
 632                 }
 633                 /*
 634                  *      Broadcast, loop and possibly keep to send on.
 635                  */
 636                 if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) 
 637                 {
 638                         if (!send_to_wire && skb->sk)
 639                         {
 640                                 atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
 641                                 skb->sk=NULL;
 642                         }
 643                         ipxitf_demux_socket(intrfc, skb, send_to_wire);
 644                         if (!send_to_wire) 
 645                                 return 0;
 646                 }
 647         }
 648 
 649         /*
 650          *      If the originating net is not equal to our net; this is routed 
 651          *      We are still charging the sender. Which is right - the driver
 652          *      free will handle this fairly.
 653          */
 654          
 655         if (ipx->ipx_source.net != intrfc->if_netnum) 
 656         {
 657                 if (++(ipx->ipx_tctrl) > ipxcfg_max_hops) 
 658                         send_to_wire = 0;
 659         }
 660 
 661         if (!send_to_wire) 
 662         {
 663                 /*
 664                  *      We do a FREE_WRITE here because this indicates how
 665                  *      to treat the socket with which the packet is 
 666                  *      associated.  If this packet is associated with a
 667                  *      socket at all, it must be the originator of the 
 668                  *      packet.   Routed packets will have no socket associated
 669                  *      with them.
 670                  */
 671                 kfree_skb(skb,FREE_WRITE);
 672                 return 0;
 673         }
 674 
 675         /*
 676          *      Determine the appropriate hardware address 
 677          */
 678          
 679         addr_len = dev->addr_len;
 680         if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) 
 681                 memcpy(dest_node, dev->broadcast, addr_len);
 682         else
 683                 memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len);
 684 
 685         /*
 686          *      Make any compensation for differing physical/data link size 
 687          */
 688          
 689         skb = ipxitf_adjust_skbuff(intrfc, skb);
 690         if (skb == NULL) 
 691                 return 0;
 692 
 693         /* set up data link and physical headers */
 694         skb->dev = dev;
 695         skb->protocol = htons(ETH_P_IPX);
 696         dl->datalink_header(dl, skb, dest_node);
 697 #if 0
 698         /* 
 699          *      Now log the packet just before transmission 
 700          */
 701          
 702         dump_pkt("IPX snd:", (ipx_packet *)skb->h.raw);
 703         dump_data("ETH hdr:", skb->data, skb->h.raw - skb->data);
 704 #endif
 705 
 706         /*
 707          *      Send it out 
 708          */
 709          
 710         dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 711         return 0;
 712 }
 713 
 714 static int ipxrtr_add_route(unsigned long, ipx_interface *, unsigned char *);
 715 
 716 static int ipxitf_add_local_route(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 717 {
 718         return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
 719 }
 720 
 721 static const char * ipx_frame_name(unsigned short);
 722 static const char * ipx_device_name(ipx_interface *);
 723 static int ipxrtr_route_skb(struct sk_buff *);
 724 
 725 static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 726 {
 727         ipx_packet      *ipx = (ipx_packet *) (skb->h.raw);
 728         ipx_interface   *i;
 729 
 730 #ifdef CONFIG_FIREWALL  
 731         /*
 732          *      We firewall first, ask questions later.
 733          */
 734          
 735         if (call_in_firewall(PF_IPX, skb->dev, ipx)!=FW_ACCEPT)
 736         {
 737                 kfree_skb(skb, FREE_READ);
 738                 return 0;
 739         }
 740         
 741 #endif  
 742 
 743         /* See if we should update our network number */
 744         if ((intrfc->if_netnum == 0L) && 
 745                 (ipx->ipx_source.net == ipx->ipx_dest.net) &&
 746                 (ipx->ipx_source.net != 0L)) 
 747         {
 748                 /* NB: NetWare servers lie about their hop count so we
 749                  * dropped the test based on it.  This is the best way
 750                  * to determine this is a 0 hop count packet.
 751                  */
 752                 if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL) 
 753                 {
 754                         intrfc->if_netnum = ipx->ipx_source.net;
 755                         (void) ipxitf_add_local_route(intrfc);
 756                 } 
 757                 else 
 758                 {
 759                         printk("IPX: Network number collision %lx\n\t%s %s and %s %s\n",
 760                                 htonl(ipx->ipx_source.net), 
 761                                 ipx_device_name(i),
 762                                 ipx_frame_name(i->if_dlink_type),
 763                                 ipx_device_name(intrfc),
 764                                 ipx_frame_name(intrfc->if_dlink_type));
 765                 }
 766         }
 767 
 768         if (ipx->ipx_dest.net == 0L)
 769                 ipx->ipx_dest.net = intrfc->if_netnum;
 770         if (ipx->ipx_source.net == 0L)
 771                 ipx->ipx_source.net = intrfc->if_netnum;
 772 
 773         if (intrfc->if_netnum != ipx->ipx_dest.net) 
 774         {
 775 #ifdef CONFIG_FIREWALL  
 776                 /*
 777                  *      See if we are allowed to firewall forward
 778                  */
 779                 if (call_fw_firewall(PF_IPX, skb->dev, ipx)!=FW_ACCEPT)
 780                 {
 781                         kfree_skb(skb, FREE_READ);
 782                         return 0;
 783                 }
 784 #endif          
 785                 /* We only route point-to-point packets. */
 786                 if ((skb->pkt_type != PACKET_BROADCAST) &&
 787                         (skb->pkt_type != PACKET_MULTICAST))
 788                         return ipxrtr_route_skb(skb);
 789                 
 790                 kfree_skb(skb,FREE_READ);
 791                 return 0;
 792         }
 793 
 794         /* see if we should keep it */
 795         if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) 
 796                 || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) 
 797         {
 798                 return ipxitf_demux_socket(intrfc, skb, 0);
 799         }
 800 
 801         /* we couldn't pawn it off so unload it */
 802         kfree_skb(skb,FREE_READ);
 803         return 0;
 804 }
 805 
 806 static void
 807 ipxitf_insert(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
 808 {
 809         ipx_interface   *i;
 810 
 811         intrfc->if_next = NULL;
 812         if (ipx_interfaces == NULL) {
 813                 ipx_interfaces = intrfc;
 814         } else {
 815                 for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
 816                         ;
 817                 i->if_next = intrfc;
 818         }
 819 
 820         if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 821                 ipx_primary_net = intrfc;
 822         MOD_INC_USE_COUNT;
 823         return;
 824 }
 825 
 826 static int 
 827 ipxitf_create_internal(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 828 {
 829         ipx_interface   *intrfc;
 830 
 831         /* Only one primary network allowed */
 832         if (ipx_primary_net != NULL) return -EEXIST;
 833 
 834         /* Must have a valid network number */
 835         if (idef->ipx_network == 0L) return -EADDRNOTAVAIL;
 836         if (ipxitf_find_using_net(idef->ipx_network) != NULL)
 837                 return -EADDRINUSE;
 838 
 839         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 840         if (intrfc==NULL)
 841                 return -EAGAIN;
 842         intrfc->if_dev=NULL;
 843         intrfc->if_netnum=idef->ipx_network;
 844         intrfc->if_dlink_type = 0;
 845         intrfc->if_dlink = NULL;
 846         intrfc->if_sklist = NULL;
 847         intrfc->if_internal = 1;
 848         intrfc->if_ipx_offset = 0;
 849         intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 850         memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
 851         ipx_internal_net = intrfc;
 852         ipx_primary_net = intrfc;
 853         ipxitf_insert(intrfc);
 854         return ipxitf_add_local_route(intrfc);
 855 }
 856 
 857 static int
 858 ipx_map_frame_type(unsigned char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 859 {
 860         switch (type) {
 861         case IPX_FRAME_ETHERII: return htons(ETH_P_IPX);
 862         case IPX_FRAME_8022: return htons(ETH_P_802_2);
 863         case IPX_FRAME_TR_8022: return htons(ETH_P_TR_802_2);
 864         case IPX_FRAME_SNAP: return htons(ETH_P_SNAP);
 865         case IPX_FRAME_8023: return htons(ETH_P_802_3);
 866         }
 867         return 0;
 868 }
 869 
 870 static int 
 871 ipxitf_create(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873         struct device   *dev;
 874         unsigned short  dlink_type = 0;
 875         struct datalink_proto   *datalink = NULL;
 876         ipx_interface   *intrfc;
 877 
 878         if (idef->ipx_special == IPX_INTERNAL) 
 879                 return ipxitf_create_internal(idef);
 880 
 881         if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
 882                 return -EEXIST;
 883 
 884         if ((idef->ipx_network != 0L) &&
 885                 (ipxitf_find_using_net(idef->ipx_network) != NULL))
 886                 return -EADDRINUSE;
 887 
 888         switch (idef->ipx_dlink_type) {
 889         case IPX_FRAME_ETHERII: 
 890                 dlink_type = htons(ETH_P_IPX);
 891                 datalink = pEII_datalink;
 892                 break;
 893         case IPX_FRAME_TR_8022:
 894                 dlink_type = htons(ETH_P_TR_802_2);
 895                 datalink = p8022tr_datalink;
 896                 break;
 897         case IPX_FRAME_8022:
 898                 dlink_type = htons(ETH_P_802_2);
 899                 datalink = p8022_datalink;
 900                 break;
 901         case IPX_FRAME_SNAP:
 902                 dlink_type = htons(ETH_P_SNAP);
 903                 datalink = pSNAP_datalink;
 904                 break;
 905         case IPX_FRAME_8023:
 906                 dlink_type = htons(ETH_P_802_3);
 907                 datalink = p8023_datalink;
 908                 break;
 909         case IPX_FRAME_NONE:
 910         default:
 911                 break;
 912         }
 913 
 914         if (datalink == NULL) 
 915                 return -EPROTONOSUPPORT;
 916 
 917         dev=dev_get(idef->ipx_device);
 918         if (dev==NULL) 
 919                 return -ENODEV;
 920 
 921         if (!(dev->flags & IFF_UP))
 922                 return -ENETDOWN;
 923 
 924         /* Check addresses are suitable */
 925         if(dev->addr_len>IPX_NODE_LEN)
 926                 return -EINVAL;
 927 
 928         if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) 
 929         {
 930                 /* Ok now create */
 931                 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
 932                 if (intrfc==NULL)
 933                         return -EAGAIN;
 934                 intrfc->if_dev=dev;
 935                 intrfc->if_netnum=idef->ipx_network;
 936                 intrfc->if_dlink_type = dlink_type;
 937                 intrfc->if_dlink = datalink;
 938                 intrfc->if_sklist = NULL;
 939                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 940                 /* Setup primary if necessary */
 941                 if ((idef->ipx_special == IPX_PRIMARY)) 
 942                         ipx_primary_net = intrfc;
 943                 intrfc->if_internal = 0;
 944                 intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
 945                 if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN)==0)
 946                 {
 947                         memset(intrfc->if_node, 0, IPX_NODE_LEN);
 948                         memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
 949                                 dev->dev_addr, dev->addr_len);
 950                 }
 951                 else
 952                         memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN);
 953                 ipxitf_insert(intrfc);
 954         }
 955 
 956         /* If the network number is known, add a route */
 957         if (intrfc->if_netnum == 0L) 
 958                 return 0;
 959 
 960         return ipxitf_add_local_route(intrfc);
 961 }
 962 
 963 static int 
 964 ipxitf_delete(ipx_interface_definition *idef)
     /* [previous][next][first][last][top][bottom][index][help] */
 965 {
 966         struct device   *dev = NULL;
 967         unsigned short  dlink_type = 0;
 968         ipx_interface   *intrfc;
 969 
 970         if (idef->ipx_special == IPX_INTERNAL) {
 971                 if (ipx_internal_net != NULL) {
 972                         ipxitf_down(ipx_internal_net);
 973                         return 0;
 974                 }
 975                 return -ENOENT;
 976         }
 977 
 978         dlink_type = ipx_map_frame_type(idef->ipx_dlink_type);
 979         if (dlink_type == 0)
 980                 return -EPROTONOSUPPORT;
 981 
 982         dev=dev_get(idef->ipx_device);
 983         if(dev==NULL) return -ENODEV;
 984 
 985         intrfc = ipxitf_find_using_phys(dev, dlink_type);
 986         if (intrfc != NULL) {
 987                 ipxitf_down(intrfc);
 988                 return 0;
 989         }
 990         return -EINVAL;
 991 }
 992 
 993 static ipx_interface *
 994 ipxitf_auto_create(struct device *dev, unsigned short dlink_type)
     /* [previous][next][first][last][top][bottom][index][help] */
 995 {
 996         struct datalink_proto *datalink = NULL;
 997         ipx_interface   *intrfc;
 998 
 999         switch (htons(dlink_type)) {
1000         case ETH_P_IPX: datalink = pEII_datalink; break;
1001         case ETH_P_802_2: datalink = p8022_datalink; break;
1002         case ETH_P_TR_802_2: datalink = p8022tr_datalink; break;
1003         case ETH_P_SNAP: datalink = pSNAP_datalink; break;
1004         case ETH_P_802_3: datalink = p8023_datalink; break;
1005         default: return NULL;
1006         }
1007         
1008         if (dev == NULL)
1009                 return NULL;
1010 
1011         /* Check addresses are suitable */
1012         if(dev->addr_len>IPX_NODE_LEN) return NULL;
1013 
1014         intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
1015         if (intrfc!=NULL) {
1016                 intrfc->if_dev=dev;
1017                 intrfc->if_netnum=0L;
1018                 intrfc->if_dlink_type = dlink_type;
1019                 intrfc->if_dlink = datalink;
1020                 intrfc->if_sklist = NULL;
1021                 intrfc->if_internal = 0;
1022                 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
1023                 intrfc->if_ipx_offset = dev->hard_header_len + 
1024                         datalink->header_length;
1025                 memset(intrfc->if_node, 0, IPX_NODE_LEN);
1026                 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
1027                         dev->dev_addr, dev->addr_len);
1028                 ipxitf_insert(intrfc);
1029         }
1030 
1031         return intrfc;
1032 }
1033 
1034 static int 
1035 ipxitf_ioctl_real(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1036 {
1037         int err;
1038         switch(cmd)
1039         {
1040                 case SIOCSIFADDR:
1041                 {
1042                         struct ifreq ifr;
1043                         struct sockaddr_ipx *sipx;
1044                         ipx_interface_definition f;
1045                         err=verify_area(VERIFY_READ,arg,sizeof(ifr));
1046                         if(err)
1047                                 return err;
1048                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
1049                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
1050                         if(sipx->sipx_family!=AF_IPX)
1051                                 return -EINVAL;
1052                         f.ipx_network=sipx->sipx_network;
1053                         memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device));
1054                         memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
1055                         f.ipx_dlink_type=sipx->sipx_type;
1056                         f.ipx_special=sipx->sipx_special;
1057                         if(sipx->sipx_action==IPX_DLTITF)
1058                                 return ipxitf_delete(&f);
1059                         else
1060                                 return ipxitf_create(&f);
1061                 }
1062                 case SIOCGIFADDR:
1063                 {
1064                         struct ifreq ifr;
1065                         struct sockaddr_ipx *sipx;
1066                         ipx_interface *ipxif;
1067                         struct device *dev;
1068                         err=verify_area(VERIFY_WRITE,arg,sizeof(ifr));
1069                         if(err)
1070                                 return err;
1071                         memcpy_fromfs(&ifr,arg,sizeof(ifr));
1072                         sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
1073                         dev=dev_get(ifr.ifr_name);
1074                         if(!dev)
1075                                 return -ENODEV;
1076                         ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type));
1077                         if(ipxif==NULL)
1078                                 return -EADDRNOTAVAIL;
1079                         sipx->sipx_family=AF_IPX;
1080                         sipx->sipx_network=ipxif->if_netnum;
1081                         memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node));
1082                         memcpy_tofs(arg,&ifr,sizeof(ifr));
1083                         return 0;
1084                 }
1085                 case SIOCAIPXITFCRT:
1086                         err=verify_area(VERIFY_READ,arg,sizeof(char));
1087                         if(err)
1088                                 return err;
1089                         return ipxcfg_set_auto_create(get_fs_byte(arg));
1090                 case SIOCAIPXPRISLT:
1091                         err=verify_area(VERIFY_READ,arg,sizeof(char));
1092                         if(err)
1093                                 return err;
1094                         return ipxcfg_set_auto_select(get_fs_byte(arg));
1095                 default:
1096                         return -EINVAL;
1097         }
1098 }
1099 
1100 static int 
1101 ipxitf_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1102 {
1103         int ret;
1104         MOD_INC_USE_COUNT;
1105         ret = ipxitf_ioctl_real (cmd,arg);
1106         MOD_DEC_USE_COUNT;
1107         return ret;
1108 }
1109 /*******************************************************************************************************************\
1110 *                                                                                                                   *
1111 *                                       Routing tables for the IPX socket layer                                     *
1112 *                                                                                                                   *
1113 \*******************************************************************************************************************/
1114 
1115 static ipx_route *
1116 ipxrtr_lookup(unsigned long net)
     /* [previous][next][first][last][top][bottom][index][help] */
1117 {
1118         ipx_route *r;
1119 
1120         for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next)
1121                 ;
1122 
1123         return r;
1124 }
1125 
1126 static int
1127 ipxrtr_add_route(unsigned long network, ipx_interface *intrfc, unsigned char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
1128 {
1129         ipx_route       *rt;
1130 
1131         /* Get a route structure; either existing or create */
1132         rt = ipxrtr_lookup(network);
1133         if (rt==NULL) {
1134                 rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
1135                 if(rt==NULL)
1136                         return -EAGAIN;
1137                 rt->ir_next=ipx_routes;
1138                 ipx_routes=rt;
1139         }
1140         else if (intrfc == ipx_internal_net)
1141                 return(-EEXIST);
1142 
1143         rt->ir_net = network;
1144         rt->ir_intrfc = intrfc;
1145         if (node == NULL) {
1146                 memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
1147                 rt->ir_routed = 0;
1148         } else {
1149                 memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
1150                 rt->ir_routed=1;
1151         }
1152         return 0;
1153 }
1154 
1155 static void
1156 ipxrtr_del_routes(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1157 {
1158         ipx_route       **r, *tmp;
1159 
1160         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
1161                 if (tmp->ir_intrfc == intrfc) {
1162                         *r = tmp->ir_next;
1163                         kfree_s(tmp, sizeof(ipx_route));
1164                 } else {
1165                         r = &(tmp->ir_next);
1166                 }
1167         }
1168 }
1169 
1170 static int 
1171 ipxrtr_create(ipx_route_definition *rd)
     /* [previous][next][first][last][top][bottom][index][help] */
1172 {
1173         ipx_interface *intrfc;
1174 
1175         /* Find the appropriate interface */
1176         intrfc = ipxitf_find_using_net(rd->ipx_router_network);
1177         if (intrfc == NULL)
1178                 return -ENETUNREACH;
1179 
1180         return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
1181 }
1182 
1183 
1184 static int 
1185 ipxrtr_delete(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
1186 {
1187         ipx_route       **r;
1188         ipx_route       *tmp;
1189 
1190         for (r = &ipx_routes; (tmp = *r) != NULL; ) {
1191                 if (tmp->ir_net == net) {
1192                         if (!(tmp->ir_routed)) {
1193                                 /* Directly connected; can't lose route */
1194                                 return -EPERM;
1195                         }
1196                         *r = tmp->ir_next;
1197                         kfree_s(tmp, sizeof(ipx_route));
1198                         return 0;
1199                 } 
1200                 r = &(tmp->ir_next);
1201         }
1202 
1203         return -ENOENT;
1204 }
1205 
1206 /*
1207  *      Checksum routine for IPX
1208  */
1209  
1210 /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */
1211 
1212 static __u16 ipx_set_checksum(ipx_packet *packet,int length) 
     /* [previous][next][first][last][top][bottom][index][help] */
1213 {
1214         /* 
1215          *      NOTE: sum is a net byte order quantity, which optimizes the 
1216          *      loop. This only works on big and little endian machines. (I
1217          *      don't know of a machine that isn't.)
1218          */
1219 
1220         __u32 sum=0;
1221 
1222         /*
1223          *      Pointer to second word - We skip the checksum field
1224          */
1225 
1226         __u16 *p=(__u16 *)&packet->ipx_pktsize;
1227 
1228         /*
1229          *      Number of complete words 
1230          */
1231 
1232         __u32 i=length>>1;
1233 
1234         /*
1235          *      Loop through all complete words except the checksum field 
1236          */
1237 
1238         while(--i)
1239                 sum+=*p++;
1240 
1241         /*
1242          *      Add on the last part word if it exists 
1243          */
1244 
1245         if(packet->ipx_pktsize&htons(1))
1246                 sum+=ntohs(0xff00)&*p;
1247 
1248         /*
1249          *      Do final fixup 
1250          */
1251          
1252         sum=(sum&0xffff)+(sum>>16);
1253 
1254         /*
1255          *      It's a pity there's no concept of carry in C 
1256          */
1257 
1258         if(sum>=0x10000)
1259                 sum++;
1260                 
1261         return ~sum;
1262 };
1263 
1264  
1265 /*
1266  *      Route an outgoing frame from a socket.
1267  */
1268 
1269 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] */
1270 {
1271         struct sk_buff *skb;
1272         ipx_interface *intrfc;
1273         ipx_packet *ipx;
1274         int size;
1275         int ipx_offset;
1276         ipx_route *rt = NULL;
1277         int err;
1278         
1279         /* Find the appropriate interface on which to send packet */
1280         if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) 
1281         {
1282                 usipx->sipx_network = ipx_primary_net->if_netnum;
1283                 intrfc = ipx_primary_net;
1284         } 
1285         else 
1286         {
1287                 rt = ipxrtr_lookup(usipx->sipx_network);
1288                 if (rt==NULL) {
1289                         return -ENETUNREACH;
1290                 }
1291                 intrfc = rt->ir_intrfc;
1292         }
1293         
1294         ipx_offset = intrfc->if_ipx_offset;
1295         size=sizeof(ipx_packet)+len;
1296         size += ipx_offset;
1297 
1298         skb=sock_alloc_send_skb(sk, size, 0, 0, &err);
1299         if(skb==NULL)
1300                 return err;
1301 
1302         skb_reserve(skb,ipx_offset);
1303         skb->free=1;
1304         skb->arp=1;
1305         skb->sk=sk;
1306 
1307         /* Fill in IPX header */
1308         ipx=(ipx_packet *)skb_put(skb,sizeof(ipx_packet));
1309         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
1310         ipx->ipx_tctrl=0;
1311         ipx->ipx_type=usipx->sipx_type;
1312         skb->h.raw = (unsigned char *)ipx;
1313 
1314         ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
1315 #ifdef CONFIG_IPX_INTERN
1316         memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
1317 #else
1318         if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)  
1319         {
1320                 /* RIP/SAP special handling for mars_nwe */
1321                 ipx->ipx_source.net = intrfc->if_netnum;
1322                 memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN);
1323         }
1324         else
1325         {
1326                 ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
1327                 memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
1328         }
1329 #endif
1330         ipx->ipx_source.sock = sk->protinfo.af_ipx.port;
1331         ipx->ipx_dest.net=usipx->sipx_network;
1332         memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
1333         ipx->ipx_dest.sock=usipx->sipx_port;
1334 
1335         memcpy_fromiovec(skb_put(skb,len),iov,len);
1336 
1337         /*
1338          *      Apply checksum. Not allowed on 802.3 links.
1339          */
1340          
1341         if(sk->no_check || intrfc->if_dlink_type==IPX_FRAME_8023)
1342                 ipx->ipx_checksum=0xFFFF;
1343         else
1344                 ipx->ipx_checksum=ipx_set_checksum(ipx, len+sizeof(ipx_packet));
1345 
1346 #ifdef CONFIG_FIREWALL  
1347         if(call_out_firewall(PF_IPX, skb->dev, ipx)!=FW_ACCEPT)
1348         {
1349                 kfree_skb(skb, FREE_WRITE);
1350                 return -EPERM;
1351         }
1352 #endif
1353         
1354         return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
1355                                 rt->ir_router_node : ipx->ipx_dest.node);
1356 }
1357         
1358 static int
1359 ipxrtr_route_skb(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
1360 {
1361         ipx_packet      *ipx = (ipx_packet *) (skb->h.raw);
1362         ipx_route       *r;
1363         ipx_interface   *i;
1364 
1365         r = ipxrtr_lookup(ipx->ipx_dest.net);
1366         if (r == NULL) {
1367                 /* no known route */
1368                 kfree_skb(skb,FREE_READ);
1369                 return 0;
1370         }
1371         i = r->ir_intrfc;
1372         (void)ipxitf_send(i, skb, (r->ir_routed) ? 
1373                         r->ir_router_node : ipx->ipx_dest.node);
1374         return 0;
1375 }
1376 
1377 /*
1378  *      We use a normal struct rtentry for route handling
1379  */
1380 
1381 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1382 {
1383         int err;
1384         struct rtentry rt;      /* Use these to behave like 'other' stacks */
1385         struct sockaddr_ipx *sg,*st;
1386 
1387         err=verify_area(VERIFY_READ,arg,sizeof(rt));
1388         if(err)
1389                 return err;
1390                 
1391         memcpy_fromfs(&rt,arg,sizeof(rt));
1392         
1393         sg=(struct sockaddr_ipx *)&rt.rt_gateway;
1394         st=(struct sockaddr_ipx *)&rt.rt_dst;
1395         
1396         if(!(rt.rt_flags&RTF_GATEWAY))
1397                 return -EINVAL;         /* Direct routes are fixed */
1398         if(sg->sipx_family!=AF_IPX)
1399                 return -EINVAL;
1400         if(st->sipx_family!=AF_IPX)
1401                 return -EINVAL;
1402                 
1403         switch(cmd)
1404         {
1405                 case SIOCDELRT:
1406                         return ipxrtr_delete(st->sipx_network);
1407                 case SIOCADDRT:
1408                 {
1409                         struct ipx_route_definition f;
1410                         f.ipx_network=st->sipx_network;
1411                         f.ipx_router_network=sg->sipx_network;
1412                         memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
1413                         return ipxrtr_create(&f);
1414                 }
1415                 default:
1416                         return -EINVAL;
1417         }
1418 }
1419 
1420 static const char *
1421 ipx_frame_name(unsigned short frame)
     /* [previous][next][first][last][top][bottom][index][help] */
1422 {
1423         switch (ntohs(frame)) {
1424         case ETH_P_IPX: return "EtherII";
1425         case ETH_P_802_2: return "802.2";
1426         case ETH_P_SNAP: return "SNAP";
1427         case ETH_P_802_3: return "802.3";
1428         case ETH_P_TR_802_2: return "802.2TR";
1429         default: return "None";
1430         }
1431 }
1432 
1433 static const char *
1434 ipx_device_name(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1435 {
1436         return (intrfc->if_internal ? "Internal" :
1437                 (intrfc->if_dev ? intrfc->if_dev->name : "Unknown"));
1438 }
1439 
1440 /* Called from proc fs */
1441 static int ipx_interface_get_info(char *buffer, char **start, off_t offset,
     /* [previous][next][first][last][top][bottom][index][help] */
1442                                   int length, int dummy)
1443 {
1444         ipx_interface *i;
1445         int len=0;
1446         off_t pos=0;
1447         off_t begin=0;
1448 
1449         /* Theory.. Keep printing in the same place until we pass offset */
1450 
1451         len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", 
1452                 "Node_Address", "Primary", "Device", "Frame_Type");
1453         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1454                 len += sprintf(buffer+len, "%08lX   ", ntohl(i->if_netnum));
1455                 len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ", 
1456                                 i->if_node[0], i->if_node[1], i->if_node[2],
1457                                 i->if_node[3], i->if_node[4], i->if_node[5]);
1458                 len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
1459                         "Yes" : "No");
1460                 len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
1461                 len += sprintf (buffer+len, "%s\n", 
1462                         ipx_frame_name(i->if_dlink_type));
1463 
1464                 /* Are we still dumping unwanted data then discard the record */
1465                 pos=begin+len;
1466                 
1467                 if(pos<offset) {
1468                         len=0;                  /* Keep dumping into the buffer start */
1469                         begin=pos;
1470                 }
1471                 if(pos>offset+length)           /* We have dumped enough */
1472                         break;
1473         }
1474         
1475         /* The data in question runs from begin to begin+len */
1476         *start=buffer+(offset-begin);   /* Start of wanted data */
1477         len-=(offset-begin);            /* Remove unwanted header data from length */
1478         if(len>length)
1479                 len=length;             /* Remove unwanted tail data from length */
1480         
1481         return len;
1482 }
1483 
1484 static int ipx_get_info(char *buffer, char **start, off_t offset,
     /* [previous][next][first][last][top][bottom][index][help] */
1485                         int length, int dummy)
1486 {
1487         ipx_socket *s;
1488         ipx_interface *i;
1489         int len=0;
1490         off_t pos=0;
1491         off_t begin=0;
1492 
1493         /* Theory.. Keep printing in the same place until we pass offset */
1494 
1495 #ifdef CONFIG_IPX_INTERN        
1496         len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
1497 #else
1498         len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
1499 #endif
1500                         "Remote_Address", "Tx_Queue", "Rx_Queue", 
1501                         "State", "Uid");
1502         for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1503                 for (s = i->if_sklist; s != NULL; s = s->next) {
1504 #ifdef CONFIG_IPX_INTERN
1505                         len += sprintf(buffer+len,
1506                                        "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
1507                                  htonl(s->protinfo.af_ipx.intrfc->if_netnum),
1508                                        s->protinfo.af_ipx.node[0],
1509                                        s->protinfo.af_ipx.node[1], 
1510                                        s->protinfo.af_ipx.node[2], 
1511                                        s->protinfo.af_ipx.node[3], 
1512                                        s->protinfo.af_ipx.node[4], 
1513                                        s->protinfo.af_ipx.node[5],
1514                                        htons(s->protinfo.af_ipx.port));
1515 #else
1516                         len += sprintf(buffer+len,"%08lX:%04X  ", 
1517                                        htonl(i->if_netnum),
1518                                        htons(s->protinfo.af_ipx.port));
1519 #endif
1520                         if (s->state!=TCP_ESTABLISHED) {
1521                                 len += sprintf(buffer+len, "%-28s", "Not_Connected");
1522                         } else {
1523                                 len += sprintf (buffer+len,
1524                                         "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
1525                                         htonl(s->protinfo.af_ipx.dest_addr.net),
1526                                         s->protinfo.af_ipx.dest_addr.node[0],
1527                                         s->protinfo.af_ipx.dest_addr.node[1], 
1528                                         s->protinfo.af_ipx.dest_addr.node[2],
1529                                         s->protinfo.af_ipx.dest_addr.node[3], 
1530                                         s->protinfo.af_ipx.dest_addr.node[4],
1531                                         s->protinfo.af_ipx.dest_addr.node[5],
1532                                         htons(s->protinfo.af_ipx.dest_addr.sock));
1533                         }
1534                         len += sprintf (buffer+len,"%08X  %08X  ", 
1535                                 s->wmem_alloc, s->rmem_alloc);
1536                         len += sprintf (buffer+len,"%02X     %03d\n", 
1537                                 s->state, SOCK_INODE(s->socket)->i_uid);
1538                 
1539                         /* Are we still dumping unwanted data then discard the record */
1540                         pos=begin+len;
1541                 
1542                         if(pos<offset)
1543                         {
1544                                 len=0;                  /* Keep dumping into the buffer start */
1545                                 begin=pos;
1546                         }
1547                         if(pos>offset+length)           /* We have dumped enough */
1548                                 break;
1549                 }
1550         }
1551         
1552         /* The data in question runs from begin to begin+len */
1553         *start=buffer+(offset-begin);   /* Start of wanted data */
1554         len-=(offset-begin);            /* Remove unwanted header data from length */
1555         if(len>length)
1556                 len=length;             /* Remove unwanted tail data from length */
1557         
1558         return len;
1559 }
1560 
1561 static int ipx_rt_get_info(char *buffer, char **start, off_t offset,
     /* [previous][next][first][last][top][bottom][index][help] */
1562                            int length, int dummy)
1563 {
1564         ipx_route *rt;
1565         int len=0;
1566         off_t pos=0;
1567         off_t begin=0;
1568 
1569         len += sprintf (buffer,"%-11s%-13s%s\n", 
1570                         "Network", "Router_Net", "Router_Node");
1571         for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
1572         {
1573                 len += sprintf (buffer+len,"%08lX   ", ntohl(rt->ir_net));
1574                 if (rt->ir_routed) {
1575                         len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n", 
1576                                 ntohl(rt->ir_intrfc->if_netnum), 
1577                                 rt->ir_router_node[0], rt->ir_router_node[1], 
1578                                 rt->ir_router_node[2], rt->ir_router_node[3], 
1579                                 rt->ir_router_node[4], rt->ir_router_node[5]);
1580                 } else {
1581                         len += sprintf (buffer+len, "%-13s%s\n",
1582                                         "Directly", "Connected");
1583                 }
1584                 pos=begin+len;
1585                 if(pos<offset)
1586                 {
1587                         len=0;
1588                         begin=pos;
1589                 }
1590                 if(pos>offset+length)
1591                         break;
1592         }
1593         *start=buffer+(offset-begin);
1594         len-=(offset-begin);
1595         if(len>length)
1596                 len=length;
1597         return len;
1598 }
1599 
1600 /*******************************************************************************************************************\
1601 *                                                                                                                   *
1602 *             Handling for system calls applied via the various interfaces to an IPX socket object                  *
1603 *                                                                                                                   *
1604 \*******************************************************************************************************************/
1605 
1606 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1607 {
1608         switch(cmd)
1609         {
1610                 default:
1611                         return(-EINVAL);
1612         }
1613 }
1614 
1615 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
1616 {
1617         ipx_socket *sk;
1618         int err,opt;
1619         
1620         sk=(ipx_socket *)sock->data;
1621         
1622         if(optval==NULL)
1623                 return(-EINVAL);
1624 
1625         err=verify_area(VERIFY_READ,optval,sizeof(int));
1626         if(err)
1627                 return err;
1628         opt=get_fs_long((unsigned long *)optval);
1629         
1630         switch(level)
1631         {
1632                 case SOL_IPX:
1633                         switch(optname)
1634                         {
1635                                 case IPX_TYPE:
1636                                         sk->protinfo.af_ipx.type=opt;
1637                                         return 0;
1638                                 default:
1639                                         return -EOPNOTSUPP;
1640                         }
1641                         break;
1642                         
1643                 case SOL_SOCKET:
1644                         return sock_setsockopt(sk,level,optname,optval,optlen);
1645 
1646                 default:
1647                         return -EOPNOTSUPP;
1648         }
1649 }
1650 
1651 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
1652         char *optval, int *optlen)
1653 {
1654         ipx_socket *sk;
1655         int val=0;
1656         int err;
1657         
1658         sk=(ipx_socket *)sock->data;
1659 
1660         switch(level)
1661         {
1662 
1663                 case SOL_IPX:
1664                         switch(optname)
1665                         {
1666                                 case IPX_TYPE:
1667                                         val=sk->protinfo.af_ipx.type;
1668                                         break;
1669                                 default:
1670                                         return -ENOPROTOOPT;
1671                         }
1672                         break;
1673                         
1674                 case SOL_SOCKET:
1675                         return sock_getsockopt(sk,level,optname,optval,optlen);
1676                         
1677                 default:
1678                         return -EOPNOTSUPP;
1679         }
1680         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
1681         if(err)
1682                 return err;
1683         put_fs_long(sizeof(int),(unsigned long *)optlen);
1684         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
1685         if (err) return err;
1686         put_fs_long(val,(unsigned long *)optval);
1687         return(0);
1688 }
1689 
1690 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
1691 {
1692         return -EOPNOTSUPP;
1693 }
1694 
1695 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1696 {
1697         if(!sk->dead)
1698                 wake_up_interruptible(sk->sleep);
1699 }
1700 
1701 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
1702 {
1703         if(!sk->dead)
1704         {
1705                 wake_up_interruptible(sk->sleep);
1706                 sock_wake_async(sk->socket, 1);
1707         }
1708 }
1709 
1710 static int ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
1711 {
1712         ipx_socket *sk;
1713         sk=(ipx_socket *)sk_alloc(GFP_KERNEL);
1714         if(sk==NULL)
1715                 return(-ENOMEM);
1716         switch(sock->type)
1717         {
1718                 case SOCK_DGRAM:
1719                         break;
1720                 default:
1721                         kfree_s((void *)sk,sizeof(*sk));
1722                         return(-ESOCKTNOSUPPORT);
1723         }
1724         sk->rcvbuf=SK_RMEM_MAX;
1725         sk->sndbuf=SK_WMEM_MAX;
1726         sk->prot=NULL;  /* So we use default free mechanisms */
1727         skb_queue_head_init(&sk->receive_queue);
1728         skb_queue_head_init(&sk->write_queue);
1729         sk->send_head=NULL;
1730         skb_queue_head_init(&sk->back_log);
1731         sk->state=TCP_CLOSE;
1732         sk->socket=sock;
1733         sk->type=sock->type;
1734         sk->mtu=IPX_MTU;
1735         sk->no_check = 1;               /* Checksum off by default */   
1736         if(sock!=NULL)
1737         {
1738                 sock->data=(void *)sk;
1739                 sk->sleep=sock->wait;
1740         }
1741         
1742         sk->state_change=def_callback1;
1743         sk->data_ready=def_callback2;
1744         sk->write_space=def_callback1;
1745         sk->error_report=def_callback1;
1746 
1747         sk->zapped=1;
1748         MOD_INC_USE_COUNT;
1749         return 0;
1750 }
1751 
1752 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
1753 {
1754         ipx_socket *sk=(ipx_socket *)sock->data;
1755         if(sk==NULL)
1756                 return(0);
1757         if(!sk->dead)
1758                 sk->state_change(sk);
1759         sk->dead=1;
1760         sock->data=NULL;
1761         ipx_destroy_socket(sk);
1762         return(0);
1763 }
1764 
1765 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
1766 {
1767         return(ipx_create(newsock,SOCK_DGRAM));
1768 }
1769 
1770 static unsigned short 
1771 ipx_first_free_socketnum(ipx_interface *intrfc)
     /* [previous][next][first][last][top][bottom][index][help] */
1772 {
1773         unsigned short  socketNum = intrfc->if_sknum;
1774 
1775         if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1776                 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1777 
1778         while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
1779                 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1780                         socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1781                 else
1782                         socketNum++;
1783 
1784         intrfc->if_sknum = socketNum;
1785         return  ntohs(socketNum);
1786 }
1787         
1788 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
1789 {
1790         ipx_socket *sk;
1791         ipx_interface *intrfc;
1792         struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
1793         
1794         sk=(ipx_socket *)sock->data;
1795         
1796         if(sk->zapped==0)
1797                 return -EIO;
1798                 
1799         if(addr_len!=sizeof(struct sockaddr_ipx))
1800                 return -EINVAL;
1801         
1802         intrfc = ipxitf_find_using_net(addr->sipx_network);
1803         if (intrfc == NULL)
1804                 return -EADDRNOTAVAIL;
1805 
1806         if (addr->sipx_port == 0) {
1807                 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1808                 if (addr->sipx_port == 0)
1809                         return -EINVAL;
1810         }
1811 
1812         if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1813                 return -EPERM;  /* protect IPX system stuff like routing/sap */
1814 
1815         sk->protinfo.af_ipx.port=addr->sipx_port;
1816 
1817 #ifdef CONFIG_IPX_INTERN
1818         if (intrfc == ipx_internal_net)
1819         {
1820                 /* The source address is to be set explicitly if the
1821                  * socket is to be bound on the internal network. If a
1822                  * node number 0 was specified, the default is used.
1823                  */
1824 
1825                 if (memcmp(addr->sipx_node, ipx_broadcast_node,
1826                            IPX_NODE_LEN) == 0)
1827                 {
1828                         return -EINVAL;
1829                 }
1830                 if (memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0)
1831                 {
1832                         memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
1833                                IPX_NODE_LEN);
1834                 }
1835                 else
1836                 {
1837                         memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN);
1838                 }
1839                 if (ipxitf_find_internal_socket(intrfc, 
1840                         sk->protinfo.af_ipx.node, 
1841                         sk->protinfo.af_ipx.port) != NULL)
1842                 {
1843                         if(sk->debug)
1844                                 printk("IPX: bind failed because port %X in"
1845                                        " use.\n", (int)addr->sipx_port);
1846                         return -EADDRINUSE;
1847                 }
1848         }
1849         else
1850         {
1851                 /* Source addresses are easy. It must be our
1852                  * network:node pair for an interface routed to IPX
1853                  * with the ipx routing ioctl()
1854                  */
1855 
1856                 memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, 
1857                         IPX_NODE_LEN);
1858                 
1859                 if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1860                         if(sk->debug)
1861                                 printk("IPX: bind failed because port %X in"
1862                                        " use.\n", (int)addr->sipx_port);
1863                         return -EADDRINUSE;        
1864                 }
1865         }
1866 
1867 #else
1868 
1869         /* Source addresses are easy. It must be our network:node pair for
1870            an interface routed to IPX with the ipx routing ioctl() */
1871 
1872         if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1873                 if(sk->debug)
1874                         printk("IPX: bind failed because port %X in use.\n",
1875                                 (int)addr->sipx_port);
1876                 return -EADDRINUSE;        
1877         }
1878 
1879 #endif
1880 
1881         ipxitf_insert_socket(intrfc, sk);
1882         sk->zapped=0;
1883         if(sk->debug)
1884                 printk("IPX: socket is bound.\n");
1885         return 0;
1886 }
1887 
1888 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1889         int addr_len, int flags)
1890 {
1891         ipx_socket *sk=(ipx_socket *)sock->data;
1892         struct sockaddr_ipx *addr;
1893         
1894         sk->state = TCP_CLOSE;  
1895         sock->state = SS_UNCONNECTED;
1896 
1897         if(addr_len!=sizeof(*addr))
1898                 return(-EINVAL);
1899         addr=(struct sockaddr_ipx *)uaddr;
1900         
1901         if(sk->protinfo.af_ipx.port==0)
1902         /* put the autobinding in */
1903         {
1904                 struct sockaddr_ipx uaddr;
1905                 int ret;
1906         
1907                 uaddr.sipx_port = 0;
1908                 uaddr.sipx_network = 0L;
1909 #ifdef CONFIG_IPX_INTERN
1910                 memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,
1911                        IPX_NODE_LEN);
1912 #endif
1913                 ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
1914                                 sizeof(struct sockaddr_ipx));
1915                 if (ret != 0) return (ret);
1916         }
1917         
1918         if(ipxrtr_lookup(addr->sipx_network)==NULL)
1919                 return -ENETUNREACH;
1920         sk->protinfo.af_ipx.dest_addr.net=addr->sipx_network;
1921         sk->protinfo.af_ipx.dest_addr.sock=addr->sipx_port;
1922         memcpy(sk->protinfo.af_ipx.dest_addr.node,
1923                 addr->sipx_node,IPX_NODE_LEN);
1924         sk->protinfo.af_ipx.type=addr->sipx_type;
1925         sock->state = SS_CONNECTED;
1926         sk->state=TCP_ESTABLISHED;
1927         return 0;
1928 }
1929 
1930 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
1931 {
1932         return(-EOPNOTSUPP);
1933 }
1934 
1935 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1936 {
1937         if(newsock->data) {
1938                 kfree_s(newsock->data,sizeof(ipx_socket));
1939                 MOD_DEC_USE_COUNT;
1940         }
1941         return -EOPNOTSUPP;
1942 }
1943 
1944 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
1945         int *uaddr_len, int peer)
1946 {
1947         ipx_address *addr;
1948         struct sockaddr_ipx sipx;
1949         ipx_socket *sk;
1950         
1951         sk=(ipx_socket *)sock->data;
1952         
1953         *uaddr_len = sizeof(struct sockaddr_ipx);
1954                 
1955         if(peer) {
1956                 if(sk->state!=TCP_ESTABLISHED)
1957                         return -ENOTCONN;
1958                 addr=&sk->protinfo.af_ipx.dest_addr;
1959                 sipx.sipx_network = addr->net;
1960                 memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
1961                 sipx.sipx_port = addr->sock;
1962         } else {
1963                 if (sk->protinfo.af_ipx.intrfc != NULL) {
1964                         sipx.sipx_network = sk->protinfo.af_ipx.intrfc->if_netnum;
1965 #ifdef CONFIG_IPX_INTERN
1966                         memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
1967 #else
1968                         memcpy(sipx.sipx_node, 
1969                                 sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
1970 #endif
1971 
1972                 } else {
1973                         sipx.sipx_network = 0L;
1974                         memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1975                 }
1976                 sipx.sipx_port = sk->protinfo.af_ipx.port;
1977         }
1978                 
1979         sipx.sipx_family = AF_IPX;
1980         sipx.sipx_type = sk->protinfo.af_ipx.type;
1981         memcpy(uaddr,&sipx,sizeof(sipx));
1982         return 0;
1983 }
1984 
1985 #if 0
1986 /*
1987  * User to dump IPX packets (debugging)
1988  */
1989 void dump_data(char *str,unsigned char *d, int len) {
     /* [previous][next][first][last][top][bottom][index][help] */
1990   static char h2c[] = "0123456789ABCDEF";
1991   int l,i;
1992   char *p, b[64];
1993   for (l=0;len > 0 && l<16;l++) {
1994     p = b;
1995     for (i=0; i < 8 ; i++, --len) {
1996           if (len > 0) {
1997               *(p++) = h2c[(d[i] >> 4) & 0x0f];
1998               *(p++) = h2c[d[i] & 0x0f];
1999           }
2000           else {
2001               *(p++) = ' ';
2002               *(p++) = ' ';
2003           }
2004       *(p++) = ' ';
2005     }
2006     *(p++) = '-';
2007     *(p++) = ' ';
2008         len += 8;
2009     for (i=0; i < 8 ; i++, --len)
2010                 if (len > 0)
2011                         *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
2012                 else
2013                         *(p++) = ' ';
2014     *p = '\000';
2015     d += i;
2016     printk("%s-%04X: %s\n",str,l*8,b);
2017   }
2018 }
2019 
2020 void dump_addr(char *str,ipx_address *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
2021   printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
2022    str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
2023    p->node[3],p->node[4],p->node[5],ntohs(p->sock));
2024 }
2025 
2026 void dump_hdr(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
2027   printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
2028    str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
2029    p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
2030   dump_addr("  IPX-DST",&p->ipx_dest);
2031   dump_addr("  IPX-SRC",&p->ipx_source);
2032 }
2033 
2034 void dump_pkt(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
2035   int len = ntohs(p->ipx_pktsize);
2036   dump_hdr(str,p);
2037   if (len > 30)
2038           dump_data(str,(unsigned char *)p + 30, len - 30);
2039 }
2040 #endif
2041 
2042 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
2043 {
2044         /* NULL here for pt means the packet was looped back */
2045         ipx_interface   *intrfc;
2046         ipx_packet *ipx;
2047         
2048         
2049         ipx=(ipx_packet *)skb->h.raw;
2050         
2051         /* Too small */
2052         
2053         if(ntohs(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
2054                 kfree_skb(skb,FREE_READ);
2055                 return 0;
2056         }
2057         
2058         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) 
2059         {
2060                 if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize))!=ipx->ipx_checksum)
2061                 {
2062                         kfree_skb(skb,FREE_READ);
2063                         return 0;
2064                 }
2065         }
2066         
2067         /* Determine what local ipx endpoint this is */
2068         intrfc = ipxitf_find_using_phys(dev, pt->type);
2069         if (intrfc == NULL) 
2070         {
2071                 if (ipxcfg_auto_create_interfaces) {
2072                         intrfc = ipxitf_auto_create(dev, pt->type);
2073                 }
2074 
2075                 if (intrfc == NULL) {
2076                         /* Not one of ours */
2077                         kfree_skb(skb,FREE_READ);
2078                         return 0;
2079                 }
2080         }
2081 
2082         return ipxitf_rcv(intrfc, skb);
2083 }
2084 
2085 static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
2086         int flags)
2087 {
2088         ipx_socket *sk=(ipx_socket *)sock->data;
2089         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name;
2090         struct sockaddr_ipx local_sipx;
2091         int retval;
2092 
2093         if (sk->zapped) 
2094                 return -EIO; /* Socket not bound */
2095         if(flags) 
2096                 return -EINVAL;
2097                 
2098         if(usipx) 
2099         {
2100                 if(sk->protinfo.af_ipx.port == 0) 
2101                 {
2102                         struct sockaddr_ipx uaddr;
2103                         int ret;
2104 
2105                         uaddr.sipx_port = 0;
2106                         uaddr.sipx_network = 0L; 
2107 #ifdef CONFIG_IPX_INTERN
2108                         memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
2109                                 ->if_node, IPX_NODE_LEN);
2110 #endif
2111                         ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
2112                                         sizeof(struct sockaddr_ipx));
2113                         if (ret != 0) return ret;
2114                 }
2115 
2116                 if(msg->msg_namelen <sizeof(*usipx))
2117                         return -EINVAL;
2118                 if(usipx->sipx_family != AF_IPX)
2119                         return -EINVAL;
2120         }
2121         else 
2122         {
2123                 if(sk->state!=TCP_ESTABLISHED)
2124                         return -ENOTCONN;
2125                 usipx=&local_sipx;
2126                 usipx->sipx_family=AF_IPX;
2127                 usipx->sipx_type=sk->protinfo.af_ipx.type;
2128                 usipx->sipx_port=sk->protinfo.af_ipx.dest_addr.sock;
2129                 usipx->sipx_network=sk->protinfo.af_ipx.dest_addr.net;
2130                 memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
2131         }
2132         
2133         retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len);
2134         if (retval < 0) 
2135                 return retval;
2136 
2137         return len;
2138 }
2139 
2140 
2141 static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
2142                  int flags, int *addr_len)
2143 {
2144         ipx_socket *sk=(ipx_socket *)sock->data;
2145         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name;
2146         struct ipx_packet *ipx = NULL;
2147         int copied = 0;
2148         int truesize;
2149         struct sk_buff *skb;
2150         int er;
2151         
2152         if(sk->err)
2153                 return sock_error(sk);
2154         
2155         if (sk->zapped)
2156                 return -EIO;
2157 
2158 
2159         skb=skb_recv_datagram(sk,flags,noblock,&er);
2160         if(skb==NULL)
2161                 return er;
2162         
2163         if(addr_len)
2164                 *addr_len=sizeof(*sipx);
2165 
2166         ipx = (ipx_packet *)(skb->h.raw);
2167         truesize=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
2168         copied = (truesize > size) ? size : truesize;
2169         skb_copy_datagram_iovec(skb,sizeof(struct ipx_packet),msg->msg_iov,copied);
2170         
2171         if(sipx)
2172         {
2173                 sipx->sipx_family=AF_IPX;
2174                 sipx->sipx_port=ipx->ipx_source.sock;
2175                 memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
2176                 sipx->sipx_network=ipx->ipx_source.net;
2177                 sipx->sipx_type = ipx->ipx_type;
2178         }
2179         skb_free_datagram(sk, skb);
2180         return(truesize);
2181 }               
2182 
2183 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
2184 {
2185         return -EOPNOTSUPP;
2186 }
2187 
2188 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
2189 {
2190         ipx_socket *sk=(ipx_socket *)sock->data;
2191         
2192         return datagram_select(sk,sel_type,wait);
2193 }
2194 
2195 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
2196 {
2197         int err;
2198         long amount=0;
2199         ipx_socket *sk=(ipx_socket *)sock->data;
2200         
2201         switch(cmd)
2202         {
2203                 case TIOCOUTQ:
2204                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
2205                         if(err)
2206                                 return err;
2207                         amount=sk->sndbuf-sk->wmem_alloc;
2208                         if(amount<0)
2209                                 amount=0;
2210                         put_fs_long(amount,(unsigned long *)arg);
2211                         return 0;
2212                 case TIOCINQ:
2213                 {
2214                         struct sk_buff *skb;
2215                         /* These two are safe on a single CPU system as only user tasks fiddle here */
2216                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
2217                                 amount=skb->len-sizeof(struct ipx_packet);
2218                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
2219                         if(err)
2220                                 return err;
2221                         put_fs_long(amount,(unsigned long *)arg);
2222                         return 0;
2223                 }
2224                 case SIOCADDRT:
2225                 case SIOCDELRT:
2226                         if(!suser())
2227                                 return -EPERM;
2228                         return(ipxrtr_ioctl(cmd,(void *)arg));
2229                 case SIOCSIFADDR:
2230                 case SIOCAIPXITFCRT:
2231                 case SIOCAIPXPRISLT:
2232                         if(!suser())
2233                                 return -EPERM;
2234                 case SIOCGIFADDR:
2235                         return(ipxitf_ioctl(cmd,(void *)arg));
2236                 case SIOCIPXCFGDATA: 
2237                 {
2238                         err=verify_area(VERIFY_WRITE,(void *)arg,
2239                                 sizeof(ipx_config_data));
2240                         if(err) return err;
2241                         return(ipxcfg_get_config_data((void *)arg));
2242                 }
2243                 case SIOCGSTAMP:
2244                         if (sk)
2245                         {
2246                                 if(sk->stamp.tv_sec==0)
2247                                         return -ENOENT;
2248                                 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
2249                                 if(err)
2250                                         return err;
2251                                 memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
2252                                 return 0;
2253                         }
2254                         return -EINVAL;
2255                 case SIOCGIFDSTADDR:
2256                 case SIOCSIFDSTADDR:
2257                 case SIOCGIFBRDADDR:
2258                 case SIOCSIFBRDADDR:
2259                 case SIOCGIFNETMASK:
2260                 case SIOCSIFNETMASK:
2261                         return -EINVAL;
2262                 default:
2263                         return(dev_ioctl(cmd,(void *) arg));
2264         }
2265         /*NOTREACHED*/
2266         return(0);
2267 }
2268 
2269 static struct proto_ops ipx_proto_ops = {
2270         AF_IPX,
2271         
2272         ipx_create,
2273         ipx_dup,
2274         ipx_release,
2275         ipx_bind,
2276         ipx_connect,
2277         ipx_socketpair,
2278         ipx_accept,
2279         ipx_getname,
2280         ipx_select,
2281         ipx_ioctl,
2282         ipx_listen,
2283         ipx_shutdown,
2284         ipx_setsockopt,
2285         ipx_getsockopt,
2286         ipx_fcntl,
2287         ipx_sendmsg,
2288         ipx_recvmsg
2289 };
2290 
2291 /* Called by protocol.c on kernel start up */
2292 
2293 static struct packet_type ipx_8023_packet_type = 
2294 
2295 {
2296         0,      /* MUTTER ntohs(ETH_P_8023),*/
2297         NULL,           /* All devices */
2298         ipx_rcv,
2299         NULL,
2300         NULL,
2301 };
2302 
2303 static struct packet_type ipx_dix_packet_type = 
2304 {
2305         0,      /* MUTTER ntohs(ETH_P_IPX),*/
2306         NULL,           /* All devices */
2307         ipx_rcv,
2308         NULL,
2309         NULL,
2310 };
2311 
2312 static struct notifier_block ipx_dev_notifier={
2313         ipxitf_device_event,
2314         NULL,
2315         0
2316 };
2317 
2318 
2319 extern struct datalink_proto    *make_EII_client(void);
2320 extern struct datalink_proto    *make_8023_client(void);
2321 extern void     destroy_EII_client(struct datalink_proto *);
2322 extern void     destroy_8023_client(struct datalink_proto *);
2323 
2324 struct proc_dir_entry ipx_procinfo = {
2325         PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
2326         1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
2327 };
2328 
2329 struct proc_dir_entry ipx_if_procinfo = {
2330         PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
2331         1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
2332 };
2333 
2334 struct proc_dir_entry ipx_rt_procinfo = {
2335         PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
2336         1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
2337 };
2338 
2339 static unsigned char    ipx_8022_type = 0xE0;
2340 static unsigned char    ipx_snap_id[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
2341 
2342 void
2343 ipx_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
2344 {
2345         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
2346 
2347         pEII_datalink = make_EII_client();
2348         ipx_dix_packet_type.type=htons(ETH_P_IPX);
2349         dev_add_pack(&ipx_dix_packet_type);
2350 
2351         p8023_datalink = make_8023_client();
2352         ipx_8023_packet_type.type=htons(ETH_P_802_3);
2353         dev_add_pack(&ipx_8023_packet_type);
2354         
2355         if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
2356                 printk("IPX: Unable to register with 802.2\n");
2357 
2358         if ((p8022tr_datalink = register_8022tr_client(ipx_8022_type, ipx_rcv)) == NULL)
2359                 printk("IPX: Unable to register with 802.2TR\n");
2360  
2361         if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
2362                 printk("IPX: Unable to register with SNAP\n");
2363         
2364         register_netdevice_notifier(&ipx_dev_notifier);
2365 
2366         proc_net_register(&ipx_procinfo);
2367         proc_net_register(&ipx_if_procinfo);
2368         proc_net_register(&ipx_rt_procinfo);
2369                 
2370         printk(KERN_INFO "Swansea University Computer Society IPX 0.34 for NET3.034\n");
2371         printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
2372 }
2373 
2374 #ifdef MODULE
2375 /* Note on MOD_{INC,DEC}_USE_COUNT:
2376  *
2377  * Use counts are incremented/decremented when
2378  * sockets are created/deleted.
2379  * 
2380  * Routes are always associated with an interface, and
2381  * allocs/frees will remain properly accounted for by
2382  * their associated interfaces.
2383  * 
2384  * Ergo, before the ipx module can be removed, all IPX
2385  * sockets be closed from user space. 
2386  */
2387 
2388 static void
2389 ipx_proto_finito(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2390 {       ipx_interface   *ifc;
2391 
2392         while (ipx_interfaces) {
2393                 ifc = ipx_interfaces;
2394                 ipx_interfaces = ifc->if_next;
2395                 ifc->if_next = NULL;
2396                 ipxitf_down(ifc);
2397         }
2398 
2399         proc_net_unregister(PROC_NET_IPX_ROUTE);
2400         proc_net_unregister(PROC_NET_IPX_INTERFACE);
2401         proc_net_unregister(PROC_NET_IPX);
2402 
2403         unregister_netdevice_notifier(&ipx_dev_notifier);
2404 
2405         unregister_snap_client(ipx_snap_id);
2406         pSNAP_datalink = NULL;
2407 
2408         unregister_8022tr_client(ipx_8022_type);
2409         p8022tr_datalink = NULL;
2410 
2411         unregister_8022_client(ipx_8022_type);
2412         p8022_datalink = NULL;
2413 
2414         dev_remove_pack(&ipx_8023_packet_type);
2415         destroy_8023_client(p8023_datalink);
2416         p8023_datalink = NULL;
2417 
2418         dev_remove_pack(&ipx_dix_packet_type);
2419         destroy_EII_client(pEII_datalink);
2420         pEII_datalink = NULL;
2421 
2422         (void) sock_unregister(ipx_proto_ops.family);
2423 
2424         return;
2425 }
2426 
2427 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2428 {
2429         ipx_proto_init(NULL);
2430         register_symtab(0);
2431         return 0;
2432 }
2433 
2434 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2435 {
2436         ipx_proto_finito();
2437         return;
2438 }
2439 #endif /* def MODULE */

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