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

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