root/drivers/net/slip.c

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

DEFINITIONS

This source file includes following definitions.
  1. ip_dump
  2. clh_dump
  3. sl_initialize
  4. sl_find
  5. sl_alloc
  6. sl_free
  7. sl_changedmtu
  8. sl_enqueue
  9. sl_dequeue
  10. sl_lock
  11. sl_unlock
  12. sl_bump
  13. sl_next
  14. sl_encaps
  15. sl_xmit
  16. sl_type_trans
  17. sl_header
  18. sl_add_arp
  19. sl_rebuild_header
  20. sl_open
  21. sl_close
  22. slip_recv
  23. slip_open
  24. slip_close
  25. slip_esc
  26. slip_unesc
  27. slip_esc6
  28. slip_unesc6
  29. sl_set_mac_address
  30. slip_ioctl
  31. slip_init

   1 /*
   2  * slip.c       This module implements the SLIP protocol for kernel-based
   3  *              devices like TTY.  It interfaces between a raw TTY, and the
   4  *              kernel's INET protocol layers (via DDI).
   5  *
   6  * Version:     @(#)slip.c      0.7.6   05/25/93
   7  *
   8  * Authors:     Laurence Culhane, <loz@holmes.demon.co.uk>
   9  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  10  *
  11  * Fixes:
  12  *              Alan Cox        :       Sanity checks and avoid tx overruns.
  13  *                                      Has a new sl->mtu field.
  14  *              Alan Cox        :       Found cause of overrun. ifconfig sl0 mtu upwards.
  15  *                                      Driver now spots this and grows/shrinks its buffers(hack!).
  16  *                                      Memory leak if you run out of memory setting up a slip driver fixed.
  17  *              Matt Dillon     :       Printable slip (borrowed from NET2E)
  18  *      Pauline Middelink       :       Slip driver fixes.
  19  *              Alan Cox        :       Honours the old SL_COMPRESSED flag
  20  *              Alan Cox        :       KISS AX.25 and AXUI IP support
  21  */
  22  
  23 #include <asm/segment.h>
  24 #include <asm/system.h>
  25 
  26 #include <linux/config.h>
  27 #include <linux/types.h>
  28 #include <linux/kernel.h>
  29 #include <linux/sched.h>
  30 #include <linux/string.h>
  31 #include <linux/mm.h>
  32 #include <linux/socket.h>
  33 #include <linux/termios.h>
  34 #include <linux/sockios.h>
  35 #include <linux/interrupt.h>
  36 #include <linux/tty.h>
  37 #include <linux/errno.h>
  38 #include <linux/stat.h>
  39 #include <linux/tty.h>
  40 #include <linux/in.h>
  41 #include "inet.h"
  42 #include "dev.h"
  43 #ifdef CONFIG_AX25
  44 #include "ax25.h"
  45 #endif
  46 #include "eth.h"
  47 #include "ip.h"
  48 #include "route.h"
  49 #include "protocol.h"
  50 #include "tcp.h"
  51 #include "skbuff.h"
  52 #include "sock.h"
  53 #include "arp.h"
  54 #include "slip.h"
  55 #include "slhc.h"
  56 
  57 #define SLIP_VERSION    "0.7.5"
  58 
  59 /* Define some IP layer stuff.  Not all systems have it. */
  60 #ifdef SL_DUMP
  61 #   define      IP_VERSION      4       /* version# of our IP software  */
  62 #   define      IPF_F_OFFSET    0x1fff  /* Offset field                 */
  63 #   define      IPF_DF          0x4000  /* Don't fragment flag          */
  64 #   define      IPF_MF          0x2000  /* More Fragments flag          */
  65 #   define      IP_OF_COPIED    0x80    /* Copied-on-fragmentation flag */
  66 #   define      IP_OF_CLASS     0x60    /* Option class                 */
  67 #   define      IP_OF_NUMBER    0x1f    /* Option number                */
  68 #endif
  69 
  70 
  71 static struct slip      sl_ctrl[SL_NRUNIT];
  72 static struct tty_ldisc sl_ldisc;
  73 static int              already = 0;
  74 
  75 
  76 /* Dump the contents of an IP datagram. */
  77 static void
  78 ip_dump(unsigned char *ptr, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80 #ifdef SL_DUMP
  81   struct iphdr *ip;
  82   struct tcphdr *th;
  83   int dlen, doff;
  84 
  85   if (inet_debug != DBG_SLIP) return;
  86 
  87   ip = (struct iphdr *) ptr;
  88   th = (struct tcphdr *) (ptr + ip->ihl * 4);
  89   printk("\r%s -> %s seq %lx ack %lx len %d\n",
  90          in_ntoa(ip->saddr), in_ntoa(ip->daddr), 
  91          ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
  92   return;
  93 
  94   printk("\r*****\n");
  95   printk("%p %d\n", ptr, len);
  96   ip = (struct iphdr *) ptr;
  97   dlen = ntohs(ip->tot_len);
  98   doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);
  99 
 100 
 101   printk("SLIP: %s->", in_ntoa(ip->saddr));
 102   printk("%s\n", in_ntoa(ip->daddr));
 103   printk(" len %u ihl %u ver %u ttl %u prot %u",
 104         dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);
 105 
 106   if (ip->tos != 0) printk(" tos %u", ip->tos);
 107   if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
 108         printk(" id %u offs %u", ntohs(ip->id), doff);
 109 
 110   if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
 111   if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
 112   printk("\n*****\n");
 113 #endif
 114 }
 115 
 116 #if 0
 117 void clh_dump(unsigned char *cp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119   if (len > 60)
 120     len = 60;
 121   printk("%d:", len);
 122   while (len > 0) {
 123     printk(" %x", *cp++);
 124     len--;
 125   }
 126   printk("\n\n");
 127 }
 128 #endif
 129 
 130 /* Initialize a SLIP control block for use. */
 131 static void
 132 sl_initialize(struct slip *sl, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134   sl->inuse             = 0;
 135   sl->sending           = 0;
 136   sl->escape            = 0;
 137   sl->flags             = 0;
 138 #ifdef SL_COMPRESSED
 139   sl->mode              = SL_MODE_CSLIP;        /* Default */
 140 #else
 141   sl->mode              = SL_MODE_SLIP;         /* Default for non compressors */
 142 #endif  
 143 
 144   sl->line              = dev->base_addr;
 145   sl->tty               = NULL;
 146   sl->dev               = dev;
 147   sl->slcomp            = NULL;
 148 
 149   /* Clear all pointers. */
 150   sl->rbuff             = NULL;
 151   sl->xbuff             = NULL;
 152   sl->cbuff             = NULL;
 153 
 154   sl->rhead             = NULL;
 155   sl->rend              = NULL;
 156   dev->rmem_end         = (unsigned long) NULL;
 157   dev->rmem_start       = (unsigned long) NULL;
 158   dev->mem_end          = (unsigned long) NULL;
 159   dev->mem_start        = (unsigned long) NULL;
 160 }
 161 
 162 
 163 /* Find a SLIP channel from its `tty' link. */
 164 static struct slip *
 165 sl_find(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167   struct slip *sl;
 168   int i;
 169 
 170   if (tty == NULL) return(NULL);
 171   for (i = 0; i < SL_NRUNIT; i++) {
 172         sl = &sl_ctrl[i];
 173         if (sl->tty == tty) return(sl);
 174   }
 175   return(NULL);
 176 }
 177 
 178 
 179 /* Find a free SLIP channel, and link in this `tty' line. */
 180 static inline struct slip *
 181 sl_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183   unsigned long flags;
 184   struct slip *sl;
 185   int i;
 186 
 187   save_flags (flags);
 188   cli();
 189   for (i = 0; i < SL_NRUNIT; i++) {
 190         sl = &sl_ctrl[i];
 191         if (sl->inuse == 0) {
 192                 sl->inuse = 1;
 193                 sl->tty = NULL;
 194                 restore_flags(flags);
 195                 return(sl);
 196         }
 197   }
 198   restore_flags(flags);
 199   return(NULL);
 200 }
 201 
 202 
 203 /* Free a SLIP channel. */
 204 static inline void
 205 sl_free(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207   unsigned long flags;
 208 
 209   if (sl->inuse) {
 210         save_flags(flags);
 211         cli();
 212         sl->inuse = 0;
 213         sl->tty = NULL;
 214         restore_flags(flags);
 215   }
 216 }
 217 
 218 /* MTU has been changed by the IP layer. Unfortunately we are not told about this, but
 219    we spot it ourselves and fix things up. We could be in an upcall from the tty
 220    driver, or in an ip packet queue. */
 221    
 222 static void sl_changedmtu(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224         struct device *dev=sl->dev;
 225         unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
 226         int l;
 227         int omtu=sl->mtu;
 228         
 229         sl->mtu=dev->mtu;
 230         l=(dev->mtu *2);
 231         
 232         DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n"));
 233         
 234         tb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 235         rb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 236         cb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 237         
 238         if(tb==NULL || rb==NULL || cb==NULL)
 239         {
 240                 printk("Unable to grow slip buffers. MTU change cancelled.\n");
 241                 sl->mtu=omtu;
 242                 dev->mtu=omtu;
 243                 if(tb!=NULL)
 244                         kfree(tb);
 245                 if(rb!=NULL)
 246                         kfree(rb);
 247                 if(cb!=NULL)
 248                         kfree(cb);
 249                 return;
 250         }
 251         
 252         cli();
 253         
 254         tf=(unsigned char *)sl->dev->mem_start;
 255         sl->dev->mem_start=(unsigned long)tb;
 256         sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
 257         rf=(unsigned char *)sl->dev->rmem_start;
 258         sl->dev->rmem_start=(unsigned long)rb;
 259         sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
 260         
 261         sl->xbuff = (unsigned char *) sl->dev->mem_start;
 262         sl->rbuff = (unsigned char *) sl->dev->rmem_start;
 263         sl->rend  = (unsigned char *) sl->dev->rmem_end;
 264         sl->rhead = sl->rbuff;
 265         
 266         cf=sl->cbuff;
 267         sl->cbuff=cb;
 268         
 269         sl->escape=0;
 270         sl->sending=0;
 271         sl->rcount=0;
 272 
 273         sti();  
 274         
 275         if(rf!=NULL)
 276                 kfree(rf);
 277         if(tf!=NULL)
 278                 kfree(tf);
 279         if(cf!=NULL)
 280                 kfree(cf);
 281 }
 282 
 283 
 284 /* Stuff one byte into a SLIP receiver buffer. */
 285 static inline void
 286 sl_enqueue(struct slip *sl, unsigned char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288   unsigned long flags;
 289 
 290   save_flags(flags);
 291   cli();
 292   if (sl->rhead < sl->rend) {
 293         *sl->rhead = c;
 294         sl->rhead++;
 295         sl->rcount++;
 296   } else sl->roverrun++;
 297   restore_flags(flags);
 298 }
 299 
 300 /* Release 'i' bytes from a SLIP receiver buffer. */
 301 static inline void
 302 sl_dequeue(struct slip *sl, int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304   unsigned long flags;
 305 
 306   save_flags(flags);
 307   cli();
 308   if (sl->rhead > sl->rbuff) {
 309         sl->rhead -= i;
 310         sl->rcount -= i;
 311   }
 312   restore_flags(flags);
 313 }
 314 
 315 
 316 /* Set the "sending" flag.  This must be atomic, hence the ASM. */
 317 static inline void
 318 sl_lock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320   unsigned long flags;
 321 
 322   save_flags(flags);
 323   cli();
 324   sl->sending = 1;
 325   sl->dev->tbusy = 1;
 326   restore_flags(flags);
 327 }
 328 
 329 
 330 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
 331 static inline void
 332 sl_unlock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334   unsigned long flags;
 335 
 336   save_flags(flags);
 337   cli();
 338   sl->sending = 0;
 339   sl->dev->tbusy = 0;
 340   restore_flags(flags);
 341 }
 342 
 343 
 344 /* Send one completely decapsulated IP datagram to the IP layer. */
 345 static void
 346 sl_bump(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 347 {
 348   int done;
 349   unsigned char c;
 350   unsigned long flags;
 351   int count;
 352 
 353   count = sl->rcount;
 354   if (sl->mode & SL_MODE_CSLIP) {
 355     if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
 356       /* make sure we've reserved enough space for uncompress to use */
 357       save_flags(flags);
 358       cli();
 359       if ((sl->rhead + 80) < sl->rend) {
 360         sl->rhead += 80;
 361         sl->rcount += 80;
 362         done = 1;
 363       } else {
 364         sl->roverrun++;
 365         done = 0;
 366       }
 367       restore_flags(flags);
 368       if (! done)  /* not enough space available */
 369         return;
 370 
 371       count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
 372       if (count <= 0) {
 373         sl->errors++;
 374         return;
 375       }
 376     } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
 377       sl->rbuff[0] &= 0x4f;
 378       if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
 379         sl->errors++;
 380         return;
 381       }
 382     }
 383   }
 384 
 385   DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
 386   ip_dump(sl->rbuff, sl->rcount);
 387 
 388   /* Bump the datagram to the upper layers... */
 389   do {
 390         DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
 391                                         sl->rcount, sl->rbuff));
 392         /* clh_dump(sl->rbuff, count); */
 393         done = dev_rint(sl->rbuff, count, 0, sl->dev);
 394         if (done == 0 || done == 1) break;
 395   } while(1);
 396 
 397   sl->rpacket++;
 398 }
 399 
 400 
 401 /* TTY finished sending a datagram, so clean up. */
 402 static void
 403 sl_next(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 404 {
 405   DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
 406   sl_unlock(sl);
 407   dev_tint(sl->dev);
 408 }
 409 
 410 
 411 /* Encapsulate one IP datagram and stuff into a TTY queue. */
 412 static void
 413 sl_encaps(struct slip *sl, unsigned char *icp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 414 {
 415   unsigned char *bp, *p;
 416   int count;
 417 
 418   DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", icp, len));
 419   DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
 420   
 421   ip_dump(icp, len);
 422   
 423   if(sl->mtu != sl->dev->mtu)   /* Someone has been ifconfigging */
 424         sl_changedmtu(sl);
 425   
 426   if(len>sl->mtu)               /* Sigh, shouldn't occur BUT ... */
 427   {
 428         len=sl->mtu;
 429         printk("slip: truncating oversized transmit packet!\n");
 430   }
 431 
 432   p = icp;
 433   if(sl->mode & SL_MODE_CSLIP)
 434           len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
 435 
 436 #ifdef OLD  
 437   /*
 438    * Send an initial END character to flush out any
 439    * data that may have accumulated in the receiver
 440    * due to line noise.
 441    */
 442   bp = sl->xbuff;
 443   *bp++ = END;
 444   count = 1;
 445 
 446   /*
 447    * For each byte in the packet, send the appropriate
 448    * character sequence, according to the SLIP protocol.
 449    */
 450   while(len-- > 0) {
 451         c = *p++;
 452         switch(c) {
 453                 case END:
 454                         *bp++ = ESC;
 455                         *bp++ = ESC_END;
 456                         count += 2;
 457                         break;
 458                 case ESC:
 459                         *bp++ = ESC;
 460                         *bp++ = ESC_ESC;
 461                         count += 2;
 462                         break;
 463                 default:
 464                         *bp++ = c;
 465                         count++;
 466         }
 467   }
 468   *bp++ = END;  
 469   count++;
 470 #else
 471   if(sl->mode & SL_MODE_SLIP6)
 472         count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
 473   else
 474         count=slip_esc(p, (unsigned char *)sl->xbuff,len);
 475 #endif            
 476   sl->spacket++;
 477   bp = sl->xbuff;
 478 
 479   /* Tell TTY to send it on its way. */
 480   DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
 481   if (tty_write_data(sl->tty, (char *) bp, count,
 482              (void (*)(void *))sl_next, (void *) sl) == 0) {
 483         DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
 484         sl_next(sl);
 485   }
 486 }
 487 
 488 
 489 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 490 static int
 491 sl_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493   struct tty_struct *tty;
 494   struct slip *sl;
 495 
 496   /* Find the correct SLIP channel to use. */
 497   sl = &sl_ctrl[dev->base_addr];
 498   tty = sl->tty;
 499   DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
 500                                 dev->name, skb, sl->sending));
 501 
 502   /*
 503    * If we are busy already- too bad.  We ought to be able
 504    * to queue things at this point, to allow for a little
 505    * frame buffer.  Oh well...
 506    */
 507   if (sl->sending) {
 508         DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
 509         sl->sbusy++;
 510         return(1);
 511   }
 512 
 513   /* We were not, so we are now... :-) */
 514   if (skb != NULL) {
 515 #ifdef CONFIG_AX25  
 516         if(sl->mode & SL_MODE_AX25)
 517         {
 518                 if(!skb->arp && dev->rebuild_header(skb+1,dev))
 519                 {
 520                         skb->dev=dev;
 521                         arp_queue(skb);
 522                         return 0;
 523                 }
 524                 skb->arp=1;
 525         }
 526 #endif          
 527         sl_lock(sl);
 528         sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
 529         if (skb->free) kfree_skb(skb, FREE_WRITE);
 530   }
 531   return(0);
 532 }
 533 
 534 
 535 /* Return the frame type ID.  This is normally IP but maybe be AX.25. */
 536 static unsigned short
 537 sl_type_trans (struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539 #ifdef CONFIG_AX25
 540         struct slip *sl=&sl_ctrl[dev->base_addr];
 541         if(sl->mode&SL_MODE_AX25)
 542                 return(NET16(ETH_P_AX25));
 543 #endif
 544   return(NET16(ETH_P_IP));
 545 }
 546 
 547 
 548 /* Fill in the MAC-level header. Not used by SLIP. */
 549 static int
 550 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
     /* [previous][next][first][last][top][bottom][index][help] */
 551           unsigned long daddr, unsigned long saddr, unsigned len)
 552 {
 553 #ifdef CONFIG_AX25
 554   struct slip *sl=&sl_ctrl[dev->base_addr];
 555   unsigned long flags;
 556   if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
 557   {
 558         /* header is an AX.25 UI frame from us to them */
 559         if(chk_addr(daddr) == IS_BROADCAST)
 560         {
 561                 *buff++=0;
 562                 memcpy(buff,dev->broadcast,dev->addr_len);      /* QST-0 */
 563         }
 564         else
 565         {
 566                 if(type!=ETH_P_IP)
 567                         printk("AX25 Encap: Non IP frame to encapsulate directed\n");
 568                 save_flags(flags);
 569                 cli();
 570                 *buff++=0;      /* KISS DATA */
 571                 memcpy(buff,&daddr,4);  /* In case arp fails */
 572                 if(arp_find(buff,daddr,dev, saddr))
 573                 {
 574                         memcpy(buff+7,&saddr,4);
 575                         buff+=14;
 576                         *buff++=LAPB_UI;        /* UI */
 577                         /* Append a suitable AX.25 PID */
 578                         *buff++=PID_IP; /* AX25 IP */
 579                         restore_flags(flags);
 580                         return ( -dev->hard_header_len);
 581                 }
 582         }
 583         buff[6]&=~LAPB_C;
 584         buff[6]&=~LAPB_E;
 585         buff+=7;
 586         memcpy(buff,dev->dev_addr,dev->addr_len);
 587         buff[6]&=~LAPB_C;
 588         buff[6]|=LAPB_E;
 589         buff+=7;
 590         *buff++=LAPB_UI;        /* UI */
 591         /* Append a suitable AX.25 PID */
 592         switch(type)
 593         {
 594                 case ETH_P_IP:
 595                         *buff++=PID_IP; /* AX25 IP */
 596                         break;
 597                 case ETH_P_ARP:
 598                         *buff++=PID_ARP;
 599                         break;
 600                 default:
 601                         *buff++=0;
 602         }
 603         
 604         return (17);
 605   }
 606 #endif  
 607 
 608   return(0);
 609 }
 610 
 611 
 612 /* Add an ARP-entry for this device's broadcast address. Not used. */
 613 static void
 614 sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 615 {
 616 #ifdef CONFIG_AX25
 617         struct slip *sl=&sl_ctrl[dev->base_addr];
 618         
 619         if(sl->mode&SL_MODE_AX25)
 620                 arp_add(addr,((char *)(skb+1))+8,dev);
 621 #endif          
 622 }
 623 
 624 
 625 /* Rebuild the MAC-level header.  Not used by SLIP. */
 626 static int
 627 sl_rebuild_header(void *buff, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 628 {
 629 #ifdef CONFIG_AX25
 630   struct slip *sl=&sl_ctrl[dev->base_addr];
 631   
 632   if(sl->mode&SL_MODE_AX25)
 633   {
 634         unsigned char *bp=(unsigned char *)buff;
 635         long dest=*(long *)(bp+1);
 636         long src=*(long *)(bp+8);
 637         if(arp_find(bp+1,dest,dev,src))
 638                 return 1;
 639         memcpy(bp+8,dev->dev_addr,7);
 640         bp[7]&=~LAPB_C;
 641         bp[7]&=~LAPB_E;
 642         bp[14]&=~LAPB_C;
 643         bp[14]|=LAPB_E;
 644         return(0);
 645   }
 646 #endif  
 647   return(0);
 648 }
 649 
 650 
 651 /* Open the low-level part of the SLIP channel. Easy! */
 652 static int
 653 sl_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 654 {
 655   struct slip *sl;
 656   unsigned char *p;
 657   unsigned long l;
 658 
 659   sl = &sl_ctrl[dev->base_addr];
 660   if (sl->tty == NULL) {
 661         DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
 662         return(-ENXIO);
 663   }
 664   sl->dev = dev;
 665 
 666   /*
 667    * Allocate the SLIP frame buffers:
 668    *
 669    * mem_end    Top of frame buffers
 670    * mem_start  Start of frame buffers
 671    * rmem_end   Top of RECV frame buffer
 672    * rmem_start Start of RECV frame buffer
 673    */
 674   l = (dev->mtu * 2);
 675   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 676   if (p == NULL) {
 677         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
 678         return(-ENOMEM);
 679   }
 680   
 681   sl->mtu               = dev->mtu;
 682   sl->dev->mem_start    = (unsigned long) p;
 683   sl->dev->mem_end      = (unsigned long) (sl->dev->mem_start + l);
 684 
 685   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 686   if (p == NULL) {
 687         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
 688         return(-ENOMEM);
 689   }
 690   sl->dev->rmem_start   = (unsigned long) p;
 691   sl->dev->rmem_end     = (unsigned long) (sl->dev->rmem_start + l);
 692 
 693   sl->xbuff             = (unsigned char *) sl->dev->mem_start;
 694   sl->rbuff             = (unsigned char *) sl->dev->rmem_start;
 695   sl->rend              = (unsigned char *) sl->dev->rmem_end;
 696   sl->rhead             = sl->rbuff;
 697 
 698   sl->escape            = 0;
 699   sl->sending           = 0;
 700   sl->rcount            = 0;
 701 
 702   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 703   if (p == NULL) {
 704         kfree((unsigned char *)sl->dev->mem_start);
 705         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
 706         return(-ENOMEM);
 707   }
 708   sl->cbuff             = p;
 709 
 710   sl->slcomp = slhc_init(16, 16);
 711   if (sl->slcomp == NULL) {
 712         kfree((unsigned char *)sl->dev->mem_start);
 713         kfree((unsigned char *)sl->dev->rmem_start);
 714         kfree(sl->cbuff);
 715         DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
 716         return(-ENOMEM);
 717   }
 718 
 719   DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
 720   return(0);
 721 }
 722 
 723 
 724 /* Close the low-level part of the SLIP channel. Easy! */
 725 static int
 726 sl_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 727 {
 728   struct slip *sl;
 729 
 730   sl = &sl_ctrl[dev->base_addr];
 731   if (sl->tty == NULL) {
 732         DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
 733         return(-EBUSY);
 734   }
 735   sl_free(sl);
 736 
 737   /* Free all SLIP frame buffers. */
 738   kfree(sl->rbuff);
 739   kfree(sl->xbuff);
 740   kfree(sl->cbuff);
 741   slhc_free(sl->slcomp);
 742 
 743   sl_initialize(sl, dev);
 744 
 745   DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
 746   return(0);
 747 }
 748 
 749 
 750 /*
 751  * Handle the 'receiver data ready' interrupt.
 752  * This function is called by the 'tty_io' module in the kernel when
 753  * a block of SLIP data has been received, which can now be decapsulated
 754  * and sent on to some IP layer for further processing.
 755  */
 756 static void
 757 slip_recv(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 758 {
 759   unsigned char buff[128];
 760   unsigned char *p;
 761   struct slip *sl;
 762   int count, error=0;
 763   
 764   DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
 765   if ((sl = sl_find(tty)) == NULL) return;      /* not connected */
 766 
 767   if(sl->mtu!=sl->dev->mtu)     /* Argh! mtu change time! - costs us the packet part received at the change */
 768         sl_changedmtu(sl);
 769         
 770   /* Suck the bytes out of the TTY queues. */
 771   do {
 772         count = tty_read_raw_data(tty, buff, 128);
 773         if (count <= 0)
 774         {
 775                 count= - count;
 776                 if(count)
 777                         error=1;
 778                 break;
 779         }
 780         p = buff;
 781 #ifdef OLD      
 782         while (count--) {
 783                 c = *p++;
 784                 if (sl->escape) {
 785                         if (c == ESC_ESC)
 786                                 sl_enqueue(sl, ESC);
 787                         else if (c == ESC_END)
 788                                 sl_enqueue(sl, END);
 789                         else
 790                                 printk ("SLIP: received wrong character\n");
 791                         sl->escape = 0;
 792                 } else {
 793                         if (c == ESC)
 794                                 sl->escape = 1;
 795                         else if (c == END) {
 796                                 if (sl->rcount > 2) sl_bump(sl);
 797                                 sl_dequeue(sl, sl->rcount);
 798                                 sl->rcount = 0;
 799                         } else  sl_enqueue(sl, c);
 800                 }
 801         }
 802 #else
 803         if(sl->mode & SL_MODE_SLIP6)
 804                 slip_unesc6(sl,buff,count,error);
 805         else
 806                 slip_unesc(sl,buff,count,error);
 807 #endif          
 808   } while(1);
 809   
 810 }
 811 
 812 
 813 /*
 814  * Open the high-level part of the SLIP channel.  
 815  * This function is called by the TTY module when the
 816  * SLIP line discipline is called for.  Because we are
 817  * sure the tty line exists, we only have to link it to
 818  * a free SLIP channel...
 819  */
 820 static int
 821 slip_open(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 822 {
 823   struct slip *sl;
 824 
 825   /* First make sure we're not already connected. */
 826   if ((sl = sl_find(tty)) != NULL) {
 827         DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
 828                                         tty->line, sl->dev->name));
 829         return(-EEXIST);
 830   }
 831 
 832   /* OK.  Find a free SLIP channel to use. */
 833   if ((sl = sl_alloc()) == NULL) {
 834         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
 835                                                 tty->line));
 836         return(-ENFILE);
 837   }
 838   sl->tty = tty;
 839   tty_read_flush(tty);
 840   tty_write_flush(tty);
 841 
 842   /* Perform the low-level SLIP initialization. */
 843   (void) sl_open(sl->dev);
 844   DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
 845                                 tty->line, sl->dev->name));
 846 
 847   /* Done.  We have linked the TTY line to a channel. */
 848   return(sl->line);
 849 }
 850 
 851 
 852 /*
 853  * Close down a SLIP channel.
 854  * This means flushing out any pending queues, and then restoring the
 855  * TTY line discipline to what it was before it got hooked to SLIP
 856  * (which usually is TTY again).
 857  */
 858 static void
 859 slip_close(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 860 {
 861   struct slip *sl;
 862 
 863   /* First make sure we're connected. */
 864   if ((sl = sl_find(tty)) == NULL) {
 865         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
 866         return;
 867   }
 868 
 869   (void) dev_close(sl->dev);
 870   DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
 871                                         tty->line, sl->dev->name));
 872 }
 873 
 874  
 875  /************************************************************************
 876   *                     STANDARD SLIP ENCAPSULATION                     *
 877   ************************************************************************
 878   *
 879   */
 880  
 881  int
 882  slip_esc(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 883  {
 884      int count = 0;
 885  
 886      /*
 887       * Send an initial END character to flush out any
 888       * data that may have accumulated in the receiver
 889       * due to line noise.
 890       */
 891  
 892      d[count++] = END;
 893  
 894      /*
 895       * For each byte in the packet, send the appropriate
 896       * character sequence, according to the SLIP protocol.
 897       */
 898  
 899      while(len-- > 0) {
 900         switch(*s) {
 901         case END:
 902             d[count++] = ESC;
 903             d[count++] = ESC_END;
 904             break;
 905         case ESC:
 906             d[count++] = ESC;
 907             d[count++] = ESC_ESC;
 908             break;
 909         default:
 910             d[count++] = *s;
 911         }
 912         ++s;
 913      }
 914      d[count++] = END;
 915      return(count);
 916  }
 917  
 918  void
 919  slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
 920  {
 921      int i;
 922  
 923      for (i = 0; i < count; ++i, ++s) {
 924         switch(*s) {
 925         case ESC:
 926             sl->flags |= SLF_ESCAPE;
 927             break;
 928         case ESC_ESC:
 929             if (sl->flags & SLF_ESCAPE)
 930                 sl_enqueue(sl, ESC);
 931             else
 932                 sl_enqueue(sl, *s);
 933             sl->flags &= ~SLF_ESCAPE;
 934             break;
 935         case ESC_END:
 936             if (sl->flags & SLF_ESCAPE)
 937                 sl_enqueue(sl, END);
 938             else
 939                 sl_enqueue(sl, *s);
 940             sl->flags &= ~SLF_ESCAPE;
 941             break;
 942         case END:
 943             if (sl->rcount > 2) 
 944                 sl_bump(sl);
 945             sl_dequeue(sl, sl->rcount);
 946             sl->rcount = 0;
 947             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
 948             break;
 949         default:
 950             sl_enqueue(sl, *s);
 951             sl->flags &= ~SLF_ESCAPE;
 952         }
 953      }
 954      if (error)
 955         sl->flags |= SLF_ERROR;
 956  }
 957  
 958  /************************************************************************
 959   *                      6 BIT SLIP ENCAPSULATION                       *
 960   ************************************************************************
 961   *
 962   */
 963  
 964  int
 965  slip_esc6(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 966  {
 967      int count = 0;
 968      int i;
 969      unsigned short v = 0;
 970      short bits = 0;
 971  
 972      /*
 973       * Send an initial END character to flush out any
 974       * data that may have accumulated in the receiver
 975       * due to line noise.
 976       */
 977  
 978      d[count++] = 0x70;
 979  
 980      /*
 981       * Encode the packet into printable ascii characters
 982       */
 983  
 984      for (i = 0; i < len; ++i) {
 985         v = (v << 8) | s[i];
 986         bits += 8;
 987         while (bits >= 6) {
 988             unsigned char c;
 989  
 990             bits -= 6;
 991             c = 0x30 + ((v >> bits) & 0x3F);
 992             d[count++] = c;
 993         }
 994      }
 995      if (bits) {
 996         unsigned char c;
 997  
 998         c = 0x30 + ((v << (6 - bits)) & 0x3F);
 999         d[count++] = c;
1000      }
1001      d[count++] = 0x70;
1002      return(count);
1003  }
1004  
1005  void
1006  slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
1007  {
1008      int i;
1009      unsigned char c;
1010  
1011      for (i = 0; i < count; ++i, ++s) {
1012         if (*s == 0x70) {
1013             if (sl->rcount > 8) {       /* XXX must be 2 for compressed slip */
1014  #ifdef NOTDEF
1015                 printk("rbuff %02x %02x %02x %02x\n",
1016                     sl->rbuff[0],
1017                     sl->rbuff[1],
1018                     sl->rbuff[2],
1019                     sl->rbuff[3]
1020                 );
1021  #endif
1022                 sl_bump(sl);
1023             }
1024             sl_dequeue(sl, sl->rcount);
1025             sl->rcount = 0;
1026             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
1027             sl->xbits = 0;
1028         } else if (*s >= 0x30 && *s < 0x70) {
1029             sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
1030             sl->xbits += 6;
1031             if (sl->xbits >= 8) {
1032                 sl->xbits -= 8;
1033                 c = (unsigned char)(sl->xdata >> sl->xbits);
1034                 sl_enqueue(sl, c);
1035             }
1036  
1037         }
1038      }
1039      if (error)
1040         sl->flags |= SLF_ERROR;
1041  }
1042 
1043 
1044 #ifdef CONFIG_AX25
1045 
1046 int sl_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
1047 {
1048         int err=verify_area(VERIFY_READ,addr,7);
1049         if(err)
1050                 return err;
1051         memcpy_fromfs(dev->dev_addr,addr,7);    /* addr is an AX.25 shifted ASCII mac address */
1052         return 0;
1053 }
1054 #endif
1055 
1056 
1057 /* Perform I/O control on an active SLIP channel. */
1058 static int
1059 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1060 {
1061   struct slip *sl;
1062   int err;
1063 
1064   /* First make sure we're connected. */
1065   if ((sl = sl_find(tty)) == NULL) {
1066         DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
1067         return(-EINVAL);
1068   }
1069 
1070   DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
1071   switch(cmd) {
1072         case SIOCGIFNAME:
1073                 err=verify_area(VERIFY_WRITE, arg, 16);
1074                 if(err)
1075                         return -err;
1076                 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
1077                 return(0);
1078         case SIOCGIFENCAP:
1079                 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
1080                 put_fs_long(sl->mode,(long *)arg);
1081                 return(0);
1082         case SIOCSIFENCAP:
1083                 err=verify_area(VERIFY_READ,arg,sizeof(long));
1084                 sl->mode=get_fs_long((long *)arg);
1085 #ifdef CONFIG_AX25              
1086                 if(sl->mode & SL_MODE_AX25)
1087                 {
1088                         sl->dev->addr_len=7;    /* sizeof an AX.25 addr */
1089                         sl->dev->hard_header_len=17;    /* We don't do digipeaters */
1090                         sl->dev->type=3;                /* AF_AX25 not an AF_INET device */
1091                 }
1092                 else
1093                 {
1094                         sl->dev->addr_len=0;    /* No mac addr in slip mode */
1095                         sl->dev->hard_header_len=0;
1096                         sl->dev->type=0;
1097                 }
1098 #endif          
1099                 return(0);
1100         case SIOCSIFHWADDR:
1101 #ifdef CONFIG_AX25      
1102                 return sl_set_mac_address(sl->dev,arg);
1103 #endif
1104         default:
1105                 return(-EINVAL);
1106   }
1107   return(-EINVAL);
1108 }
1109 
1110 
1111 /* Initialize the SLIP driver.  Called by DDI. */
1112 int
1113 slip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1114 {
1115   struct slip *sl;
1116   int i;
1117 #ifdef CONFIG_AX25  
1118   static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1119   static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1120 #endif
1121 
1122   sl = &sl_ctrl[dev->base_addr];
1123 
1124   if (already++ == 0) {
1125         printk("SLIP: version %s (%d channels)\n",
1126                                 SLIP_VERSION, SL_NRUNIT);
1127         printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1128 #ifdef CONFIG_AX25
1129         printk("AX25: KISS encapsulation enabled\n");
1130 #endif  
1131         /* Fill in our LDISC request block. */
1132         sl_ldisc.flags  = 0;
1133         sl_ldisc.open   = slip_open;
1134         sl_ldisc.close  = slip_close;
1135         sl_ldisc.read   = NULL;
1136         sl_ldisc.write  = NULL;
1137         sl_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
1138                                    unsigned int, unsigned long)) slip_ioctl;
1139         sl_ldisc.handler = slip_recv;
1140         if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
1141                 printk("ERROR: %d\n", i);
1142   }
1143 
1144   /* Set up the "SLIP Control Block". */
1145   sl_initialize(sl, dev);
1146 
1147   /* Clear all statistics. */
1148   sl->rcount            = 0;                    /* SLIP receiver count  */
1149   sl->rpacket           = 0;                    /* #frames received     */
1150   sl->roverrun          = 0;                    /* "overrun" counter    */
1151   sl->spacket           = 0;                    /* #frames sent out     */
1152   sl->sbusy             = 0;                    /* "xmit busy" counter  */
1153   sl->errors            = 0;                    /* not used at present  */
1154 
1155   /* Finish setting up the DEVICE info. */
1156   dev->mtu              = SL_MTU;
1157   dev->hard_start_xmit  = sl_xmit;
1158   dev->open             = sl_open;
1159   dev->stop             = sl_close;
1160   dev->hard_header      = sl_header;
1161   dev->add_arp          = sl_add_arp;
1162   dev->type_trans       = sl_type_trans;
1163 #ifdef HAVE_SET_MAC_ADDR
1164 #ifdef CONFIG_AX25
1165   dev->set_mac_address  = sl_set_mac_address;
1166 #endif
1167 #endif
1168   dev->hard_header_len  = 0;
1169   dev->addr_len         = 0;
1170   dev->type             = 0;
1171 #ifdef CONFIG_AX25  
1172   memcpy(dev->broadcast,ax25_bcast,7);          /* Only activated in AX.25 mode */
1173   memcpy(dev->dev_addr,ax25_test,7);            /*    ""      ""       ""    "" */
1174 #endif  
1175   dev->queue_xmit       = dev_queue_xmit;
1176   dev->rebuild_header   = sl_rebuild_header;
1177   for (i = 0; i < DEV_NUMBUFFS; i++)
1178                 dev->buffs[i] = NULL;
1179 
1180   /* New-style flags. */
1181   dev->flags            = 0;
1182   dev->family           = AF_INET;
1183   dev->pa_addr          = 0;
1184   dev->pa_brdaddr       = 0;
1185   dev->pa_mask          = 0;
1186   dev->pa_alen          = sizeof(unsigned long);
1187 
1188   return(0);
1189 }

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