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

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