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

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