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

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