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

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