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

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