root/net/ipx/af_ipx.c

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

DEFINITIONS

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

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