root/net/inet/ipx.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipx_remove_socket
  2. ipx_insert_socket
  3. ipx_find_socket
  4. ipx_destroy_socket
  5. ipx_get_info
  6. ipxrtr_get_local_net
  7. ipxrtr_get_default_net
  8. ipxrtr_get_dev
  9. ipxrtr_add_localnet
  10. ipxrtr_create
  11. ipxrtr_delete_localnet
  12. ipxrtr_delete
  13. ipxrtr_device_event
  14. ipxrtr_ioctl
  15. ipx_rt_get_info
  16. ipx_fcntl
  17. ipx_setsockopt
  18. ipx_getsockopt
  19. ipx_listen
  20. def_callback1
  21. def_callback2
  22. ipx_create
  23. ipx_dup
  24. ipx_release
  25. first_free_socketnum
  26. ipx_bind
  27. ipx_connect
  28. ipx_socketpair
  29. ipx_accept
  30. ipx_getname
  31. dump_data
  32. dump_addr
  33. dump_hdr
  34. dump_pkt
  35. ipx_rcv
  36. ipx_sendto
  37. ipx_send
  38. ipx_recvfrom
  39. ipx_write
  40. ipx_recv
  41. ipx_read
  42. ipx_shutdown
  43. ipx_select
  44. ipx_ioctl
  45. ipx_proto_init

   1 /*
   2  *      Implements an IPX socket layer (badly - but I'm working on it).
   3  *
   4  *      This code is derived from work by
   5  *              Ross Biro       :       Writing the original IP stack
   6  *              Fred Van Kempen :       Tidying up the TCP/IP
   7  *
   8  *      Many thanks go to Keith Baker, Institute For Industrial Information
   9  *      Technology Ltd, Swansea University for allowing me to work on this
  10  *      in my own time even though it was in some ways related to commercial
  11  *      work I am currently employed to do there.
  12  *
  13  *      All the material in this file is subject to the Gnu license version 2.
  14  *      Neither Alan Cox nor the Swansea University Computer Society admit liability
  15  *      nor provide warranty for any of this software. This material is provided 
  16  *      as is and at no charge.         
  17  *
  18  *      Revision 0.21:  Uses the new generic socket option code.
  19  *      Revision 0.22:  Gcc clean ups and drop out device registration. Use the
  20  *                      new multi-protocol edition of hard_header 
  21  *      Revision 0.23:  IPX /proc by Mark Evans.
  22  *                      Adding a route will overwrite any existing route to the same
  23  *                      network.
  24  *      Revision 0.24:  Supports new /proc with no 4K limit
  25  *      Revision 0.25:  Add ephemeral sockets, passive local network 
  26  *                      identification, support for local net 0 and
  27  *                      multiple datalinks <Greg Page>
  28  *      Revision 0.26:  Device drop kills IPX routes via it. (needed for modules)
  29  *      Revision 0.27:  Autobind <Mark Evans>
  30  *      Revision 0.28:  Small fix for multiple local networks <Thomas Winder>
  31  *      Revision 0.29:  Assorted major errors removed <Mark Evans>
  32  *                      Small correction to promisc mode error fix <Alan Cox>
  33  *                      Asynchronous I/O support.
  34  *                      Changed to use notifiers and the newer packet_type stuff.
  35  *                      Assorted major fixes <Alejandro Liu>
  36  */
  37   
  38 #include <linux/config.h>
  39 #include <linux/errno.h>
  40 #include <linux/types.h>
  41 #include <linux/socket.h>
  42 #include <linux/in.h>
  43 #include <linux/kernel.h>
  44 #include <linux/sched.h>
  45 #include <linux/timer.h>
  46 #include <linux/string.h>
  47 #include <linux/sockios.h>
  48 #include <linux/net.h>
  49 #include <linux/ipx.h>
  50 #include <linux/inet.h>
  51 #include <linux/netdevice.h>
  52 #include <linux/skbuff.h>
  53 #include "sock.h"
  54 #include <asm/segment.h>
  55 #include <asm/system.h>
  56 #include <linux/fcntl.h>
  57 #include <linux/mm.h>
  58 #include <linux/termios.h>      /* For TIOCOUTQ/INQ */
  59 #include <linux/interrupt.h>
  60 #include "p8022.h"
  61 
  62 #ifdef CONFIG_IPX
  63 /***********************************************************************************************************************\
  64 *                                                                                                                       *
  65 *                                               Handlers for the socket list.                                           *
  66 *                                                                                                                       *
  67 \***********************************************************************************************************************/
  68 
  69 static ipx_socket *volatile ipx_socket_list=NULL;
  70 
  71 /*
  72  *      Note: Sockets may not be removed _during_ an interrupt or inet_bh
  73  *      handler using this technique. They can be added although we do not
  74  *      use this facility.
  75  */
  76  
  77 static void ipx_remove_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         ipx_socket *s;
  80         
  81         cli();
  82         s=ipx_socket_list;
  83         if(s==sk)
  84         {
  85                 ipx_socket_list=s->next;
  86                 sti();
  87                 return;
  88         }
  89         while(s && s->next)
  90         {
  91                 if(s->next==sk)
  92                 {
  93                         s->next=sk->next;
  94                         sti();
  95                         return;
  96                 }
  97                 s=s->next;
  98         }
  99         sti();
 100 }
 101 
 102 static void ipx_insert_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         cli();
 105         sk->next=ipx_socket_list;
 106         ipx_socket_list=sk;
 107         sti();
 108 }
 109 
 110 static ipx_socket *ipx_find_socket(int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         ipx_socket *s;
 113         s=ipx_socket_list;
 114         while(s)
 115         {
 116                 if(s->ipx_source_addr.sock==port)
 117                 {
 118                         return(s);
 119                 }
 120                 s=s->next;
 121         }
 122         return(NULL);
 123 }
 124 
 125 /*
 126  *      This is only called from user mode. Thus it protects itself against
 127  *      interrupt users but doesn't worry about being called during work.
 128  *      Once it is removed from the queue no interrupt or bottom half will
 129  *      touch it and we are (fairly 8-) ) safe.
 130  */
 131  
 132 static void ipx_destroy_socket(ipx_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134         struct sk_buff *skb;
 135         ipx_remove_socket(sk);
 136         
 137         while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
 138         {
 139                 kfree_skb(skb,FREE_READ);
 140         }
 141         
 142         kfree_s(sk,sizeof(*sk));
 143 }
 144 
 145 
 146 /* Called from proc fs */
 147 int ipx_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149         ipx_socket *s;
 150         int len=0;
 151         off_t pos=0;
 152         off_t begin=0;
 153 
 154         /* Theory.. Keep printing in the same place until we pass offset */
 155         
 156         len += sprintf (buffer,"Type local_address             rem_address              tx_queue rx_queue st uid\n");
 157         for (s = ipx_socket_list; s != NULL; s = s->next)
 158         {
 159                 len += sprintf (buffer+len,"%02X   ", s->ipx_type);
 160                 len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%04X ", htonl(s->ipx_source_addr.net),
 161                         s->ipx_source_addr.node[0], s->ipx_source_addr.node[1], s->ipx_source_addr.node[2],
 162                         s->ipx_source_addr.node[3], s->ipx_source_addr.node[4], s->ipx_source_addr.node[5],
 163                         htons(s->ipx_source_addr.sock));
 164                 len += sprintf (buffer+len,"%08lX:%02X%02X%02X%02X%02X%02X:%04X ", htonl(s->ipx_dest_addr.net),
 165                         s->ipx_dest_addr.node[0], s->ipx_dest_addr.node[1], s->ipx_dest_addr.node[2],
 166                         s->ipx_dest_addr.node[3], s->ipx_dest_addr.node[4], s->ipx_dest_addr.node[5],
 167                         htons(s->ipx_dest_addr.sock));
 168                 len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
 169                 len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
 170                 
 171                 /* Are we still dumping unwanted data then discard the record */
 172                 pos=begin+len;
 173                 
 174                 if(pos<offset)
 175                 {
 176                         len=0;                  /* Keep dumping into the buffer start */
 177                         begin=pos;
 178                 }
 179                 if(pos>offset+length)           /* We have dumped enough */
 180                         break;
 181         }
 182         
 183         /* The data in question runs from begin to begin+len */
 184         *start=buffer+(offset-begin);   /* Start of wanted data */
 185         len-=(offset-begin);            /* Remove unwanted header data from length */
 186         if(len>length)
 187                 len=length;             /* Remove unwanted tail data from length */
 188         
 189         return len;
 190 }
 191 
 192 /*******************************************************************************************************************\
 193 *                                                                                                                   *
 194 *                                       Routing tables for the IPX socket layer                                     *
 195 *                                                                                                                   *
 196 \*******************************************************************************************************************/
 197 
 198 
 199 static struct datalink_proto    *p8022_datalink = NULL;
 200 static struct datalink_proto    *pEII_datalink = NULL;
 201 static struct datalink_proto    *p8023_datalink = NULL;
 202 static struct datalink_proto    *pSNAP_datalink = NULL;
 203 
 204 static ipx_route *ipx_router_list=NULL;
 205 static ipx_route *ipx_localnet_list=NULL;
 206 
 207 static ipx_route *
 208 ipxrtr_get_local_net(struct device *dev, unsigned short datalink)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         ipx_route *r;
 211         unsigned long flags;
 212         save_flags(flags);
 213         cli();
 214         r=ipx_localnet_list;
 215         while(r!=NULL)
 216         {
 217                 if((r->dev==dev) && (r->dlink_type == datalink))
 218                 {
 219                         restore_flags(flags);
 220                         return r;
 221                 }
 222                 r=r->nextlocal;
 223         }
 224         restore_flags(flags);
 225         return NULL;
 226 }
 227         
 228 static ipx_route *
 229 ipxrtr_get_default_net(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         return ipx_localnet_list;
 232 }
 233 
 234 static ipx_route *ipxrtr_get_dev(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {
 236         ipx_route *r;
 237         unsigned long flags;
 238         save_flags(flags);
 239         cli();
 240         r=ipx_router_list;
 241         while(r!=NULL)
 242         {
 243                 if(r->net==net)
 244                 {
 245                         restore_flags(flags);
 246                         return r;
 247                 }
 248                 r=r->next;
 249         }
 250         restore_flags(flags);
 251         return NULL;
 252 }
 253 
 254 static void ipxrtr_add_localnet(ipx_route *newnet)
     /* [previous][next][first][last][top][bottom][index][help] */
 255 {
 256         ipx_route *r;
 257         unsigned long flags;
 258         save_flags(flags);
 259         cli();
 260 
 261         newnet->nextlocal = NULL;
 262         if (ipx_localnet_list == NULL) {
 263                 ipx_localnet_list = newnet;
 264                 restore_flags(flags);
 265                 return;
 266         }
 267 
 268         r=ipx_localnet_list;
 269         while(r->nextlocal!=NULL)
 270                 r=r->nextlocal;
 271 
 272         r->nextlocal = newnet;
 273         
 274         restore_flags(flags);
 275         return;
 276 }
 277 
 278 static int ipxrtr_create(struct ipx_route_def *r)
     /* [previous][next][first][last][top][bottom][index][help] */
 279 {
 280         ipx_route *rt=ipxrtr_get_dev(r->ipx_network);
 281         struct device *dev;
 282         unsigned short  dlink_type;
 283         struct datalink_proto *datalink = NULL;
 284 
 285         if (r->ipx_flags & IPX_RT_BLUEBOOK) {
 286                 dlink_type = htons(ETH_P_IPX);
 287                 datalink = pEII_datalink;
 288         } else if (r->ipx_flags & IPX_RT_8022) {
 289                 dlink_type = htons(ETH_P_802_2);
 290                 datalink = p8022_datalink;
 291         } else if (r->ipx_flags & IPX_RT_SNAP) {
 292                 dlink_type = htons(ETH_P_SNAP);
 293                 datalink = pSNAP_datalink;
 294         } else {
 295                 dlink_type = htons(ETH_P_802_3);
 296                 datalink = p8023_datalink;
 297         }
 298 
 299         if (datalink == NULL) {
 300                 printk("IPX: Unsupported datalink protocol.\n");
 301                 return -EPROTONOSUPPORT;
 302         }
 303 
 304         if(r->ipx_router_network!=0)
 305         {
 306                 /* Adding an indirect route */
 307                 ipx_route *rt1=ipxrtr_get_dev(r->ipx_router_network);
 308                 if(rt1==NULL)
 309                         return -ENETUNREACH;
 310                 if(rt1->flags&IPX_RT_ROUTED)
 311                         return -EMULTIHOP;
 312                 if (rt==NULL)
 313                 {
 314                         rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);  /* Because we are brave and don't lock the table! */
 315                         if(rt==NULL)
 316                                 return -EAGAIN;
 317                         rt->next=ipx_router_list;
 318                         ipx_router_list=rt;
 319                 }
 320                 rt->net=r->ipx_network;
 321                 rt->router_net=r->ipx_router_network;
 322                 memcpy(rt->router_node,r->ipx_router_node,sizeof(rt->router_node));
 323                 rt->flags=IPX_RT_ROUTED;
 324                 rt->dlink_type = dlink_type;
 325                 rt->datalink = datalink;
 326                 rt->dev=rt1->dev;
 327                 return 0;
 328         }
 329         /* Add a direct route */
 330         dev=dev_get(r->ipx_device);
 331         if(dev==NULL)
 332                 return -ENODEV;
 333         /* Check addresses are suitable */
 334         if(dev->addr_len>6)
 335                 return -EINVAL;
 336         if(dev->addr_len<2)
 337                 return -EINVAL;
 338         if (ipxrtr_get_local_net(dev, dlink_type) != NULL)
 339                 return -EEXIST;
 340         /* Ok now create */
 341         rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);  /* Because we are brave and don't lock the table! */
 342         if(rt==NULL)
 343                 return -EAGAIN;
 344         rt->next=ipx_router_list;
 345         ipx_router_list=rt;
 346         rt->router_net=0;
 347         memset(rt->router_node,0,sizeof(rt->router_node));
 348         rt->dev=dev;
 349         rt->net=r->ipx_network;
 350         rt->flags=0;
 351         rt->dlink_type = dlink_type;
 352         rt->datalink = datalink;
 353         ipxrtr_add_localnet(rt);
 354         return 0;
 355 }
 356 
 357 
 358 static int ipxrtr_delete_localnet(ipx_route *d)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360         ipx_route **r = &ipx_localnet_list;
 361         ipx_route *tmp;
 362 
 363         while ((tmp = *r) != NULL) {
 364                 if (tmp == d) {
 365                         *r = tmp->next;
 366                         return 0;
 367                 }
 368                 r = &tmp->nextlocal;
 369         }
 370         return -ENOENT;
 371 }
 372 
 373 static int ipxrtr_delete(long net)
     /* [previous][next][first][last][top][bottom][index][help] */
 374 {
 375         ipx_route **r = &ipx_router_list;
 376         ipx_route *tmp;
 377 
 378         while ((tmp = *r) != NULL) {
 379                 if (tmp->net == net) {
 380                         *r = tmp->next;
 381                         if (tmp->router_net == 0) {
 382                                 ipxrtr_delete_localnet(tmp);
 383                         }
 384                         kfree_s(tmp, sizeof(ipx_route));
 385                         return 0;
 386                 }
 387                 r = &tmp->next;
 388         }
 389         return -ENOENT;
 390 }
 391 
 392 int ipxrtr_device_event(unsigned long event, void *ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 393 {
 394         struct device *dev=ptr;
 395         ipx_route **r = &ipx_router_list;
 396         ipx_route *tmp;
 397 
 398         if(event!=NETDEV_DOWN)
 399                 return NOTIFY_DONE;
 400         while ((tmp = *r) != NULL) {
 401                 if (tmp->dev == dev) {
 402                         *r = tmp->next;
 403                         if(tmp->router_net == 0)
 404                                 ipxrtr_delete_localnet(tmp);
 405                         kfree_s(tmp, sizeof(ipx_route));
 406                 }
 407                 r = &tmp->next;
 408         }
 409         return NOTIFY_DONE;
 410 }
 411 
 412 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414         int err;
 415         switch(cmd)
 416         {
 417                 case SIOCDELRT:
 418                         err=verify_area(VERIFY_READ,arg,sizeof(long));
 419                         if(err)
 420                                 return err;
 421                         return ipxrtr_delete(get_fs_long(arg));
 422                 case SIOCADDRT:
 423                 {
 424                         struct ipx_route_def f;
 425                         err=verify_area(VERIFY_READ,arg,sizeof(f));
 426                         if(err)
 427                                 return err;
 428                         memcpy_fromfs(&f,arg,sizeof(f));
 429                         return ipxrtr_create(&f);
 430                 }
 431                 default:
 432                         return -EINVAL;
 433         }
 434 }
 435 
 436 int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438         ipx_route *rt;
 439         int len=0;
 440         off_t pos=0;
 441         off_t begin=0;
 442 
 443         len += sprintf (buffer,"Net      Router                Flags Dev   Frame\n");
 444         for (rt = ipx_router_list; rt != NULL; rt = rt->next)
 445         {
 446                 len += sprintf (buffer+len,"%08lX %08lX:%02X%02X%02X%02X%02X%02X %02X    %s  %d\n", ntohl(rt->net),
 447                         ntohl(rt->router_net), rt->router_node[0], rt->router_node[1], rt->router_node[2],
 448                         rt->router_node[3], rt->router_node[4], rt->router_node[5], rt->flags, rt->dev->name,
 449                         ntohs(rt->dlink_type));
 450                 pos=begin+len;
 451                 if(pos<offset)
 452                 {
 453                         len=0;
 454                         begin=pos;
 455                 }
 456                 if(pos>offset+length)
 457                         break;
 458         }
 459         *start=buffer+(offset-begin);
 460         len-=(offset-begin);
 461         if(len>length)
 462                 len=length;
 463         return len;
 464 }
 465 
 466 /*******************************************************************************************************************\
 467 *                                                                                                                   *
 468 *             Handling for system calls applied via the various interfaces to an IPX socket object                  *
 469 *                                                                                                                   *
 470 \*******************************************************************************************************************/
 471  
 472 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 473 {
 474         ipx_socket *sk=(ipx_socket *)sock->data;
 475         switch(cmd)
 476         {
 477                 default:
 478                         return(-EINVAL);
 479         }
 480 }
 481 
 482 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484         ipx_socket *sk;
 485         int err,opt;
 486         
 487         sk=(ipx_socket *)sock->data;
 488         
 489         if(optval==NULL)
 490                 return(-EINVAL);
 491 
 492         err=verify_area(VERIFY_READ,optval,sizeof(int));
 493         if(err)
 494                 return err;
 495         opt=get_fs_long((unsigned long *)optval);
 496         
 497         switch(level)
 498         {
 499                 case SOL_IPX:
 500                         switch(optname)
 501                         {
 502                                 case IPX_TYPE:
 503                                         if(!suser())
 504                                                 return(-EPERM);
 505                                         sk->ipx_type=opt;
 506                                         return 0;
 507                                 default:
 508                                         return -EOPNOTSUPP;
 509                         }
 510                         break;
 511                         
 512                 case SOL_SOCKET:                
 513                         return sock_setsockopt(sk,level,optname,optval,optlen);
 514 
 515                 default:
 516                         return -EOPNOTSUPP;
 517         }
 518 }
 519 
 520 static int ipx_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 521         char *optval, int *optlen)
 522 {
 523         ipx_socket *sk;
 524         int val=0;
 525         int err;
 526         
 527         sk=(ipx_socket *)sock->data;
 528 
 529         switch(level)
 530         {
 531 
 532                 case SOL_IPX:
 533                         switch(optname)
 534                         {
 535                                 case IPX_TYPE:
 536                                         val=sk->ipx_type;
 537                                         break;
 538                                 default:
 539                                         return -ENOPROTOOPT;
 540                         }
 541                         break;
 542                         
 543                 case SOL_SOCKET:
 544                         return sock_getsockopt(sk,level,optname,optval,optlen);
 545                         
 546                 default:
 547                         return -EOPNOTSUPP;
 548         }
 549         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
 550         if(err)
 551                 return err;
 552         put_fs_long(sizeof(int),(unsigned long *)optlen);
 553         err=verify_area(VERIFY_WRITE,optval,sizeof(int));
 554         put_fs_long(val,(unsigned long *)optval);
 555         return(0);
 556 }
 557 
 558 static int ipx_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 559 {
 560         return -EOPNOTSUPP;
 561 }
 562 
 563 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 564 {
 565         if(!sk->dead)
 566                 wake_up_interruptible(sk->sleep);
 567 }
 568 
 569 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 570 {
 571         if(!sk->dead)
 572         {
 573                 wake_up_interruptible(sk->sleep);
 574                 sock_wake_async(sk->socket, 1);
 575         }
 576 }
 577 
 578 static int ipx_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 579 {
 580         ipx_socket *sk;
 581         sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
 582         if(sk==NULL)
 583                 return(-ENOMEM);
 584         switch(sock->type)
 585         {
 586                 case SOCK_DGRAM:
 587                         break;
 588                 default:
 589                         kfree_s((void *)sk,sizeof(*sk));
 590                         return(-ESOCKTNOSUPPORT);
 591         }
 592         sk->dead=0;
 593         sk->next=NULL;
 594         sk->broadcast=0;
 595         sk->rcvbuf=SK_RMEM_MAX;
 596         sk->sndbuf=SK_WMEM_MAX;
 597         sk->wmem_alloc=0;
 598         sk->rmem_alloc=0;
 599         sk->inuse=0;
 600         sk->shutdown=0;
 601         sk->prot=NULL;  /* So we use default free mechanisms */
 602         sk->broadcast=0;
 603         sk->err=0;
 604         skb_queue_head_init(&sk->receive_queue);
 605         skb_queue_head_init(&sk->write_queue);
 606         sk->send_head=NULL;
 607         skb_queue_head_init(&sk->back_log);
 608         sk->state=TCP_CLOSE;
 609         sk->socket=sock;
 610         sk->type=sock->type;
 611         sk->ipx_type=0;         /* General user level IPX */
 612         sk->debug=0;
 613         
 614         memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
 615         memset(&sk->ipx_source_addr,'\0',sizeof(sk->ipx_source_addr));
 616         sk->mtu=IPX_MTU;
 617         
 618         if(sock!=NULL)
 619         {
 620                 sock->data=(void *)sk;
 621                 sk->sleep=sock->wait;
 622         }
 623         
 624         sk->state_change=def_callback1;
 625         sk->data_ready=def_callback2;
 626         sk->write_space=def_callback1;
 627         sk->error_report=def_callback1;
 628 
 629         sk->zapped=1;
 630         return(0);
 631 }
 632 
 633 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 634 {
 635         return(ipx_create(newsock,SOCK_DGRAM));
 636 }
 637 
 638 static int ipx_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640         ipx_socket *sk=(ipx_socket *)sock->data;
 641         if(sk==NULL)
 642                 return(0);
 643         if(!sk->dead)
 644                 sk->state_change(sk);
 645         sk->dead=1;
 646         sock->data=NULL;
 647         ipx_destroy_socket(sk);
 648         return(0);
 649 }
 650                 
 651 static unsigned short first_free_socketnum(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 652 {
 653         static unsigned short   socketNum = 0x4000;
 654 
 655         while (ipx_find_socket(ntohs(socketNum)) != NULL)
 656                 if (socketNum > 0x7ffc)
 657                         socketNum = 0x4000;
 658                 else
 659                         socketNum++;
 660 
 661         return  ntohs(socketNum);
 662 }
 663         
 664 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 665 {
 666         ipx_socket *sk;
 667         struct ipx_route *rt;
 668         unsigned char   *nodestart;
 669         struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
 670         
 671         sk=(ipx_socket *)sock->data;
 672         
 673         if(sk->zapped==0)
 674                 return(-EIO);
 675                 
 676         if(addr_len!=sizeof(struct sockaddr_ipx))
 677                 return -EINVAL;
 678         
 679         if (addr->sipx_port == 0) 
 680         {
 681                 addr->sipx_port = first_free_socketnum();
 682                 if (addr->sipx_port == 0)
 683                         return -EINVAL;
 684         }
 685                 
 686         if(ntohs(addr->sipx_port)<0x4000 && !suser())
 687                 return(-EPERM); /* protect IPX system stuff like routing/sap */
 688         
 689         /* Source addresses are easy. It must be our network:node pair for
 690            an interface routed to IPX with the ipx routing ioctl() */
 691 
 692         if(ipx_find_socket(addr->sipx_port)!=NULL)
 693         {
 694                 if(sk->debug)
 695                         printk("IPX: bind failed because port %X in use.\n",
 696                                 (int)addr->sipx_port);
 697                 return -EADDRINUSE;        
 698         }
 699 
 700         sk->ipx_source_addr.sock=addr->sipx_port;
 701 
 702         if (addr->sipx_network == 0L) 
 703         {
 704                 rt = ipxrtr_get_default_net();
 705         }
 706         else 
 707         {
 708                 rt = ipxrtr_get_dev(addr->sipx_network);
 709         }
 710 
 711         if(rt == NULL)
 712         {
 713                 if(sk->debug)
 714                         printk("IPX: bind failed (no device for net %lX)\n",
 715                                 sk->ipx_source_addr.net);
 716                 return -EADDRNOTAVAIL;
 717         }
 718 
 719         sk->ipx_source_addr.net=rt->net;
 720 
 721         /* IPX addresses zero pad physical addresses less than 6 */
 722         memset(sk->ipx_source_addr.node,'\0',6);
 723         nodestart = sk->ipx_source_addr.node + (6 - rt->dev->addr_len);
 724         memcpy(nodestart,rt->dev->dev_addr,rt->dev->addr_len);
 725 
 726         ipx_insert_socket(sk);
 727         sk->zapped=0;
 728         if(sk->debug)
 729                 printk("IPX: socket is bound.\n");
 730         return(0);
 731 }
 732 
 733 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 734         int addr_len, int flags)
 735 {
 736         ipx_socket *sk=(ipx_socket *)sock->data;
 737         struct sockaddr_ipx *addr;
 738         
 739         sk->state = TCP_CLOSE;  
 740         sock->state = SS_UNCONNECTED;
 741 
 742         if(addr_len!=sizeof(*addr))
 743                 return(-EINVAL);
 744         addr=(struct sockaddr_ipx *)uaddr;
 745         
 746         if(sk->ipx_source_addr.net==0)
 747         /* put the autobinding in */
 748         {
 749                 struct sockaddr_ipx uaddr;
 750                 int ret;
 751         
 752                 uaddr.sipx_port = 0;
 753                 uaddr.sipx_network = 0L; 
 754                 ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
 755                 if (ret != 0) return (ret);
 756         }
 757         
 758         sk->ipx_dest_addr.net=addr->sipx_network;
 759         sk->ipx_dest_addr.sock=addr->sipx_port;
 760         memcpy(sk->ipx_dest_addr.node,addr->sipx_node,sizeof(sk->ipx_source_addr.node));
 761         if(ipxrtr_get_dev(sk->ipx_dest_addr.net)==NULL)
 762                 return -ENETUNREACH;
 763         sk->ipx_type=addr->sipx_type;
 764         sock->state = SS_CONNECTED;
 765         sk->state=TCP_ESTABLISHED;
 766         return(0);
 767 }
 768 
 769 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 770 {
 771         return(-EOPNOTSUPP);
 772 }
 773 
 774 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 775 {
 776         if(newsock->data)
 777                 kfree_s(newsock->data,sizeof(ipx_socket));
 778         return -EOPNOTSUPP;
 779 }
 780 
 781 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 782         int *uaddr_len, int peer)
 783 {
 784         ipx_address *addr;
 785         struct sockaddr_ipx sipx;
 786         ipx_socket *sk;
 787         
 788         sk=(ipx_socket *)sock->data;
 789         
 790         *uaddr_len = sizeof(struct sockaddr_ipx);
 791                 
 792         if(peer)
 793         {
 794                 if(sk->state!=TCP_ESTABLISHED)
 795                         return -ENOTCONN;
 796                 addr=&sk->ipx_dest_addr;
 797         }
 798         else
 799                 addr=&sk->ipx_source_addr;
 800                 
 801         sipx.sipx_family = AF_IPX;
 802         sipx.sipx_type = sk->ipx_type;
 803         sipx.sipx_port = addr->sock;
 804         sipx.sipx_network = addr->net;
 805         memcpy(sipx.sipx_node,addr->node,sizeof(sipx.sipx_node));
 806         memcpy(uaddr,&sipx,sizeof(sipx));
 807         return(0);
 808 }
 809 
 810 #if 0
 811 /*
 812  * User to dump IPX packets (debugging)
 813  */
 814 void dump_data(char *str,unsigned char *d) {
     /* [previous][next][first][last][top][bottom][index][help] */
 815   static char h2c[] = "0123456789ABCDEF";
 816   int l,i;
 817   char *p, b[64];
 818   for (l=0;l<16;l++) {
 819     p = b;
 820     for (i=0; i < 8 ; i++) {
 821       *(p++) = h2c[d[i] & 0x0f];
 822       *(p++) = h2c[(d[i] >> 4) & 0x0f];
 823       *(p++) = ' ';
 824     }
 825     *(p++) = '-';
 826     *(p++) = ' ';
 827     for (i=0; i < 8 ; i++)  *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
 828     *p = '\000';
 829     d += i;
 830     printk("%s-%04X: %s\n",str,l*8,b);
 831   }
 832 }
 833 
 834 void dump_addr(char *str,ipx_address *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 835   printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
 836    str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
 837    p->node[3],p->node[4],p->node[5],ntohs(p->sock));
 838 }
 839 
 840 void dump_hdr(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 841   printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
 842    str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
 843    p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
 844   dump_addr("  IPX-DST",&p->ipx_dest);
 845   dump_addr("  IPX-SRC",&p->ipx_source);
 846 }
 847 
 848 void dump_pkt(char *str,ipx_packet *p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 849   dump_hdr(str,p);
 850   dump_data(str,(unsigned char *)p);
 851 }
 852 #endif
 853 
 854 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 855 {
 856         /* NULL here for pt means the packet was looped back */
 857         ipx_socket *sock;
 858         ipx_packet *ipx;
 859         ipx_route *rt;
 860         ipx_route *ln;
 861         unsigned char IPXaddr[6];
 862         
 863         ipx=(ipx_packet *)skb->h.raw;
 864         
 865         if(ipx->ipx_checksum!=IPX_NO_CHECKSUM)
 866         {
 867                 /* We don't do checksum options. We can't really. Novell don't seem to have documented them.
 868                    If you need them try the XNS checksum since IPX is basically XNS in disguise. It might be
 869                    the same... */
 870                 kfree_skb(skb,FREE_READ);
 871                 return(0);
 872         }
 873         
 874         /* Too small */
 875         if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet))
 876         {
 877                 kfree_skb(skb,FREE_READ);
 878                 return(0);
 879         }
 880         
 881         /* Too many hops */
 882         if(ipx->ipx_tctrl>16)
 883         {
 884                 kfree_skb(skb,FREE_READ);
 885                 return(0);
 886         }
 887         
 888         /* Determine what local ipx endpoint this is */
 889         ln = ipxrtr_get_local_net(dev, pt->type);
 890         if (ln == NULL) 
 891         {
 892                 kfree_skb(skb,FREE_READ);
 893                 return(0);
 894         }
 895 
 896         memset(IPXaddr, '\0', 6);
 897         memcpy(IPXaddr+(6 - dev->addr_len), dev->dev_addr, dev->addr_len);
 898 
 899         /* Not us/broadcast */
 900         if(memcmp(IPXaddr,ipx->ipx_dest.node,6)!=0
 901              && memcmp(ipx_broadcast_node,ipx->ipx_dest.node,6)!=0)
 902         {
 903                 /**********************************************************************************************
 904                 
 905                         IPX router. Roughly as per the Novell spec. This doesn't handle netbios flood fill
 906                         broadcast frames. See the Novell IPX router specification for more details
 907                         (for ftp from ftp.novell.com)
 908                         
 909                 ***********************************************************************************************/
 910                 
 911                 int incoming_size;
 912                 int outgoing_size;
 913                 struct sk_buff *skb2;
 914                 int free_it=0;
 915                 
 916                 /* Rule: Don't forward packets that have exceeded the hop limit. This is fixed at 16 in IPX */
 917                 if((ipx->ipx_tctrl==16) || (skb->pkt_type!=PACKET_HOST))
 918                 {
 919                         kfree_skb(skb,FREE_READ);
 920                         return(0);
 921                 }
 922 
 923                 ipx->ipx_tctrl++;
 924                 /* Don't forward if we don't have a route. We ought to go off and start hunting out routes but
 925                    if someone needs this _THEY_ can add it */           
 926                 rt=ipxrtr_get_dev(ipx->ipx_dest.net);
 927                 if(rt==NULL)   /* Unlike IP we can send on the interface we received. Eg doing DIX/802.3 conversion */
 928                 {
 929                         kfree_skb(skb,FREE_READ);
 930                         return(0);
 931                 }
 932 
 933                 /*
 934                  *      Ok, before we forward, make sure this is not a local packet on the 
 935                  *      other network 
 936                  */
 937                 if (rt->router_net == 0) 
 938                 {
 939                         memset(IPXaddr,'\0',6);
 940                         memcpy(IPXaddr+(6-rt->dev->addr_len),rt->dev->dev_addr,rt->dev->addr_len);
 941                         if (memcmp(IPXaddr,ipx->ipx_dest.node,6) == 0) 
 942                                 goto DELIVER;
 943                 }
 944         
 945                 /* Check for differences in outgoing and incoming packet size */
 946                 incoming_size = skb->len - ntohs(ipx->ipx_pktsize);
 947                 outgoing_size = rt->datalink->header_length + rt->dev->hard_header_len;
 948                 if(incoming_size != outgoing_size)
 949                 {
 950                         /* A different header length causes a copy. Awkward to avoid with the current
 951                            sk_buff stuff. */
 952                         skb2=alloc_skb(ntohs(ipx->ipx_pktsize) + outgoing_size,
 953                                         GFP_ATOMIC);
 954                         if(skb2==NULL)
 955                         {
 956                                 kfree_skb(skb,FREE_READ);
 957                                 return 0;
 958                         }
 959                         free_it=1;
 960                         skb2->len=ntohs(ipx->ipx_pktsize) + outgoing_size;
 961                         skb2->mem_addr = skb2;
 962                         skb2->sk = NULL;
 963                         skb2->free = 1;
 964                         skb2->arp = 1;
 965                         skb2->len = ntohs(ipx->ipx_pktsize) + outgoing_size;
 966 
 967                         /*
 968                          *      NOTE: src arg for memcpy used to be (skb+1)+insize
 969                          *      however, that doesn't work... (dunno why)
 970                          *      it should though...
 971                          */
 972                         
 973                         memcpy((char *)(skb2+1)+outgoing_size,ipx,
 974                                 ntohs(ipx->ipx_pktsize));
 975                 }
 976                 else
 977                 {
 978                         skb2=skb;
 979                 }
 980 
 981                 /* Now operate on the buffer */
 982                 /* Increase hop count */
 983                 
 984                 skb2->dev = rt->dev;
 985                 rt->datalink->datalink_header(rt->datalink, skb2, 
 986                         (rt->flags&IPX_RT_ROUTED)?rt->router_node
 987                                                 :ipx->ipx_dest.node);
 988 
 989                 dev_queue_xmit(skb2,rt->dev,SOPRI_NORMAL);
 990 
 991                 if(free_it)
 992                         kfree_skb(skb,FREE_READ);
 993                 return(0);
 994         }
 995         /************ End of router: Now sanity check stuff for us ***************/
 996 DELIVER:        
 997         /* Ok its for us ! */
 998         if (ln->net == 0L) {
 999 /*              printk("IPX: Registering local net %lx\n", ipx->ipx_dest.net);*/
1000                 ln->net = ipx->ipx_dest.net;
1001         }
1002 
1003         sock=ipx_find_socket(ipx->ipx_dest.sock);
1004         if(sock==NULL)  /* But not one of our sockets */
1005         {
1006                 kfree_skb(skb,FREE_READ);
1007                 return(0);
1008         }
1009 
1010         /* Check to see if this socket needs its network number */
1011         ln = ipxrtr_get_default_net();
1012         if (sock->ipx_source_addr.net == 0L)
1013                 sock->ipx_source_addr.net = ln->net;
1014         
1015         if(sock_queue_rcv_skb(sock, skb)<0)
1016         {
1017                 kfree_skb(skb,FREE_READ);       /* Socket is full */
1018                 return(0);
1019         }
1020         
1021         return(0);
1022 }
1023 
1024 static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1025         unsigned flags, struct sockaddr *usip, int addr_len)
1026 {
1027         ipx_socket *sk=(ipx_socket *)sock->data;
1028         struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)usip;
1029         struct sockaddr_ipx local_sipx;
1030         struct sk_buff *skb;
1031         struct device *dev;
1032         struct ipx_packet *ipx;
1033         int size;
1034         ipx_route *rt;
1035         struct datalink_proto *dl = NULL;
1036         unsigned char IPXaddr[6];
1037         int self_addressing = 0;
1038         int broadcast = 0;
1039 
1040         if(flags)
1041                 return -EINVAL;
1042                 
1043         if(usipx)
1044         {
1045                 if(sk->ipx_source_addr.net==0)
1046                 /* put the autobinding in */
1047                 {
1048                         struct sockaddr_ipx uaddr;
1049                         int ret;
1050 
1051                         uaddr.sipx_port = 0;
1052                         uaddr.sipx_network = 0L; 
1053                         ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
1054                         if (ret != 0) return (ret);
1055                 }
1056 
1057                 if(addr_len <sizeof(*usipx))
1058                         return(-EINVAL);
1059                 if(usipx->sipx_family != AF_IPX)
1060                         return -EINVAL;
1061                 if(htons(usipx->sipx_port)<0x4000 && !suser())
1062                         return -EPERM;
1063         }
1064         else
1065         {
1066                 if(sk->state!=TCP_ESTABLISHED)
1067                         return -ENOTCONN;
1068                 usipx=&local_sipx;
1069                 usipx->sipx_family=AF_IPX;
1070                 usipx->sipx_type=sk->ipx_type;
1071                 usipx->sipx_port=sk->ipx_dest_addr.sock;
1072                 usipx->sipx_network=sk->ipx_dest_addr.net;
1073                 memcpy(usipx->sipx_node,sk->ipx_dest_addr.node,sizeof(usipx->sipx_node));
1074         }
1075         
1076         if(sk->debug)
1077                 printk("IPX: sendto: Addresses built.\n");
1078 
1079         if(memcmp(&usipx->sipx_node,&ipx_broadcast_node,6)==0) 
1080         {
1081                 if (!sk->broadcast)
1082                         return -ENETUNREACH;
1083                 broadcast = 1;
1084         }
1085 
1086         /* Build a packet */
1087         
1088         if(sk->debug)
1089                 printk("IPX: sendto: building packet.\n");
1090                 
1091         size=sizeof(ipx_packet)+len;    /* For mac headers */
1092 
1093         /* Find out where this has to go */
1094         if (usipx->sipx_network == 0L) {
1095                 rt = ipxrtr_get_default_net();
1096                 if (rt != NULL)
1097                         usipx->sipx_network = rt->net;
1098         } else
1099                 rt=ipxrtr_get_dev(usipx->sipx_network);
1100 
1101         if(rt==NULL)
1102         {
1103                 return -ENETUNREACH;
1104         }
1105         
1106         dev=rt->dev;
1107         dl = rt->datalink;
1108         
1109         size += dev->hard_header_len;
1110         size += dl->header_length;
1111 
1112         if(sk->debug)
1113                 printk("IPX: sendto: allocating buffer (%d)\n",size);
1114         
1115         if(size+sk->wmem_alloc>sk->sndbuf) {
1116                 return -EAGAIN;
1117         }
1118                 
1119         skb=alloc_skb(size,GFP_KERNEL);
1120         if(skb==NULL)
1121                 return -ENOMEM;
1122                 
1123         skb->mem_addr=skb;
1124         skb->sk=sk;
1125         skb->free=1;
1126         skb->arp=1;
1127         skb->len=size;
1128 
1129         sk->wmem_alloc+=skb->mem_len;
1130 
1131         if(sk->debug)
1132                 printk("Building MAC header.\n");               
1133         skb->dev=rt->dev;
1134         
1135         /* Build Data Link header */
1136         dl->datalink_header(dl, skb, 
1137                 (rt->flags&IPX_RT_ROUTED)?rt->router_node:usipx->sipx_node);
1138 
1139         /* See if we are sending to ourself */
1140         memset(IPXaddr, '\0', 6);
1141         memcpy(IPXaddr+(6 - skb->dev->addr_len), skb->dev->dev_addr, 
1142                         skb->dev->addr_len);
1143 
1144         self_addressing = !memcmp(IPXaddr, 
1145                                 (rt->flags&IPX_RT_ROUTED)?rt->router_node
1146                                 :usipx->sipx_node,
1147                                 6);
1148 
1149         /* Now the IPX */
1150         if(sk->debug)
1151                 printk("Building IPX Header.\n");
1152         ipx=(ipx_packet *)skb->h.raw;
1153         ipx->ipx_checksum=0xFFFF;
1154         ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
1155         ipx->ipx_tctrl=0;
1156         ipx->ipx_type=usipx->sipx_type;
1157 
1158         memcpy(&ipx->ipx_source,&sk->ipx_source_addr,sizeof(ipx->ipx_source));
1159         ipx->ipx_dest.net=usipx->sipx_network;
1160         memcpy(ipx->ipx_dest.node,usipx->sipx_node,sizeof(ipx->ipx_dest.node));
1161         ipx->ipx_dest.sock=usipx->sipx_port;
1162         if(sk->debug)
1163                 printk("IPX: Appending user data.\n");
1164         /* User data follows immediately after the IPX data */
1165         memcpy_fromfs((char *)(ipx+1),ubuf,len);
1166         if(sk->debug)
1167                 printk("IPX: Transmitting buffer\n");
1168         if((dev->flags&IFF_LOOPBACK) || self_addressing) {
1169                 struct packet_type      pt;
1170 
1171                 /* loop back */
1172                 pt.type = rt->dlink_type;
1173                 sk->wmem_alloc-=skb->mem_len;
1174                 skb->sk = NULL;
1175                 ipx_rcv(skb,dev,&pt);
1176         } else {
1177                 if (broadcast) {
1178                         struct packet_type      pt;
1179                         struct sk_buff          *skb2;
1180 
1181                         /* loop back */
1182                         pt.type = rt->dlink_type;
1183                         
1184                         skb2=alloc_skb(skb->len, GFP_ATOMIC);
1185                         skb2->mem_addr=skb2;
1186                         skb2->free=1;
1187                         skb2->arp=1;
1188                         skb2->len=skb->len;
1189                         skb2->sk = NULL;
1190                         skb2->h.raw = skb2->data + rt->datalink->header_length
1191                                 + dev->hard_header_len;
1192                         memcpy(skb2->data, skb->data, skb->len);
1193                         ipx_rcv(skb2,dev,&pt);
1194                 }
1195                 dev_queue_xmit(skb,dev,SOPRI_NORMAL);
1196         }
1197         return len;
1198 }
1199 
1200 static int ipx_send(struct socket *sock, void *ubuf, int size, int noblock, unsigned flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1201 {
1202         return ipx_sendto(sock,ubuf,size,noblock,flags,NULL,0);
1203 }
1204 
1205 static int ipx_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1206                    unsigned flags, struct sockaddr *sip, int *addr_len)
1207 {
1208         ipx_socket *sk=(ipx_socket *)sock->data;
1209         struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)sip;
1210         struct ipx_packet       *ipx = NULL;
1211         /* FILL ME IN */
1212         int copied = 0;
1213         struct sk_buff *skb;
1214         int er;
1215         
1216         if(sk->err)
1217         {
1218                 er= -sk->err;
1219                 sk->err=0;
1220                 return er;
1221         }
1222         
1223         if(addr_len)
1224                 *addr_len=sizeof(*sipx);
1225 
1226         skb=skb_recv_datagram(sk,flags,noblock,&er);
1227         if(skb==NULL)
1228                 return er;
1229 
1230         ipx = (ipx_packet *)(skb->h.raw);
1231         copied=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
1232         skb_copy_datagram(skb,sizeof(struct ipx_packet),ubuf,copied);
1233         
1234         if(sipx)
1235         {
1236                 sipx->sipx_family=AF_IPX;
1237                 sipx->sipx_port=ipx->ipx_source.sock;
1238                 memcpy(sipx->sipx_node,ipx->ipx_source.node,sizeof(sipx->sipx_node));
1239                 sipx->sipx_network=ipx->ipx_source.net;
1240                 sipx->sipx_type = ipx->ipx_type;
1241         }
1242         skb_free_datagram(skb);
1243         return(copied);
1244 }               
1245 
1246 
1247 static int ipx_write(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1248 {
1249         return ipx_send(sock,ubuf,size,noblock,0);
1250 }
1251 
1252 
1253 static int ipx_recv(struct socket *sock, void *ubuf, int size , int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
1254         unsigned flags)
1255 {
1256         ipx_socket *sk=(ipx_socket *)sock->data;
1257         if(sk->zapped)
1258                 return -ENOTCONN;
1259         return ipx_recvfrom(sock,ubuf,size,noblock,flags,NULL, NULL);
1260 }
1261 
1262 static int ipx_read(struct socket *sock, char *ubuf, int size, int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1263 {
1264         return ipx_recv(sock,ubuf,size,noblock,0);
1265 }
1266 
1267 
1268 static int ipx_shutdown(struct socket *sk,int how)
     /* [previous][next][first][last][top][bottom][index][help] */
1269 {
1270         return -EOPNOTSUPP;
1271 }
1272 
1273 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1274 {
1275         ipx_socket *sk=(ipx_socket *)sock->data;
1276         
1277         return datagram_select(sk,sel_type,wait);
1278 }
1279 
1280 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1281 {
1282         int err;
1283         long amount=0;
1284         ipx_socket *sk=(ipx_socket *)sock->data;
1285         
1286         switch(cmd)
1287         {
1288                 case TIOCOUTQ:
1289                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1290                         if(err)
1291                                 return err;
1292                         amount=sk->sndbuf-sk->wmem_alloc;
1293                         if(amount<0)
1294                                 amount=0;
1295                         put_fs_long(amount,(unsigned long *)arg);
1296                         return 0;
1297                 case TIOCINQ:
1298                 {
1299                         struct sk_buff *skb;
1300                         /* These two are safe on a single CPU system as only user tasks fiddle here */
1301                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
1302                                 amount=skb->len;
1303                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1304                         put_fs_long(amount,(unsigned long *)arg);
1305                         return 0;
1306                 }
1307                 case SIOCADDRT:
1308                 case SIOCDELRT:
1309                         if(!suser())
1310                                 return -EPERM;
1311                         return(ipxrtr_ioctl(cmd,(void *)arg));
1312                 case SIOCGSTAMP:
1313                         if (sk)
1314                         {
1315                                 if(sk->stamp.tv_sec==0)
1316                                         return -ENOENT;
1317                                 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
1318                                 if(err)
1319                                         return err;
1320                                         memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
1321                                 return 0;
1322                         }
1323                         return -EINVAL;
1324                 case SIOCGIFCONF:
1325                 case SIOCGIFFLAGS:
1326                 case SIOCSIFFLAGS:
1327                 case SIOCGIFADDR:
1328                 case SIOCSIFADDR:
1329                 case SIOCGIFDSTADDR:
1330                 case SIOCSIFDSTADDR:
1331                 case SIOCGIFBRDADDR:
1332                 case SIOCSIFBRDADDR:
1333                 case SIOCGIFNETMASK:
1334                 case SIOCSIFNETMASK:
1335                 case SIOCGIFMETRIC:
1336                 case SIOCSIFMETRIC:
1337                 case SIOCGIFMEM:
1338                 case SIOCSIFMEM:
1339                 case SIOCGIFMTU:
1340                 case SIOCSIFMTU:
1341                 case SIOCSIFLINK:
1342                 case SIOCGIFHWADDR:
1343                 case SIOCSIFHWADDR:
1344                 case OLD_SIOCGIFHWADDR:
1345                         return(dev_ioctl(cmd,(void *) arg));
1346 
1347 
1348                 default:
1349                         return -EINVAL;
1350         }
1351         /*NOTREACHED*/
1352         return(0);
1353 }
1354 
1355 static struct proto_ops ipx_proto_ops = {
1356         AF_IPX,
1357         
1358         ipx_create,
1359         ipx_dup,
1360         ipx_release,
1361         ipx_bind,
1362         ipx_connect,
1363         ipx_socketpair,
1364         ipx_accept,
1365         ipx_getname,
1366         ipx_read,
1367         ipx_write,
1368         ipx_select,
1369         ipx_ioctl,
1370         ipx_listen,
1371         ipx_send,
1372         ipx_recv,
1373         ipx_sendto,
1374         ipx_recvfrom,
1375         ipx_shutdown,
1376         ipx_setsockopt,
1377         ipx_getsockopt,
1378         ipx_fcntl,
1379 };
1380 
1381 /* Called by ddi.c on kernel start up */
1382 
1383 static struct packet_type ipx_8023_packet_type = 
1384 
1385 {
1386         0,      /* MUTTER ntohs(ETH_P_8023),*/
1387         0,              /* copy */
1388         ipx_rcv,
1389         NULL,
1390         NULL,
1391 };
1392  
1393 static struct packet_type ipx_dix_packet_type = 
1394 {
1395         0,      /* MUTTER ntohs(ETH_P_IPX),*/
1396         NULL,           /* Al devices */
1397         ipx_rcv,
1398         NULL,
1399         NULL,
1400 };
1401  
1402 static struct notifier_block ipx_dev_notifier={
1403         ipxrtr_device_event,
1404         NULL,
1405         0
1406 };
1407 
1408 
1409 extern struct datalink_proto    *make_EII_client(void);
1410 extern struct datalink_proto    *make_8023_client(void);
1411 
1412 void ipx_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1413 {
1414         unsigned char   val = 0xE0;
1415         (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
1416 
1417         pEII_datalink = make_EII_client();
1418         ipx_dix_packet_type.type=htons(ETH_P_IPX);
1419         dev_add_pack(&ipx_dix_packet_type);
1420 
1421         p8023_datalink = make_8023_client();
1422         ipx_8023_packet_type.type=htons(ETH_P_802_3);
1423         dev_add_pack(&ipx_8023_packet_type);
1424         
1425         if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
1426                 printk("IPX: Unable to register with 802.2\n");
1427 
1428         register_netdevice_notifier(&ipx_dev_notifier);
1429                 
1430         printk("Swansea University Computer Society IPX 0.29 BETA for NET3.019\n");
1431         
1432 }
1433 #endif

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