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

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