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

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