root/net/ipx/af_ipx.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipxcfg_set_auto_create
  2. ipxcfg_set_auto_select
  3. ipxcfg_get_config_data
  4. ipx_remove_socket
  5. ipx_destroy_socket
  6. ipxitf_clear_primary_net
  7. ipxitf_find_using_phys
  8. ipxitf_find_using_net
  9. ipxitf_insert_socket
  10. ipxitf_find_socket
  11. ipxitf_down
  12. ipxitf_device_event
  13. ipxitf_def_skb_handler
  14. ipxitf_demux_socket
  15. ipxitf_adjust_skbuff
  16. ipxitf_send
  17. ipxitf_add_local_route
  18. ipxitf_rcv
  19. ipxitf_insert
  20. ipxitf_create_internal
  21. ipx_map_frame_type
  22. ipxitf_create
  23. ipxitf_delete
  24. ipxitf_auto_create
  25. ipxitf_ioctl
  26. ipxrtr_lookup
  27. ipxrtr_add_route
  28. ipxrtr_del_routes
  29. ipxrtr_create
  30. ipxrtr_delete
  31. ipxrtr_route_packet
  32. ipxrtr_route_skb
  33. ipxrtr_ioctl
  34. ipx_frame_name
  35. ipx_device_name
  36. ipx_get_interface_info
  37. ipx_get_info
  38. ipx_rt_get_info
  39. ipx_fcntl
  40. ipx_setsockopt
  41. ipx_getsockopt
  42. ipx_listen
  43. def_callback1
  44. def_callback2
  45. ipx_create
  46. ipx_release
  47. ipx_dup
  48. ipx_first_free_socketnum
  49. ipx_bind
  50. ipx_connect
  51. ipx_socketpair
  52. ipx_accept
  53. ipx_getname
  54. dump_data
  55. dump_addr
  56. dump_hdr
  57. dump_pkt
  58. ipx_rcv
  59. ipx_sendto
  60. ipx_send
  61. ipx_recvfrom
  62. ipx_write
  63. ipx_recv
  64. ipx_read
  65. ipx_shutdown
  66. ipx_select
  67. ipx_ioctl
  68. ipx_proto_init

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

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