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
  28. ipxrtr_lookup
  29. ipxrtr_add_route
  30. ipxrtr_del_routes
  31. ipxrtr_create
  32. ipxrtr_delete
  33. ipxrtr_route_packet
  34. ipxrtr_route_skb
  35. ipxrtr_ioctl
  36. ipx_frame_name
  37. ipx_device_name
  38. ipx_interface_get_info
  39. ipx_get_info
  40. ipx_rt_get_info
  41. ipx_fcntl
  42. ipx_setsockopt
  43. ipx_getsockopt
  44. ipx_listen
  45. def_callback1
  46. def_callback2
  47. ipx_create
  48. ipx_release
  49. ipx_dup
  50. ipx_first_free_socketnum
  51. ipx_bind
  52. ipx_connect
  53. ipx_socketpair
  54. ipx_accept
  55. ipx_getname
  56. dump_data
  57. dump_addr
  58. dump_hdr
  59. dump_pkt
  60. ipx_rcv
  61. ipx_sendmsg
  62. ipx_recvmsg
  63. ipx_shutdown
  64. ipx_select
  65. ipx_ioctl
  66. ipx_proto_init

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

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