root/net/inet/ipx.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipxcfg_set_auto_create
  2. ipxcfg_set_auto_select
  3. ipxcfg_get_config_data
  4. ipx_remove_socket
  5. ipx_destroy_socket
  6. ipxitf_clear_primary_net
  7. ipxitf_find_using_phys
  8. ipxitf_find_using_net
  9. ipxitf_insert_socket
  10. ipxitf_find_socket
  11. ipxitf_down
  12. ipxitf_device_event
  13. ipxitf_def_skb_handler
  14. ipxitf_demux_socket
  15. ipxitf_adjust_skbuff
  16. ipxitf_send
  17. ipxitf_add_local_route
  18. ipxitf_rcv
  19. ipxitf_insert
  20. ipxitf_create_internal
  21. ipx_map_frame_type
  22. ipxitf_create
  23. ipxitf_delete
  24. ipxitf_auto_create
  25. ipxitf_ioctl
  26. ipxrtr_lookup
  27. ipxrtr_add_route
  28. ipxrtr_del_routes
  29. ipxrtr_create
  30. ipxrtr_delete
  31. ipxrtr_route_packet
  32. ipxrtr_route_skb
  33. ipxrtr_ioctl
  34. ipx_frame_name
  35. ipx_device_name
  36. ipx_get_interface_info
  37. ipx_get_info
  38. ipx_rt_get_info
  39. ipx_fcntl
  40. ipx_setsockopt
  41. ipx_getsockopt
  42. ipx_listen
  43. def_callback1
  44. def_callback2
  45. ipx_create
  46. ipx_release
  47. ipx_dup
  48. ipx_first_free_socketnum
  49. ipx_bind
  50. ipx_connect
  51. ipx_socketpair
  52. ipx_accept
  53. ipx_getname
  54. dump_data
  55. dump_addr
  56. dump_hdr
  57. dump_pkt
  58. ipx_rcv
  59. ipx_sendto
  60. ipx_send
  61. ipx_recvfrom
  62. ipx_write
  63. ipx_recv
  64. ipx_read
  65. ipx_shutdown
  66. ipx_select
  67. ipx_ioctl
  68. ipx_proto_init

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

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