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

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